Newsroom
AIEII

从零搭建你的第一个 MCP Server:让 AI 操控你的数据库和 API

MCP 是 AI 时代的 USB-C 接口。这篇教程手把手教你用 TypeScript 写一个 MCP Server,让 Claude、ChatGPT 都能直接查询你的数据。

2026年03月07日

从零搭建你的第一个 MCP Server:让 AI 操控你的数据库和 API

你有没有想过一个问题:为什么 ChatGPT 能帮你写代码,却不能帮你查一下数据库里有多少用户?

答案很简单——它没有权限,也没有通道。

AI 模型再聪明,也只能在"沙盒"里运转。它看不到你的文件系统,摸不到你的 API,更不知道你的 PostgreSQL 里存了什么。

MCP(Model Context Protocol)就是解决这个问题的。

它是 Anthropic 在 2024 年底提出的开放协议,目标只有一个:给 AI 一个标准化的方式来调用外部工具和读取外部数据。你可以把它理解成 AI 时代的 USB-C 接口——不管是 Claude、ChatGPT 还是 Gemini,只要支持 MCP,就能用同一套标准连接你的服务。

截至 2026 年初,Anthropic、OpenAI、Microsoft 都已宣布支持 MCP。这不再是某一家的私有协议,而是行业共识。

学会写 MCP Server,意味着你的任何服务——数据库、内部 API、文件系统、甚至硬件设备——都能被 AI 直接调用。

这篇教程,就是带你从零开始写一个。


前置准备

在动手之前,确认你的机器上有以下工具:

  • Node.js 18+(推荐 20 LTS)
  • TypeScript(本教程使用 TS,但纯 JS 也能跑)
  • 一个终端(macOS Terminal、Windows PowerShell、VS Code 内置终端都行)
  • Claude Desktop 或 Claude Code(用于最终测试)

如果你还没安装 Node.js,去 nodejs.org 下载 LTS 版本,一路 Next 就行。


Step 1:初始化项目

打开终端,创建一个新目录并初始化:

mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
npx tsc --init

这五行做了什么:

  1. 创建项目目录并进入
  2. 初始化 package.json
  3. 安装 MCP SDK(核心库)和 Zod(参数校验)
  4. 安装 TypeScript 和 Node 类型定义(开发依赖)
  5. 生成 tsconfig.json

接下来修改 tsconfig.json,确保以下配置正确:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

再修改 package.json,添加两行:

{
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

"type": "module" 很关键。MCP SDK 使用 ESM 模块,没有这行会报 ERR_REQUIRE_ESM 错误。这是新手最常踩的第一个坑。


Step 2:理解 MCP 的三个核心概念

在写代码之前,先搞清楚 MCP 的三个原语(Primitives)。不需要记住所有细节,理解类比就够了:

1. Tools — AI 可以调用的"函数"

类比:遥控器上的按钮。按一下"查询用户",就执行一次查询。

Tools 是最常用的能力。AI 看到你注册的工具列表和描述后,会自主判断什么时候该调用哪个工具、传什么参数。

2. Resources — AI 可以读取的"数据源"

类比:书架上的书。AI 知道有哪些书,需要的时候去翻。

Resources 是只读的数据,比如配置文件、数据库 Schema、系统状态。AI 可以主动请求读取。

3. Prompts — 预设的对话模板

类比:常用话术手册。“遇到客户投诉,先说 XX,再说 XX。”

Prompts 提供结构化的对话模板,引导 AI 按特定流程处理问题。

本教程聚焦 Tools,因为它是 90% 场景的核心。掌握了 Tools,Resources 和 Prompts 的写法大同小异。


Step 3:写你的第一个 MCP Server

创建 src/index.ts 文件:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 1. 创建 MCP Server 实例
const server = new McpServer({
  name: "my-first-mcp",
  version: "1.0.0",
});

// 2. 注册一个简单工具:获取当前时间
server.tool(
  "get_current_time",        // 工具名称(AI 用这个来调用)
  "获取当前的日期和时间",       // 工具描述(AI 根据这个判断何时使用)
  {},                         // 参数定义(这个工具不需要参数)
  async () => {
    return {
      content: [{
        type: "text",
        text: new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" })
      }]
    };
  }
);

// 3. 注册一个带参数的工具:计算 BMI
server.tool(
  "calculate_bmi",
  "根据身高体重计算 BMI 指数",
  {
    height: z.number().describe("身高(厘米)"),
    weight: z.number().describe("体重(公斤)"),
  },
  async ({ height, weight }) => {
    const heightM = height / 100;
    const bmi = weight / (heightM * heightM);
    let category = "";
    if (bmi < 18.5) category = "偏瘦";
    else if (bmi < 24) category = "正常";
    else if (bmi < 28) category = "偏胖";
    else category = "肥胖";

    return {
      content: [{
        type: "text",
        text: `BMI: ${bmi.toFixed(1)},分类: ${category}`
      }]
    };
  }
);

// 4. 启动服务器
const transport = new StdioServerTransport();
await server.connect(transport);

逐段解释:

第 1 段:创建实例。 nameversion 是必填项,客户端用它们来识别你的 Server。

第 2 段:注册 get_current_time 工具。 这是一个零参数工具——AI 调用它不需要传任何东西,直接返回当前时间。注意返回值的格式:必须是 { content: [{ type: "text", text: "..." }] }。这是 MCP 协议规定的标准格式。

第 3 段:注册 calculate_bmi 工具。 这个工具需要两个参数:heightweight。参数用 Zod Schema 定义,AI 会根据 .describe() 里的描述来理解每个参数的含义。

第 4 段:启动。 StdioServerTransport 意味着 Server 通过标准输入/输出(stdin/stdout)和客户端通信。这是本地运行 MCP Server 的标准方式。

注意:MCP SDK 的 API 在持续演进。从 v2 版本开始,官方推荐使用 server.registerTool() 替代 server.tool(),配置通过对象传入。但 server.tool() 在当前版本仍然可用,且语法更简洁,适合入门学习。


Step 4:编译和测试

编译 TypeScript:

npm run build

如果没有报错,dist/ 目录下会生成 index.js

你可以先用命令行快速验证 Server 能否启动:

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | node dist/index.js

如果看到一段 JSON 响应(包含 serverInfo),说明 Server 运行正常。

如果报错 Cannot find module,检查 package.json 里有没有 "type": "module"。这是最常见的问题。


Step 5:连接到 Claude Desktop

MCP Server 本身只是一个程序。要让 AI 用上它,需要在客户端配置。

以 Claude Desktop 为例,编辑配置文件:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

添加以下内容:

{
  "mcpServers": {
    "my-first-mcp": {
      "command": "node",
      "args": ["/你的绝对路径/my-mcp-server/dist/index.js"]
    }
  }
}

务必使用绝对路径。 相对路径在 Claude Desktop 中不可靠。

保存后重启 Claude Desktop。如果配置正确,你会在对话界面看到一个工具图标(锤子或扳手),点击可以看到 get_current_timecalculate_bmi 两个工具。

现在试着对 Claude 说:“现在几点了?” 或者 “帮我算一下 BMI,我身高 175cm,体重 70kg”。

Claude 会自动识别意图,调用你的 MCP Server,然后把结果整合到回答中。

如果你用的是 Claude Code,配置更简单。在项目根目录创建 .mcp.json

{
  "mcpServers": {
    "my-first-mcp": {
      "command": "node",
      "args": ["dist/index.js"]
    }
  }
}

启动 Claude Code 后,它会自动加载这个 Server。


Step 6:进阶 — 连接数据库

到这里,你已经能写一个基础的 MCP Server 了。但真正有价值的场景是让 AI 操作你的数据。

下面展示如何添加一个查询 SQLite 的工具。先安装依赖:

npm install better-sqlite3
npm install -D @types/better-sqlite3

然后在 src/index.ts 中添加:

import Database from "better-sqlite3";

server.tool(
  "query_users",
  "查询用户表中的数据",
  {
    limit: z.number().optional().default(10).describe("返回数量限制"),
  },
  async ({ limit }) => {
    const db = new Database("./users.db");
    const rows = db.prepare("SELECT * FROM users LIMIT ?").all(limit);
    db.close();
    return {
      content: [{ type: "text", text: JSON.stringify(rows, null, 2) }]
    };
  }
);

这段代码做了什么:

  1. 打开当前目录下的 users.db 文件
  2. 执行 SELECT * FROM users 查询,限制返回条数
  3. 将结果序列化为 JSON 返回给 AI

AI 拿到原始数据后,会自动进行分析、汇总、对比——这才是 MCP 的威力所在。你不需要写任何可视化逻辑或报表页面,AI 就是你的"数据分析师"。

安全提醒:上面的示例用了只读查询。在生产环境中,一定要对 SQL 做白名单校验或限制为只读模式(new Database("./users.db", { readonly: true })),防止 AI 误执行 DELETE 或 DROP。


Step 7:发布到 npm(可选)

如果你想让别人也能用你的 MCP Server,可以发布到 npm。

package.json 中添加:

{
  "name": "mcp-server-my-tool",
  "bin": {
    "mcp-server-my-tool": "dist/index.js"
  },
  "files": ["dist"]
}

dist/index.js 文件顶部确保有 shebang:

#!/usr/bin/env node

然后:

npm login
npm publish

发布后,别人就可以这样使用:

npx mcp-server-my-tool

常见问题

Q: MCP Server 崩溃了怎么办?

查看 stderr 输出。MCP 的通信走 stdout,而错误信息走 stderr。如果你在 Claude Desktop 中遇到问题,可以在终端手动运行 node dist/index.js,看有没有报错。Claude Desktop 的日志目录在 ~/Library/Logs/Claude/ 下。

Q: Claude 看不到我的工具?

三个排查步骤:(1) 确认配置文件中的路径是绝对路径;(2) 确认 npm run build 编译成功;(3) 完全退出 Claude Desktop 后重新打开(不是关窗口,是 Quit)。

Q: 能同时运行多个 MCP Server 吗?

可以。在配置文件的 mcpServers 对象中添加多个条目即可。每个 Server 都是独立进程,互不干扰。

Q: 除了 stdio,还有别的通信方式吗?

有。MCP SDK 还支持 Streamable HTTP 传输,适合远程部署的场景。本地开发用 stdio 就够了。


下一步

你已经掌握了 MCP Server 的核心开发流程。接下来可以探索:

  1. 官方文档modelcontextprotocol.io — 协议规范和 SDK 参考
  2. 社区 Server 列表github.com/punkpeye/awesome-mcp-servers — 数百个现成的 MCP Server,涵盖数据库、API、文件系统、浏览器控制等
  3. 给自己的 API 写适配层:你公司内部有 REST API?花 30 分钟给它套一层 MCP,就能让 AI 直接调用。这是最有实战价值的练习

MCP 的核心思想并不复杂:定义工具、描述参数、返回结果。 剩下的——什么时候调用、传什么参数、怎么组合多个工具的输出——全部交给 AI 来决策。

你要做的,就是把你的能力"暴露"出去。AI 会自己想办法用好它。


本文由 AIEII 编辑部撰写。如果你觉得这篇文章有价值,欢迎分享给你的朋友。

广告合作联系
立即联系 →
加入会员申请
了解详情 →
← MiniMax M2.5:性能媲美 Claude,价格只要二 … AI 模型定价崩塌:当智能变得「便宜到不值一提」 →
💬 Comments
8 min read