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

如果你一步步跟着我的教程走,你会发现AI在这里怎么不好用了?怎么只能生成一些简单的?怎么一复杂就把自己的代码改的乱乱的?

那就恭喜你,终于是入了AI的坑,这还是上下文和提问技巧的问题

举一个例子吧,比如你需要流式传输方式

提问

局部选中你需要的代码,提问

修复

然后出现错修复这个小问题

继续修复

不停的修复这个单功能的错误(千万不要一次性让它写或者修复多个功能,容易乱)

测试

没有报错,但不清楚是否适合

测试发现,并不是我想要的流式,我想要的每输出一句就输出出来,

继续让AI修改

报错修复

验证

到这边你就会发现,mcp sdk 其实并不支持流式传输

//引用依赖
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 {
      console.error(`处理用户查询: ${params.query.substring(0, 50)}${params.query.length > 50 ? '...' : ''}`);
      


      console.error('发送请求到 Dify API...');
      
      // 发送请求到 Dify API
      const response = await axios.post(
        `${DIFY_API_URL}/chat-messages`,
        {
          inputs: {},
          query: params.query,
          response_mode: "streaming",
          conversation_id: "",  // 默认为空
          user: "mcp_cursor_user"
        },
        {
          headers: {
            'Authorization': `Bearer ${DIFY_API_KEY}`,
            'Content-Type': 'application/json'
          },
          responseType: 'stream'
        }
      );

      console.error('收到 Dify 流式响应,开始处理...');
      
      // 处理流式响应
      let fullResponse = "";
      let isError = false;
      let buffer = ""; // 添加缓冲区存储不完整的数据
      
      try {
        // 处理流式数据
        for await (const chunk of response.data) {
          // 将新的数据添加到缓冲区
          buffer += chunk.toString();
          
          // 按行分割,但保留最后一个不完整的行
          const lines = buffer.split("\n");
          buffer = lines.pop() || ""; // 保存最后一个可能不完整的行到缓冲区
          
          for (const line of lines) {
            if (!line.trim() || !line.startsWith("data: ")) continue;
            
            try {
              // 解析 JSON 数据
              const jsonData = JSON.parse(line.slice(6));
              
              if (jsonData.error) {
                isError = true;
                fullResponse = `错误: ${jsonData.error}`;
                console.error('Dify API 流式响应错误:', jsonData.error);
                break;
              }
              
              // 累加响应内容
              if (jsonData.answer) {
                fullResponse += jsonData.answer;
                // 可以添加进度日志
                console.error(`已接收内容长度: ${fullResponse.length}`);
              }
            } catch (e) {
              // 忽略解析错误,等待更多数据
              continue;
            }
          }
          
          if (isError) break;
        }

        // 处理缓冲区中剩余的数据
        if (buffer.trim() && buffer.startsWith("data: ")) {
          try {
            const jsonData = JSON.parse(buffer.slice(6));
            if (jsonData.answer) {
              fullResponse += jsonData.answer;
            }
          } catch (e) {
            // 忽略最后一块数据的解析错误
          }
        }

      } catch (streamError: unknown) {
        console.error("处理流数据时出错:", streamError);
        const errorMessage = streamError instanceof Error 
          ? streamError.message 
          : String(streamError);
        
        return { 
          content: [{ 
            type: "text", 
            text: `处理 Dify 响应流时出错: ${errorMessage}` 
          }]
        };
      }

      console.error(`Dify 响应处理完成,响应长度: ${fullResponse.length}`);
      
      // 返回完整的响应
      return { 
        content: [
          { type: "text", text: fullResponse || "没有获取到回答" }
        ]
      };
    } 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);
});