Back to blog
    Cursor + MCP + 微調模型:代碼編輯器內的領域 AI
    cursormcplocal-modelcode-editorfine-tuningsegment:vibecoder

    Cursor + MCP + 微調模型:代碼編輯器內的領域 AI

    Cursor 支持 MCP 伺服器。將您的微調領域模型連接到 Cursor,直接在編輯器內獲得專業 AI 能力——在您的代碼庫上訓練的代碼生成、您風格的文檔、領域特定的自動補全。

    EErtas Team·

    Cursor 是大多數 vibe coder 每天使用的 AI 原生代碼編輯器。它支持 MCP 伺服器——這意味著您可以將微調的模型連接到 Cursor,直接從您的編碼環境調用領域特定的 AI 能力,無需切換上下文。

    用途:在您的代碼庫風格上訓練的代碼文檔模型、在您的模式上訓練的領域特定代碼生成器、以您產品聲音書寫的內容模型,這一切都可作為 Cursor 工具訪問。

    為什麼領域模型在 Cursor 中優於通用模型

    Cursor 的內建 AI(Claude Sonnet、GPT-4o)在一般編碼任務上表現出色。它在以下方面存在困難:

    您代碼庫的特定模式: 通用 AI 不知道您團隊的命名慣例、架構決策或您選擇標準化的庫。它會生成語法正確但不符合您代碼庫的代碼。

    您的文檔風格: 通用 AI 寫通用文檔。在您現有文檔上訓練的模型,寫出聽起來像您其他文檔的文檔。

    領域特定邏輯: 如果您的應用程式處理複雜的業務邏輯(稅務計算、醫療保健工作流、法律文件處理),通用 AI 做出有根據的猜測。在您的領域邏輯上訓練的模型生成正確的業務邏輯。

    在您的代碼庫和領域上微調的模型,產生您團隊中的資深開發人員認為合適的輸出。

    為 Cursor 設置 MCP 伺服器

    Cursor 從 ~/.cursor/mcp.json(或項目級別的 .cursor/mcp.json)讀取 MCP 配置。

    步驟 1:構建以代碼為重心的 MCP 伺服器

    // cursor-domain-mcp/server.mjs
    import { Server } from '@modelcontextprotocol/sdk/server/index.js';
    import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
    import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
    
    const OLLAMA_URL = 'http://localhost:11434/api/chat';
    const MODEL = 'my-codebase-model';
    
    const server = new Server(
      { name: 'codebase-assistant', version: '1.0.0' },
      { capabilities: { tools: {} } }
    );
    
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: 'generate_code',
          description: 'Generate code following the project\'s specific patterns, naming conventions, and library choices. Use for creating new functions, components, or modules that should match existing code style.',
          inputSchema: {
            type: 'object',
            properties: {
              description: { type: 'string', description: 'What code to generate' },
              file_context: { type: 'string', description: 'Relevant existing code from the codebase for context' },
              language: { type: 'string', description: 'Programming language or framework' }
            },
            required: ['description']
          }
        },
        {
          name: 'write_documentation',
          description: 'Write documentation in the project\'s established style — same format, same level of detail, same terminology. Use for JSDoc, README sections, or inline comments.',
          inputSchema: {
            type: 'object',
            properties: {
              code: { type: 'string', description: 'The code to document' },
              doc_type: { type: 'string', description: 'jsdoc, readme, comment, or api-reference' }
            },
            required: ['code']
          }
        },
        {
          name: 'domain_query',
          description: 'Answer domain-specific questions about the business logic, industry rules, or specialized requirements that the codebase implements.',
          inputSchema: {
            type: 'object',
            properties: {
              question: { type: 'string', description: 'The domain question to answer' }
            },
            required: ['question']
          }
        }
      ]
    }));
    
    server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;
    
      let prompt;
      if (name === 'generate_code') {
        prompt = `Generate code for: ${args.description}
    ${args.file_context ? `\nExisting code context:\n${args.file_context}` : ''}
    ${args.language ? `\nLanguage/Framework: ${args.language}` : ''}`;
      } else if (name === 'write_documentation') {
        prompt = `Write ${args.doc_type || 'documentation'} for this code:\n\n${args.code}`;
      } else if (name === 'domain_query') {
        prompt = args.question;
      } else {
        throw new Error(`Unknown tool: ${name}`);
      }
    
      const response = await fetch(OLLAMA_URL, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          model: MODEL,
          messages: [{ role: 'user', content: prompt }],
          stream: false
        })
      });
    
      const data = await response.json();
      return { content: [{ type: 'text', text: data.message.content }] };
    });
    
    const transport = new StdioServerTransport();
    await server.connect(transport);

    步驟 2:添加到 Cursor MCP 配置

    創建或編輯 ~/.cursor/mcp.json

    {
      "mcpServers": {
        "codebase-assistant": {
          "command": "node",
          "args": ["/absolute/path/to/cursor-domain-mcp/server.mjs"]
        }
      }
    }

    重新啟動 Cursor。工具出現在 Cursor 聊天面板中。

    訓練適合 Cursor 集成的正確模型

    對於代碼生成: 訓練資料應是來自您自己代碼庫的(任務描述,正確實現)對。從您的 git 歷史中提取:提交消息 + diff = (任務,實現)對。

    對於文檔: 訓練資料:現有的已記錄函數——(代碼塊,對應的文檔字符串/README 部分)對。

    對於領域知識: 訓練資料:內部 Wiki、架構決策記錄、領域詞彙表、來自 Slack 或 Confluence 的現有問答。轉換為(問題,答案)格式。

    在 Cursor Chat 中使用模型

    在 Cursor 的聊天面板(Cmd+L / Ctrl+L)中,您可以調用您的工具:

    「使用 codebase-assistant 為 [描述] 生成一個新的 API 端點」

    或讓 Cursor 在識別到模式匹配您工具描述時自動調用它。您的工具描述越具體,Cursor 就越能準確地將其路由到您的工具而不是其內建模型。

    獨立開發者的實際工作流:

    1. 打開 Cursor Chat
    2. 粘貼您想要實現的簽名/界面
    3. Cursor 調用 generate_code 工具 → 您的微調模型以您的風格生成實現
    4. Cursor 顯示生成的代碼並解釋它
    5. 應用到文件

    模型不替代 Cursor 的內建智能——它用您特定代碼庫的知識增強它。


    Ship AI that runs on your users' devices.

    Ertas early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    延伸閱讀

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Keep reading