用 MCP 把自己的接口接入 AI

概念

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添加到上下文

官方代码解释

GitHub - modelcontextprotocol/typescript-sdk: The official TypeScript SDK for Model Context Protocol servers and clients

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);

再把结果发回模型,继续对话。

相关推荐
大家的林语冰5 小时前
✌️ Deno 2.9 来了,ESM 直接导入 CSS,甚至能开发桌面应用?!
前端·javascript·node.js
不简说6 小时前
JS 代码技巧 vol.1 — 10 个让代码少写 30% 的小套路
前端·javascript·面试
Hilaku6 小时前
为什么业务型前端容易遭遇中年危机?
前端·javascript·程序员
এ慕ོ冬℘゜6 小时前
深度解析 JavaScript:赋予 Web 灵魂的“全栈语言”
开发语言·前端·javascript
iCOD3R6 小时前
Skill - 3秒生成精美GitHub主页
前端·程序员·ai编程
爱勇宝6 小时前
《道德经》第5章:生产环境不相信眼泪
前端·后端·架构
掘金者阿豪6 小时前
LEFT JOIN 凭空消失的背后,是优化器偷偷帮你做了决定
前端·后端
HackTwoHub6 小时前
AntiDebug Mcp、AI逆向绕过前端,Hook 加密接口,抓取 Vue 路由漏洞,接入 MCP 让 AI 自动化挖掘前端漏洞
前端·vue.js·人工智能·安全·web安全·网络安全·系统安全
Mr_凌宇6 小时前
AI 应用工程进阶扩展学习笔记 二
前端·面试
Hyyy7 小时前
Git Worktree 完全讲解
前端·后端·面试