☰
深度学习-163-MCP技术之使用Cherry Studio调用本地自定义mcp-server:把STDIO/SSE配置改到TaoToken
2026/10/7 19:52:04 网站建设 项目流程

1. 从一次本地 MCP 调用失败说起:Cherry Studio 接 mcp-server 到底卡在哪

如果你最近在折腾 MCP,大概率会遇到这样一个场景:本地用 Python 写了个 mcp-server,mcp dev server.py在浏览器里点一点 Tools 和 Resources 都正常,可一旦把它塞进 Cherry Studio,要么连接状态一直转圈,要么聊天时模型根本不触发工具调用。问题往往不在你的业务代码,而在传输层配置——STDIO 的启动命令、参数换行、工作目录,SSE 的 endpoint 和鉴权,任何一处对不上,客户端就拿不到工具列表。

MCP 全称 Model Context Protocol,你可以把它理解成 AI 大模型的标准化工具箱接口。mcp-server 就是那个工具箱本体,本质是一段 Python 或 Node.js 程序,对外暴露 Tools(可产生副作用,类似 POST)和 Resources(只读数据,类似 GET)。Cherry Studio 则是负责把大模型和这些工具箱连起来的桌面客户端。它支持两种连接方式:STDIO 走操作系统标准输入输出,适合本地进程;SSE 走 HTTP 长连接,适合把 server 单独部署后远程调用。

这篇内容聚焦一件事:把本地自定义 mcp-server 的 endpoint 与鉴权配置,统一改到 TaoToken 通道,并在 Cherry Studio 里完成一次可复现的调用。适合已经写过简单 mcp-server、但在客户端接入环节反复踩坑的开发者。下面从环境准备讲到 STDIO/SSE 两套配置,再给出连通性验证和报错排查,命令和配置片段都可以直接复制。

2. 前置准备:TaoToken 通道与 mcp-server 工程初始化

在动 Cherry Studio 之前,先把两件事做扎实:一是拿到 TaoToken 的调用凭证,二是把本地 mcp-server 工程跑起来。很多人跳过第一步直接配客户端,结果模型侧根本没通,误以为是 MCP 配置错了。

先说 TaoToken。它是一个统一的大模型调用通道,提供兼容 OpenAI 风格的 API 入口,Base URL 是https://taotoken.net/api。你需要先在控制台创建一个 API Key,这个 Key 后面会同时用在两处:Cherry Studio 的模型配置,以及 mcp-server 内部如果要用大模型能力时的调用。控制台地址是https://taotoken.net/console,API Keys 管理页在https://taotoken.net/api-keys。创建时建议按用途命名,比如cherry-mcp-local,方便后面排查是哪个 Key 出的问题。

接着初始化 mcp-server 工程。推荐用 uv 管理 Python 项目,版本隔离干净,启动命令也短。假设你已经装好 uv,执行:

uv init mcp_server -p 3.13 cd mcp_server uv add "mcp[cli]"

uv init会生成.venv、pyproject.toml和main.py。uv add "mcp[cli]"把 MCP 的 SDK 和命令行工具装上,后面mcp dev调试模式就靠它。工程结构大致是这样:

mcp_server/ ├── .venv/ ├── pyproject.toml ├── main.py └── server.py # 我们接下来要写的

然后写server.py。核心就三段:导入 FastMCP、用装饰器声明工具和资源、最后mcp.run()指定传输协议。

from mcp.server.fastmcp import FastMCP mcp = FastMCP("Demo") @mcp.tool() def add(a: int, b: int) -> int: """Add two numbers""" return a + b @mcp.resource("greeting://{name}") def get_greeting(name: str) -> str: """Get a personalized greeting""" return f"Hello, {name}!" if __name__ == "__main__": mcp.run(transport='stdio')

这里有两个细节必须强调。第一,@mcp.tool()下面函数的 docstring 不能省,它是用自然语言告诉大模型这个工具干什么的,模型靠它决定要不要调用。第二,类型标注a: int, b: int -> int也要写全,模型据此判断传参类型,缺了容易调用失败。@mcp.resource则对应只读数据,不会产生副作用,类似 REST 里的 GET。

写完先用调试模式验证一遍:

uv run mcp dev server.py

浏览器打开http://127.0.0.1:6274/,点 Connect,在 Tools 标签里调add,传2和3,应该返回5;在 Resources 里请求greeting://world,返回Hello, world!。这一步通了,说明 server 本身没问题,接下来所有问题都出在客户端配置上。

3. 可复制配置:STDIO 与 SSE 两套 Cherry Studio 接入片段

这一节是全文的核心,给出 Cherry Studio 侧可以直接抄的配置。先明确一个原则:Cherry Studio 里 MCP 服务器的配置,本质是告诉客户端「用什么方式、在哪个路径、启动哪个程序」或者「连哪个 URL」。STDIO 和 SSE 的差别就在这里。

3.1 STDIO 方式:command 与 args 的换行陷阱

STDIO 模式下,Cherry Studio 会自己拉起 mcp-server 进程,通过标准输入输出通信。配置项主要是 command 和 args。很多人第一次配就栽在 args 上——Cherry Studio 要求每个参数单独一行,不能像命令行那样空格分隔。

在 Cherry Studio 设置里找到 MCP 服务器,新增一个,类型选stdio,然后填:

command: D:\Anaconda3\envs\python311\Scripts\uv.exe args: --directory D:\CODE\mcp_server run --with mcp mcp run server.py

注意command要填 uv 可执行文件的绝对路径,不是uv这个字符串。Windows 下如果你用 conda 环境,路径类似上面;如果用官方 uv 安装,通常在%USERPROFILE%\.local\bin\uv.exe。--directory指定工程目录,保证 uv 能找到pyproject.toml和.venv。后面run --with mcp mcp run server.py是让 uv 在临时环境里带上 mcp 依赖去执行 server.py。

如果你希望 mcp-server 内部也走 TaoToken 通道调用模型,可以在启动参数里注入环境变量,或者直接在 server.py 里读取。更规范的做法是在 Cherry Studio 的 MCP 配置里加 env 字段:

{ "mcpServers": { "local-demo-stdio": { "command": "D:\\Anaconda3\\envs\\python311\\Scripts\\uv.exe", "args": [ "--directory", "D:\\CODE\\mcp_server", "run", "--with", "mcp", "mcp", "run", "server.py" ], "env": { "TAOTOKEN_BASE_URL": "https://taotoken.net/api", "TAOTOKEN_API_KEY": "sk-你的Key" } } } }

这份 JSON 对应 Cherry Studio 图形界面里的字段,图形界面保存后底层就是这个结构。三件套要记牢:Base URL 是https://taotoken.net/api,Key 是控制台创建的,Model ID 在模型配置里选。STDIO 模式下 MCP 本身不直接暴露 URL,但 server 内部若调用模型,用的就是这套。

3.2 SSE 方式:endpoint 与鉴权改到 TaoToken 统一通道

SSE 模式适合把 mcp-server 单独跑在一个进程或一台机器上,Cherry Studio 通过 HTTP 连接。改法很简单,把server.py最后一行改成:

if __name__ == "__main__": mcp.run(transport='sse')

然后启动服务端。FastMCP 默认监听0.0.0.0:8000,SSE 路径是/sse:

uv run server.py

启动后你会看到类似Uvicorn running on http://0.0.0.0:8000的输出。此时在 Cherry Studio 里新增 MCP 服务器,类型选sse,URL 填:

http://127.0.0.1:8000/sse

如果 server 部署在远程,把127.0.0.1换成实际地址。这里就是「把 endpoint 改到 TaoToken 统一通道」的关键:当你的 mcp-server 需要调用大模型时,不要在代码里散落各家 API 地址,而是统一读TAOTOKEN_BASE_URL,这样 STDIO 和 SSE 两种模式下 server 内部逻辑完全一致,只是对外传输方式不同。

SSE 模式下如果要做鉴权,可以在 FastMCP 初始化时传入自定义的 Starlette app,或者用反向代理加 Header 校验。简单场景下,本地调试可以先不加鉴权,等部署到内网再补。下面是一个带环境变量读取的 server 片段,展示如何把模型调用统一到 TaoToken:

import os from mcp.server.fastmcp import FastMCP BASE_URL = os.getenv("TAOTOKEN_BASE_URL", "https://taotoken.net/api") API_KEY = os.getenv("TAOTOKEN_API_KEY", "") mcp = FastMCP("Demo") @mcp.tool() def ask_model(prompt: str) -> str: """Send a prompt to the unified model channel and return the answer""" # 这里用你习惯的 HTTP 客户端调用 BASE_URL + /v1/chat/completions # Header 带上 Authorization: Bearer {API_KEY} return f"received: {prompt}" if __name__ == "__main__": mcp.run(transport='sse')

STDIO 与 SSE 的取舍可以对照下面这张表:

维度STDIOSSE
进程位置客户端本机拉起独立部署,可远程
通信方式标准输入输出HTTP 长连接
配置重点command + args 换行URL + 鉴权 Header
适用场景本地开发调试内网共享、多客户端
启动命令uv run mcp run server.pyuv run server.py

配完保存并激活,切到工具标签,应该能看到add和ask_model两个工具。看不到就回到第 5 节排查。

4. 验证请求:从工具列表到一次成功的模型调用

配置保存只是第一步,真正要验证的是「模型能不能看到工具、能不能调起来」。这一步分三层验证,逐层排除。

第一层,验证 mcp-server 本身。STDIO 模式下,Cherry Studio 激活服务器后,工具列表应该立刻出现。如果列表为空,说明客户端没成功拉起进程,去看 Cherry Studio 的日志,通常会有spawn uv ENOENT之类的提示,意思是找不到 uv 可执行文件,回到第 3 节把 command 改成绝对路径。

第二层,验证模型侧通道。在 Cherry Studio 的模型设置里,添加一个自定义模型提供商,Base URL 填https://taotoken.net/api,API Key 填控制台创建的 Key,Model ID 填你开通的模型名。保存后点测试,能返回内容说明通道通了。这一步不通,后面 MCP 调用了也没意义,因为模型根本没法发起工具调用请求。

第三层,端到端聊天测试。新建对话,选择刚才配好的模型,在输入框上方勾选或激活你的 MCP 服务器。然后发一句:

帮我算一下 128 加 256 等于多少

如果一切正常,你会看到对话里出现工具调用过程:模型先输出一段「我要调用 add 工具」,然后显示参数{"a": 128, "b": 256},接着返回结果384,最后模型用自然语言总结。这个过程在 Cherry Studio 里通常折叠成一个小卡片,点开能看到完整的请求和响应。

SSE 模式的验证多一步:先在终端确认服务端在跑。执行:

curl -N http://127.0.0.1:8000/sse

正常会看到持续输出的事件流,类似event: endpoint和data: /messages/?session_id=...。如果 curl 直接报连接拒绝,说明 server 没启动或端口被占。确认服务端 OK 后,Cherry Studio 里点激活,工具列表出现即成功。

再补一个模型侧的直接验证,确认 TaoToken 通道可用:

curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的Key" \ -H "Content-Type: application/json" \ -d '{ "model": "你的模型ID", "messages": [{"role": "user", "content": "ping"}] }'

返回带choices字段的 JSON 就说明通道正常。这一步和 MCP 无关,但能帮你快速区分「是模型通道问题」还是「是 MCP 配置问题」。我试过好几次,最后发现是 Key 复制时多了个空格,模型侧一直 401,白白怀疑了半天 MCP。

5. 本篇常见错排查:401、local proxy failed 与 reading choices

这一节按真实报错来,遇到哪个查哪个。

401 Unauthorized。出现在模型侧,说明 TaoToken 的 Key 不对或没带上。检查三处:Key 是否复制完整、Header 是否是Authorization: Bearer sk-xxx、Base URL 是否是https://taotoken.net/api而不是别的路径。注意 Base URL 后面拼接的是/v1/chat/completions,不要重复写/v1。

local proxy failed / spawn uv ENOENT。出现在 STDIO 模式激活 MCP 服务器时。根因是 Cherry Studio 找不到 command 指定的可执行文件。解决:把 command 改成 uv 的绝对路径,Windows 下用双反斜杠或正斜杠。另外确认--directory指向的目录里确实有pyproject.toml,否则 uv 会报找不到项目。

reading 'choices' of undefined。这个报错通常出现在模型返回体结构不符合预期时。常见原因是 Base URL 配错,请求打到了非兼容端点,返回的不是标准 OpenAI 格式。确认 URL 是https://taotoken.net/api,并且模型 ID 填的是通道里真实存在的。如果用的是 SSE 模式且 server 内部也调模型,检查 server 里读的环境变量有没有生效。

OAuth 相关报错。如果你接的是需要 OAuth 的远程 MCP 服务,Cherry Studio 会弹出授权流程。本地自定义 server 一般用不到 OAuth,但如果你的 server 部署在需要鉴权的网关上,可能会看到OAuth callback failed。此时优先检查回调地址是否可达,本地调试建议先关掉鉴权,跑通链路再补。

工具列表为空但进程已启动。STDIO 模式下进程起来了,但工具没注册上。检查@mcp.tool()的 docstring 是否为空,类型标注是否完整。FastMCP 对这两项有要求,缺了可能导致工具不被识别。另外确认mcp.run()的 transport 和客户端配置的类型一致,STDIO 配成 SSE 会连不上。

SSE 连接后立刻断开。多半是 URL 少了/sse后缀,或者服务端监听地址和客户端访问地址不一致。本地调试统一用127.0.0.1,不要一边localhost一边0.0.0.0。如果服务端在容器里,确认端口映射正确。

排查顺序建议固定下来:先 curl 模型通道,再 curl SSE endpoint,最后看 Cherry Studio 日志。这样能快速定位是通道问题、server 问题还是客户端配置问题,不用来回猜。

6. 把配置沉淀下来:Coding Plan 与后续接入

链路跑通之后,建议把这份配置沉淀成可复用的模板。STDIO 的 JSON 片段、SSE 的 URL 和鉴权 Header、TaoToken 的 Base URL 与 Key 管理方式,整理成一个mcp-config.md放在工程根目录。下次换机器或换客户端,直接抄,不用重新踩一遍换行和路径的坑。

如果你后续要做长期的编码类 Agent,或者需要更稳定的模型调用配额,可以了解下 Coding Plan,它面向持续编码和 Agent 场景,地址是https://taotoken.net/coding-plan。模型对话调试入口在https://taotoken.net/chat,接入文档在https://taotoken.net/doc,API Keys 管理在https://taotoken.net/api-keys。这几个入口按需取用,本地 MCP 调试阶段用 API Keys 和文档就够了。

最后留一个实用习惯:每次改完 mcp-server 代码,先在mcp dev里验证工具行为,再重启 Cherry Studio 里的服务器。客户端有缓存,改了代码不重启,看到的还是旧工具列表。这个坑我踩过不止一次,明明代码改了,聊天时调用的还是老逻辑,重启一下就好。把「改代码 → mcp dev 验证 → 重启客户端 → 聊天测试」当成固定流程,能省下大量排查时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询