MCP服务器Lambda SDK

用于构建在AWS Lambda上运行的Model Context Protocol服务器的TypeScript SDK,支持通过装饰器定义工具并自动处理JSON-RPC路由、验证和会话管理。

  • by TyagoVeras
  • TypeScript
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 TyagoVeras/mcp-lambda-nodejs

使用说明

mcp lambda nodejs

用于构建的TypeScript SDK 模型上下文协议 (MCP)服务器,其运行方式为 AWS Lambda函数.

使用装饰器定义MCP工具,连接单个处理程序,然后部署——SDK自动处理JSON-RPC路由、Zod验证、CORS和会话管理。

需求

  • Node.js 18+
  • TypeScript 5.0+ experimentalDecorators 和 emitDecoratorMetadata 启用

安装

npm install mcp-lambda-nodejs
# peer dependency
npm install --save-dev @types/aws-lambda

快速开始

1.在中启用装饰器元数据 tsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

2.创建MCP服务器类

// calculator-server.ts
import { MCPServer, MCPTool, z } from 'mcp-lambda-nodejs';

@MCPServer({
  name: 'my-calculator',
  version: '1.0.0'
})
export class CalculatorServer {
  @MCPTool({
    title: 'Add Numbers',
    description: 'Adds two numbers together',
    inputSchema: {
      a: z.number().describe('First number'),
      b: z.number().describe('Second number')
    },
    outputSchema: {
      result: z.number().describe('The sum'),
      operation: z.string().describe('Human-readable equation')
    }
  })
  async add(params: { a: number; b: number }) {
    return {
      result: params.a + params.b,
      operation: `${params.a} + ${params.b} = ${params.a + params.b}`
    };
  }
}

3.创建Lambda处理程序

// handler.ts
import { APIGatewayProxyEventV2, APIGatewayProxyResultV2, MCPHandlerFactory } from 'mcp-lambda-nodejs';
import { CalculatorServer } from './calculator-server';

const handler = MCPHandlerFactory.createHandler(CalculatorServer, 'calculator');

export async function main(event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> {
  return handler(event);
}

4.部署(无服务器框架示例)

# serverless.yml
service: my-mcp-server

provider:
  name: aws
  runtime: nodejs20.x
  build:
    esbuild:
      bundle: true

functions:
  calculator:
    handler: handler.main
    events:
      - httpApi:
          path: /calculator
          method: post
      - httpApi:
          path: /calculator
          method: options
serverless deploy

5.呼叫您的MCP服务器

# List tools
curl -X POST https://<your-api>.execute-api.<region>.amazonaws.com/calculator \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

# Call a tool
curl -X POST https://<your-api>.execute-api.<region>.amazonaws.com/calculator \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": { "name": "add", "arguments": { "a": 5, "b": 3 } }
  }'

答复:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [{ "type": "text", "text": "{\"result\":8,\"operation\":\"5 + 3 = 8\"}" }],
    "structuredContent": { "result": 8, "operation": "5 + 3 = 8" }
  }
}

API 参考

@MCPServer(config)

注册MCP服务器的类装饰器。

字段 类型 描述
name string 服务器标识符
version string 服务器版本

@MCPTool(config)

方法装饰器,将方法作为MCP工具公开。

字段 类型 描述
title string 人类可读的工具名称
description string 该工具的功能是什么
inputSchema Record<string, ZodType> 每个输入字段的Zod模式
outputSchema Record<string, ZodType> 每个输出字段的Zod模式

方法名称将成为工具的 name 在MCP协议中。

MCPHandlerFactory.createHandler(ServerClass, serverName?)

返回AWS Lambda处理程序(APIGatewayProxyEventV2 → APIGatewayProxyResultV2).

参数 类型 说明
ServerClass 类 装饰服务器类
serverName string? 用于实例键控的名称(可选)

自动处理:

  • CORS飞行前(OPTIONS)
  • JSON-RPC 2.0解析和路由
  • initialize, tools/list, tools/call, resources/list, prompts/list
  • 通过Zod进行输入/输出验证

MCPSessionManager

可选的会话状态管理器,用于需要跨调用维护状态的工具。

import { MCPSessionManager } from 'mcp-lambda-nodejs';

const sessionManager = new MCPSessionManager();

// Create session
const session = await sessionManager.createSession({ ttlHours: 2 });

// Update state
await sessionManager.updateSessionState(session.sessionId, { lastValue: 42 });

// Read session
const current = await sessionManager.getSession(session.sessionId);

默认存储为 内存中。对于多容器部署,注入自定义 SessionStorage:

import { MCPSessionManager, SessionStorage, MCPSession } from 'mcp-lambda-nodejs';

class DynamoDBSessionStorage implements SessionStorage {
  async get(sessionId: string): Promise<MCPSession | null> {
    /* ... */
  }
  async set(session: MCPSession): Promise<void> {
    /* ... */
  }
  async delete(sessionId: string): Promise<void> {
    /* ... */
  }
  async cleanup(): Promise<void> {
    /* ... */
  }
}

const sessionManager = new MCPSessionManager(new DynamoDBSessionStorage());

请求中的会话ID

通过 mcp-session-id 作为HTTP报头。SDK会自动提取它,并在工具参数不存在时将其注入到工具参数中:

curl -X POST https://... \
  -H "mcp-session-id: user-abc-123" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{...}}'

高级用法

有状态的工具

import { MCPServer, MCPTool, MCPSessionManager, z } from 'mcp-lambda-nodejs';

@MCPServer({ name: 'stateful-server', version: '1.0.0' })
export class StatefulServer {
  private sessionManager = new MCPSessionManager();

  @MCPTool({
    title: 'Increment Counter',
    description: 'Increments a per-session counter',
    inputSchema: { sessionId: z.string().optional() },
    outputSchema: { count: z.number() }
  })
  async increment(params: { sessionId?: string }) {
    const session = params.sessionId ? await this.sessionManager.getSession(params.sessionId) : null;

    const count = ((session?.state.count as number) ?? 0) + 1;

    if (params.sessionId) {
      await this.sessionManager.updateSessionState(params.sessionId, { count });
    }

    return { count };
  }
}

错误处理

在工具方法中抛出-SDK捕获它并返回正确的MCP错误响应:

@MCPTool({
  title: 'Safe Divide',
  description: 'Divides two numbers',
  inputSchema: { dividend: z.number(), divisor: z.number() },
  outputSchema: { result: z.number() }
})
async divide(params: { dividend: number; divisor: number }) {
  if (params.divisor === 0) {
    throw new Error('Division by zero');
  }
  return { result: params.dividend / params.divisor };
}

支持的JSON-RPC方法

方法 说明
initialize 握手——返回协议版本和功能
tools/list 列出所有 @MCPTool-装饰方法
tools/call 按名称调用工具
resources/list 返回空列表(存根)
resources/read 未实施
prompts/list 返回空列表(存根)
prompts/get 未实施

依赖项

包装 用途
@modelcontextprotocol/sdk MCP协议实现
zod 架构验证
reflect-metadata 装饰元数据
uuid 会话ID生成

许可证

MIT© 蒂亚戈·维拉斯

贡献

  1. 分叉回购
  2. 创建要素分支
  3. 通过测试进行更改
  4. 打开拉取请求

问题: https://github.com/TyagoVeras/mcp-lambda-nodejs/issues