# Directory Structure
```
├── .gitignore
├── package.json
├── README.md
├── src
│ └── index.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
# Dependencies
node_modules/
package-lock.json
# Build output
dist/
# IDE and editor files
.vscode/
.DS_Store
# Environment variables
.env
.env.*
# Logs
*.log
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
# Cursor MCP Server
This repository contains a Model Context Protocol (MCP) server implementation that provides a tool for searching git-spice documentation within Cursor IDE.
## Features
- Integration with Cursor IDE through MCP protocol
- Real-time git-spice documentation search
- Simple and efficient documentation parsing
## Prerequisites
- Node.js (v16 or higher)
- Cursor IDE
- npm or yarn package manager
## Installation
1. Clone this repository:
```bash
git clone <repository-url>
cd <repository-name>
```
2. Install dependencies:
```bash
npm install
# or
yarn install
```
3. Build the project:
```bash
npm run build
# or
yarn build
```
## Configuration
### Server Configuration
The server is pre-configured with the following capabilities:
- Tools capability
- Resources capability
- Prompts capability
### Cursor IDE Configuration
1. Open Cursor IDE settings:
- On macOS: `Cmd + ,`
- On Windows/Linux: `Ctrl + ,`
2. Navigate to the "Extensions" section
3. Find the MCP Server settings and add a new server configuration:
```json
{
"name": "Git Spice MCP Server",
"command": "node",
"args": ["dist/index.js"],
"cwd": "/path/to/your/project"
}
```
4. Save the settings and refresh the MCP
## Usage
When using Cursor in agent mode, the MCP server will be automatically detected and the git-spice documentation search tool will be available. The agent will prompt you to use the tool when relevant to your queries.
## Project Structure
- `src/index.ts`: Main server implementation
- `src/`: Source code directory
- `dist/`: Compiled output directory
## Acknowledgments
- [Model Context Protocol](https://github.com/modelcontextprotocol)
- [git-spice](https://github.com/abhinav/git-spice)
- [Cursor IDE](https://cursor.sh)
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
{
"name": "test-mcp",
"version": "1.0.0",
"type": "module",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "tsc -w"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.8.0",
"@types/node": "^20.0.0",
"@types/node-fetch": "^2.6.12",
"node-fetch": "^3.3.2",
"typescript": "^5.0.0",
"zod": "^3.24.2"
},
"devDependencies": {
"ts-node": "^10.9.2"
}
}
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
import fetch from 'node-fetch';
// Function to fetch and parse git-spice documentation
async function fetchGitSpiceDocs(): Promise<string> {
try {
const response = await fetch('https://abhinav.github.io/git-spice/cli/reference/');
const html = await response.text();
// Basic HTML parsing to extract text content
// Remove HTML tags and decode HTML entities
const textContent = html
.replace(/<[^>]*>/g, '') // Remove HTML tags
.replace(/&[^;]+;/g, '') // Remove HTML entities
.replace(/\s+/g, ' ') // Normalize whitespace
.trim();
return textContent;
} catch (error) {
console.error('Failed to fetch git-spice documentation:', error);
return 'Error: Failed to fetch documentation. Please try again later.';
}
}
async function startServer() {
try {
// Create an MCP server with explicit capabilities
const server = new McpServer({
name: "Git spice help MCP Server",
version: "1.0.0",
capabilities: {
tools: {}, // Enable tools capability
resources: {}, // Enable resources capability
prompts: {} // Enable prompts capability
}
});
// Add a git-spice documentation search tool
server.tool("git_spice_help",
{ query: z.string() },
async ({ query }) => {
console.log('Git Spice help search called with query:', query);
// Fetch and search documentation
const docs = await fetchGitSpiceDocs();
const lines = docs.split('\n');
// Search for matches (case-insensitive)
const matches = lines
.filter((line: string) => line.toLowerCase().includes(query.toLowerCase()))
.join('\n');
const result = matches.length > 0
? matches
: `No matches found for "${query}" in git-spice documentation.`;
return {
content: [{ type: "text", text: result }]
};
}
);
// Create and connect the transport
const transport = new StdioServerTransport();
console.log('Starting MCP Server...');
await server.connect(transport);
console.log('MCP Server connected and ready');
} catch (error) {
console.error('Failed to start MCP server:', error);
process.exit(1);
}
}
// Handle uncaught errors
process.on('uncaughtException', (error) => {
console.error('Uncaught exception:', error);
});
process.on('unhandledRejection', (error) => {
console.error('Unhandled rejection:', error);
});
// Start the server
startServer();
```