AIHero
    06 / 06Model Context Protocol 教程 · 阅读约 4 分钟

    将你的 MCP 服务器发布到 NPM

    使用 Node.js 轻松将 MCP 服务器发布到 NPM。通过简单命令向全球发布更新,并按照分步指南完成分发。

    Matt Pocock
    Matt Pocock
    源代码
    本页目录

    MCP 设计的一大优势,是可以借助免费可用的工具轻松分发 MCP Server。

    在这个示例中,我们会把 这个简单的 MCP Server 发布到 NPM。

    完成发布后,任何安装了 Node 的用户都能立即通过以下方式运行 MCP Server: npx运行 MCP Server。以后我们可以继续发布更新,而用户会自动获得这些更新。

    我们会遵循我之前在 Total TypeScript 文章中介绍的 创建 NPM 包的方法.

    基础原理

    用户将使用以下方式运行 MCP Server: npx运行 MCP Server。它是 Node.js 自带的工具,允许用户运行 NPM 上的任何包。

    用户会运行以下命令:

    npx -y @mattpocockuk/mcp-server-example@latest

    该命令会:

    1. 把包的最新版本下载到全局缓存(使用 @latest 标签)
    2. 忽略首次运行包时通常出现的确认消息(使用 -y 标记)。
    3. 运行该包 package.json file

    因此,这是一种无需预先安装即可运行包的方式。

    需要注意,这种方式并非没有风险。如果包来自不受信任的来源,运行前一定要先检查源代码。

    设置 Server

    Server 和 Transport 会放在一个名为 main.ts。用户运行 Server 时,实际执行的就是这个文件。

    我们会在该文件顶部添加一行 shebang。

    这是一行特殊指令,用来告诉操作系统如何运行文件。在这里,我们指定使用 Node.js 运行。

    #!/usr/bin/env node
    import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
    import { z } from "zod";
    const server = new McpServer({
    name: "Weather Service",
    version: "1.0.0",
    });
    server.tool(
    "getWeather",
    {
    city: z.string(),
    },
    async ({ city }) => {
    return {
    content: [
    {
    type: "text",
    text: `The weather in ${city} is sunny!`,
    },
    ],
    };
    },
    );
    const transport = new StdioServerTransport();
    await server.connect(transport);

    package.json

    我们需要一个 package.json 文件来描述这个包,内容如下:

    {
    "name": "@mattpocockuk/mcp-server-example",
    "version": "0.0.1",
    "description": "An example of a MCP server",
    "bin": {
    "mcp-server-example": "./dist/main.js"
    },
    "files": ["dist"],
    "type": "module",
    "scripts": {
    "build": "tsc",
    "ci": "npm run build",
    "prepublishOnly": "npm run ci"
    },
    "dependencies": {
    "@modelcontextprotocol/sdk": "^1.7.0"
    }
    }

    注意,如果把代码复制到自己的 package.json.

    package.json#bin

    该文件最重要的部分是 bin 字段。它会告诉 npx 执行 MCP Server 时应该运行哪个文件。有关这套逻辑的详细说明见 here。其中最重要的一句话是:

    如果包的 bin 字段中引用的文件,相关配置位于 package.json ……都会使用该命令。

    因此,只要在 bin 字段中保留单个条目,无论名称是什么, npx 都会运行对应文件。在本例中,该文件是 mcp-server-example.

    {
    "bin": {
    "mcp-server-example": "./dist/main.js"
    },
    }

    最终要运行的文件是 ./dist/main.js。该文件由 TypeScript 构建生成。

    TypeScript

    TypeScript 负责把我们的 .ts 文件转换为 Node 可以运行的 .js 的文件中。

    首先添加一个 tsconfig.json 文件中,需要删除其中的注释:

    {
    "compilerOptions": {
    /* Base Options: */
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "es2022",
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,
    "verbatimModuleSyntax": true,
    /* Strictness */
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "module": "NodeNext",
    "outDir": "dist",
    "lib": ["ES2022"]
    }
    }

    该文件会告诉 TypeScript 如何构建项目,其中最重要的是 outDir 字段。它告诉 TypeScript 把构建产物放在哪里。这意味着 main.ts 会被转换为 dist/main.js.

    发布包

    要发布这个包,需要运行以下命令:

    npm publish --access public

    这会把包发布到 NPM,其中 --access public 标记表示任何人都能安装它。

    过程中可能会遇到以下几种错误:

    • 如果尚未登录,需要先运行 npm login
    • 如果包名已经被占用,就需要更换名称。

    解决这些问题后,包就会成功发布!

    测试运行

    可以运行以下命令进行测试:

    npx -y @mattpocockuk/mcp-server-example@latest

    这会运行包的最新版本。也可以通过修改 @latest to @1.0.0 ,指定任何想要运行的版本。

    有些反直觉的是,终端中不会显示任何内容,因为 Server 正在监听 stdin 中的命令。

    可以尝试把它连接到 Cursor 这样的 MCP Host,并询问所在城市的天气。

    总结

    本文展示了把 MCP Server 发布到 NPM 有多么简单。这意味着任何安装了 Node.js 的用户,都能通过一条命令运行你的 Server。

    这是一种非常强大的 MCP Server 分发方式,可以让任何需要的人使用。