MCP 入门指南:用 TypeScript 与 Python 让 AI 连接真实世界

发布时间:2026/10/12 3:01:30
MCP 入门指南:用 TypeScript 与 Python 让 AI 连接真实世界 1. 为什么你的 AI 还困在沙盒里MCP Server 到底解决什么问题你可能已经习惯了这样的场景让 Claude 或 GPT 帮你分析一段代码它讲得头头是道但你让它直接读一下你本地项目里的config.json它就无能为力了。大语言模型本身很强但它被关在一个没有文件系统、没有数据库、没有内网 API 的沙盒里。每次想让 AI 接触真实数据就得自己写一套 Function Calling 的适配层序列化参数、解析返回、注入上下文换个 AI 应用又得重写一遍。MCPModel Context Protocol就是冲着这个重复劳动来的。它定义了一套 AI 应用与外部工具之间的通信标准你可以把它理解成 AI 世界的 USB 接口你按协议实现一个 MCP Server所有支持 MCP 的宿主应用Claude Desktop、各类 IDE 插件、自研 Agent 框架都能直接调用你的工具不需要为每个宿主单独适配。这篇文章面向第一次接触 MCP 的开发者目标很明确从零跑通一个可运行的 MCP Server。我会用 TypeScript 和 Python 各写一个最小示例给出完整的项目结构、依赖清单、启动命令以及连接验证和调用结果检查的步骤。你跟着做半小时内就能让 AI 调用到你本地的工具和数据。先厘清三个核心角色后面写代码时心里有张图Host运行 AI 模型的宿主应用比如 Claude Desktop它负责管理多个客户端连接。Client由 Host 创建与某个 Server 保持一对一连接处理协议层的 JSON-RPC 通信。Server你写的独立进程向 AI 暴露 Tools可执行操作、Resources可读数据、Prompts提示词模板三类能力。通信底层是 JSON-RPC 2.0传输方式主要有两种stdio 走标准输入输出适合本地进程HTTP SSE 适合远程服务。入门阶段我们用 stdio配置最简单调试也直观。MCP Server 能暴露的三类能力决定了 AI 能做什么能力方向典型场景谁触发ToolsAI 执行操作查数据库、调 API、跑命令模型主动调用ResourcesAI 读取数据读文件、取 schema、加载配置应用控制加载Prompts复用模板代码审查、SQL 生成用户或应用选择一个工具的定义长这样本质是一段带 JSON Schema 的描述告诉模型这个工具叫什么、干什么、需要什么参数{ name: search_files, description: 在指定目录中搜索文件, inputSchema: { type: object, properties: { path: { type: string }, pattern: { type: string } } } }模型看到这段描述后会在需要时发起调用你的 Server 执行完把结果按协议返回。整个过程你不需要关心模型内部怎么决策只需要把工具实现好、描述写清楚。描述写得越准确模型选对工具的概率越高这一点在后面实战里会反复体现。2. 动手前的准备TaoToken 接入与 MCP 开发环境搭建写 MCP Server 本身不需要联网调用大模型但你要验证「AI 真的能调用我的工具」就需要一个能连 MCP 的宿主环境。我实测下来用 TaoToken 提供的模型对话和 API 能力来配合验证是最顺的路径它兼容主流协议配置里填 Base URL、Key、Model ID 三件套就能跑省去自己搭一套 Agent 框架的功夫。先把账号和 Key 准备好。打开 https://taotoken.net/api-keys 创建一个 API Key复制保存。这个 Key 后面会用在宿主配置里格式通常以sk-开头。如果你还没注册从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 进去即可。接着确认本地开发环境。TypeScript 版本需要 Node.js 18 以上Python 版本需要 Python 3.10 以上。先检查版本node --version python --version如果版本不够去官网下载对应安装包升级。Node 建议用 nvm 管理多版本Python 建议用 pyenv 或直接装最新稳定版。TypeScript 项目的初始化命令如下注意modelcontextprotocol/sdk是核心依赖zod用来定义参数 schemamkdir my-mcp-server cd my-mcp-server npm init -y npm install modelcontextprotocol/sdk zod npm install -D typescript types/node tsx npx tsc --initPython 项目更简单建虚拟环境后装一个包就够mkdir my-mcp-server cd my-mcp-server python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install mcp这里有个容易踩的坑Python 的mcp包在 3.10 以下版本会报语法错误因为 FastMCP 用到了新版的类型标注语法。如果你在 3.9 环境里装完运行报TypeError: type object is not subscriptable别怀疑代码先升级 Python。关于宿主配置MCP Server 通过 stdio 启动时宿主会用你配置的 command 和 args 去拉起进程。所以配置里最关键的是路径要写绝对路径相对路径在不同工作目录下会找不到文件。这一点在下一节的配置文件里会具体展示。如果你打算长期做 MCP 相关的编码和 Agent 开发可以了解一下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content它在连续编码场景下的额度策略更划算。不过入门阶段先用按量计费的 API Key 完全够用。环境准备好后目录结构建议这样组织TypeScript 和 Python 分开避免依赖混淆my-mcp-server/ ├── ts-version/ │ ├── src/index.ts │ ├── package.json │ └── tsconfig.json └── py-version/ ├── server.py └── venv/3. 可复制配置TypeScript 与 Python 双版本 MCP Server 实现这一节直接给可运行的代码。先看 TypeScript 版本实现一个天气查询工具重点是理解server.tool()的注册方式和返回结构。创建ts-version/src/index.tsimport { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { z } from zod; const server new McpServer({ name: weather-server, version: 1.0.0, }); const weatherData: Recordstring, { temp: number; condition: string } { beijing: { temp: 22, condition: 晴 }, shanghai: { temp: 25, condition: 多云 }, shenzhen: { temp: 28, condition: 阵雨 }, }; server.tool( get_weather, 获取指定城市的天气信息, { city: z.string().describe(城市名称拼音) }, async ({ city }) { const weather weatherData[city.toLowerCase()]; if (!weather) { return { content: [{ type: text, text: 未找到城市 ${city} 的天气数据 }], }; } return { content: [ { type: text, text: ${city} 天气${weather.condition}温度 ${weather.temp}°C, }, ], }; } ); async function main() { const transport new StdioServerTransport(); await server.connect(transport); console.error(Weather MCP Server 已启动); } main().catch(console.error);对应的ts-version/package.json必须声明type: module否则 ESM 导入会报错{ name: weather-mcp-server, version: 1.0.0, type: module, scripts: { build: tsc, start: node dist/index.js, dev: tsx src/index.ts } }tsconfig.json里把module设为NodeNext、target设为ES2022outDir指向dist。改完执行npm run build产物在dist/index.js。Python 版本用 FastMCP代码量更少。创建py-version/server.pyfrom mcp.server.fastmcp import FastMCP mcp FastMCP(weather-server) weather_data { beijing: {temp: 22, condition: 晴}, shanghai: {temp: 25, condition: 多云}, shenzhen: {temp: 28, condition: 阵雨}, } mcp.tool() def get_weather(city: str) - str: 获取指定城市的天气信息 Args: city: 城市名称拼音 weather weather_data.get(city.lower()) if not weather: return f未找到城市 {city} 的天气数据 return f{city} 天气{weather[condition]}温度 {weather[temp]}°C mcp.resource(weather://cities) def list_cities() - str: 返回支持的城市列表 return \n.join(weather_data.keys()) if __name__ __main__: mcp.run()注意 Python 版本里mcp.tool()装饰器会自动把函数签名和 docstring 转成工具描述所以 docstring 一定要写清楚参数含义模型靠它判断怎么传参。接下来是宿主配置。以 Claude Desktop 为例配置文件路径macOS~/Library/Application Support/Claude/claude_desktop_config.jsonWindows%APPDATA%\Claude\claude_desktop_config.jsonTypeScript 版本配置{ mcpServers: { weather: { command: node, args: [/absolute/path/to/ts-version/dist/index.js] } } }Python 版本配置{ mcpServers: { weather: { command: /absolute/path/to/py-version/venv/bin/python, args: [/absolute/path/to/py-version/server.py] } } }Python 这里强烈建议用虚拟环境里的 python 绝对路径而不是系统python否则依赖找不到会直接启动失败。如果你用的是 Cline 或 CC Switch 这类支持 MCP 的工具配置结构类似同样需要 Base URL、Key、Model ID 三件套来连接模型侧MCP Server 侧则填 command 和 args。4. 验证请求与成功结果确认 AI 真的调用了你的工具配置写完后先别急着开宿主用 MCP Inspector 单独验证 Server 能不能正常响应。这是官方提供的调试工具能直接列出工具、手动调用、看返回npx modelcontextprotocol/inspector node ts-version/dist/index.js运行后终端会输出一个本地地址浏览器打开左侧能看到get_weather工具点进去填{city: beijing}点执行。如果返回北京 天气晴温度 22°C说明 Server 本身没问题。Python 版本用内置的 dev 命令mcp dev py-version/server.py它会启动一个类似的调试界面同样能列出工具和资源。这一步能过再进宿主验证。重启 Claude Desktop在对话里输入「北京今天天气怎么样」。正常情况下Claude 会先显示一个工具调用卡片参数是{city: beijing}然后返回天气结果。如果你看到的是模型直接编了一个天气说明工具没被识别回到上一节检查配置路径。用 TaoToken 的模型对话页面https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content也能做类似验证把 MCP Server 挂上去后发一条需要调用工具的指令观察返回里有没有工具调用记录。验证成功的标志有三个宿主启动日志里出现 Server 已连接对话中模型发起了工具调用返回内容和你 Server 里的数据一致。三个都满足第一个 MCP 场景就跑通了。再补一个更实用的文件搜索工具帮你理解真实场景。TypeScript 版本核心逻辑import * as fs from fs/promises; import * as path from path; async function searchFiles( dir: string, pattern: string, results: string[] [] ): Promisestring[] { const entries await fs.readdir(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath path.join(dir, entry.name); if (entry.isDirectory()) { if (!entry.name.startsWith(.) entry.name ! node_modules) { await searchFiles(fullPath, pattern, results); } } else if (entry.name.toLowerCase().includes(pattern.toLowerCase())) { results.push(fullPath); } } return results; } server.tool( search_by_name, 按文件名搜索文件, { directory: z.string().describe(搜索的根目录), pattern: z.string().describe(文件名匹配模式), }, async ({ directory, pattern }) { try { const results await searchFiles(directory, pattern); return { content: [ { type: text, text: results.length 0 ? 找到 ${results.length} 个文件:\n${results.join(\n)} : 未找到匹配的文件, }, ], }; } catch (error) { return { content: [{ type: text, text: 搜索失败: ${error} }], isError: true, }; } } );Python 版本用Path.rglob更简洁from pathlib import Path mcp.tool() def search_by_name(directory: str, pattern: str) - str: 按文件名搜索文件 Args: directory: 搜索的根目录 pattern: 文件名匹配模式 root Path(directory) if not root.exists(): return f目录不存在: {directory} results [] for p in root.rglob(*): if any(part.startswith(.) or part node_modules for part in p.parts): continue if p.is_file() and pattern.lower() in p.name.lower(): results.append(str(p)) if results: return f找到 {len(results)} 个文件:\n \n.join(results[:50]) return 未找到匹配的文件跑通后你可以让 AI 帮你「在 /Users/me/project 下找所有名字带 config 的文件」它会自动调用这个工具并返回真实路径列表。这就是 MCP 让 AI 连接真实世界的具体形态。5. 本篇常见报错排查401、local proxy failed 与 reading choices入门阶段最容易卡在连接和鉴权上这里按真实报错逐条给排查路径。401 Unauthorized这个报错通常出现在模型侧调用不是 MCP Server 本身。检查你配置里的 API Key 是否完整、有没有多余空格、是否过期。TaoToken 的 Key 在 https://taotoken.net/api-keys 管理重新生成一个替换即可。如果用的是环境变量确认变量名拼写和加载顺序Node 里process.env.XXX在 dotenv 加载前读取会拿到 undefined。local proxy failed / connection refused宿主启动 MCP Server 时进程没拉起来。九成是路径问题。检查配置里的command和args是不是绝对路径Python 版本是否指向虚拟环境里的解释器。手动在终端执行一遍配置里的命令比如node /abs/path/dist/index.js看能不能正常启动。如果报Cannot find module说明依赖没装或构建产物不存在回项目目录跑npm install npm run build。reading choices of undefined这个报错一般出现在模型返回结构解析阶段说明请求没拿到预期的响应体。常见原因是 Base URL 配错比如漏了/v1或多了斜杠。确认你的 Base URL 是https://taotoken.net/api不要带多余路径。另外检查 Model ID 是否拼写正确模型名写错时部分网关会返回空体解析时就报这个错。OAuth / authentication failed如果你用的是 Claude Code 或类似工具它可能走 OAuth 流程。检查登录态是否过期重新走一次授权。如果是 API Key 模式确认请求头格式是Authorization: Bearer sk-xxx少个 Bearer 也会鉴权失败。工具列表为空宿主连上了 Server但看不到工具。检查server.tool()注册是否在server.connect()之前执行异步注册顺序错了会导致工具没挂上。Python 版本检查装饰器是否作用在函数上缩进错误会让装饰器失效。stdio 通信乱码TypeScript 版本里如果用console.log输出调试信息会污染 stdout导致协议解析失败。所有日志必须走console.error因为 stdout 是留给 JSON-RPC 的。这个坑我踩过现象是宿主一直转圈不返回排查半天才发现是日志打错了流。排查顺序建议先手动跑 Server 确认能启动再用 Inspector 确认工具能调用最后才查宿主配置。逐层排除比一上来就怀疑模型靠谱得多。6. 把 MCP 用起来从最小示例到你的第一个真实工具跑通天气和文件搜索之后你已经掌握了 MCP Server 的完整骨架定义工具、注册 schema、处理调用、返回结果。接下来把它换成你真正需要的场景就行。如果你想让 AI 查内部数据库把weatherData换成数据库查询注意用参数化查询防注入。如果想让 AI 调内部 API把 HTTP 请求封装进工具函数超时和重试逻辑写在里面。如果想让 AI 读项目配置用 Resources 暴露文件 URI比 Tools 更合适因为资源是只读的权限边界更清晰。安全上有三条底线值得记住。路径类工具一定要做越界校验用户传../../etc/passwd这种路径时直接拒绝function validatePath(userPath: string, allowedRoot: string): string { const resolved path.resolve(allowedRoot, userPath); if (!resolved.startsWith(allowedRoot)) { throw new Error(路径越界); } return resolved; }参数用 zod 或类型标注做严格约束能枚举就别用自由字符串。工具只暴露必要的操作别把整个 shell 执行能力开放出去。调试时优先用 MCP Inspector它比在宿主里反复重启快得多。日志统一走 stderrstdout 保持干净。性能上耗时操作记得分页返回别一次性把几万行数据塞进上下文。等你需要长期跑编码类 Agent、频繁调用 MCP 工具时可以看看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content额度策略更适合高频场景。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content遇到协议细节可以对照查。现在把你手头最重复的那件事写成第一个工具。比如每天要手动整理的日志、要反复查的配置项、要同步的数据表。写成一个 MCP Server让 AI 替你调。这才是 MCP 真正的价值不是又一个协议而是让 AI 从聊天框里走出来真正碰到你的世界。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询