MCP协议服务器

一个基于MCP协议的AI模型连接服务器,提供工具、资源和提示模板等核心功能,适用于AI模型与外部数据和能力的连接。

  • by chuckmeyer
  • JavaScript
  • 本地部署
  • 更新于
在 GitHub 查看 chuckmeyer/hello-mcp

使用说明

你好,mcp

作为学习练习而构建的最小MCP服务器。使用Streamable HTTP传输并演示核心MCP原语:工具和资源。

什么是MCP?

这 模型上下文协议 (MCP)是一个将人工智能模型与外部数据和功能连接起来的开放标准。MCP服务器公开了三种类型的原语:

原始 目的 发起人
工具 做事(允许有副作用) 模型
资源 暴露数据(只读) 客户端/用户
提示 可重用的提示模板 客户端/用户

项目结构

src/
  server.js            # Entry point — HTTP transport
  stdio.js             # Entry point — stdio transport (Claude Desktop)
  mcp.js               # MCP server + tool/resource registration
  data/
    greetings.js       # Shared data (language → greeting mapping)
  tools/
    helloWorld.js      # No-input tool
    helloName.js       # Tool with a required string input
    greetName.js       # Tool with error handling and MCP logging
    listLanguages.js   # Tool that exposes the languages list to the model
  resources/
    languages.js       # Static resource exposing available languages

传输:流式HTTP

此服务器使用 StreamableHTTPServerTransport 从 @modelcontextprotocol/sdk。它作为一个普通的Node.js HTTP服务器运行,并在以下位置处理MCP消息 POST /mcp.

关键细节:

  • 跑步 无状态模式 (sessionIdGenerator: undefined)--每个请求都会得到一个新的传输实例
  • 客户端必须发送 Accept: application/json, text/event-stream 否则服务器将以406拒绝
  • 传输根据请求处理JSON响应和SSE流

工具

工具已注册 server.registerTool(name, config, handler).

  • config.description --向模型显示,以便它知道何时使用该工具
  • config.inputSchema --Zod fields的一个普通对象;SDK将其封装 z.object() 自动地
  • 输入是 在传输层验证 在调用处理程序之前,返回无效的输入 -32602 从未达到你的代码

你好_世界

无输入。总是回来 "Hello, World!".

你好名

需要一个必填项 name 弦。退货 "Hello, {name}!".

greet_name

需要一个 name 字符串和a language 弦。返回指定语言的问候语,或 isError 如果语言不受支持,请进行响应。用途 sendLoggingMessage 通过MCP协议发出信息、警告和调试日志消息——在MCP检查器通知面板中可见。

list_语言

无输入。返回支持的语言列表。对于资源未出现在模型中的Claude Desktop很有用——模型可以在以下情况下调用此工具来发现有效选项 greet_name 返回错误。

资源

资源已注册 server.registerResource(name, uri, config, reader).

  • 每个资源都有一个 统一资源标识符 (例如。 languages://list)客户端用来获取它
  • 阅读器返回 { contents: [{ uri, text }] }
  • 资源是只读的,没有副作用

languages://list

返回支持的语言键的JSON数组。由相同的支持 greetings.js 使用的数据 greet_name 工具。

运行服务器

HTTP流(MCP检查器、远程客户端)

npm install
npm start

MCP端点将在 http://localhost:3000/mcp.

要在其他端口上运行:

PORT=3001 npm start

stdio(克劳德桌面)

Claude Desktop生成进程本身——无需事先运行服务器。添加以下内容 ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "hello-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/hello-mcp/src/stdio.js"]
    }
  }
}

编辑配置后退出并重新启动Claude Desktop。检查 克劳德菜单→ 设置→ 开发者 确认服务器显示绿点。

MCP检验员测试

npx @modelcontextprotocol/inspector

在中打开检查器 铬 (不是Brave——它的隐私设置会阻止localhost请求),将传输设置为 可流式传输的HTTP,然后进入 http://localhost:3000/mcp.

您还可以使用原始curl进行测试:

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list",
    "params": {}
  }'

关键教训

  • 多个传输,一个服务器 — mcp.js 与交通无关; server.js (HTTP)和 stdio.js (stdio)是单独的入口点,它们都导入相同的服务器实例
  • 关注点分离 — server.js 拥有HTTP传输, mcp.js 拥有MCP服务器,每个工具/资源都存在于自己的文件中
  • 单一真相来源 --共享数据 src/data/ 通过工具和资源进口;无重复
  • Zod验证是免费的 --定义一个 inputSchema 在处理程序运行之前自动进行输入验证
  • registerTool 超过 tool --the tool() 方法已弃用; registerTool() 使用更清晰的配置对象模式
  • 无状态vs有状态 --无状态模式更简单,适用于大多数用例;状态模式通过以下方式添加会话跟踪 sessionIdGenerator
  • 服务器依赖处理程序的工厂模式 --需要调用的处理程序 server.sendLoggingMessage() 无法导入 server 直接(循环依赖)。相反,导出a createHandler(server) 工厂关闭服务器实例并返回处理程序函数。 mcp.js 电话 createHandler(server) 在注册时。
  • isError: true vs投掷 --返回 isError: true 将错误文本作为其可以推理的可读工具输出发送回模型;投掷会产生模型看不到的协议级JSON-RPC错误
  • MCP记录 — server.sendLoggingMessage({ level, message }) 通过MCP协议向客户端发送日志消息;在MCP检查员的通知面板中可见
  • Claude Desktop中的资源与工具 --Claude Desktop不会向模型显示资源;如果模型需要访问,则将相同的数据作为工具公开