README.md•4.52 kB
# OpenAPI MCP Server - AWS Lambda Deployment
Serverless deployment of the [AWS Labs OpenAPI MCP Server](https://awslabs.github.io/mcp/servers/openapi-mcp-server/) on AWS Lambda with API Gateway.
## Overview
This project wraps the awslabs openapi-mcp-server to run as a serverless Lambda function, enabling MCP (Model Context Protocol) clients to interact with OpenAPI-defined APIs through AWS infrastructure.
## Architecture
- **Lambda Function**: FastMCP server with HTTP transport (Starlette ASGI)
- **API Gateway**: HTTP API exposing the MCP endpoints
- **Transport**: Mangum ASGI adapter (no child process overhead)
## Prerequisites
- Python 3.12+
- [uv](https://github.com/astral-sh/uv) package manager
- AWS CLI configured
- AWS CDK CLI: `npm install -g aws-cdk`
## Local Setup
Install dependencies:
```bash
uv sync
```
## Deployment
This project uses [just](https://github.com/casey/just) for task automation. Install it with:
```bash
brew install just # macOS
cargo install just # or via cargo
```
### 1. Bootstrap CDK (first time only)
```bash
just bootstrap
```
### 2. Deploy Stack
Deploy with custom API configuration using environment variables:
```bash
# Configure your API via environment variables
export API_NAME=MyAPI
export API_BASE_URL=https://api.example.com
export API_SPEC_URL=https://api.example.com/openapi.json
export AUTH_TYPE=none
# Deploy (stack name will be: openapi-mcp-myapi)
just deploy
```
Or deploy the Petstore example:
```bash
just deploy-pet
```
### Configuration Parameters
Configure via environment variables:
- `API_NAME`: Display name for the API (also used for stack naming)
- `API_BASE_URL`: Base URL of the target API
- `API_SPEC_URL`: URL to the OpenAPI specification (JSON or YAML)
- `AUTH_TYPE`: Authentication method (`none`, `basic`, `bearer`, `api_key`, `cognito`)
Default values (from justfile):
- `API_NAME`: PetstoreAPI
- `API_BASE_URL`: https://petstore3.swagger.io/api/v3
- `API_SPEC_URL`: https://petstore3.swagger.io/api/v3/openapi.json
- `AUTH_TYPE`: none
Stack naming: The CDK stack name is automatically generated as `openapi-mcp-<api-name>` (lowercase, non-alphanumeric characters except dots replaced with dashes)
Examples:
- `API_NAME=PetstoreAPI` → stack: `openapi-mcp-petstoreapi`
- `API_NAME="My API"` → stack: `openapi-mcp-my-api`
- `API_NAME="API_v2.0"` → stack: `openapi-mcp-api-v2.0`
### Additional Auth Configuration
Set environment variables in [cdk/openapi_mcp_stack.py](cdk/openapi_mcp_stack.py) for authentication:
**Basic Auth:**
- `AUTH_USERNAME`
- `AUTH_PASSWORD`
**Bearer Token:**
- `AUTH_TOKEN`
**API Key:**
- `AUTH_API_KEY`
- `AUTH_API_KEY_NAME`
- `AUTH_API_KEY_IN` (header/query/cookie)
**Cognito:**
- `AUTH_COGNITO_CLIENT_ID`
- `AUTH_COGNITO_USERNAME`
- `AUTH_COGNITO_PASSWORD`
- `AUTH_COGNITO_USER_POOL_ID`
- `AUTH_COGNITO_REGION`
### 3. Monitor Deployment
Check stack status:
```bash
just status
```
View Lambda logs:
```bash
just logs
```
Get the deployed API URL from CloudFormation outputs.
## Testing
Test locally with Docker:
```bash
# Build and run locally
just docker-build
just docker-run
# Run tests against local server
just test
# Stop local server
just docker-stop
```
Test the deployed Lambda function:
```bash
# Automatically fetches API URL from CloudFormation and runs tests
just test-deployed
```
Or test manually with curl:
```bash
curl -X POST https://<api-url>/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
```
## Performance Considerations
- **Cold Start**: ~1-2 seconds (initializes MCP server + loads OpenAPI spec)
- **Warm Start**: ~100-300ms (reuses server instance)
- **Timeout**: 30 seconds (configurable in stack)
- **Memory**: 512 MB (configurable in stack)
## Cost Optimization
- Requests: Pay per invocation
- Memory/Duration: 512 MB x execution time
- API Gateway: HTTP API (cheaper than REST API)
## Development
Run MCP server locally:
```bash
uv run awslabs.openapi-mcp-server \
--api-name MyAPI \
--api-url https://api.example.com \
--spec-url https://api.example.com/openapi.json
```
## Cleanup
Destroy the deployed stack:
```bash
# Make sure API_NAME matches the deployed stack
export API_NAME=MyAPI # or whatever you deployed
just destroy
# Or for Petstore
API_NAME=PetstoreAPI just destroy
```
## License
This project includes code from [awslabs/mcp](https://github.com/awslabs/mcp) licensed under Apache-2.0.
See [LICENSE](LICENSE) and [NOTICE](NOTICE) files.