本文最后更新于 2025-03-21,文章内容可能已经过时。

为了加快博客文章的编写,本文使用ai辅助编写,更加清晰,比我手写的强多了,没那么多废话......

官方版SDK

  • src/index.ts - MCP服务器实现,提供两个工具:say_helloadd

  • package.json - 项目依赖和脚本

  • tsconfig.json - TypeScript配置

MCP服务器搭建步骤

1. 初始化项目

# 创建项目目录
mkdir mcp_demo_1
cd mcp_demo_1

# 初始化npm项目
npm init -y

# 安装依赖
npm install @modelcontextprotocol/sdk zod
npm install --save-dev typescript @types/node
  • mkdir mcp_demo_1:创建一个名为 mcp_demo_1 的文件夹

  • cd mcp_demo_1:进入(切换工作目录到)刚创建的 mcp_demo_1 文件夹

  • npm init -y:快速生成默认的 package.json 文件(包含项目名称、版本、依赖等基础信息)

  • npm install @modelcontextprotocol/sdk zod:安装两个运行依赖包(@modelcontextprotocol/sdk SDK 库和 zod 数据验证库)

  • npm install --save-dev typescript @types/node:安装两个开发依赖包(typescript 编译器 和 Node.js 的 TypeScript 类型定义文件)

2. 配置TypeScript

创建tsconfig.json文件:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "outDir": "build",
    "rootDir": "src",
    "sourceMap": true,
    "declaration": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build"]
}
  • compilerOptions:TypeScript 编译器的全局配置项

    • "target": "ES2022"
      将代码编译为 ECMAScript 2022 标准,支持最新的 JavaScript 特性

    • "module": "NodeNext"
      使用 Node.js 原生的模块系统(.mjs/.cjs 文件扩展名自动识别)

    • "moduleResolution": "NodeNext"
      按照 Node.js 的模块解析规则查找依赖(兼容 package.jsonexports 字段)

    • "esModuleInterop": true
      允许 CommonJS 和 ES 模块互操作(如 import React from 'react' 写法)

    • "forceConsistentCasingInFileNames": true
      强制文件名大小写敏感(避免跨平台系统的大小写冲突)

    • "strict": true
      启用所有严格类型检查(包括空值检查、隐式 any 类型报错等)

    • "skipLibCheck": true
      跳过第三方库的类型检查(提升编译速度,但可能降低类型安全性)

    • "outDir": "build"
      输出编译后的文件到 build 目录(与源代码分离)

    • "rootDir": "src"
      指定源代码根目录为 src(编译器仅编译此目录下的文件)

    • "sourceMap": true
      生成 .map 文件(便于调试时映射编译后代码到源代码)

    • "declaration": true
      生成 .d.ts 类型声明文件(供其他 TypeScript 项目使用你的库)

    • "resolveJsonModule": true
      允许直接导入 JSON 文件(如 import data from './data.json'

  • include": ["src/**/*"]
    指定编译范围:src 目录及其子目录下的所有文件

  • exclude": ["node_modules", "build"]
    排除编译范围:node_modulesbuild 目录下的所有文件

3. 编写MCP服务器代码

创建src/index.ts文件:

#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 创建MCP服务器
const server = new McpServer({
  name: "hello-world",
  version: "1.0.0"
});

// 添加一个简单的打招呼工具
server.tool(
  "say_hello",
  { name: z.string().describe("要问候的名字") },
  async (params: { name: string }) => ({
    content: [{ type: "text", text: `你好,${params.name}!欢迎使用MCP!` }]
  })
);

// 添加一个加法工具
server.tool(
  "add",
  { 
    a: z.number().describe("第一个数字"), 
    b: z.number().describe("第二个数字") 
  },
  async (params: { a: number, b: number }) => ({
    content: [{ type: "text", text: `${params.a} + ${params.b} = ${params.a + params.b}` }]
  })
);

// 启动服务器
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP Hello World 服务器已启动");
}

main().catch((error) => {
  console.error("服务器启动失败:", error);
  process.exit(1);
});

脚本声明和环境准备

#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

#!/usr/bin/env node:声明这是一个 Node.js 可执行脚本

  • 导入的模块作用:

    • McpServer:MCP 服务端核心类

    • StdioServerTransport:基于标准输入输出的通信模块

    • zod:用于数据验证的库

创建 MCP 服务器实例

const server = new McpServer({
  name: "服务器名称",
  version: "版本号"
});
  • 初始化一个 MCP 服务:

    • name:服务唯一标识名

    • version:服务版本号(用于接口兼容性管理)注册工具方法:打招呼功能

server.tool(
  "工具名称",
  { 参数1: z.类型().describe("参数描述") },
  async (params) => {
    // 实现逻辑
    return { content: [{ type: "text", text: "返回结果" }] };
  }
);
  • 工具注册三要素:

    1. 工具名称"say_hello"

    2. 参数验证:使用 Zod 定义必须的字符串类型 name 参数

    3. 处理函数:接收参数后返回包含问候文本的标准化响应

注册工具方法:加法计算

server.tool(
  "add",
  { 
    a: z.number().describe("第一个数字"), 
    b: z.number().describe("第二个数字") 
  },
  async (params: { a: number, b: number }) => ({
    content: [{ type: "text", text: `${params.a} + ${params.b} = ${params.a + params.b}` }]
  })
);
  • 与前一工具类似,但:

    • 参数定义为两个数字 ab

    • 处理函数返回计算结果的文本

服务器启动逻辑

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP Hello World 服务器已启动");
}
  • 关键步骤:

    1. 创建标准输入输出通信通道 (StdioServerTransport)

    2. 将服务器绑定到该通道

    3. 输出启动成功提示(到标准错误流避免干扰主输出)

错误处理

main().catch((error) => {
  console.error("服务器启动失败:", error);
  process.exit(1);
});
  • 异常捕获机制:

    • 打印详细的错误信息

    • 以非零状态码退出进程(1 表示异常终止)

4. 更新package.json

确保package.json包含以下内容:

{
  "name": "mcp_demo_1",
  "version": "1.0.0",
  "description": "MCP服务器示例",
  "main": "dist/index.js",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.7.0",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@types/node": "^22.13.10",
    "typescript": "^5.8.2"
  }
}
  • "name": "mcp_demo_1"
    定义项目名称标识(遵循 npm 包命名规范,使用小写和连字符)

  • "version": "1.0.0"
    指定项目版本号(遵循语义化版本规范)

  • "description": "MCP服务器示例"
    添加项目描述(显示在 npm 仓库和开发文档中)

  • "main": "dist/index.js"
    指定项目入口文件(指向 TypeScript 编译后的输出目录)

  • "type": "module"
    启用 ES 模块系统(允许使用 import/export 语法)

  • "scripts":定义 npm 快捷命令

    • "build": "tsc"
      执行 TypeScript 编译(根据 tsconfig.json 配置生成 JS 文件)

    • "start": "node dist/index.js"
      运行编译后的入口文件(启动服务)

  • "dependencies":生产环境依赖

    • "@modelcontextprotocol/sdk": "^1.7.0"
      MCP 协议核心 SDK(提供服务器和客户端功能)

    • "zod": "^3.22.4"
      数据验证库(用于接口参数类型校验)

  • "devDependencies":开发环境依赖

    • "@types/node": "^22.13.10"
      Node.js 类型定义文件(提供 TypeScript 类型支持)

    • "typescript": "^5.8.2"
      TypeScript 编译器(用于代码编译和类型检查)

5. 编译

# 编译项目
npm run build

6.运行

服务已经起来了,我们该如何去测试当前服务是否运行正确呢?

不需要单独去制作一个客户端去测试

使用https://github.com/wong2/mcp-cli项目

使用方式

//注意目录位置,你也可以使用绝对地址
npx @wong2/mcp-cli node ./build/index.js args...

在cursor终端中可以直接运行,他会跳出2个工具,一个是say hello 一个是 add,请使用 键盘“上下”来选择使用哪个工具,“回车”是确认

say_hello

向指定名字的人打招呼。

  • 参数

    • name: 要问候的名字

  • 返回

    • 包含问候语的文本

add

计算两个数字的和。

  • 参数

    • a: 第一个数字

    • b: 第二个数字

  • 返回

    • 包含加法计算结果的文本