目标

拿到一个远程 MCP 端点 URL(如 https://example.com/mcp),不装 SDK、不看源码,只用 curl 搞清楚三件事:它是谁、提供哪些工具、每个工具要什么参数。

什么是 MCP 端点

MCP (Model Context Protocol, 模型上下文协议) 是 AI 应用调外部工具的开放协议(类比:AI 应用的 USB-C 接口)。一个"远程 MCP 端点"就是一个 HTTP URL,背后跑着 MCP Server,像一台工具售货机:

  • 发固定格式的问话 → 它回固定格式的答案
  • 全程 JSON-RPC 2.0(一种"发请求带编号、回响应带同一编号"的消息格式)
  • 概念笔记见 MCP (Model Context Protocol)

协议两代(2026-09 现状,探测前必知)

MCP 规范按日期版本化,目前有两代并存,探测时要先试旧代、再试新代:

旧代(2024-11-05 / 2025-03-26 / 2025-06-18)新代(2026-07-28)
握手方法initialize → notifications/initializedserver/discover(可选,每请求自带元数据)
状态有会话状态无状态 (stateless),每个请求自描述
元数据位置params 顶层(protocolVersion 等)每个请求的 _meta 字段(io.modelcontextprotocol/protocolVersion 等)
客户端原语sampling / logging / elicitation仅 elicitation;sampling 与 logging 已弃用

实际大量现存 server 仍只说旧代协议,所以 curl 探测先用旧代 initialize,报错再换新代。

探测四步法

第 0 步:探活

先 GET 一下,看服务器怎么回:

curl -x http://127.0.0.1:7890 -s -i "https://example.com/mcp" | head -20

可能出现:

  • 401 Unauthorized + WWW-Authenticate: Bearer → 端点活着,但要令牌(token,一串密码字符串放请求头里)
  • 404 → 路径不对
  • 405 Method Not Allowed → 常见于对 GET 的正常拒绝(Streamable HTTP 只收 POST),反而说明端点存在

第 1 步:握手(旧代 initialize)

curl -x http://127.0.0.1:7890 -s -X POST "https://example.com/mcp" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}'

成功回包里能看到:serverInfo(服务器名和版本)、protocolVersion(它决定的协议版本)、capabilities(它支持哪些原语,如 tools / resources / prompts)。

两个头都不能省:

  • Content-Type: application/json —— 告诉它发的是 JSON
  • Accept: application/json, text/event-stream —— Streamable HTTP 传输层要求同时接受普通 JSON 和 SSE(Server-Sent Events,服务器流式推送),缺了可能回 406

第 2 步:拿菜单(tools/list)

curl ... -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

回包的 tools 数组就是"菜单",每个工具带:

  • name:调用时用的唯一名字
  • title / description:给人看的说明
  • inputSchema:JSON Schema(一种描述"要填哪些空、每个空什么类型、哪些必填"的标准格式)——这就是参数说明书,机器可读,读了就知道怎么调

参数不用猜、不用 mock,全在 inputSchema 里。但 schema ≠ 实际行为,工具好不好用要真调用一次才知道。

第 3 步:试调用(tools/call)

curl ... -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"工具名","arguments":{"参数名":"值"}}}'

回包 content 数组是执行结果(type: "text" 就是文本)。

实战记录:6767.chat/agent/handouts/mcp

2026-09-01 实测(tx 服务器 handouts-agent-server,Node 22 + @modelcontextprotocol/sdk):

  1. POST initialize(无 token)→ 401 {"error":"unauthorized"},响应头 WWW-Authenticate: Bearer
  2. 带 Bearer key 重试 initialize → 200,回包:
{"result":{"protocolVersion":"2025-03-26","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"handouts-agent-server","version":"0.1.0"}},"jsonrpc":"2.0","id":1}

注意回包是 SSE 格式:event: message 行 + data: {json} 行,和请求头里声明的 text/event-stream 对应。

  1. tools/list → 三个工具:
工具作用关键参数
handouts_check服务能力 + 我的队列概览无参数
handouts_create建讲义生成任务,秒回 taskIdinstructions(≤20000 字)、files[](base64,单文件 8MiB / 共 20MiB / ≤20 个)、mainFileName
handouts_list列任务 / 按 taskId 查进度,5-10 秒轮询taskId(uuid)、limit(1-100)
  1. handouts_check 调用成功,返回:ownerId: "admin"、mode: "asynchronous-polling"、capabilities: [check, create, list, download]、limits(队列上限 10、任务保留 86400000ms=24h)、当前队列全空。
  2. handouts_list 调用成功,返回 [](还没有任务)。

结论:端点完全可用。handouts_create 亦实测通过:上传 12KB Markdown,任务约 12 分钟完成(queued → running/agent_using_tools → succeeded),downloadUrl 下载到合法 PDF。PDF 下载也要带 Bearer key。

发现服务器端 bug(2026-09-01):生成的 PDF 中文全部缺失——英文(RLHF、SFT、Transformer)正常渲染,中文位置空白;版式(封面/目录/树图/列表)完好。症状指向 tx 上 PDF 渲染环节缺 CJK 字体或未启用 CJK 支持,需在服务器端修(装中文字体 + LaTeX/模板启用 CJK),与 MCP 调用端无关。

架构细节见 MCP (Model Context Protocol) 的"远程异步任务型 MCP Server 架构"一节。

常见坑

  • WebFetch 工具对很多域名会被挡(企业/网络策略直接拦截),别死磕,改 curl 走本地代理(本机 7890,备选 7897)。官方文档站每篇页面加 .md 后缀就是纯 markdown,适合 curl 抓。
  • Accept 头缺失:只发 application/json 不带 text/event-stream,部分 server 回 406。
  • 401 别硬猜:WWW-Authenticate: Bearer 就是要 Bearer token;没有 key 就找文档或问服务方,不要暴力试。
  • 两代协议混着来:initialize 报"method not found"类错误时,换 server/discover 试新代。
  • 官网上唯一稳定的入口是 https://modelcontextprotocol.io/llms.txt(全站文档索引,专为大模型阅读设计)。

参考链接


本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps