news 2026/9/28 4:05:12

[AIAgent-MCP]从连不上到跑通:MCP Inspector 本地调试 MCP Server 实战记录(TaoToken 统一 Key 接入版)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[AIAgent-MCP]从连不上到跑通:MCP Inspector 本地调试 MCP Server 实战记录(TaoToken 统一 Key 接入版)

1. 为什么 MCP Inspector 连不上本地 Server

MCP Inspector 是官方给 MCP Server 做可视化调试的交互式工具,说白了就是 MCP 世界的 Postman:能列出 Server 暴露的 tools、resources、prompts,填入参数直接调用,看返回结果。适合正在写 MCP Server 的开发者、做 AI Agent 工具链的同学,以及想把内部能力封装成 MCP 接口但不确定通不通的人。

我最近在本地起了一个基于 FastMCP 的 Server,用mcp.run(transport="streamable-http")启动,命令行看着一切正常,端口也监听了,但 Inspector 里点 Connect 就是转圈,Server 端日志刷出一堆和 session、CORS 相关的报错。换成 SSE 模式又是另一套问题。折腾一圈才理清:问题不在 Inspector,而在 Server 的 ASGI 组装方式——FastMCP 自带的run()把 app 包得太死,跨域和 session header 没暴露出来,Inspector 拿不到Mcp-Session-Id,握手直接断。

这篇就把从连不上到跑通的完整链路写清楚:Starlette 怎么挂载 streamable_http_app、CORS 要放哪些 origin、Inspector 的 Transport Type 和 URL 怎么填、SSE 旧模式怎么切,以及怎么用 TaoToken 的统一 Key 给 Server 里的模型调用兜底。全程可复制,照着改就能复现。

2. TaoToken 前置:统一 Key 与 API 通道

MCP Server 本身只是协议层,真正干活时经常要调模型——比如一个summarizetool 内部要请求大模型。如果每个 tool 都自己配一套 key,本地调试会非常乱。我的做法是让 Server 统一走 TaoToken 的 API 通道,一个 Key 覆盖多家模型,调试时只关心协议通不通,不用来回换配置。

TaoToken 在这里的角色是「统一入口」:官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 端点是 https://taotoken.net/api 。你需要在控制台建一个 Key,然后把它写进 Server 的环境变量或配置文件。注意 API 地址不带 UTM 参数,直接写https://taotoken.net/api即可。

拿 Key 的入口在控制台,创建后复制那串sk-开头的字符串。建议不要硬编码进server.py,用.env或系统环境变量注入,后面 Inspector 调试时改配置不用动代码。如果你后面要做长期编码或 Agent 循环调用,可以看下 Coding Plan;只是验证模型连通性,用模型对话页面点几下就够了。

3. 可复制配置:Starlette + CORS 骨架

核心改动就一处:别用mcp.run(),改成手动组装 Starlette app,把streamable_http_app()挂到路由上,再套一层CORSMiddleware。下面是我实测能跑通的server.py骨架。

# server.py import os from contextlib import asynccontextmanager from starlette.applications import Starlette from starlette.middleware.cors import CORSMiddleware from starlette.routing import Mount from mcp.server.fastmcp import FastMCP import uvicorn mcp = FastMCP("demo-server") @mcp.tool() def add(a: int, b: int) -> int: """两数相加,用于验证 tool 调用链路""" return a + b @mcp.tool() def summarize(text: str) -> str: """调用 TaoToken 统一通道做摘要(示例占位)""" # 实际请求走 https://taotoken.net/api return f"received {len(text)} chars" @asynccontextmanager async def lifespan(app): async with mcp.session_manager.run(): yield app = Starlette( routes=[ Mount("/", app=mcp.streamable_http_app()), ], lifespan=lifespan, ) app = CORSMiddleware( app, allow_origins=[ "http://localhost:6274", "http://127.0.0.1:6274", ], allow_methods=["GET", "POST", "DELETE", "OPTIONS"], allow_headers=["*"], expose_headers=["Mcp-Session-Id"], ) if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8000)

几个关键点必须对上,错一个就连不上:

配置项值作用
Mount 路径/挂streamable_http_app()实际端点变成/mcp
allow_originslocalhost:6274和127.0.0.1:6274Inspector 默认端口
expose_headersMcp-Session-Id浏览器要读到这个头
allow_methods含 DELETE关闭 session 用
lifespanmcp.session_manager.run()不写会报 session 未初始化

启动命令:

uv run server.py # 或 python server.py

看到Uvicorn running on http://127.0.0.1:8000就说明 Server 起来了。此时先别急着开 Inspector,用 curl 探一下端点是否活着:

curl -i -X POST http://127.0.0.1:8000/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

返回里带Mcp-Session-Id响应头,说明协议层通了。这一步能省掉后面一半的排查时间。

4. 验证请求:Inspector 连接与 Run Tool

先启动 Inspector:

npx @modelcontextprotocol/inspector

如果浏览器打不开,命令行里设一下 host:

set HOST=127.0.0.1 npx @modelcontextprotocol/inspector

启动后 URL 会变成127.0.0.1:6274,浏览器就能访问了。进入界面后按下面填:

  • Transport Type:Streamable HTTP
  • URL:http://127.0.0.1:8000/mcp
  • Connection Type:Direct

点 Connect。连上后右侧出现资源面板,因为示例 Server 只定义了 tools,点 Tools 面板再点 List Tools,就能看到add和summarize。选中add,右侧出现参数表单,填a=3、b=4,点 Run Tool,返回7就说明整条链路通了。

如果要用 SSE 旧模式,Server 端把 Mount 那行换掉:

app = Starlette( routes=[ Mount("/", app=mcp.sse_app()), ], )

注意 SSE 模式不需要lifespan,去掉即可。Inspector 里 Transport Type 选SSE,URL 填http://127.0.0.1:8000/sse,其余操作一样。不过 SSE 是旧实现,新项目建议直接用 Streamable HTTP。

5. 本篇常见错排查

连不上、Server 日志报 session 相关错误:八成是没写lifespan,或者用了mcp.run()而不是手动挂载。streamable_http_app()依赖 session manager 的生命周期,必须用lifespan包住。

浏览器控制台报 CORS:检查allow_origins是否同时包含localhost:6274和127.0.0.1:6274。只写一个,另一个访问方式就会被拦。

连上了但 List Tools 为空:确认 tool 是用@mcp.tool()装饰的,且函数有类型注解和 docstring。缺类型注解时 FastMCP 可能无法生成参数 schema。

Run Tool 报 400 或参数校验失败:Inspector 表单是按 schema 生成的,如果 schema 里参数是必填但你没填,会直接报错。对照右侧描述补全。

端口冲突:8000 被占用时换端口,但 Inspector 里的 URL 也要同步改,别只改一边。

curl 能通、Inspector 不通:基本锁定在 CORS 和expose_headers。Mcp-Session-Id没暴露,浏览器读不到,后续请求就带不上 session。

6. 继续调试与接入

跑通之后,日常调试就是改 tool、重启 Server、Inspector 里重新 List Tools 再 Run。Server 里如果涉及模型调用,统一走 TaoToken 的 API 通道,Key 在控制台管理,接入细节看接入文档。需要验证模型返回是否正常,直接用模型对话页面测;要做长期编码或 Agent 循环,Coding Plan 更合适。API Keys 页面负责建 Key 和轮换,别把 Key 写进代码提交到仓库。

实测下来,MCP Inspector 最大的价值是省掉了自己写 MCP Client 的成本——协议握手、session 管理、参数表单它都替你做了,你只需要专注 Server 端逻辑。把 Starlette 挂载和 CORS 这两处配对,后面基本不会再卡在连接上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 4:04:42

解决wordpress手机看不了视频播放器:3种方案对比评测与真实成本拆解

解决wordpress手机看不了视频播放器:3种方案对比评测与真实成本拆解 做网站的朋友都知道,模板网站虽然便宜快,但往往丑得让人没脾气,功能更是缺胳膊少腿。尤其是遇到wordpress手机看不了视频播放器这种基础bug,很多甲方直接抓狂,觉得几千块建站费白扔了。其实这背后不仅是代码问题,更是选型和…

作者头像 李华
网站建设 2026/9/28 4:04:29

5个维度揭秘:厦门公司注册网站哪家好,拒绝模板烂大街

5个维度揭秘:厦门公司注册网站哪家好,拒绝模板烂大街 别再被那些千篇一律的模板网站忽悠了。你花大几千甚至上万做的“企业门面”,客户打开看一眼就关掉,连注册账号的按钮都懒得点,这就是典型的“模板网站太丑不够用”。…

作者头像 李华
网站建设 2026/9/28 4:04:27

2026最新公司策划书模板避坑指南,省钱又高效

2026最新公司策划书模板避坑指南,省钱又高效 找建站公司怕被坑高价?别急,今天这篇2026最新实战干货,帮你用公司策划书模板把成本砍半。 SEO原理速懂:为什么模板能省钱 核心逻辑:模板是标准化产品,定制是非标服务。…

作者头像 李华
网站建设 2026/9/28 4:04:08

避开备案坑:找企业案例的网站保姆级建站教程

避开备案坑:找企业案例的网站保姆级建站教程 刚接手新站点,后台一堆报错,最头疼的还是那个让人抓狂的 备案流程一头雾水 。域名解析好了,服务器也租了,结果卡在ICP备案上,材料反复被退回,搞了三天还没动静。这时候你急需一份靠谱的 保姆级建站教程…

作者头像 李华
网站建设 2026/9/28 4:03:47

2026最新wordpress插件拖拽避坑指南:解决域名服务器搞不懂

2026最新wordpress插件拖拽避坑指南:解决域名服务器搞不懂 域名解析报错?服务器配置超时?很多做WordPress的朋友,明明买了最贵的云服务器,装好了数据库,结果页面打不开,或者后台拖个插件就卡死。这背后的核心矛盾,往往不是代码写错了,而是 域名服务器搞不懂 你的网络请求走向。…

作者头像 李华