使用说明
你好,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--thetool()方法已弃用;registerTool()使用更清晰的配置对象模式- 无状态vs有状态 --无状态模式更简单,适用于大多数用例;状态模式通过以下方式添加会话跟踪
sessionIdGenerator - 服务器依赖处理程序的工厂模式 --需要调用的处理程序
server.sendLoggingMessage()无法导入server直接(循环依赖)。相反,导出acreateHandler(server)工厂关闭服务器实例并返回处理程序函数。mcp.js电话createHandler(server)在注册时。 isError: truevs投掷 --返回isError: true将错误文本作为其可以推理的可读工具输出发送回模型;投掷会产生模型看不到的协议级JSON-RPC错误- MCP记录 —
server.sendLoggingMessage({ level, message })通过MCP协议向客户端发送日志消息;在MCP检查员的通知面板中可见 - Claude Desktop中的资源与工具 --Claude Desktop不会向模型显示资源;如果模型需要访问,则将相同的数据作为工具公开