此项目提供了一个传输方式,用于需要连接到 MCP Server 的 Hono 应用程序。官方的 TypeScript SDK(链接)设计为与 express 一起使用。
如果你尝试按照他们的说明进行操作,并将 express 替换为 hono,你会发现这不会起作用。即使你将 HttpBinding 设置为环境变量(参考 @hono/node-server 中的一个示例),
它仍然无法工作,因为一些头部信息会在响应发送后被添加。
这个实现受到了以下 拉取请求 的启发。
你可以使用此传输方式,直到官方 SDK 支持 Hono。
pnpm add -D hono-mcp-server-sse-transport
import { Hono } from 'hono';
import { serve } from '@hono/node-server';
import { streamSSE } from 'hono/streaming';
import { SSETransport } from 'hono-mcp-server-sse-transport';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
const mcpServer = new McpServer(
{
name: 'your-mcp-server-name',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
},
);
// 这里你可以添加你的工具
// ...
const app = new Hono();
// 为了支持多个同时连接,我们有一个从 sessionId 到 transport 的查找对象
const transports: { [sessionId: string]: SSETransport } = {};
app.get('/sse', (c) => {
return streamSSE(c, async (stream) => {
const transport = new SSETransport('/messages', stream);
transports[transport.sessionId] = transport;
stream.onAbort(() => {
delete transports[transport.sessionId];
});
await mcpServer.connect(transport);
while (true) {
// 这将保持连接处于活动状态
// 你也可以等待一个永远不会解决的 promise
await stream.sleep(60_000);
}
});
});
app.post('/messages', async (c) => {
const sessionId = c.req.query('sessionId');
const transport = transports[sessionId];
if (transport == null) {
return c.text('未找到 sessionId 对应的传输', 400);
}
return await transport.handlePostMessage(c);
});
serve(
{
fetch: app.fetch,
port: 3000,
},
);