# mcpbytes-lambda-apigw
[](https://www.python.org/downloads/)
[](https://spec.modelcontextprotocol.io/)
[](https://opensource.org/licenses/Apache-2.0)
Production-ready AWS API Gateway transport adapter for [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers. Seamlessly converts between HTTP requests and MCP JSON-RPC with enterprise-grade authentication and CORS handling.
## π **Quick Start**
```python
from mcpbytes_lambda.core import MCPServer
from mcpbytes_lambda.apigw import ApiGatewayAdapter
# Create your MCP server with tools
mcp = MCPServer(name="my-server", version="1.0.0")
@mcp.tool(name="example.tool")
def my_tool(message: str) -> str:
return f"Processed: {message}"
# Zero-boilerplate Lambda handler
def lambda_handler(event, context):
adapter = ApiGatewayAdapter()
return adapter.handle(event, mcp) # That's it!
```
## β¨ **Features**
- **π Smart Authentication** - Auto-detects Lambda Authorizers, supports custom token validation
- **π CORS Compliance** - Full preflight handling with configurable origins
- **π‘ MCP Streamable HTTP** - Compliant with MCP 2025-06-18 transport specification
- **β‘ High Performance** - Optimized for AWS Lambda cold starts and execution
- **π‘οΈ Input Validation** - JSON-RPC 2.0 validation with detailed error responses
- **π Production Logging** - Structured logging for debugging and monitoring
- **π Base64 Support** - Automatic handling of API Gateway base64 encoding
## π **Authentication**
The API Gateway adapter provides flexible authentication with smart auto-detection:
### Authentication Flow
1. **Lambda Authorizer Detection**: Auto-detects and uses existing Lambda Authorizer context
2. **Token Format Validation**: Validates Bearer token format when auth is required
3. **Custom Validation**: Executes custom token validation logic (if provided)
4. **User Context Access**: Provides unified access to authentication context
### Usage Patterns
#### Lambda Authorizer (Auto-detected)
```python
def lambda_handler(event, context):
adapter = ApiGatewayAdapter(require_auth=True)
user_info = adapter.get_user_context(event) # From Lambda Authorizer
return adapter.handle(event, mcp_server)
```
#### Custom Token Validation
```python
import jwt
from typing import Dict, Any, Union
def validate_jwt_token(token: str) -> Union[Dict[str, Any], bool]:
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
return {"user_id": payload["sub"], "role": payload["role"]}
except jwt.InvalidTokenError:
return False
def lambda_handler(event, context):
adapter = ApiGatewayAdapter(require_auth=True, token_validator=validate_jwt_token)
user_info = adapter.get_user_context(event) # From custom validator
return adapter.handle(event, mcp_server)
```
## βοΈ **Configuration**
```python
adapter = ApiGatewayAdapter(
cors_origin="https://myapp.com", # CORS origin header
require_auth=True, # Enable authentication
auth_header="Authorization", # Auth header name
token_validator=my_custom_validator # Custom validation function
)
```
### Parameters:
- `cors_origin`: CORS origin header value (default: "*")
- `require_auth`: Whether to require Bearer token authentication (default: False)
- `auth_header`: Header name for authentication token (default: "Authorization")
- `token_validator`: Optional custom token validation function
- Should return `Dict[str, Any]` for user context on success
- Should return `False` for explicit rejection
- Should return `True` for acceptance without context
- May raise exceptions for validation errors
## π **Requirements**
- Python 3.12+
- `mcpbytes-lambda-core` package
- AWS API Gateway Lambda Proxy Integration
- Bearer token authentication (via Lambda Authorizer or custom validation)
## ποΈ **Architecture**
```
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β API Gateway βββββΆβ APIGW Adapter βββββΆβ MCP Core β
β HTTP Request β β (Transport) β β JSON-RPC β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β β β
β βΌ β
β βββββββββββββββββββ β
β β Authentication β β
β β CORS Handling β β
β β Error Mapping β β
β βββββββββββββββββββ β
β β
βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ
β HTTP Response ββββββββββββββββββββββββββββββββ Tool Results β
β (200/500) β β JSON-RPC β
βββββββββββββββββββ βββββββββββββββββββ
```
## π οΈ **Usage Examples**
### **Basic Lambda Handler**
```python
def lambda_handler(event, context):
adapter = ApiGatewayAdapter()
return adapter.handle(event, mcp)
```
### **Lambda Authorizer Integration**
```python
def lambda_handler(event, context):
adapter = ApiGatewayAdapter(require_auth=True)
# Access user context from Lambda Authorizer
user_info = adapter.get_user_context(event)
if user_info:
print(f"User: {user_info.get('principalId')}")
return adapter.handle(event, mcp)
```
### **JWT Token Validation**
```python
import jwt
import os
from typing import Dict, Any, Union
from mcpbytes_lambda.core.exceptions import AuthenticationError
def validate_jwt(token: str) -> Union[Dict[str, Any], bool]:
try:
payload = jwt.decode(token, os.environ["JWT_SECRET"], algorithms=["HS256"])
return {
"user_id": payload["sub"],
"email": payload["email"],
"role": payload.get("role", "user")
}
except jwt.ExpiredSignatureError:
raise AuthenticationError("Token has expired")
except jwt.InvalidTokenError:
return False
def lambda_handler(event, context):
adapter = ApiGatewayAdapter(
require_auth=True,
token_validator=validate_jwt
)
user_context = adapter.get_user_context(event)
return adapter.handle(event, mcp)
```
### **Multi-Server Routing**
```python
# Route to different MCP servers based on path
def lambda_handler(event, context):
path = event.get("path", "")
if path.startswith("/math"):
server = math_mcp_server
elif path.startswith("/weather"):
server = weather_mcp_server
else:
server = default_mcp_server
adapter = ApiGatewayAdapter(require_auth=True)
return adapter.handle(event, server)
```
## π‘ **MCP Protocol Compliance**
### **Streamable HTTP Transport (2025-06-18)**
β
HTTP POST for JSON-RPC requests/notifications/responses
β
HTTP GET for optional Server-Sent Events (SSE) streams
β
Proper status codes: 200 OK, 202 Accepted, 4xx/5xx errors
β
MCP-Protocol-Version header support
β
Bearer token authentication (RFC 6750)
β
Session management with Mcp-Session-Id
β
CORS preflight handling
β
Content negotiation (application/json + text/event-stream)
### **Lambda Limitations**
β Server-Sent Events (SSE) streaming not supported
β Real-time server-to-client notifications not supported
β HTTP GET for stream initiation not supported
β Stream resumability not supported
*For full streaming support, deploy as a long-running server process.*
### **Required Headers**
**Client must send:**
```http
POST /your-endpoint HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream #BOTH headers
Authorization: Bearer <token> #if needed/enabled
MCP-Protocol-Version: 2025-06-18 / multiple supported
```
**Server responds with:**
```http
HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: https://example.com
```
### **JSON-RPC Format**
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "example.tool",
"arguments": {"message": "Hello MCP!"}
},
"id": "request-1"
}
```
## π **Error Handling**
### **HTTP Status Codes**
- **200 OK** - CORS preflight successful, JSON-RPC requests processed
- **400 Bad Request** - Malformed requests, unsupported protocol versions
- **401 Unauthorized** - Missing or invalid Bearer token
- **403 Forbidden** - Origin not allowed (CORS violation)
- **406 Not Acceptable** - Accept header doesn't include required content types
- **415 Unsupported Media Type** - Content-Type is not application/json
- **500 Internal Server Error** - JSON-RPC error or server failure
### **JSON-RPC Error Codes**
```python
# Standard JSON-RPC 2.0 error codes
-32700 # Parse error (invalid JSON)
-32600 # Invalid request (missing method, bad headers)
-32601 # Method not found
-32602 # Invalid params
-32603 # Internal error
```
## π‘οΈ **Security Best Practices**
### **Authentication Strategies**
1. **Lambda Authorizer** (Recommended for production)
- Centralized authentication logic
- Automatic caching and performance optimization
- Built-in AWS integration
2. **Custom Token Validation**
- Flexible validation logic
- Support for JWT, API keys, custom tokens
- Direct integration with your auth system
### **Environment Variables**
```bash
# Production CORS configuration
ALLOWED_ORIGINS="https://example.com,https://app.example.com"
# JWT Secret for token validation
JWT_SECRET="your-secret-key"
# Development (allows all origins - not recommended for production)
# ALLOWED_ORIGINS="" # Empty = allow all
```
### **API Gateway Setup**
```yaml
# SAM Template example
Resources:
McpApi:
Type: AWS::Serverless::Api
Properties:
Cors:
AllowMethods: "'POST,OPTIONS'"
AllowHeaders: "'Content-Type,Authorization,MCP-Protocol-Version'"
AllowOrigin: "'*'" # Override with adapter's origin validation
Auth:
DefaultAuthorizer: TokenAuth
Authorizers:
TokenAuth:
FunctionArn: !GetAtt AuthFunction.Arn
```
## π **Deployment**
### **SAM Template**
```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
McpFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Handler: handler.lambda_handler
Runtime: python3.12
Environment:
Variables:
ALLOWED_ORIGINS: "https://myapp.com,https://admin.myapp.com"
JWT_SECRET: !Ref JWTSecret
Events:
McpApi:
Type: Api
Properties:
Path: /mcp
Method: any
```
### **CDK Deployment**
```python
from aws_cdk import aws_lambda as lambda_
from aws_cdk import aws_apigateway as apigw
lambda_function = lambda_.Function(
self, "McpFunction",
runtime=lambda_.Runtime.PYTHON_3_12,
handler="handler.lambda_handler",
code=lambda_.Code.from_directory("src/"),
environment={
"ALLOWED_ORIGINS": "https://myapp.com",
"JWT_SECRET": jwt_secret.secret_value_from_json("secret").to_string()
}
)
api = apigw.RestApi(self, "McpApi")
api.root.add_proxy(default_integration=apigw.LambdaIntegration(lambda_function))
```
## π€ **Contributing**
1. Fork the repository
2. Create a feature branch: `git checkout -b feature-name`
3. Make your changes and add tests
4. Run tests: `python -m pytest`
5. Submit a pull request
## π **License**
Apache 2.0 License - see [LICENSE](../../LICENSE) for details.
## π **Related Packages**
- [`mcpbytes-lambda-core`](../core/) - Transport-agnostic MCP server core
- [`mcpbytes-lambda-stdio`](../stdio/) - Stdio transport adapter
## π **Documentation**
- [MCP Specification](https://spec.modelcontextprotocol.io/)
- [AWS API Gateway Documentation](https://docs.aws.amazon.com/apigateway/)
- [AWS Lambda Proxy Integration](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html)
- [Project Examples](../../examples/)
---
Built with β€οΈ for the MCP ecosystem
Raw data
{
"_id": null,
"home_page": null,
"name": "mcpbytes-lambda-apigw",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "api-gateway, aws-lambda, cors, mcp, model-context-protocol, serverless, transport",
"author": null,
"author_email": "\"MCPBytes.com\" <hello@mcpbytes.com>",
"download_url": "https://files.pythonhosted.org/packages/b1/dc/24f3010e1cfaab9b2b19351f468eb8d89269fc201ffe25a5dedebe6d7a56/mcpbytes_lambda_apigw-0.1.0.tar.gz",
"platform": null,
"description": "# mcpbytes-lambda-apigw\n\n[](https://www.python.org/downloads/)\n[](https://spec.modelcontextprotocol.io/)\n[](https://opensource.org/licenses/Apache-2.0)\n\nProduction-ready AWS API Gateway transport adapter for [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers. Seamlessly converts between HTTP requests and MCP JSON-RPC with enterprise-grade authentication and CORS handling.\n\n## \ud83d\ude80 **Quick Start**\n\n```python\nfrom mcpbytes_lambda.core import MCPServer\nfrom mcpbytes_lambda.apigw import ApiGatewayAdapter\n\n# Create your MCP server with tools\nmcp = MCPServer(name=\"my-server\", version=\"1.0.0\")\n\n@mcp.tool(name=\"example.tool\")\ndef my_tool(message: str) -> str:\n return f\"Processed: {message}\"\n\n# Zero-boilerplate Lambda handler\ndef lambda_handler(event, context):\n adapter = ApiGatewayAdapter()\n return adapter.handle(event, mcp) # That's it!\n```\n\n## \u2728 **Features**\n\n- **\ud83d\udd12 Smart Authentication** - Auto-detects Lambda Authorizers, supports custom token validation\n- **\ud83c\udf10 CORS Compliance** - Full preflight handling with configurable origins\n- **\ud83d\udce1 MCP Streamable HTTP** - Compliant with MCP 2025-06-18 transport specification\n- **\u26a1 High Performance** - Optimized for AWS Lambda cold starts and execution\n- **\ud83d\udee1\ufe0f Input Validation** - JSON-RPC 2.0 validation with detailed error responses\n- **\ud83d\udcca Production Logging** - Structured logging for debugging and monitoring\n- **\ud83d\udd04 Base64 Support** - Automatic handling of API Gateway base64 encoding\n\n## \ud83d\udd10 **Authentication**\n\nThe API Gateway adapter provides flexible authentication with smart auto-detection:\n\n### Authentication Flow\n1. **Lambda Authorizer Detection**: Auto-detects and uses existing Lambda Authorizer context\n2. **Token Format Validation**: Validates Bearer token format when auth is required \n3. **Custom Validation**: Executes custom token validation logic (if provided)\n4. **User Context Access**: Provides unified access to authentication context\n\n### Usage Patterns\n\n#### Lambda Authorizer (Auto-detected)\n```python\ndef lambda_handler(event, context):\n adapter = ApiGatewayAdapter(require_auth=True)\n user_info = adapter.get_user_context(event) # From Lambda Authorizer\n return adapter.handle(event, mcp_server)\n```\n\n#### Custom Token Validation\n```python\nimport jwt\nfrom typing import Dict, Any, Union\n\ndef validate_jwt_token(token: str) -> Union[Dict[str, Any], bool]:\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[\"HS256\"])\n return {\"user_id\": payload[\"sub\"], \"role\": payload[\"role\"]}\n except jwt.InvalidTokenError:\n return False\n\ndef lambda_handler(event, context):\n adapter = ApiGatewayAdapter(require_auth=True, token_validator=validate_jwt_token)\n user_info = adapter.get_user_context(event) # From custom validator\n return adapter.handle(event, mcp_server)\n```\n\n## \u2699\ufe0f **Configuration**\n\n```python\nadapter = ApiGatewayAdapter(\n cors_origin=\"https://myapp.com\", # CORS origin header\n require_auth=True, # Enable authentication\n auth_header=\"Authorization\", # Auth header name \n token_validator=my_custom_validator # Custom validation function\n)\n```\n\n### Parameters:\n- `cors_origin`: CORS origin header value (default: \"*\")\n- `require_auth`: Whether to require Bearer token authentication (default: False)\n- `auth_header`: Header name for authentication token (default: \"Authorization\")\n- `token_validator`: Optional custom token validation function\n - Should return `Dict[str, Any]` for user context on success\n - Should return `False` for explicit rejection\n - Should return `True` for acceptance without context\n - May raise exceptions for validation errors\n\n## \ud83d\udccb **Requirements**\n\n- Python 3.12+\n- `mcpbytes-lambda-core` package\n- AWS API Gateway Lambda Proxy Integration\n- Bearer token authentication (via Lambda Authorizer or custom validation)\n\n## \ud83c\udfd7\ufe0f **Architecture**\n\n```\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 API Gateway \u2502\u2500\u2500\u2500\u25b6\u2502 APIGW Adapter \u2502\u2500\u2500\u2500\u25b6\u2502 MCP Core \u2502\n\u2502 HTTP Request \u2502 \u2502 (Transport) \u2502 \u2502 JSON-RPC \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u2502 \u2502 \u2502\n \u2502 \u25bc \u2502\n \u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n \u2502 \u2502 Authentication \u2502 \u2502\n \u2502 \u2502 CORS Handling \u2502 \u2502\n \u2502 \u2502 Error Mapping \u2502 \u2502\n \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n \u2502 \u2502\n \u25bc \u25bc\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 HTTP Response \u2502\u25c0\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 Tool Results \u2502\n\u2502 (200/500) \u2502 \u2502 JSON-RPC \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n## \ud83d\udee0\ufe0f **Usage Examples**\n\n### **Basic Lambda Handler**\n\n```python\ndef lambda_handler(event, context):\n adapter = ApiGatewayAdapter()\n return adapter.handle(event, mcp)\n```\n\n### **Lambda Authorizer Integration**\n\n```python\ndef lambda_handler(event, context):\n adapter = ApiGatewayAdapter(require_auth=True)\n \n # Access user context from Lambda Authorizer\n user_info = adapter.get_user_context(event)\n if user_info:\n print(f\"User: {user_info.get('principalId')}\")\n \n return adapter.handle(event, mcp)\n```\n\n### **JWT Token Validation**\n\n```python\nimport jwt\nimport os\nfrom typing import Dict, Any, Union\nfrom mcpbytes_lambda.core.exceptions import AuthenticationError\n\ndef validate_jwt(token: str) -> Union[Dict[str, Any], bool]:\n try:\n payload = jwt.decode(token, os.environ[\"JWT_SECRET\"], algorithms=[\"HS256\"])\n return {\n \"user_id\": payload[\"sub\"],\n \"email\": payload[\"email\"],\n \"role\": payload.get(\"role\", \"user\")\n }\n except jwt.ExpiredSignatureError:\n raise AuthenticationError(\"Token has expired\")\n except jwt.InvalidTokenError:\n return False\n\ndef lambda_handler(event, context):\n adapter = ApiGatewayAdapter(\n require_auth=True,\n token_validator=validate_jwt\n )\n \n user_context = adapter.get_user_context(event)\n return adapter.handle(event, mcp)\n```\n\n### **Multi-Server Routing**\n\n```python\n# Route to different MCP servers based on path\ndef lambda_handler(event, context):\n path = event.get(\"path\", \"\")\n \n if path.startswith(\"/math\"):\n server = math_mcp_server\n elif path.startswith(\"/weather\"):\n server = weather_mcp_server\n else:\n server = default_mcp_server\n \n adapter = ApiGatewayAdapter(require_auth=True)\n return adapter.handle(event, server)\n```\n\n## \ud83d\udce1 **MCP Protocol Compliance**\n\n### **Streamable HTTP Transport (2025-06-18)**\n\u2705 HTTP POST for JSON-RPC requests/notifications/responses \n\u2705 HTTP GET for optional Server-Sent Events (SSE) streams \n\u2705 Proper status codes: 200 OK, 202 Accepted, 4xx/5xx errors \n\u2705 MCP-Protocol-Version header support \n\u2705 Bearer token authentication (RFC 6750) \n\u2705 Session management with Mcp-Session-Id \n\u2705 CORS preflight handling \n\u2705 Content negotiation (application/json + text/event-stream) \n\n### **Lambda Limitations**\n\u274c Server-Sent Events (SSE) streaming not supported \n\u274c Real-time server-to-client notifications not supported \n\u274c HTTP GET for stream initiation not supported \n\u274c Stream resumability not supported \n\n*For full streaming support, deploy as a long-running server process.*\n\n### **Required Headers**\n\n**Client must send:**\n```http\nPOST /your-endpoint HTTP/1.1\nContent-Type: application/json\nAccept: application/json, text/event-stream #BOTH headers\nAuthorization: Bearer <token> #if needed/enabled\nMCP-Protocol-Version: 2025-06-18 / multiple supported\n```\n\n**Server responds with:**\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\nAccess-Control-Allow-Origin: https://example.com\n```\n\n### **JSON-RPC Format**\n\n```json\n{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"example.tool\",\n \"arguments\": {\"message\": \"Hello MCP!\"}\n },\n \"id\": \"request-1\"\n}\n```\n\n## \ud83d\udd0d **Error Handling**\n\n### **HTTP Status Codes**\n\n- **200 OK** - CORS preflight successful, JSON-RPC requests processed\n- **400 Bad Request** - Malformed requests, unsupported protocol versions\n- **401 Unauthorized** - Missing or invalid Bearer token\n- **403 Forbidden** - Origin not allowed (CORS violation)\n- **406 Not Acceptable** - Accept header doesn't include required content types\n- **415 Unsupported Media Type** - Content-Type is not application/json\n- **500 Internal Server Error** - JSON-RPC error or server failure\n\n### **JSON-RPC Error Codes**\n\n```python\n# Standard JSON-RPC 2.0 error codes\n-32700 # Parse error (invalid JSON)\n-32600 # Invalid request (missing method, bad headers)\n-32601 # Method not found \n-32602 # Invalid params\n-32603 # Internal error\n```\n\n## \ud83d\udee1\ufe0f **Security Best Practices**\n\n### **Authentication Strategies**\n1. **Lambda Authorizer** (Recommended for production)\n - Centralized authentication logic\n - Automatic caching and performance optimization\n - Built-in AWS integration\n\n2. **Custom Token Validation**\n - Flexible validation logic\n - Support for JWT, API keys, custom tokens\n - Direct integration with your auth system\n\n### **Environment Variables**\n\n```bash\n# Production CORS configuration\nALLOWED_ORIGINS=\"https://example.com,https://app.example.com\"\n\n# JWT Secret for token validation\nJWT_SECRET=\"your-secret-key\"\n\n# Development (allows all origins - not recommended for production)\n# ALLOWED_ORIGINS=\"\" # Empty = allow all\n```\n\n### **API Gateway Setup**\n\n```yaml\n# SAM Template example\nResources:\n McpApi:\n Type: AWS::Serverless::Api\n Properties:\n Cors:\n AllowMethods: \"'POST,OPTIONS'\"\n AllowHeaders: \"'Content-Type,Authorization,MCP-Protocol-Version'\"\n AllowOrigin: \"'*'\" # Override with adapter's origin validation\n Auth:\n DefaultAuthorizer: TokenAuth\n Authorizers:\n TokenAuth:\n FunctionArn: !GetAtt AuthFunction.Arn\n```\n\n## \ud83d\ude80 **Deployment**\n\n### **SAM Template**\n\n```yaml\nAWSTemplateFormatVersion: '2010-09-09'\nTransform: AWS::Serverless-2016-10-31\n\nResources:\n McpFunction:\n Type: AWS::Serverless::Function\n Properties:\n CodeUri: .\n Handler: handler.lambda_handler\n Runtime: python3.12\n Environment:\n Variables:\n ALLOWED_ORIGINS: \"https://myapp.com,https://admin.myapp.com\"\n JWT_SECRET: !Ref JWTSecret\n Events:\n McpApi:\n Type: Api\n Properties:\n Path: /mcp\n Method: any\n```\n\n### **CDK Deployment**\n\n```python\nfrom aws_cdk import aws_lambda as lambda_\nfrom aws_cdk import aws_apigateway as apigw\n\nlambda_function = lambda_.Function(\n self, \"McpFunction\",\n runtime=lambda_.Runtime.PYTHON_3_12,\n handler=\"handler.lambda_handler\",\n code=lambda_.Code.from_directory(\"src/\"),\n environment={\n \"ALLOWED_ORIGINS\": \"https://myapp.com\",\n \"JWT_SECRET\": jwt_secret.secret_value_from_json(\"secret\").to_string()\n }\n)\n\napi = apigw.RestApi(self, \"McpApi\")\napi.root.add_proxy(default_integration=apigw.LambdaIntegration(lambda_function))\n```\n\n## \ud83e\udd1d **Contributing**\n\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feature-name`\n3. Make your changes and add tests\n4. Run tests: `python -m pytest`\n5. Submit a pull request\n\n## \ud83d\udcc4 **License**\n\nApache 2.0 License - see [LICENSE](../../LICENSE) for details.\n\n## \ud83d\udd17 **Related Packages**\n\n- [`mcpbytes-lambda-core`](../core/) - Transport-agnostic MCP server core\n- [`mcpbytes-lambda-stdio`](../stdio/) - Stdio transport adapter\n\n## \ud83d\udcda **Documentation**\n\n- [MCP Specification](https://spec.modelcontextprotocol.io/)\n- [AWS API Gateway Documentation](https://docs.aws.amazon.com/apigateway/)\n- [AWS Lambda Proxy Integration](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html)\n- [Project Examples](../../examples/)\n\n---\n\nBuilt with \u2764\ufe0f for the MCP ecosystem\n",
"bugtrack_url": null,
"license": null,
"summary": "AWS API Gateway transport adapter for mcpbytes-lambda-core",
"version": "0.1.0",
"project_urls": {
"Documentation": "https://github.com/MCPBytes/mcpbytes-lambda#readme",
"Homepage": "https://mcpbytes.com/",
"Issues": "https://github.com/MCPBytes/mcpbytes-lambda/issues",
"Repository": "https://github.com/MCPBytes/mcpbytes-lambda"
},
"split_keywords": [
"api-gateway",
" aws-lambda",
" cors",
" mcp",
" model-context-protocol",
" serverless",
" transport"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "f918c24e58daf0561b7e4878f678c5ebc18379a27706d0922c89f41707f10729",
"md5": "7c4662574dab5d4eb96f12956d2af46d",
"sha256": "90f56a4c555355e5d5a6e833a947482d36d71d50be38d0630e62800373075ea5"
},
"downloads": -1,
"filename": "mcpbytes_lambda_apigw-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7c4662574dab5d4eb96f12956d2af46d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 11745,
"upload_time": "2025-09-01T01:42:35",
"upload_time_iso_8601": "2025-09-01T01:42:35.382035Z",
"url": "https://files.pythonhosted.org/packages/f9/18/c24e58daf0561b7e4878f678c5ebc18379a27706d0922c89f41707f10729/mcpbytes_lambda_apigw-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b1dc24f3010e1cfaab9b2b19351f468eb8d89269fc201ffe25a5dedebe6d7a56",
"md5": "9c06147b3df8cbefe0febf49a927ba94",
"sha256": "7d7a7ab9b6c8f756932434040bbaf1e48fd4890876860a27b416a4618441b4f1"
},
"downloads": -1,
"filename": "mcpbytes_lambda_apigw-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "9c06147b3df8cbefe0febf49a927ba94",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 10084,
"upload_time": "2025-09-01T01:42:36",
"upload_time_iso_8601": "2025-09-01T01:42:36.457592Z",
"url": "https://files.pythonhosted.org/packages/b1/dc/24f3010e1cfaab9b2b19351f468eb8d89269fc201ffe25a5dedebe6d7a56/mcpbytes_lambda_apigw-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-01 01:42:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "MCPBytes",
"github_project": "mcpbytes-lambda#readme",
"github_not_found": true,
"lcname": "mcpbytes-lambda-apigw"
}