An MCP (Model Context Protocol) server SDK for AWS serverless architecture with familiar, official SDK-like API design and Bearer token authentication.
lambda-mcp-adaptor
is a TypeScript/JavaScript SDK that provides an official SDK-like experience for building MCP (Model Context Protocol) servers on AWS serverless architecture. It offers a clean, intuitive API similar to other popular SDKs, making it easy to define tools, resources, and prompts with Bearer token authentication support.
- 🚀 Official SDK-like API: Familiar and intuitive interface similar to popular SDKs
- ⚡ Simple Tool Registration: Easy-to-use fluent API for defining server capabilities
- 🌐 AWS Serverless Ready: Built specifically for API Gateway and Lambda deployment
- 🔧 Zero Configuration: Works out of the box with sensible defaults
- 🛡️ Built-in Validation: Automatic input validation and error handling
- 📊 Stateless Architecture: Designed for serverless environments (no session management)
- 🔐 Bearer Token Authentication: Simple authentication with multiple validation methods
This library implements the Streamable HTTP transport as defined in the MCP specification 2025-03-26. Key implementation details:
- Transport: Uses HTTP POST requests for client-to-server communication
- Protocol: JSON-RPC 2.0 over HTTP with proper error handling
- Architecture: Stateless design for AWS Lambda serverless deployment
Unlike traditional MCP servers that may use session management, this implementation is designed for stateless serverless environments. This means each request is handled independently without maintaining server-side session state, which is a requirement for AWS Lambda deployments.
graph LR
subgraph "Application Host Process"
H["Host<br/>(VS Code etc)"]
C[MCP Client]
H --> C
end
subgraph "AWS Cloud"
AG["Amazon API Gateway<br/>(HTTP API)"]
L[AWS Lambda<br/>MCP Tools & Resources etc]
C -->|"Streamable HTTP(stateless)<br/>Bearer Token Auth(option)"| AG
AG --> L
end
The library provides multiple authentication methods:
import { createMCPServer, createLambdaHandler, Auth } from 'lambda-mcp-adaptor';
// Single Bearer token
const server = createMCPServer(config)
.auth(Auth.bearerToken(process.env.MCP_TOKEN));
// Multiple Bearer tokens (for token rotation)
const server = createMCPServer(config)
.auth(Auth.bearerTokens([process.env.MCP_TOKEN_1, process.env.MCP_TOKEN_2]));
// Custom authentication function
const server = createMCPServer(config)
.auth(Auth.custom(async (authHeader) => {
// Your custom validation logic
return authHeader === `Bearer ${process.env.CUSTOM_TOKEN}`;
}));
Authentication is optional - existing code works without authentication.
See the example directory for complete working examples:
- Basic Example (
example/mcp-server/
): Simple MCP server without authentication - Authenticated Example (
example/mcp-server-auth/
): Server with Bearer token authentication
Both examples are deployed on AWS serverless architecture (API Gateway + Lambda) with comprehensive tools and features including mathematical operations, text processing, and utility functions.
Install directly from GitHub:
npm install github:moritalous/lambda-mcp-adaptor
sam init --runtime nodejs22.x --name my-mcp-server --app-template hello-world
cd my-mcp-server
npm install github:moritalous/lambda-mcp-adaptor zod
Replace the contents of app.mjs
:
import { createMCPServer, createLambdaHandler, Auth } from 'lambda-mcp-adaptor';
import { z } from 'zod';
// Create MCP server
const server = createMCPServer({
name: 'My MCP Server',
version: '1.0.0',
description: 'A powerful MCP server with authentication'
});
// Add authentication (optional)
server.auth(Auth.bearerToken(process.env.MCP_TOKEN));
// Register tools with simple API
server.tool('calculate', {
operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
a: z.number(),
b: z.number()
}, async ({ operation, a, b }) => {
let result;
switch (operation) {
case 'add': result = a + b; break;
case 'subtract': result = a - b; break;
case 'multiply': result = a * b; break;
case 'divide': result = a / b; break;
}
return {
content: [{ type: 'text', text: `${a} ${operation} ${b} = ${result}` }]
};
});
// Export Lambda handler (handles all the complexity for you)
export const lambdaHandler = createLambdaHandler(server);
Update your template.yaml
to include API Gateway and environment variables:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
MCPToken:
Type: String
Description: Bearer token for MCP authentication
NoEcho: true
Resources:
MCPServerFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./
Handler: app.lambdaHandler
Runtime: nodejs22.x
Environment:
Variables:
MCP_TOKEN: !Ref MCPToken
Events:
MCPEndpoint:
Type: Api
Properties:
Path: /mcp
Method: post
MCPOptions:
Type: Api
Properties:
Path: /mcp
Method: options
Outputs:
MCPServerApi:
Description: "API Gateway endpoint URL for MCP Server"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/mcp"
sam build
sam deploy --guided --parameter-overrides MCPToken=your-secret-token-here
Creates a new MCP server instance.
const server = createMCPServer({
name: 'My Server', // Required: Server name
version: '1.0.0', // Required: Server version
description: 'Description', // Optional: Server description
protocolVersion: '2025-03-26' // Optional: MCP protocol version
});
Add authentication to your MCP server (optional).
// Single Bearer token
server.auth(Auth.bearerToken('your-secret-token'));
// Multiple Bearer tokens (for rotation)
server.auth(Auth.bearerTokens(['token1', 'token2']));
// Custom authentication
server.auth(Auth.custom(async (authHeader) => {
// Your validation logic
return isValidToken(authHeader);
}));
Register a tool with automatic input validation.
server.tool('tool_name', {
param1: z.string().describe('Parameter description'),
param2: z.number().optional().default(42),
param3: z.enum(['option1', 'option2'])
}, async ({ param1, param2, param3 }) => {
// Tool implementation with validated inputs
return {
content: [{ type: 'text', text: 'Result' }],
isError: false // Optional: indicates if this is an error response
};
});
Input Schema Types:
z.string()
- String parameterz.number()
- Numeric parameterz.boolean()
- Boolean parameterz.enum(['a', 'b'])
- Enumerated valuesz.array(z.string())
- Array of stringsz.object({...})
- Nested object.optional()
- Optional parameter.default(value)
- Default value.describe('...')
- Parameter description
Return Format:
{
content: [
{ type: 'text', text: 'Response text' },
{ type: 'image', data: 'base64...', mimeType: 'image/png' }
],
isError: false // Optional: true for error responses
}
Creates an AWS Lambda handler for API Gateway integration from an MCP server instance.
export const lambdaHandler = createLambdaHandler(server);
import { createMCPServer, Auth } from 'lambda-mcp-adaptor';
import { z } from 'zod';
// Create test server
const server = createMCPServer({
name: 'Test Server',
version: '1.0.0'
});
// Add authentication
server.auth(Auth.bearerToken('test-token'));
server.tool('test_tool', {
input: z.string()
}, async ({ input }) => {
return { content: [{ type: 'text', text: `Echo: ${input}` }] };
});
// Test tool directly
const result = await server.handleRequest({
jsonrpc: '2.0',
id: 1,
method: 'tools/call',
params: {
name: 'test_tool',
arguments: { input: 'Hello World' }
}
});
console.log(result); // { content: [{ type: 'text', text: 'Echo: Hello World' }] }
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
Licensed under the Apache License, Version 2.0. See LICENSE for details.
- MCP Specification - Official MCP documentation
- MCP Streamable HTTP Transport - Transport specification
- Zod Documentation - Schema validation library
- AWS Lambda Documentation - AWS Lambda guide
- AWS API Gateway Documentation - AWS API Gateway guide