AWS Lambda MCP Server: A serverless HTTP handler for the Model Context Protocol (MCP) using AWS Lambda.
Project description
MCP Lambda Handler
A Python library for building serverless Model Context Protocol (MCP) HTTP servers on AWS Lambda. Register tools and resources using decorators, plug in session storage, and drop the handler into any Lambda function.
Installation
pip install aws-lambda-mcp-server
Quick Start
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(name="my-mcp-server", version="1.0.0")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
def lambda_handler(event, context):
return mcp.handle_request(event, context)
Tools
Type hints become the input schema automatically
from typing import Optional
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(name="my-mcp-server")
@mcp.tool()
def search_products(
query: str,
max_results: int,
category: Optional[str],
) -> str:
"""Search the product catalogue.
Args:
query: Search keywords
max_results: Maximum number of results to return
category: Optional category filter
"""
# ... your logic here
return f"Found results for: {query}"
Supported types: str, int, float, bool, List[T], Dict[str, T], Optional[T], and Enum.
Enum parameters
from enum import Enum
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(name="my-mcp-server")
class Environment(Enum):
DEV = "dev"
STAGING = "staging"
PROD = "prod"
@mcp.tool()
def deploy(service: str, env: Environment) -> str:
"""Deploy a service to an environment.
Args:
service: Name of the service to deploy
env: Target environment
"""
return f"Deploying {service} to {env.value}"
Returning images
Return bytes from a tool and the handler automatically base64-encodes them as an image content block. JPEG, PNG, GIF, and WebP are auto-detected.
import boto3
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(name="my-mcp-server")
@mcp.tool()
def get_chart(metric: str) -> bytes:
"""Generate a chart for a metric and return it as an image.
Args:
metric: The metric name to chart
"""
s3 = boto3.client("s3")
obj = s3.get_object(Bucket="my-charts", Key=f"{metric}.png")
return obj["Body"].read()
Resources
Static resource
from awslabs.mcp_lambda_handler import MCPLambdaHandler
from awslabs.mcp_lambda_handler.types import StaticResource
mcp = MCPLambdaHandler(name="my-mcp-server")
mcp.add_resource(StaticResource(
uri="config://app/settings",
name="App Settings",
content='{"timeout": 30, "retries": 3}',
description="Application configuration",
mime_type="application/json",
))
File resource
from awslabs.mcp_lambda_handler import MCPLambdaHandler
from awslabs.mcp_lambda_handler.types import FileResource
mcp = MCPLambdaHandler(name="my-mcp-server")
mcp.add_resource(FileResource(
uri="docs://openapi",
path="/var/task/openapi.yaml",
name="OpenAPI Spec",
description="API specification",
))
Resource decorator (dynamic content)
import json
import boto3
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(name="my-mcp-server")
@mcp.resource(
uri="data://live-config",
name="Live Config",
description="Config fetched from Parameter Store at read time",
mime_type="application/json",
)
def live_config():
ssm = boto3.client("ssm")
value = ssm.get_parameter(Name="/myapp/config")["Parameter"]["Value"]
return value
Session Management
Stateless (default)
No session store is configured — each request is independent. Session IDs are still issued but nothing is persisted.
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(name="my-mcp-server")
DynamoDB sessions
Pass a DynamoDB table name to enable persistent sessions with a 24-hour TTL.
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(
name="my-mcp-server",
session_store="mcp-sessions", # DynamoDB table name
)
Or use DynamoDBSessionStore directly:
from awslabs.mcp_lambda_handler import MCPLambdaHandler
from awslabs.mcp_lambda_handler.session import DynamoDBSessionStore
mcp = MCPLambdaHandler(
name="my-mcp-server",
session_store=DynamoDBSessionStore(table_name="mcp-sessions"),
)
Reading and writing session data from a tool
from awslabs.mcp_lambda_handler import MCPLambdaHandler
mcp = MCPLambdaHandler(name="my-mcp-server", session_store="mcp-sessions")
@mcp.tool()
def increment_counter() -> str:
"""Increment the per-session counter."""
session = mcp.get_session()
count = session.get("count", 0) + 1 if session else 1
mcp.update_session(lambda s: s.set("count", count))
return f"Count is now {count}"
@mcp.tool()
def get_counter() -> str:
"""Get the current per-session counter value."""
session = mcp.get_session()
count = session.get("count", 0) if session else 0
return f"Count: {count}"
Custom session backend
Subclass SessionStore to use any storage backend:
from typing import Any, Dict, Optional
from awslabs.mcp_lambda_handler import MCPLambdaHandler
from awslabs.mcp_lambda_handler.session import SessionStore
import uuid
class RedisSessionStore(SessionStore):
def __init__(self, redis_client):
self.redis = redis_client
def create_session(self, session_data: Optional[Dict[str, Any]] = None) -> str:
session_id = str(uuid.uuid4())
self.redis.setex(session_id, 86400, json.dumps(session_data or {}))
return session_id
def get_session(self, session_id: str) -> Optional[Dict[str, Any]]:
data = self.redis.get(session_id)
return json.loads(data) if data else None
def update_session(self, session_id: str, session_data: Dict[str, Any]) -> bool:
self.redis.setex(session_id, 86400, json.dumps(session_data))
return True
def delete_session(self, session_id: str) -> bool:
self.redis.delete(session_id)
return True
mcp = MCPLambdaHandler(
name="my-mcp-server",
session_store=RedisSessionStore(redis_client),
)
Example Architecture
A typical deployment looks like:
Client → API Gateway (/mcp)
│
├── Lambda Authorizer (validates bearer token)
│
└── MCP Lambda (this library)
│
└── DynamoDB (optional session store)
The Lambda function receives API Gateway proxy events and returns proxy responses — no extra configuration needed.
Development
git clone https://github.com/awslabs/mcp.git
cd mcp/src/mcp-lambda-handler
pip install -e ".[dev]"
pytest
License
Apache-2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aws_lambda_mcp_server-0.1.14.tar.gz.
File metadata
- Download URL: aws_lambda_mcp_server-0.1.14.tar.gz
- Upload date:
- Size: 71.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52cacb23239131008b0c1b88a6e8d5469eb2a602b579e8ab81701c3aacfd7b3c
|
|
| MD5 |
4deefd0c184e8f612c049401f4c6b357
|
|
| BLAKE2b-256 |
bc8ec8adf49a64f2cea06c3e78e80e225f1360c1a3c9f2196af44bcca3550cd6
|
Provenance
The following attestation bundles were made for aws_lambda_mcp_server-0.1.14.tar.gz:
Publisher:
publish-mcp-lambda-handler.yml on getlinksc/aws-lambda-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aws_lambda_mcp_server-0.1.14.tar.gz -
Subject digest:
52cacb23239131008b0c1b88a6e8d5469eb2a602b579e8ab81701c3aacfd7b3c - Sigstore transparency entry: 1206193612
- Sigstore integration time:
-
Permalink:
getlinksc/aws-lambda-mcp-server@178e61a8645f90f9fc855b573c3e20f1efd0b283 -
Branch / Tag:
refs/tags/v0.1.14 - Owner: https://github.com/getlinksc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-mcp-lambda-handler.yml@178e61a8645f90f9fc855b573c3e20f1efd0b283 -
Trigger Event:
release
-
Statement type:
File details
Details for the file aws_lambda_mcp_server-0.1.14-py3-none-any.whl.
File metadata
- Download URL: aws_lambda_mcp_server-0.1.14-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e0a80c03fbc026239852bf0fd7fc3eefd34e89eacaee4672cf9b1a525654a4a
|
|
| MD5 |
a45dade567929adc963aee7664878633
|
|
| BLAKE2b-256 |
5f1932275a1c6cdfb878a9f3aad629cca1308a895521ccc310c13b6fb2cccdd9
|
Provenance
The following attestation bundles were made for aws_lambda_mcp_server-0.1.14-py3-none-any.whl:
Publisher:
publish-mcp-lambda-handler.yml on getlinksc/aws-lambda-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aws_lambda_mcp_server-0.1.14-py3-none-any.whl -
Subject digest:
8e0a80c03fbc026239852bf0fd7fc3eefd34e89eacaee4672cf9b1a525654a4a - Sigstore transparency entry: 1206193621
- Sigstore integration time:
-
Permalink:
getlinksc/aws-lambda-mcp-server@178e61a8645f90f9fc855b573c3e20f1efd0b283 -
Branch / Tag:
refs/tags/v0.1.14 - Owner: https://github.com/getlinksc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-mcp-lambda-handler.yml@178e61a8645f90f9fc855b573c3e20f1efd0b283 -
Trigger Event:
release
-
Statement type: