本文最后更新于 2025-03-21,文章内容可能已经过时。

不要有AI能解决一切的错觉,放弃幻想

经过反复测试各种方式,小白方式的提问,细节方式的提问等等
明确告知你AI并不能通过短短几句话,将MCP服务器给你搭建出来,使用AI的技巧是告知它足够详细的步骤,而且由于技术新旧的问题,它自己的知识库并不一定能正确引用,需要你自行去喂数据

那该怎么做?

拆解需求,逐步喂文档,让它去操作,慢慢来,不要急

使用AI整理需求

首先你需要分析一下一个dify与mcp服务器的组成是什么?(可以通过AI去进行思路整理,按照流程走,就非常舒畅啦)


简要整理想法,让AI去润色

```txt

我需要使用Model Context Protocol协议,构建一个Model Context Protocol服务器,stdio本地运行。

https://github.com/modelcontextprotocol/typescript-sdk/blob/main/README.md

这是mcp ts的sdk,

主要目的用来连接cursor与dify,dify是开源的大语言模型 (LLM) 应用开发平台,可以集成多家大模型服务搭建工作流,知识库等,dify具有丰富的api服务,可以将大部分功能以api形式,让其他服务进行调用,

我可以通过mcp让cursor使用dify的知识库,查询自己整理的知识

dify的话是使用http请求的api,post参数返回信息等等

上面是我所需要的散碎的步骤,通过cusor逐步让AI去操作(期间根据所需补充相对技术的参数)

我需要你帮我整理一个简单明确的流程待办计划

```

请帮我润色一下这句话,要求逻辑清晰

AI润色后,根据需求优化

我计划利用 Model Context Protocol (MCP) 和其 TypeScript SDK,开发一个通过标准输入输出 (stdio) 通信的本地 MCP 服务器。该服务器将连接 Cursor 编辑器和 Dify 平台。Dify 是一个开源 LLM 应用开发平台,我用它来构建知识库,并计划通过其提供的 HTTP POST API 来进行知识查询。整个流程的目的是让 Cursor 编辑器通过 MCP 协议,间接调用 Dify 的 API,实现对我 Dify 知识库的查询。我将通过 Cursor 指导 AI 逐步实现这一流程,并在过程中按需补充必要的技术细节(如 API 密钥、端点等)。

请参考这个链接下的部分流程:https://www.5ee.net/archives/tmXJAgWz
请您协助我整理出一个结构清晰的开发流程和待办事项列表,请注意我需要的是待办事项列表,而不是具体实现代码,我只需要简单清晰明了的结构列表

AI给的结果

我使用的是deepseek r1 来梳理待办流程

阶段 1:基础环境准备

  1. 安装依赖

    • 安装 Node.js 环境(≥16.x)

    • 初始化 TypeScript 项目

    • 安装 MCP TypeScript SDK 和相关依赖(如 @mcp/sdk

    • 配置 TypeScript 编译器和开发调试工具(如 ts-node, nodemon

  2. 获取 API 凭证

    • 从 Dify 控制台获取 API 密钥(DIFY_API_KEY

    • 记录 Dify 知识库查询接口的 HTTP 端点(如 https://api.dify.ai/v1/query


阶段 2:MCP 服务器核心开发

  1. 协议通信层

    • 实现标准输入输出(stdio)的监听与响应

    • 根据 MCP 协议定义消息解析器(JSON-RPC 格式)

    • 处理 Cursor 编辑器发送的请求消息(mcp.request

  2. Dify 服务集成

    • 封装 HTTP POST 客户端(Axios 或 fetch

    • 实现 Dify API 请求参数构造:

      • Headers:Authorization: Bearer {DIFY_API_KEY}

      • Body:包含用户查询内容(如 query: string

    • 处理 Dify 响应并提取知识库结果

  3. 逻辑桥接

    • 将 Cursor 请求映射为 Dify API 输入

    • 将 Dify 响应包装为 MCP 协议格式(mcp.response

    • 处理异常流程(网络错误、协议格式错误等)


阶段 3:测试与调试

  1. 单元测试

    • 测试 MCP 消息解析逻辑

    • 测试 Dify API 独立调用(用 mock 数据验证)

    • 测试错误处理(如 API 密钥失效、超时)

  2. 集成测试

    • 启动本地 MCP 服务器并连接 Cursor

    • 通过 Cursor 发送模拟查询请求

    • 验证 Dify 返回结果在 Cursor 的显示格式

  3. 调试优化

    • 添加日志模块(记录请求/响应、错误信息)

    • 验证并发请求处理能力(可选)

    • 性能调优(如缓存高频查询结果)


阶段 4:部署与维护

  1. 本地化运行

    • 编写启动脚本(如 start-server.sh

    • 配置环境变量(API 密钥、Dify 端点)

    • 生成可执行文件(可选 pkg 打包)

  2. 安全加固

    • 加密存储 API 密钥(如使用 dotenv + .env 文件)

    • 限制本地端口访问权限(如仅允许 localhost)

  3. 文档补充

    • 编写 MCP 服务器配置说明

    • 记录 Cursor 连接步骤(如编辑器插件配置)


关键依赖项检查清单

  • 确认 MCP SDK 兼容性(与 Cursor 版本匹配)

  • 验证 Dify API 的速率限制(避免频繁调用被封禁)

  • 确保 stdio 通信无缓冲阻塞问题

按此列表逐步推进,可在开发过程中补充具体实现细节(如协议字段定义或错误码映射)。

按照流程构建

ai给的并不完全是对的,你可以参考,但不能完全依赖。

这个时候前面两篇文章的作用就来了,结合上面AI梳理的流程,咱们慢慢走~

https://www.5ee.net/archives/c2vlqvcS

阶段 1:基础环境准备

一些基础信息可以查看这篇文章哦

https://www.5ee.net/archives/tmXJAgWz

安装依赖

#1、安装node.js https://nodejs.org/zh-cn 这个自己下载配置环境变量

#2、初始化npm项目
npm init -y

#3、安装依赖sdk zod和ts
npm install @modelcontextprotocol/sdk zod
npm install --save-dev typescript @types/node

执行完毕后

配置TypeScript

创建tsconfig.json文件:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "outDir": "build",
    "rootDir": "src",
    "sourceMap": true,
    "declaration": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build"]
}

阶段 2:MCP 服务器核心开发

新建一个文件src/index.ts

根据我之前的教程,你可以新增包含必要的代码模板

//引用依赖
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 创建MCP服务器
const server = new McpServer({
  name: "mcp_dify_server",
  version: "1.0.0"
});

// 添加一个简单的打招呼工具
server.tool(
  "say_hello",
  { name: z.string().describe("要问候的名字") },
  async (params: { name: string }) => ({
    content: [{ type: "text", text: `你好,${params.name}!欢迎使用MCP!` }]
  })
);

// 启动服务器
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP Hello World 服务器已启动");
}

main().catch((error) => {
  console.error("服务器启动失败:", error);
  process.exit(1);
});

dify API

curl -X POST 'https://api.dify.ai/v1/chat-messages' \
--header 'Authorization: Bearer {api_key}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "inputs": {},
    "query": "问题",
    "response_mode": "blocking",
    "conversation_id": "",
    "user": "用户名"
}'

API凭证

#使用官方地址进行测试
DIFY_API_URL=https://api.dify.ai/v1
DIFY_API_KEY=app-6smfwu5QOvpCuniGHd6QWjhn

使用curl测试一下,通透

参数分析

inputs: 可为空,它的主要作用是传入app定义的变量值,这里没有

query: 传递当前所输入的参数,就是问题

response_mode:blocking 默认即可

conversation_id:会话 ID,需要基于之前的聊天记录继续对话,必须传之前消息的 conversation_id,默认为空的情况下会自动创建一个id

user:必填,这里定义为固定值:cursor_user

自己组成一个提问

当然也可以使用AI润色一下,这里我就没润色了

//dify API 使用方式:
curl -X POST 'https://api.dify.ai/v1/chat-messages' \
--header 'Authorization: Bearer {api_key}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "inputs": {},
    "query": "问题",
    "response_mode": "blocking",
    "conversation_id": "",
    "user": "用户名"
}'

//参数说明:
inputs 可为空,它的主要作用是传入app定义的变量值,这里没有
query: 传递当前所输入的参数,就是问题
response_mode:blocking 默认即可
conversation_id:会话 ID,需要基于之前的聊天记录继续对话,必须传之前消息的 conversation_id,默认为空的情况下会自动创建一个id
user:必填,这里定义为固定值:cursor_user


//单独定义一个api凭证参数变量
DIFY_API_URL=https://api.dify.ai/v1
DIFY_API_KEY=app-6smfwu5QOvpCuniGHd6QWjhn


使用post 请求适配一下现在的格式

使用edit模式

使用edit模式进行提问,选中需要修改的行以及 规则

我这边修改完之后需要安装依赖和新建一个环境变量,基本上已经算是差不多了

阶段3:调试与测试

调试

更新package.json 依旧看这个哦

https://www.5ee.net/archives/tmXJAgWz#4.-%E6%9B%B4%E6%96%B0package.json
{
  "name": "mcp_dify_sever",
  "version": "1.0.0",
  "description": "dify 聊天工具",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.7.0",
    "axios": "^1.8.4",
    "dotenv": "^16.4.7",
    "zod": "^3.24.2"
  },
  "devDependencies": {
    "@types/node": "^22.13.10",
    "typescript": "^5.8.2"
  }
}

编译

# 编译项目

npm run build

第一次报错了

使用AI去修复这个问题

测试

npx @wong2/mcp-cli node ./build/index.js args...

成功

现在可以提问,但也不是完全成功,需要调整,

告诉AI,让它帮我调整
会话id为空

完整代码

它只有一个非常简单的功能实现,需要其他功能需要扩展,它的构成其实非常简单,如果你会点js/ts会非常容易上手

//引用依赖
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import axios from 'axios';
import dotenv from 'dotenv';

// 加载环境变量
dotenv.config();

// Dify API 配置
const DIFY_API_URL = process.env.DIFY_API_URL || 'https://api.dify.ai/v1';
const DIFY_API_KEY = process.env.DIFY_API_KEY;

// 创建MCP服务器
const server = new McpServer({
  name: "hello-world",
  version: "1.0.0"
});

  
// 添加 Dify 聊天工具
server.tool(
  "dify_chat",
  { 
    query: z.string().describe("用户的问题或指令")
  },
  async (params) => {
    try {
      // 准备请求数据
      const requestData = {
        inputs: {},
        query: params.query,
        response_mode: "blocking",
        conversation_id: "",  // 默认为空
        user: "cursor_user"
      };

      // 发送请求到 Dify API
      const response = await axios.post(
        `${DIFY_API_URL}/chat-messages`, 
        requestData,
        {
          headers: {
            'Authorization': `Bearer ${DIFY_API_KEY}`,
            'Content-Type': 'application/json'
          }
        }
      );

      // 直接返回 Dify 的回答文本
      return { 
        content: [
          { type: "text", text: response.data.answer || "没有获取到回答" }
        ]
      };
    } catch (error) {
      console.error('Dify API 调用失败:', error);
      // 安全地提取错误信息
      const errorMessage = error instanceof Error 
        ? error.message 
        : String(error);
        
      return { 
        content: [
          { type: "text", text: `调用 Dify API 时出错: ${errorMessage}` }
        ]
      };
    }
  }
);

// 启动服务器
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP dify sever 服务器已启动");
}

main().catch((error) => {
  console.error("服务器启动失败:", error);
  process.exit(1);
});

阶段4: 部署

根据官方教程,在Cursor中创建MCP服务器有三种方式,按推荐顺序排列:

是不是觉得官方给的3种方式只能看懂一个ui配置?哈哈,我也是看了半天才看懂前两条的含义,到底是什么意思。。。

https://docs.cursor.com/context/model-context-protocol

1、项目配置文件(推荐)

在项目目录中创建.cursor/mcp.json文件,

参数需要注意
DIFY_API_URL:就是url
DIFY_API_KEY:则是key
MCP_REQUEST_TIMEOUT:超时时间 默认30秒哦,如果你的dify工作流过于时间久需要调整这个参数的时间,
官方没找到变量相关的问题,查了我整整半天的资料,才找到这个超时时间环境变量

{
    "mcpServers": {
      "mcp_dify_sever": {
        "command": "node",
        "args": ["G:/mcp/mcp_demo/build/index.js"],
        "env": {
          "DIFY_API_URL": "https://api.dify.ai/v1",
          "DIFY_API_KEY": "app-6smfwu5QOvpCuniGHd6QWjhn",
          "MCP_REQUEST_TIMEOUT": "120000",
        }
      }
    }
  }

2、全局配置文件

在用户主目录创建~/.cursor/mcp.json文件

C:\Users\Administrator\.cursor

方式和上面一样,就是全局都会启用这个服务器,看功能而定

3、UI配置(不推荐)

通过Cursor设置界面添加,不支持环境变量,基本上来说就是废物

不推荐添加,但这个位置要用哦,因为你配置了项目配置或者全局配置,需要在这个地方启动