1. Resource 从「本地正常」到「Claude Code 看不到」,中间缺了两层
本地 MCP Server 注册好两个 Resource,MCP Inspector 里一切正常,Claude Code 里却一个都看不到。先别急着翻代码——你缺的可能不是 MCP 配置,而是模型通道。TaoToken 的官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end ,先去那里把 API Key 申请下来,再回头看成因。
1.1 本地 MCP Server 一切正常,为什么 Claude Code 看不到
假设你的 mcp_demo_server.py 用 FastMCP 写了两个 Resource:一个用 config://app/settings 返回应用配置,一个用 docs://help/about 返回 Markdown 说明。启动服务后,打开 MCP Inspector 连上 localhost:8000/sse,两个 Resource 都整整齐齐列在 Resources 标签页里。可一进 Claude Code,Resource 面板就是空的,有时甚至显示连接失败。
这种「本地正常,切换客户端就失效」的现象,在 MCP 开发里非常典型。大部分情况不是 Resource 注册逻辑写错了,而是客户端与服务器之间的网络链路没走通。你的 MCP Server 跑在 SSE 传输层上,客户端需要先连到 SSE 端点,服务器才能通过这条长连接把数据推回去。Claude Code 如果回连不到你本地的 8000 端口,resources/list 请求根本发不出来,Resource 自然就是空的。
1.2 拆解问题:网络链路和模型通道,缺一不可
但这里还有一个更隐蔽的前提:Claude Code 本身不内置模型。它要执行一次 resources/list,并读懂返回的 URI、标题、描述,背后必须调用一个语言模型。如果你没有给它配好 API 通道,它即使连上了 MCP Server,也没办法把「列表为空」或「列表有数据」转化成你能理解的结论。所以我常说,这类问题要拆成两层看:第一层是网络链路,cpolar 隧道有没有真正把请求转发进来;第二层是模型通道,Claude Code 有没有一个可用的 API 可以调。
TaoToken 解决的就是第二层。它提供一个统一的、与 Anthropic API 兼容的接入地址,让你用一个 Key 对接 Claude Code,不用在多个平台之间来回复制密钥。这篇文章的排查顺序是:先在本地确认 MCP Server 没问题,然后给 Claude Code 配上 TaoToken,再用 cpolar 开一条临时公网隧道,最后让 Claude Code 通过这条隧道调用 resources/list,把问题彻底拆开。
2. 本地自检:MCP Server、curl、MCP Inspector 三件套
在动任何网络工具之前,先把本地环境跑通。这一步花不了两分钟,但能帮你过滤掉一半的无效折腾。
2.1 确认 MCP Server 真的在监听 8000 端口
假设你的 mcp_demo_server.py 长这样:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo-server")
@mcp.resource("config://app/settings")
def get_settings() -> str:
return "theme=dark\nlanguage=zh-CN\nmax_items=50"
@mcp.resource("docs://help/about")
def get_about() -> str:
return "# About\n\nThis is a demo MCP server."
if __name__ == "__main__":
mcp.run(transport="sse")
终端执行 python mcp_demo_server.py,正常输出应该包含 Uvicorn running on http://localhost:8000。如果提示端口被占用,用 lsof -i :8000 或 netstat -ano | findstr :8000(Windows)查一下是谁在占用。换了端口也没关系,后面 cpolar 和 Claude Code 的地址跟着改就行。
2.2 用 curl 快速验证 SSE 端点
另开一个终端,执行:
curl -N http://localhost:8000/sse
正常情况下你会看到两行初始化事件:
event: endpoint
data: /message?session_id=abc123
event: initialized
data: {}
因为 SSE 是长连接,curl 会一直挂着不退,这属于正常现象。如果看到 Connection refused,说明服务器没启动;如果看到 curl: (52) Empty reply from server,说明进程起来了但没正确绑定到 SSE 端点。这两种情况都先回本地排查,不要急着穿透。
2.3 用 MCP Inspector 在本地过一遍 Resource 列表
MCP Inspector 是官方提供的调试工具,适合做这一步:
npx @modelcontextprotocol/inspector
浏览器打开 http://localhost:5173,连接方式选「Streamable HTTP」,地址填 http://localhost:8000/sse。连接成功后切到 Resources 标签页,如果能看到你注册的两个 Resource,说明 Resource 注册代码本身没问题,问题出在链路。如果这步就看不到,那请回去检查 @mcp.resource 的装饰器、URI 格式和 list_resources 的返回值,暂时不用往下读。
3. 给 Claude Code 配 TaoToken:settings.json 里写入兼容 API
3.1 为什么 Claude Code 需要单独配 API 通道
Claude Code 本身只是一个 AI 编程工具外壳,所有对话、工具调用、结果解释都需要向语言模型 API 发起请求。当你让它「看看 MCP 里有什么 Resource」时,它实际要做三件事:连上 MCP Server、发送 resources/list、把返回的 JSON 渲染成可读的列表。这每一步都依赖模型推理。如果 API 没接好,Claude Code 可能直接提示连接失败,也可能假装执行了但没有后续输出。
TaoToken 做的就是把这件事简化。你不需要手动去不同平台申请多个密钥,也不用在环境变量里反复横跳。只需要在 TaoToken 官网注册一次,拿到一个有统一格式的 API Key,然后告诉 Claude Code 去访问 https://taotoken.net/api 这个 Base URL 即可。
3.2 修改 ~/.claude/settings.json
Claude Code 的全局配置存放在 ~/.claude/settings.json。打开这个文件(没有就新建),在 env 节点下写入:
{
"env": {
"ANTHROPIC_BASE_URL": "https://taotoken.net/api",
"ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY",
"ANTHROPIC_MODEL": "YOUR_MODEL_ID"
}
}
注意三个要点:
ANTHROPIC_BASE_URL填接口地址https://taotoken.net/api,不要加/v1,也不要追加?utm_source=...之类的追踪参数。官网链接和接口地址是两个东西,混在一起会导致连接失败。ANTHROPIC_AUTH_TOKEN的值,是你在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 这个页面创建的 API Key,不是 cpolar 的 token。文章中统一用YOUR_API_KEY占位。ANTHROPIC_MODEL的模型 ID,以 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 的模型广场为准。模型列表会随服务商更新,不要照抄别人博客里的旧 ID。
保存后重启 Claude Code。你可以随便输入一句「你好」,看它能否正常回复。能回复,说明模型通道已经通了。这一步做完,Claude Code 才有能力介入 MCP 的资源分析。
3.3 配置错误的典型表现
最常见的问题是 Base URL 写错。有人习惯性地写成 https://taotoken.net/api/v1,结果 Claude Code 报地址不存在;也有人把带 UTM 的官网链接直接粘到了接口地址里,Claude Code 会把那串参数当成路径的一部分,同样连不通。记住:官网是给人点进去注册用的,接口地址是给工具填的。如果 /status 里显示连接异常,先检查这两处有没有混用,再去模型广场核对一遍模型 ID。
4. 用 cpolar 给 MCP Server 生成临时公网地址
本地确认无误,模型通道也配好了,下一步就是把你的 MCP Server 从 localhost 暴露到一个公网地址。cpolar 在这里只负责网络穿透,不参与你的 API 调用。
4.1 安装 cpolar
按操作系统选一条命令:
# macOS
brew install cpolar
# Linux
curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash
Windows 用户去 cpolar 官网下载安装包。装完执行 cpolar version 验证一下。注意:cpolar 的 token 和 TaoToken 的 API Key 是两套完全不同的凭证,后面注册时别搞混。
4.2 注册并获取 cpolar token
cpolar 需要一个账号来绑定本地隧道。注册后进入仪表盘,在 Auth Token 页面复制你的 token,然后执行:
cpolar authtoken YOUR_CPOLAR_TOKEN
这条命令会把 cpolar token 写入本地配置文件,之后每次启动隧道都会自动带上。这里出现的 YOUR_CPOLAR_TOKEN 是 cpolar 的凭证,跟 TaoToken 没有关系。TaoToken 的 Key 只会出现在 Claude Code 的 settings.json 里。
4.3 启动 HTTP 隧道
MCP Server 监听的是 8000 端口,所以启动隧道时也要映射 8000:
cpolar http 8000
如果 8000 端口已经被其他服务占用,先解决冲突,或者回到 MCP Server 换一个端口再启动。隧道起来后,终端会输出类似:
Forwarding https://abc123.cpolar.cn -> http://localhost:8000
这个 https://abc123.cpolar.cn 就是你 MCP Server 的临时公网地址。免费套餐的域名是随机的,有效期大约 24 小时,适合短时调试。如果你需要长期固定地址,可以考虑付费套餐,但调试场景没必要。
4.4 验证公网地址能访问 MCP Server
再用 curl 验证一遍公网链路:
curl -N https://abc123.cpolar.cn/sse
如果能看到和本地一样的 event: initialized,说明隧道已经通了。如果返回 404,检查你有没有漏掉 /sse 路径;如果一直卡住没有输出,打开 cpolar 的 Web UI http://127.0.0.1:9200,看看隧道状态是否 online。有时候是防火墙拦截了 8000 端口,这种情况需要先放行本地端口。
5. 让 Claude Code 通过公网地址连接 MCP Server
5.1 在项目下创建 .mcp.json
Claude Code 的 MCP 配置与 Claude Desktop 的 claude_desktop_config.json 不同。Claude Code 读取的是项目根目录下的 .mcp.json,或者通过 claude mcp add 命令写入配置。在项目目录创建 .mcp.json:
{
"mcpServers": {
"demo-server": {
"type": "http",
"url": "https://abc123.cpolar.cn/sse"
}
}
}
如果你更喜欢命令行,也可以这样:
claude mcp add demo-server --transport http https://abc123.cpolar.cn/sse
两种方式任选其一。注意 url 必须是 cpolar 生成的公网地址,不要再填 localhost。这一步等价于原文里「把 MCP Server 配置改为公网地址」的操作,只是针对 Claude Code 换成了它自己的配置文件。
5.2 重启 Claude Code 并确认连接状态
修改配置后,重启 Claude Code。在对话中输入 /mcp,你应该能看到 demo-server 处于 connected 状态。如果显示失败,先检查 cpolar 隧道是否还活着,再确认 .mcp.json 的 JSON 格式有没有写错。
然后直接提出一个明确的要求:
调用 demo-server 的 resources/list,列出它注册的所有 Resource。
Claude Code 会发起一次 resources/list 请求。如果模型通道和网络链路都正常,它会返回:
App Settings: config://app/settings
About Page: docs://help/about
看到这个结果,说明之前「Resource 看不到」的问题已经定位到网络链路,而不是 Resource 注册代码。
5.3 如果 Claude Code 仍然报错,别急着改代码
如果这步失败了,不要立刻回去改 MCP Server 的代码。先去确认一个关键问题:resources/list 请求到底有没有到达你的 MCP Server?这正是下一章 cpolar 4040 面板要解决的问题。很多时候,Claude Code 显示连接失败,但请求其实已经通过了 cpolar 隧道,只是返回结果在传输中出了问题。要拆开「网络链路不通」和「Resource 注册有问题」这两类原因,光靠客户端侧报错远远不够。
6. 用 cpolar 4040 面板拆解回调链路
6.1 打开 4040 请求检查面板
cpolar 启动时会在本地额外开启一个 http://127.0.0.1:4040 的请求检查界面。这里可以看到 cpolar 接收到的每一个 HTTP 请求的详细信息,包括路径、请求头、请求体(JSON-RPC 消息内容)。
现在做一个小实验:在 Claude Code 里再次触发「查看 Resource」的动作,然后立刻切到 4040 面板,在请求列表里搜索 resources/list。
- 如果找到了
POST /message请求,且请求体里 method 是resources/list,说明网络链路是通的,问题可能在服务器端返回,或者在 Claude Code 的渲染层。 - 如果没有任何请求进来,说明 Claude Code 根本没有成功连接 MCP Server。这时候重点检查
.mcp.json的 URL、cpolar 隧道状态,以及 Claude Code 的/mcp连接状态。
6.2 服务器端 Resource 注册的三个盲区
如果请求确实到达了服务器,但 resources/list 的响应里没有你的两个 Resource,再回头检查这三处:
- capabilities 声明缺失:MCP 协议要求服务器在 initialize 阶段声明自己支持 resources。FastMCP 通常会自动完成,但如果你用低层 SDK 手写协议,很容易漏掉这一步。
- URI scheme 不被客户端渲染:
config://这样的 scheme 在 MCP 协议里是合法的,但某些客户端 UI 只渲染自己认识的 scheme。比如 Claude Code 对file://、https://的支持通常更好,遇到config://可能就显示不了。你可以临时改成file://app/settings试试。 - SSE 长连接断开:cpolar 免费隧道如果长时间没有请求,可能会被回收。这时客户端重连不稳定,
resources/list就发不过来。重启隧道再试一次,往往能恢复。
6.3 对比 Inspector 的响应结果
用 MCP Inspector 在本地连同一个 MCP Server,得到的 resources/list 响应体和通过 cpolar 隧道返回的应该完全一致。如果 Inspect 能列出,而通过公网地址列出时为空,重点看 4040 面板里的实际响应体。cpolar 免费套餐可能对长连接有超时或缓冲策略,导致响应不完整。拿 4040 显示的原始 JSON 和 Inspector 的结果并排对比,差异一目了然。
7. 验证完毕,关掉隧道
7.1 及时关闭临时隧道
排查完成的标准很简单:Claude Code 能通过公网地址连上 MCP Server,并且成功列出 Resource。确认问题已经分开后,马上回到 cpolar 前台按 Ctrl + C 关掉隧道。然后打开 http://127.0.0.1:9200,确认在线隧道列表已经空了。临时隧道不需要长期运行,留着只会增加安全风险。
7.2 安全提醒
cpolar 生成的是随机临时地址,隧道一关立即失效,所以适合短时调试。但如果你在 MCP Server 里挂了数据库账号、内部 API Key 或用户数据,千万不要用公网隧道直接暴露。本文示例里的 Resource 只是返回字符串,没有敏感信息,所以才能这样操作。生产环境请通过内网、带鉴权的网关或专用通道访问,而不是临时穿透。
7.3 最后看一眼用量
问题拆完,模型的调用量也产生了。回到 https://taotoken.net/?utm_source=taotoken_aicg_blog_end ,在用量页面里看看刚才那几轮分析消耗了多少 token。这样可以建立一个大致的感知:用 Claude Code 排一次 MCP 故障,大约会烧掉多少额度。下次再遇到 Resource 看不到的问题,你就会更清楚该优先查网络链路,还是先看模型通道有没有掉线。




被折叠的 条评论
为什么被折叠?



