给 AI 装个"工具箱":MCP 协议入门与 Node.js 实战
你有没有想过一件事:AI 聊天模型很聪明,但它没办法直接读你的本地文件、查天气预报、更新 GitHub Issue,或者在数据库里跑一条 SQL。
这不是能力问题,是协议问题。大模型生在云端,活在自己的世界里。要让它们真正"动起来",你需要一个中间层------一个 AI 能理解和调用的标准接口。
MCP(Model Context Protocol)就是干这个的。它不是某个公司的私有方案,而是 Anthropic 推出来的开放协议,想把 AI 工具调用做到像 USB 接口一样即插即用。
这篇文章不讲概念堆砌,直接上手写一个 Node.js MCP Server,让它能查天气、算时间、读文件,然后让 AI 通过它来完成任务。

一、MCP 到底长什么样?
MCP 的架构只有三个角色:
- Host:AI 宿主,比如 Claude Desktop、Cursor、VS Code 插件
- Client:Host 内部运行的 MCP 客户端,负责连接 Server
- Server:你写的工具,暴露一些"能力"(resources 和 tools)
一个 MCP Server 可以提供:
- Tools:AI 可以调用的函数,比如 get_weather(city)、search_web(query)
- Resources:暴露给 AI 读的数据,比如本地文件、日志、数据库结果
- Prompts:预置的对话模板
通信走 JSON-RPC,传输层可以是 stdio(子进程管道)或者 SSE(HTTP 流)。本地开发用 stdio 就够了,不需要跑 HTTP 服务。
二、搭一个最简 MCP Server
安装依赖
bash
mkdir mcp-weather-demo && cd mcp-weather-demo
npm init -y
npm install @modelcontextprotocol/sdk
创建 server.js
javascript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
const server = new Server(
{ name: 'demo-tools', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'get_current_time',
description: '获取当前时间,支持时区参数',
inputSchema: {
type: 'object',
properties: {
timezone: { type: 'string', description: '时区,如 Asia/Shanghai' },
},
},
},
{
name: 'read_file',
description: '读取本地文本文件',
inputSchema: {
type: 'object',
properties: { path: { type: 'string', description: '文件绝对路径' } },
required: ['path'],
},
},
],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case 'get_current_time': {
const tz = args?.timezone || 'Asia/Shanghai';
const text = new Date().toLocaleString('zh-CN', { timeZone: tz });
return { content: [{ type: 'text', text: '当前时间:' + text }] };
}
case 'read_file': {
const fs = await import('fs/promises');
try {
const content = await fs.readFile(args.path, 'utf-8');
return { content: [{ type: 'text', text: content }] };
} catch (err) {
return { isError: true, content: [{ type: 'text', text: err.message }] };
}
}
default:
return { isError: true, content: [{ type: 'text', text: '未知工具' }] };
}
});
const transport = new StdioServerTransport();
await server.connect(transport);
就这么简单。一个 Server 就是一个 Node.js 进程,通过 stdin/stdout 和 AI 通信。
三、本地测试:不用 AI 也能跑
MCP Server 可以独立测试,不需要任何 AI 客户端。最方便的是 Anthropic 官方 MCP Inspector:
bash
npx @modelcontextprotocol/inspector node server.js
它会打开一个 Web UI,让你手动调用工具、查看返回结果。

四、集成到实际 AI 客户端
方式 1:Claude Desktop
在 MCP 配置中添加:
json
{
"mcpServers": {
"demo-tools": {
"command": "node",
"args": ["C:/path/to/your/server.js"]
}
}
}
重启后,Claude 就会自动发现你的工具。
方式 2:VS Code + Cline
Cline 是 VS Code 里的 AI 编码插件,支持 MCP。在 Cline 配置里添加 MCP Server 的启动命令即可。
方式 3:自定义 AI 客户端
javascript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({ command: 'node', args: ['./server.js'] });
const client = new Client({ name: 'my-app', version: '1.0.0' });
await client.connect(transport);
const tools = await client.listTools();
console.log(tools.tools.map(t => t.name));
const result = await client.callTool({
name: 'get_current_time',
arguments: { timezone: 'Asia/Shanghai' },
});
console.log(result.content[0].text);
五、加一个更实用的工具:查天气
javascript
// 工具定义
{
name: 'get_weather',
description: '查询指定城市的实时天气',
inputSchema: {
type: 'object',
properties: { city: { type: 'string', description: '城市名,如北京、上海' } },
required: ['city'],
},
}
// 工具处理逻辑
case 'get_weather': {
const city = args.city;
const url = 'https://wttr.in/' + encodeURIComponent(city) + '?format=%C+%t+%h+%w';
const res = await fetch(url);
const text = await res.text();
return { content: [{ type: 'text', text: city + ' 天气:' + text }] };
}
wttr.in 是免费终端天气服务,不需要 API Key。如果对精度要求更高,可以换成 OpenWeatherMap 或和风天气。

六、安全注意事项
MCP 给 AI 开了"工具通道",安全需要认真考虑。
1. 最小权限原则
不要暴露 exec、shell、delete_file 这类高风险工具。如果确实需要写文件,加上白名单路径限制。
2. 输入验证
AI 生成的参数不一定可靠。对每个参数做类型检查,拒绝不符合预期的输入。
3. 不要硬编码敏感信息
token、密码放在环境变量里,不要直接写在代码中。
4. 超时与限流
长时间运行的工具要加超时控制,防止 AI 意外调用导致 Server 卡死。
七、MCP 能做什么?真实场景
| 场景 | 工具示例 |
|---|---|
| 代码审查 | list_git_changes()、get_diff_content() |
| 数据库查询 | query_sql(sql) 只读模式 |
| 文件操作 | read_file()、search_files(pattern) 只读 |
| 外部 API | search_web()、get_news() |
| 系统监控 | get_disk_usage()、check_process() |
| 项目管理 | create_issue()、list_prs() |
| 文档查询 | search_docs(query) |
八、常见问题
Q1:MCP 和 Function Calling 有什么区别?
OpenAI 也有 Function Calling,但那是平台特定能力。MCP 是开放协议,不绑定模型或平台,而且把工具、资源和提示词统一管理。
Q2:一定要用 Node.js 吗?
不一定。MCP SDK 有 Python、TypeScript、Java、Kotlin 版本,用你熟悉的语言即可。
Q3:可以同时连接多个 MCP Server 吗?
可以。Host 能同时连接多个 Server,AI 会自动发现所有工具。
Q4:生产环境用 stdio 还是 SSE?
本地开发用 stdio 最方便。需要远程访问时用 SSE 或 Streamable HTTP。
Q5:MCP 安全吗?
协议本身不是关键,风险来自你暴露的工具。只读工具风险较小,写操作必须做权限控制和人工确认。
九、总结
MCP 的精髓不在于复杂,而在于它把"AI 工具化"标准化了。你写一个标准 MCP Server,所有支持 MCP 的客户端都能用,不必为每个平台单独适配。
今天就动手试试:从 get_current_time 开始,加 read_file,再加 get_weather。不到 100 行代码,你的 AI 就有了真正的"工具箱"。
下次你对 AI 说"帮我看看这个文件"或"查一下天气",它就不用回答"抱歉,我无法执行这个操作"了------因为它真的可以。