VPPATEL-SPS/mcp-lambda-server
If you are the rightful owner of mcp-lambda-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The Model Context Protocol (MCP) server template is a reusable AWS SAM blueprint for deploying a server on AWS Lambda and API Gateway, featuring token-based authorization and customizable tools.
Generic MCP Lambda Server Template
A reusable AWS SAM template and reference implementation for deploying a Model Context Protocol (MCP) server on AWS Lambda and API Gateway with token-based authorization. Use this generic blueprint to build and extend your own MCP tools, integrating custom business logic, data sources, or external APIs as needed.
β¨ What's Included
- AWS SAM / CloudFormation infrastructure (API Gateway, Lambda, optional DynamoDB table, session store)
- pluggable token authorizer (simple bearer token)
- Session persistence table (TTL-based)
- Example tools (echo, add, utc_timestamp, optional DynamoDB sample)
- Minimal dependency footprint
π Project Structure
mcp-lambda-server/
βββ template.yml # SAM infrastructure definition
βββ README.md # This guide
βββ authorizer/
β βββ app.py # Custom Lambda token authorizer
βββ server/
β βββ app.py # MCP server + example tools
β βββ requirements.txt # Python dependencies
βββ examples/
βββ simple_client.py # Minimal MCP call example
βββ strands_client.py # Interactive Strands Agent chat example
π§° Example Tools Provided
Tool | Purpose |
---|---|
echo(text) | Returns the same text (connectivity sanity check) |
add(a, b) | Adds two numbers and returns a structured JSON result |
utc_timestamp() | Returns current UTC timestamp & ISO8601 string |
list_items(limit) | (Optional) Lists items from a demo DynamoDB table if configured |
health() | Basic server/config status |
You can remove or extend these freely.
π Architecture
βββββββββββββββ HTTPS (Bearer token) ββββββββββββββββ
β MCP Client β ββββββββββββββββββββββββΆ β API Gateway β
βββββββββββββββ β (Authorizer)β
ββββββββ¬ββββββββ
βInvoke
βββββββββΌβββββββββ
β Lambda (MCP) β
βββββββββ¬βββββββββ
β (optional)
βββββββββΌβββββββββ
β DynamoDB Table β
ββββββββββββββββββ
π Security Model
- Simple bearer token (passed as
Authorization: Bearer <token>
) validated by a Lambda authorizer. - Token stored as a NoEcho CloudFormation parameter (not logged in plaintext).
- Session table uses TTL for automatic cleanup.
β Parameters (template.yml)
Name | Description | Default | Required |
---|---|---|---|
McpAuthToken | Bearer token clients must send | your-secure-token-here | Yes (change in prod) |
CreateDemoTable | Create a sample DynamoDB table for list_items tool | false | No |
DemoTableName | Name of existing or new table (if CreateDemoTable=true) | McpDemoItems | Conditionally |
π§ͺ Local Development (Option A: SAM CLI)
# From repo root (where template.yml resides)
cd mcp-lambda-server
sam build
sam local invoke McpServerFunction --event events/sample.json
You can craft a minimal invoke event (POST body) β see the awslabs.mcp_lambda_handler
docs for request schema. Usually you'll deploy and call via HTTP instead.
π Deployment
cd mcp-lambda-server
sam build
sam deploy \
--stack-name generic-mcp-server \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
McpAuthToken="REPLACE_WITH_STRONG_TOKEN" \
CreateDemoTable="true" \
DemoTableName="McpDemoItems"
After deployment note the output McpApiUrl
, e.g.:
https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/mcp
π Connecting From GitHub Copilot (mcp.json)
Example entry:
{
"servers": {
"generic-mcp": {
"url": "https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/mcp",
"requestInit": {
"headers": { "Authorization": "Bearer REPLACE_WITH_STRONG_TOKEN" }
}
}
}
}
β Adding New Tools
In server/app.py
:
@mcp_server.tool()
def my_new_tool(arg1: str) -> str:
return json.dumps({"tool": "my_new_tool", "arg1": arg1})
Return plain strings or JSON-serialized strings. Keep responses concise & structured.
π§± DynamoDB Demo Table Schema (Optional)
If CreateDemoTable=true
, a PAY_PER_REQUEST table with partition key pk
is created. You can manually insert sample items:
aws dynamodb put-item \
--table-name McpDemoItems \
--item '{"pk":{"S":"item#1"},"message":{"S":"Hello"}}'
Then call list_items(limit=25)
via MCP client.
π§ͺ Quick MCP Client Smoke Test (Python)
from mcp.client.streamable_http import streamablehttp_client
from strands.tools.mcp import MCPClient
API_URL = "https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/mcp"
TOKEN = "REPLACE_WITH_STRONG_TOKEN"
client = MCPClient(lambda: streamablehttp_client(
url=API_URL,
headers={"Authorization": f"Bearer {TOKEN}"}
))
with client:
tools = client.list_tools_sync()
print("Tools:", [t.name for t in tools])
res = client.call_tool_sync("utc_timestamp", {})
print(res.content[0].text)
π©βπ» Minimal Direct Usage Example
(See examples/simple_client.py
)
from mcp.client.streamable_http import streamablehttp_client
from strands.tools.mcp import MCPClient
import json
API_URL = "https://your-api.execute-api.us-east-1.amazonaws.com/Prod/mcp"
TOKEN = "YOUR_TOKEN"
client = MCPClient(lambda: streamablehttp_client(
url=API_URL,
headers={"Authorization": f"Bearer {TOKEN}"}
))
with client:
for t in client.list_tools_sync():
print("Tool:", t.name, t.description)
# Call echo tool
resp = client.call_tool_sync("echo", {"text": "hello"})
print("echo β", resp.content[0].text)
π£ Interactive Strands Agent Chat Example
(See examples/strands_client.py
) Uses a Bedrock model + discovered MCP tools.
Key steps:
- Build MCP client with bearer auth
- List tools
- Construct Agent(model=..., tools=tools)
- Read user input loop and invoke
agent(user_text)
Environment requirements:
strands
(and its Bedrock integration) & dependencies- Correct Bedrock model ID with region access
π Example Scripts Summary
File | Purpose |
---|---|
examples/simple_client.py | Minimal list + call tool demonstration |
examples/strands_client.py | Interactive chat loop with Strands Agent |
π©Ί Health & Troubleshooting
Symptom | Check |
---|---|
403 Unauthorized | Ensure header uses correct bearer token & matches deployed parameter |
500 Error (tool) | CloudWatch logs for McpServerFunction for stack traces |
Timeout | Increase Lambda timeout in Globals.Function.Timeout |
Empty tool list | Confirm correct URL path /mcp and POST method |
Fetch logs quickly:
sam logs -n McpServerFunction --stack-name generic-mcp-server --tail
π§Ή Maintenance
- Update code β
sam build && sam deploy
- Rotate token β deploy new parameter, update all clients
- Add tools β modify
server/app.py
and redeploy
π License
Use freely in your org; validate security posture before production.
Feel free to tailor this template further for your specific domain logic (Jira, internal APIs, etc.).