MCP学习工具

一个包含MCP客户端与示例MCP Server的学习型仓库,用于通过MCP协议与外部工具交互,并利用Azure OpenAI的Chat Completions功能进行函数调用。

  • by BelieveInBehavior
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 BelieveInBehavior/MCP-EXAMLES

使用说明

MCP-learning

一个包含 MCP 客户端与示例 MCP Server 的学习型仓库(monorepo)。

  • mcp-client-typescript/: TypeScript 编写的 MCP 客户端(CLI),调用 Azure OpenAI 的 Chat Completions(function calling)能力,并通过 MCP 协议与外部工具交互。
  • weather/: TypeScript 编写的示例 MCP Server,向客户端暴露工具(tools)。

目录结构

./
├─ README.md
├─ mcp-client-typescript/
│  ├─ src/index.ts
│  ├─ build/index.js
│  ├─ package.json
│  └─ tsconfig.json
└─ weather/
   ├─ src/index.ts
   ├─ build/index.js
   ├─ package.json
   └─ tsconfig.json

快速开始

  1. 安装依赖并构建
cd weather && npm i && npm run build
cd ../mcp-client-typescript && npm i && npm run build
  1. 配置 Azure OpenAI 环境变量(mcp-client-typescript/.env)
AZURE_ENDPOINT="https://<your-azure-openai-endpoint>"
AZURE_API_KEY="<your-azure-openai-key>" # 或设置 AZURE_OPENAI_API_KEY
AZURE_MODEL="<your-deployment-name>"    # 如 gpt-4o, gpt-4o-mini 等对应的部署名
  1. 启动客户端,连接示例 Server(以 weather 为例)
# 终端 A:直接运行客户端(会在 CLI 中提示输入 Query)
node /Users/Desktop/mcp-learning/mcp-client-typescript/build/index.js \
     /Users/Desktop/mcp-learning/weather/build/index.js

提示:客户端内部会启动一个基于 stdio 的 MCP 连接(StdioClientTransport)。serverScriptPath 传入的就是 Server 的可执行脚本(上例为 weather/build/index.js)。

mcp-client-typescript 工作原理(与 @index.ts 同步)

mcp-client-typescript/src/index.ts 的核心逻辑:

  • 连接 MCP Server,获取其 tools 列表,并将其转化为 Chat Completions 的函数调用工具描述(tools)。
  • 会话循环 while (true) 中:
    • 将当前 messages 发给 Azure OpenAI 的 Chat Completions。
    • 取得 assistant 响应:
      • 无论有无 tool_calls,先把该 assistant 消息完整(含 content 与 tool_calls 字段)追加进 messages。
      • 若不存在任何 tool_calls,说明不需要再调用工具,本轮对话结束,直接返回。
      • 若存在 tool_calls:
        • 逐个解析工具名与参数,调用 MCP Server 提供的对应工具。
        • 工具调用成功:把结果以 role: "tool"、并带上对应的 tool_call_id 追加到 messages。
        • 工具调用失败:把结构化错误也以 role: "tool"、并带上对应的 tool_call_id 追加到 messages。
    • 继续下一轮 while (true),把最新的 messages(包含工具返回)再次发送给模型,让模型阅读工具结果进行二次推理或生成最终答案。

这样实现后,满足了 OpenAI/Azure 的函数调用协议约束:

  • 任意 tool 消息必须紧跟在包含 tool_calls 的 assistant 消息之后。
  • 每条 tool 消息必须携带与其对应的 tool_call_id,供模型对齐。

错误信息 push 到 messages 的理念与格式

将“工具失败”视为一种“可供模型进一步思考的中间观测值”。因此:

  • 工具失败时,不中断对话;将错误以 role: "tool" 的消息推送回模型,模型可基于错误复盘、调整参数或更换策略,形成自修复闭环。
  • 错误负载采用结构化 JSON,便于模型检索关键信息与制定下一步动作。

推荐错误负载结构:

{
  "ok": false,
  "toolName": "<工具名>",
  "args": { "...调用参数..." },
  "error": {
    "name": "Error",
    "message": "具体错误信息",
    "stack": "堆栈(如可用)"
  },
  "timestamp": "2025-10-20T08:00:00.000Z"
}

工具调用与错误回传流程(中文流程图)

用户输入 Query
      │
      ▼
Azure OpenAI Chat Completions(附 tools)
      │
      ▼
返回 assistant(可能包含 tool_calls)
      │
      ├─ 无 tool_calls → 追加 assistant 到 messages → 返回结果(对话回显/结束)
      │
      └─ 有 tool_calls → 追加完整 assistant(含 tool_calls)到 messages
                │
                ├─ 遍历每个 tool_call:
                │       ├─ 调用 MCP 工具(传入解析后的参数)
                │       ├─ 成功 → 以 role:"tool" + tool_call_id 追加结果到 messages
                │       └─ 失败 → 以 role:"tool" + tool_call_id 追加结构化错误JSON到 messages
                │
                ▼
       将更新后的 messages 再次发送给模型(形成“读工具结果→继续推理”的闭环)

自修复与“自进化”建议

  • 会话内自修复:上述闭环让模型能基于工具错误继续思考与重试,快速收敛到可行方案。
  • 真正自进化:需要把“错误—修复”经验沉淀到会话之外(测试、文档、规则库、默认参数模板,或自动生成 PR ),从而长期提升能力。
  • 建议为错误引入分级与策略:
    • 可重试(网络/限流)→ 指数退避、限制最大重试次数
    • 可修复(参数/权限)→ 自动校正参数、请求权限或切换工具
    • 不可修复(缺资源/策略)→ 直接反馈用户与记录

常见问题(Troubleshooting)

  • 报错:Invalid parameter: messages with role 'tool' must be a response to a preceeding message with 'tool_calls'.

    • 处理:确保先将包含 tool_calls 的 assistant 消息追加到 messages,随后再追加对应的 tool 消息。
  • 工具错误对象被串成 [object Object]

    • 处理:对错误进行结构化序列化(name/message/stack),并以 JSON 字符串化后写入 content。

运行与开发小贴士

  • weather 是一个示例 MCP Server,你可以按需扩展其工具集合。
  • mcp-client-typescript 的 processQuery 采用永真循环,仅当当前轮 assistant 不再包含 tool_calls 时返回,避免过早终止导致工具结果无法被模型消费。
  • 本仓库使用 ESM("type": "module")。

若你在本仓库上继续扩展,请优先更新本 README 的“目录结构”和“工作原理”章节,保持文档与实现同步。