首页 / 资讯中心 / 文章详情

吴恩达讲解MCP基础概念:从客户端-服务器架构到Streamable HTTP的TaoToken实践

吴恩达讲解MCP基础概念:从客户端-服务器架构到Streamable HTTP的TaoToken实践 ★ FEATURED ARTICLE
1. 从一次 MCP 接入翻车说起客户端-服务器架构到底怎么跑你可能已经看过吴恩达那期讲解 MCP 的视频里面把 MCP 拆成客户端、服务器、工具、资源、提示词模板几个部分讲得很清楚。但真正动手的时候问题往往出在“连接”这一步服务器写好了客户端却连不上本地 stdio 能跑换成远程 Streamable HTTP 就报错SDK 版本对不上初始化流程直接卡死。我自己第一次搭 MCP 服务端时用的是 Python SDK本地 stdio 传输跑得挺顺结果一换成远程 Streamable HTTP客户端一直停在 initialize 阶段日志里只有一行connection closed。后来才发现是端点路径写错了服务器监听的是/mcp客户端却连到了根路径。这种坑在 MCP 里特别常见因为 MCP 的客户端-服务器架构是一对一连接主机内部维护多个客户端每个客户端对应一个服务器连接任何一环对不上整条链路就断了。MCP 是什么一句话它是一个开放协议标准化了大语言模型应用如何获取工具、数据资源和提示词模板。能做什么让你的 AI 应用不用为每个数据源重复写集成逻辑构建一次、随处复用。适合谁正在做 AI Agent、研究助手、编码助手需要连接 GitHub、Google Drive、本地文件系统这类外部系统的开发者。这篇不重复视频里的概念而是把镜头对准“怎么跑起来”。我会用 TaoToken 统一 API 通道作为模型侧入口配合 Python MCP SDK从服务端配置到客户端调用再到 Streamable HTTP 连通性验证一步步走完。你跟着做能拿到一份可复制的配置片段、一段能跑的客户端连接代码以及一套排错对照表。MCP 的通信机制里初始化流程是关键客户端发 initialize 请求服务器返回响应并发送通知确认然后双方进入消息交换阶段。这个阶段里客户端可以发请求服务器也可以发请求通知消息双向传递最后连接终止。理解这套流程比背 API 名字重要得多因为大部分连接问题都出在初始化没走完。传输机制这块本地服务器用标准输入输出客户端把服务器作为子进程启动通过 stdin/stdout 读写。远程服务器早期用 HTTPSSE只支持有状态连接新版本引入 Streamable HTTP同时支持有状态和无状态。Streamable HTTP 通过 HTTP 的 GET 和 POST 请求访问特定端点比如/mcp路径初始化请求服务器返回响应想启动或升级 SSE 功能可以发一个可选的 GET 请求否则就发 POST 请求收响应。未来 Streamable HTTP 是推荐方式因为它能同时覆盖两种连接模式。下面进入实操。我会先讲 TaoToken 的前置准备再给可复制的服务端配置然后是客户端连接代码接着验证请求最后把常见报错一个个拆开。2. TaoToken 前置准备统一 API 通道与 MCP 的关系MCP 解决的是“AI 应用怎么连外部工具和数据源”但它不负责模型本身怎么调用。你的 MCP 客户端里最终还是要有一个 LLM 来理解用户意图、决定调用哪个工具。TaoToken 在这里的角色就是提供统一的 API 通道让你在 MCP 客户端里用同一个入口调用不同模型不用为每个模型单独配一套鉴权和端点。先明确三件套Base URL、API Key、Model ID。这三样在 MCP 客户端配置里缺一不可后面写配置文件时会反复用到。Base URL 用https://taotoken.net/api注意这个地址不带任何查询参数。API Key 在控制台的 API Keys 页面生成生成后复制保存页面关掉就看不到了。Model ID 根据你要用的模型填比如claude-sonnet-4-20250514这类标识具体以模型对话页面展示的为准。如果你还没生成 Key可以走这个路径先打开官网了解服务范围再进控制台创建 API Key。官网地址是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content控制台在https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI Keys 页面在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。这三个链接按顺序走一遍Key 就到手了。拿到 Key 之后先别急着写 MCP 服务端。我建议先用模型对话页面做一次最小验证确认 Key 能用、模型能回。模型对话地址是https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content在里面发一句“你好”能收到回复就说明通道没问题。这一步花不了一分钟但能帮你排除掉后面一半的报错来源。为什么要在 MCP 之前做这一步因为 MCP 客户端的报错经常是复合的可能是 MCP 服务器没起来也可能是模型侧鉴权失败还可能是传输层断了。如果你先确认模型通道是通的后面排错就只需要盯 MCP 这一层。TaoToken 的接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content里面有针对不同语言和框架的接入示例。写 MCP 客户端时模型调用部分可以直接参考文档里的 Python 示例把 Base URL 和 Key 换成你自己的就行。这里有个细节MCP 客户端里调用模型和普通脚本里调用模型用的是同一套 API。区别在于MCP 客户端会把工具定义、资源列表、提示词模板一起塞进上下文让模型知道有哪些工具可用。所以你在配置模型参数时除了 Base URL、Key、Model ID还要留意上下文长度因为工具定义会占掉一部分 token。如果你打算长期跑编码类 Agent或者需要频繁调用模型做工具编排可以考虑 Coding Plan地址是https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。它适合那种需要持续、稳定调用模型的场景比按次调用更省心。前置准备就这些。总结一下Base URL 用https://taotoken.net/apiKey 从 API Keys 页面生成Model ID 按需选先用模型对话验证通道再进 MCP 配置。下面进入服务端配置。3. 可复制配置MCP 服务端与客户端 settings 片段这一节给两份配置一份是 MCP 服务端的一份是客户端的。服务端用 Python SDK 写客户端用 JSON 配置。两份都尽量做到复制即用你只需要替换 Key 和路径。先看服务端。MCP 服务端的核心是定义工具、资源、提示词模板然后选择传输方式。本地调试用 stdio远程部署用 Streamable HTTP。下面是一个最小可用的服务端示例暴露一个工具、一个资源、一个提示词模板# mcp_server.py from mcp.server.fastmcp import FastMCP mcp FastMCP(demo-server) mcp.tool() def add(a: int, b: int) - int: 两数相加 return a b mcp.resource(config://app) def get_config() - str: 返回应用配置 return app_namedemo,version1.0 mcp.prompt() def summarize(text: str) - str: 生成摘要提示词 return f请用三句话总结以下内容\n{text} if __name__ __main__: mcp.run(transportstreamable-http, host0.0.0.0, port8000)这段代码里mcp.tool()装饰的函数会自动生成工具模式定义客户端调用时会带上参数和返回值类型。mcp.resource()暴露只读数据URI 可以自定义这里用了config://app这种命名方式。mcp.prompt()定义提示词模板用户按需选择不用自己从零写提示工程。传输方式这里选了streamable-http监听 8000 端口。如果你只想本地跑把transport改成stdio去掉 host 和 port 参数就行。Streamable HTTP 的好处是同时支持有状态和无状态连接远程部署时更灵活。服务端跑起来后客户端需要一份配置来连接。如果你用的是 Cline、Claude Code 这类支持 MCP 的客户端配置通常是一个 JSON 文件。下面这份配置同时覆盖了 MCP 服务端连接和模型侧调用{ mcpServers: { demo-server: { url: http://127.0.0.1:8000/mcp, transport: streamable-http } }, llm: { baseUrl: https://taotoken.net/api, apiKey: 你的_API_KEY, modelId: claude-sonnet-4-20250514 } }注意url里的路径是/mcp这是 Streamable HTTP 的端点路径。很多连接失败就是因为这里写成了根路径或者别的路径。transport字段明确指定streamable-http避免客户端猜错。如果你用的是 Codex 这类需要auth.json的工具配置会不太一样。Codex 的auth.json通常长这样{ base_url: https://taotoken.net/api, api_key: 你的_API_KEY, model: claude-sonnet-4-20250514 }三件套还是那三样Base URL、Key、Model ID。不管客户端是 JSON、TOML 还是auth.json这三个值不能少。再给一份 TOML 格式的适合某些用 TOML 做配置的客户端[mcp_servers.demo-server] url http://127.0.0.1:8000/mcp transport streamable-http [llm] base_url https://taotoken.net/api api_key 你的_API_KEY model_id claude-sonnet-4-20250514三份配置的核心信息一致你按自己客户端的格式选一份。配置写完后先别急着启动客户端用 curl 验证一下服务端是否可达。4. 验证请求Streamable HTTP 连通性与客户端调用服务端和配置都就绪后先做连通性验证。这一步能帮你把“服务端没起来”和“客户端配置错”两类问题分开。先用 curl 发一个初始化请求。Streamable HTTP 的初始化走 POST端点是你配置里的/mcpcurl -X POST http://127.0.0.1:8000/mcp \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 1, method: initialize, params: { protocolVersion: 2024-11-05, capabilities: {}, clientInfo: {name: curl-test, version: 1.0} } }如果服务端正常你会收到一个 JSON-RPC 响应里面包含serverInfo和capabilities。这一步走通说明 Streamable HTTP 传输层没问题。接着验证工具调用。发一个tools/list请求看看服务端暴露了哪些工具curl -X POST http://127.0.0.1:8000/mcp \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 2, method: tools/list, params: {} }响应里应该能看到add这个工具参数是a和b返回类型是整数。如果这里返回空列表说明服务端的mcp.tool()装饰器没生效检查一下 SDK 版本和装饰器写法。然后调一次工具curl -X POST http://127.0.0.1:8000/mcp \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 3, method: tools/call, params: { name: add, arguments: {a: 3, b: 4} } }预期返回7。这一步通了说明工具定义、参数解析、执行返回整条链路都正常。curl 验证完之后再用 Python 客户端跑一遍完整流程。下面这段代码用 MCP SDK 的客户端接口连接服务端并调用工具# mcp_client.py import asyncio from mcp import ClientSession from mcp.client.streamable_http import streamablehttp_client async def main(): async with streamablehttp_client(http://127.0.0.1:8000/mcp) as (read, write, _): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() print(可用工具:, [t.name for t in tools.tools]) result await session.call_tool(add, {a: 3, b: 4}) print(调用结果:, result.content) asyncio.run(main())跑之前确认一下 SDK 版本streamablehttp_client是新版才有的旧版用的是sse_client。如果你装的是旧版要么升级 SDK要么把传输方式改成 SSE。升级命令pip install --upgrade mcp客户端跑通后你会看到可用工具列表和调用结果。这时候再把模型侧接进来在客户端里调用 TaoToken 的 API把工具定义塞进上下文让模型决定调用哪个工具。模型对话页面可以用来验证模型侧是否正常地址是https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。完整链路是用户输入 → 模型理解意图 → 模型返回工具调用请求 → MCP 客户端执行工具 → 结果回传模型 → 模型生成最终回复。这条链路里MCP 负责工具执行TaoToken 负责模型调用两者通过客户端里的配置衔接。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节把 MCP 接入过程中最常见的几类报错拆开讲。每个报错都给现象、原因、解法你对照着查。401 Unauthorized。现象是客户端调用模型时返回 401或者 MCP 服务端返回 401。如果是模型侧检查 API Key 是否复制完整、是否有多余空格、是否已经过期。TaoToken 的 Key 在 API Keys 页面生成生成后立即复制页面刷新后不再显示完整 Key。如果是 MCP 服务端返回 401检查服务端是否配置了鉴权中间件以及客户端请求头里有没有带对凭证。local proxy failed。现象是客户端启动时报local proxy failed或类似错误。这通常和本地网络环境有关检查代理设置是否干扰了本地回环地址。MCP 服务端跑在127.0.0.1时请求不应该走外部代理。把127.0.0.1和localhost加入代理排除列表或者临时关闭代理再试。reading choices 报错。现象是模型调用返回reading choices相关错误通常是响应格式不符合预期。检查 Model ID 是否写对Base URL 是否是https://taotoken.net/api请求体是否符合 OpenAI 兼容格式。如果用的是非 OpenAI 兼容的模型确认客户端是否支持该模型的响应结构。OAuth 相关报错。现象是客户端提示 OAuth 认证失败或 token 无效。MCP 的远程服务器可能要求 OAuth 鉴权检查客户端是否配置了正确的 OAuth 流程。如果你用的是 TaoToken 的 API Key 鉴权确认客户端没有误走 OAuth 分支。有些客户端会优先尝试 OAuth需要在配置里显式指定鉴权方式为 API Key。连接停在 initialize 阶段。现象是客户端日志显示 initialize 请求已发送但没有收到响应。检查服务端是否真的在监听配置的端口端点路径是否是/mcp传输方式是否匹配。用 curl 发一个 initialize 请求能收到响应就说明服务端没问题问题在客户端配置。工具列表为空。现象是tools/list返回空数组。检查服务端装饰器是否生效SDK 版本是否支持当前写法函数是否有类型注解。mcp.tool()装饰的函数需要明确的参数类型和返回类型否则模式定义生成会失败。Streamable HTTP 连接被重置。现象是 POST 请求发出后连接被重置。检查服务端是否支持 Streamable HTTP有些旧版 SDK 只支持 SSE。升级 SDK 到最新版或者把传输方式改成sse再试。排错时有个通用思路先用 curl 验证服务端再用 Python 客户端验证 SDK最后接模型。每一步单独验证不要混在一起。这样出问题时能快速定位是哪一层。如果你在排错过程中需要查接入文档地址是https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。API Key 管理和生成在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。6. 把 MCP 服务端接到更多客户端复用与扩展MCP 服务端写一次可以接到多个客户端。这是 MCP 相比自定义工具集成的核心优势不用为每个应用重复写集成逻辑。你写的那个demo-server既能被 Python 客户端调用也能被支持 MCP 的桌面应用调用。只要客户端支持 Streamable HTTP 传输配置里填上服务端地址和端点路径就能连上。如果你用的是 Claude Code 这类编码助手它内置了 MCP 客户端能力配置方式参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content里的说明。复用服务端时注意传输方式的兼容性。本地 stdio 适合单机调试远程 Streamable HTTP 适合多客户端共享。如果你要把服务端部署到远程把transport改成streamable-http监听0.0.0.0客户端配置里的 URL 换成服务器公网地址或内网地址。提示词模板这块服务端定义好之后客户端可以按需选择。用户不用自己写提示工程直接选模板就行。这是 MCP 提示词模板的设计初衷减轻用户在提示工程上的负担让经过验证的提示词能被复用。资源系统也是类似逻辑。服务端暴露只读数据客户端可以选择是否纳入上下文。资源用 URI 标识支持 MIME 类型指定动态资源可以用模板化 URI类似 Python 的 f-string 格式化。如果你要长期跑编码类 Agent或者需要频繁调用模型做工具编排Coding Plan 会比按次调用更合适地址是https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。它适合那种需要持续、稳定调用模型的场景。最后给一个实用技巧MCP 服务端的日志一定要打开。Python SDK 默认会输出连接、初始化、工具调用的日志这些日志在排错时比客户端报错更有用。如果日志不够详细可以在服务端加日志级别配置把 DEBUG 级别的日志打开能看到完整的消息交换过程。服务端和客户端都跑通之后你可以试着把工具、资源、提示词模板逐步加多观察模型在工具选择上的表现。工具描述写得越清楚模型选得越准。这是提示词模板和工具定义需要反复打磨的地方也是 MCP 实践里最花时间但最值得投入的部分。
阅读完成 · 觉得有帮助?
咨询建站