概念
MCP和API的区别?
一句话总结:MCP 是为大模型量身定制的API,让模型能像人一样对话式调用工具;传统 API 则是给程序员用的,需要代码对接。
特性 | MCP | 传统 API |
---|---|---|
目标 | 给 LLM(大模型)提供上下文和功能,专为 LLM 设计 | 给应用或前端提供数据和功能,供人或程序调用 |
调用方式 | 可以通过工具(Tool)或资源(Resource)动态提供信息,支持提示模板(Prompt)和交互 | 通常是 REST/GraphQL 调用,直接请求数据或触发动作 |
返回内容 | 可以包含文本、结构化内容、ResourceLink(资源引用)等,便于 LLM 消化和生成 | 通常返回 JSON 或二进制数据 |
交互方式 | 支持持续会话、交互式输入(elicitation)、上下文感知 | 请求-响应模式,通常无持续会话(除非额外实现) |
扩展性 | 可以随时动态注册/更新工具、资源、提示模板 | 扩展需要新增 API 接口或改后端逻辑 |
几个概念:
- resources:类似API的GET接口,用来提供数据,不能有副作用。比如根据参数返回数据库查询结果
- tools:类似POST操作,调用外部服务,然后返回结果
- prompts:预定义好的对话模板,比如给review-code定义好一些预设,模型需要去review code时会把prompt添加到上下文
官方代码解释
typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Create an MCP server
const server = new McpServer({
name: "demo-server",
version: "1.0.0"
});
// Add an addition tool
server.registerTool("add",
{
title: "Addition Tool",
description: "Add two numbers",
inputSchema: { a: z.number(), b: z.number() }
},
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
// Add a dynamic greeting resource
server.registerResource(
"greeting",
new ResourceTemplate("greeting://{name}", { list: undefined }),
{
title: "Greeting Resource", // Display name for UI
description: "Dynamic greeting generator"
},
async (uri, { name }) => ({
contents: [{
uri: uri.href,
text: `Hello, ${name}!`
}]
})
);
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);
title、description是模型可读取的,用来知道工具的作用。inputSchema 告诉模型工具需要的参数和类型。
模型端会根据对话上下文或者用户输入生成参数,例如:
sequenceDiagram
participant U as 用户
participant M as 模型 (LLM)
participant MCP as MCP 服务器
participant T as 工具: add
U->>M: 请输入 "请帮我算 3 + 5"
M->>M: 解析意图 → 识别需要调用 add 工具
M->>M: 按 schema 生成参数 { a: 3, b: 5 }
M->>MCP: 调用工具请求 (add, {a:3, b:5})
MCP->>T: 执行加法
T-->>MCP: 返回结果 8
MCP-->>M: 返回 { content: "8" }
M-->>U: 回复 "结果是 8"
让大模型调用mcp
首先在本地创建mcp server
javascript
# /Projects/mcp-demo
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Create an MCP server
const server = new McpServer({
name: "demo-server",
version: "1.0.0"
});
// Add an addition tool
server.registerTool("add",
{
title: "Addition Tool",
description: "Add two numbers",
inputSchema: { a: z.number(), b: z.number() }
},
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
// Add a dynamic greeting resource
server.registerResource(
"greeting",
new ResourceTemplate("greeting://{name}", { list: undefined }),
{
title: "Greeting Resource", // Display name for UI
description: "Dynamic greeting generator"
},
async (uri, { name }) => ({
contents: [{
uri: uri.href,
text: `Hello, ${name}!`
}]
})
);
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);
cursor使用
按command + shfirt + p ,输入 open mcp settings
点击 new mcp server,会创建 ~/.cursor/mcp.json
,写入如下配置,保存后会全局生效:
json
{
"mcpServers": {
"test-tools": {
"command": "tsx",
"args": ["/Projects/mcp-demo/server.ts"]
}
}
}
这样cursor就知道如何启动mcp服务器,列出所有工具、resource等等。

当你在 Cursor 配好 ~/.cursor/mcp.json
后:
- Cursor 会在后台 启动你的 server.ts ,通过 stdio(标准输入/输出流)跟它通信;
- 启动时,MCP server 会向 Cursor 声明自己有哪些工具、资源、prompts;
- 模型对话时,如果 Cursor 判断需要用到某个 MCP 工具,就会把参数补齐,然后发消息给 MCP server;
- MCP server 返回结果,Cursor 再交给模型。
这种是零开发成本,但前提是你在 Cursor 里使用。
自己实现调用逻辑
如果你有一个自己的 AI API 调用逻辑(例如调用 OpenAI、Anthropic、DeepSeek...),想让它知道 MCP 工具,就要模拟 Cursor 的做法:
流程分三步:
(1) 启动 MCP server
用 SDK 提供的 client 启动你的 server.ts:
typescript
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { McpClient } from "@modelcontextprotocol/sdk/client/mcp.js";
const transport = new StdioClientTransport({
command: "tsx",
args: ["./server.ts"]
});
const client = new McpClient(transport);
await client.connect();
(2) 取出 MCP 工具定义
typescript
const tools = await client.listTools();
console.log("Available tools:", tools);
这里会返回工具的 name, title, description, inputSchema ------ 你要把这些转成 OpenAI API 的 functions
或 Anthropic 的 tools
格式。
(3) 把工具注册给大模型
以 OpenAI 为例:
typescript
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "请帮我算 3 + 5" }],
tools: tools.map(tool => ({
type: "function",
function: {
name: tool.name,
description: tool.description,
parameters: tool.inputSchema // MCP 的 schema 可以直接转
}
}))
});
(4) 执行工具调用
模型可能返回:
typescript
{
"tool_calls": [
{
"function": "add",
"arguments": { "a": 3, "b": 5 }
}
]
}
你就用 MCP client 去执行:
typescript
const result = await client.callTool("add", { a: 3, b: 5 });
console.log("MCP result:", result);
再把结果发回模型,继续对话。