Skip to main content
Glama
eleva

cdk-serverless-mcp-server

by eleva
README.md
# 🧠 cdk-serverless-mcp-server
A super simple Model Context Protocol (MCP) server deployed on AWS Lambda and exposed via Amazon API Gateway, deployed with AWS CDK.
This skeleton is based on the awesome work of [FrΓ©dΓ©ric Barthelet](https://github.com/fredericbarthelet): which has developed a middy middleware for Model Context Protocol (MCP) server integration with AWS Lambda functions in [this repo](https://github.com/fredericbarthelet/middy-mcp)

## Long story
- πŸ“– [Read the full article here on dev.to](https://dev.to/aws-builders/from-serverless-framework-to-aws-cdk-rebuilding-our-minimal-serverless-mcp-server-1232)
- πŸ“– [Read the first article of the series here on dev.to](https://dev.to/aws-builders/deploy-a-minimal-mcp-server-on-aws-lambda-with-serverless-framework-3e42)


## πŸ›  Features
- πŸͺ„ Minimal MCP server setup using @modelcontextprotocol/sdk
- πŸš€ Deployed as a single AWS Lambda function
- 🌐 HTTP POST endpoint exposed via API Gateway at /mcp
- πŸ”„ Supports local development testing with jest
- πŸ§ͺ Includes a simple example tool (add) with JSON-RPC interaction

## πŸ“¦ Project Structure
```
cdk-serverless-mcp-server/
β”œβ”€β”€ __tests__/                              # Jest tests
β”œβ”€β”€ bin/                                    # CDK entry point
β”œβ”€β”€ cdk-serverless-mcp-server.ts                # CDK app
β”œβ”€β”€ lib/                                    # CDK stack
β”‚   └── cdk-serverless-mcp-server-stack.ts      # CDK stack
β”œβ”€β”€ src/                                    # Source code
β”‚   └── index.mjs                               # MCP server handler
β”œβ”€β”€ .gitignore                              # Git ignore file
β”œβ”€β”€ cdk.json                                # CDK Project config
β”œβ”€β”€ package.json                            # Project dependencies
β”œβ”€β”€ package-lock.json                       # Project lock file
β”œβ”€β”€ README.md                               # This documentation file
```

## πŸ›  Prerequisites
- Node.js v22+
- [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-typescript.html) v2+

## πŸš€ Getting Started

1. Install dependencies:
```bash
npm install
```

2. Install AWS CDK globally (if not already installed):
```bash
npm install -g aws-cdk
```

3. Test Locally with jest
```bash
npm run test
```

## 🧬 Code Breakdown
This code is based on the awesome work of [FrΓ©dΓ©ric Barthelet](https://github.com/fredericbarthelet): which has developed a middy middleware for Model Context Protocol (MCP) server integration with AWS Lambda functions in [this repo](https://github.com/fredericbarthelet/middy-mcp)

### src/index.js
```javascript
import middy from "@middy/core";
import httpErrorHandler from "@middy/http-error-handler";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import mcpMiddleware from "middy-mcp";

const server = new McpServer({
  name: "Lambda hosted MCP Server",
  version: "1.0.0",
});

server.tool("add", { a: z.number(), b: z.number() }, async ({ a, b }) => ({
  content: [{ type: "text", text: String(a + b) }],
}));

export const handler = middy()
  .use(mcpMiddleware({ server }))
  .use(httpErrorHandler());
```

## πŸ“‘ Deploy to AWS

Just run:

```bash
npm run layer-dependencies-install # install dependencies for the layer
```

Then, deploy the stack:
```bash
cdk bootstrap
cdk deploy
```
After deployment, the MCP server will be live at the URL output by the command.

## πŸ§ͺ Once deployed, test with curl requests

### List tools
```bash
curl --location 'http://your-endpoint/dev/mcp' \
--header 'content-type: application/json' \
--header 'accept: application/json' \
--header 'jsonrpc: 2.0' \
--data '{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "id": 1
}'
```

### βž• Use the add Tool
```bash
curl --location 'http://your-endpoint/dev/mcp' \
--header 'content-type: application/json' \
--header 'accept: application/json' \
--header 'jsonrpc: 2.0' \
--data '{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "add",
    "arguments": {
      "a": 5,
      "b": 3
    }
  }
}'
```

## πŸ“˜ License
MIT β€” feel free to fork, tweak, and deploy your own version!