在 Cursor 中配置自定义 MCP 服务器:打造你的 AI 开发工具链

引言

随着 AI 编程助手的普及,开发者们越来越希望能够定制化自己的开发环境。Cursor 作为一款强大的 AI 编程编辑器,提供了 Model Context Protocol (MCP) 支持,新版本的MCP配置采用json文件配置方式,与老版本配置方式不同。

什么是 MCP?

Model Context Protocol (MCP) 是一种协议,用于连接本地或远程的 AI 模型和服务。它通过标准输入输出(stdio)进行通信,使用 JSON-RPC 2.0 协议格式,让开发者能够扩展 Cursor 的功能,集成自己的 AI 工具。

MCP 的核心优势在于:

  • 标准化协议:统一的 JSON-RPC 2.0 格式
  • 本地集成:无需额外的网络服务
  • 灵活扩展:支持自定义工具和功能
  • 安全可靠:本地运行,数据不外泄

Cursor MCP 配置基础

配置文件位置

Cursor 的 MCP 配置存储在用户设置中,通常位于:

  • Windows: %APPDATA%\.Cursor\mcp.json

配置结构

MCP 配置采用 JSON 格式,基本结构如下:

{
  "mcpServers": {
    "server-name": {
      "command": "python",
      "args": ["script.py"],
      "cwd": "/path/to/script/directory"
    }
  }
}

配置参数说明

  • mcpServers: MCP 服务器配置的根节点
  • server-name: 服务器名称,用于标识不同的 MCP 服务
  • command: 启动命令,通常是 pythonnode
  • args: 命令行参数数组,指定要执行的脚本
  • cwd: 工作目录,脚本文件所在的绝对路径

实战:配置 AI Commit Message 生成器

让我们以一个实用的 AI Commit Message 生成器为例,展示完整的 MCP 配置过程。

项目结构

AI-commit-msg-MCP/
├── cursor_mcp_server_v2.py    # MCP 服务器脚本
├── ai_commit.py               # AI 生成逻辑
├── requirements.txt           # Python 依赖
└── README.md                 # 项目说明

1. 创建 MCP 服务器脚本

首先,我们需要创建一个符合 MCP 协议的服务器脚本:

#!/usr/bin/env python3
"""
Cursor MCP Server - AI Commit Message 生成器
"""

import json
import sys
import os
import git
from typing import Dict, Any, Optional
from ai_commit import AICommitGenerator

class CursorMCPServer:
    def __init__(self):
        self.ai_generator = AICommitGenerator()
        self.request_id = 0
        self.initialized = False
    
    def send_response(self, result: Any = None, error: Any = None):
        """发送响应给Cursor"""
        response = {
            "jsonrpc": "2.0",
            "id": self.request_id
        }
        
        if error:
            response["error"] = error
        else:
            response["result"] = result
        
        print(json.dumps(response), flush=True)
    
    def handle_initialize(self, params: Dict[str, Any]):
        """处理初始化请求"""
        self.initialized = True
        self.send_response({
            "protocolVersion": "2024-11-05",
            "capabilities": {
                "tools": {}
            },
            "serverInfo": {
                "name": "ai-commit-mcp",
                "version": "1.0.0"
            }
        })
    
    def handle_tools_list(self, params: Dict[str, Any]):
        """处理工具列表请求"""
        if not self.initialized:
            self.send_response(error={
                "code": -32002,
                "message": "Server not initialized"
            })
            return
        
        tools = [
            {
                "name": "generate_commit_message",
                "description": "Generate a commit message based on git diff",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "diff": {
                            "type": "string",
                            "description": "Git diff content (optional)"
                        },
                        "repo_path": {
                            "type": "string",
                            "description": "Repository path",
                            "default": "."
                        }
                    }
                }
            },
            {
                "name": "get_commit_prompt",
                "description": "Get commit message prompt data for Cursor AI",
                "inputSchema": {
                    "type": "object",
                    "properties": {}
                }
            },
            {
                "name": "get_staged_diff",
                "description": "Get current git staged diff",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "repo_path": {
                            "type": "string",
                            "description": "Repository path",
                            "default": "."
                        }
                    }
                }
            }
        ]
        
        self.send_response({"tools": tools})
    
    def handle_tools_call(self, params: Dict[str, Any]):
        """处理工具调用请求"""
        if not self.initialized:
            self.send_response(error={
                "code": -32002,
                "message": "Server not initialized"
            })
            return
        
        tool_name = params.get("name")
        tool_args = params.get("arguments", {})
        
        try:
            if tool_name == "generate_commit_message":
                # 处理生成 commit message 的逻辑
                diff = tool_args.get("diff", "")
                repo_path = tool_args.get("repo_path", ".")
                
                if diff:
                    prompt_data = self.ai_generator.get_commit_prompt_data(diff, repo_path)
                else:
                    diff = self.ai_generator.get_staged_diff(repo_path)
                    prompt_data = self.ai_generator.get_commit_prompt_data(diff, repo_path)
                
                self.send_response({
                    "content": [
                        {
                            "type": "text",
                            "text": f"Commit message prompt generated successfully.\n\n**Prompt for Cursor AI:**\n\n{prompt_data['prompt']}"
                        }
                    ]
                })
                
            elif tool_name == "get_commit_prompt":
                # 获取当前 staged changes 的提示词
                diff = self.ai_generator.get_staged_diff()
                prompt_data = self.ai_generator.get_commit_prompt_data(diff)
                
                self.send_response({
                    "content": [
                        {
                            "type": "text",
                            "text": f"Commit prompt data retrieved.\n\n**Prompt for Cursor AI:**\n\n{prompt_data['prompt']}"
                        }
                    ]
                })
                
            elif tool_name == "get_staged_diff":
                # 获取当前 git staged diff
                repo_path = tool_args.get("repo_path", ".")
                diff = self.ai_generator.get_staged_diff(repo_path)
                
                if diff:
                    self.send_response({
                        "content": [
                            {
                                "type": "text",
                                "text": f"Current staged diff:\n\n```diff\n{diff}\n```"
                            }
                        ]
                    })
                else:
                    self.send_response({
                        "content": [
                            {
                                "type": "text",
                                "text": "No staged changes found."
                            }
                        ]
                    })
            else:
                self.send_response(error={
                    "code": -32601,
                    "message": f"Tool not found: {tool_name}"
                })
                
        except Exception as e:
            self.send_response(error={
                "code": -32603,
                "message": f"Error calling tool {tool_name}: {str(e)}"
            })
    
    def handle_request(self, request: Dict[str, Any]):
        """处理请求"""
        method = request.get("method")
        params = request.get("params", {})
        self.request_id = request.get("id", 0)
        
        if method == "initialize":
            self.handle_initialize(params)
        elif method == "tools/list":
            self.handle_tools_list(params)
        elif method == "tools/call":
            self.handle_tools_call(params)
        else:
            self.send_response(error={
                "code": -32601,
                "message": f"Method not found: {method}"
            })
    
    def run(self):
        """运行MCP服务器"""
        print("AI Commit MCP Server started", file=sys.stderr)
        
        for line in sys.stdin:
            try:
                request = json.loads(line.strip())
                self.handle_request(request)
            except json.JSONDecodeError as e:
                print(f"Invalid JSON: {e}", file=sys.stderr)
                continue
            except Exception as e:
                print(f"Error processing request: {e}", file=sys.stderr)
                continue

if __name__ == "__main__":
    server = CursorMCPServer()
    server.run()

2. Cursor MCP 配置

在 Cursor 的设置中添加以下配置:

{
  "mcpServers": {
    "ai-commit-mcp": {
      "command": "python",
      "args": ["cursor_mcp_server_v2.py"],
      "cwd": "D:/myproject/AI-commit-msg-MCP"
    }
  }
}

3. 配置说明

  • ai-commit-mcp: 服务器名称,可以自定义
  • command: 使用 Python 解释器
  • args: 指定要执行的脚本文件
  • cwd: 脚本文件所在的绝对路径(注意使用正斜杠)

4. 重启 Cursor

配置完成后,必须重启 Cursor 才能生效。

使用自定义 MCP 工具

验证配置

重启 Cursor 后,你应该能在工具面板中看到 3 个新工具:

  • generate_commit_message
  • get_commit_prompt
  • get_staged_diff

在聊天中使用

在 Cursor 的 AI 聊天中,你可以直接使用这些工具:

请帮我生成一个 commit message

AI 会自动调用相应的工具来获取 git diff 并生成提示词。

手动调用工具

你也可以明确指定要使用的工具:

请使用 get_commit_prompt 工具获取当前的 commit 提示词

高级配置技巧

1. 多服务器配置

你可以配置多个 MCP 服务器:

{
  "mcpServers": {
    "ai-commit-mcp": {
      "command": "python",
      "args": ["cursor_mcp_server_v2.py"],
      "cwd": "D:/myproject/AI-commit-msg-MCP"
    },
    "code-analyzer": {
      "command": "node",
      "args": ["analyzer.js"],
      "cwd": "C:/tools/code-analyzer"
    },
    "test-generator": {
      "command": "python",
      "args": ["test_gen.py"],
      "cwd": "/home/user/test-tools"
    }
  }
}

2. 环境变量配置

如果需要传递环境变量,可以添加 env 配置:

{
  "mcpServers": {
    "ai-commit-mcp": {
      "command": "python",
      "args": ["cursor_mcp_server_v2.py"],
      "cwd": "D:/myproject/AI-commit-msg-MCP",
      "env": {
        "OPENAI_API_KEY": "your-api-key",
        "DEBUG": "true"
      }
    }
  }
}

3. 不同操作系统的路径配置

为了跨平台兼容,建议使用正斜杠:

{
  "mcpServers": {
    "ai-commit-mcp": {
      "command": "python",
      "args": ["cursor_mcp_server_v2.py"],
      "cwd": "D:/myproject/AI-commit-msg-MCP"
    }
  }
}

故障排除

常见问题

  1. 工具显示为 0 个

    • 检查配置文件路径是否正确
    • 确保脚本文件存在且有执行权限
    • 重启 Cursor
  2. 工具调用失败

    • 检查 Python 环境是否正确
    • 查看 Cursor 输出面板的错误信息
    • 确保依赖包已安装
  3. 路径问题

    • 使用绝对路径
    • 避免路径中包含中文字符
    • 使用正斜杠作为路径分隔符

调试技巧

  1. 查看 Cursor 输出面板

    • 打开 Cursor 的输出面板
    • 查看 MCP 相关的日志信息
  2. 测试 MCP 服务器

    • 创建测试脚本验证服务器功能
    • 确保 JSON-RPC 协议实现正确
  3. 检查文件权限

    • 确保脚本文件可读可执行
    • 检查工作目录权限

最佳实践

1. 项目组织

  • 将 MCP 服务器脚本放在独立的目录中
  • 使用版本控制管理配置
  • 创建详细的文档说明

2. 错误处理

  • 实现完善的错误处理机制
  • 提供有意义的错误信息
  • 记录详细的日志信息

3. 性能优化

  • 避免在工具调用中执行耗时操作
  • 使用异步处理处理复杂任务
  • 合理缓存计算结果

4. 安全性

  • 验证输入参数
  • 避免执行危险操作
  • 保护敏感信息

扩展思路

1. 集成更多 AI 服务

你可以基于 MCP 协议集成各种 AI 服务:

  • 代码审查工具
  • 文档生成器
  • 测试用例生成器
  • 性能分析工具

2. 创建工具链

将多个 MCP 服务器组合成完整的开发工具链:

  • 代码分析 → 测试生成 → 文档更新
  • 提交信息生成 → 代码审查 → 部署

3. 社区贡献

将你的 MCP 工具开源,供其他开发者使用:

  • 发布到 GitHub
  • 创建详细的安装文档
  • 提供示例和教程

总结

Cursor 的 MCP 功能为开发者提供了强大的扩展能力,让我们能够定制化自己的 AI 开发环境。通过本文的介绍,你应该已经了解了如何配置和使用自定义 MCP 服务器。

关键要点:

  1. MCP 配置必须重启 Cursor 生效
  2. 使用绝对路径避免路径问题
  3. 实现正确的 JSON-RPC 2.0 协议
  4. 提供完善的错误处理和日志记录

随着 AI 编程助手的发展,MCP 协议将成为连接各种 AI 工具的重要桥梁。掌握 MCP 配置技能,将让你在 AI 编程时代拥有更强的竞争力。

开始你的 MCP 之旅,打造属于你的 AI 开发工具链吧!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐