This is the English translation of my original Japanese article: https://zenn.dev/arvehisa/articles/host-remote-mcp-on-lambda
Background
Previously, I wrote an article about creating a Local Memory MCP to give Claude memory capabilities. Shortly after, Claude Mobile added support for Remote MCP, and I wanted to give memory capabilities to Claude on mobile devices as well. This motivated me to implement a remote version of my Local MCP Server using AWS Lambda.
Why Lambda?
Serverless and Event-Driven
My use case involves Claude accessing my Memory MCP to retrieve or create memories about me during conversations. This happens at most a few dozen times per day, so there's no need for a constantly running server. This perfectly matches Lambda's event-driven architecture.
Individual Use Cases Fit Within the Free Tier
AWS Lambda's free tier includes:
- 1 million requests per month free
- 400,000 GB-seconds of compute time per month free
I also use DynamoDB for memory storage, which has its own free tier:
- 25GB storage per month free
- 25 RCU/25 WCU free
This theoretically allows processing about 200M read/write requests combined per month.
Best of all, these aren't just 12-month free tier benefits—they're permanently free. For lightweight processing like MCP, individual usage should easily stay within these free tier limits.
Libraries Used
When I asked Claude to find suitable libraries, it discovered AWS's official Python library called mcp_lambda_handler
.
https://github.com/awslabs/mcp/tree/8d90be5c403af4829a45d8f03093f830ffed6285/src/mcp-lambda-handler
Local vs Remote Architecture
I learned this while writing the article, so I'll document it here for my own reference.
Different Communication Methods
Both local and remote MCP use JSON-RPC 2.0 protocol at the application layer, but they differ in communication methods:
- Local: JSON-RPC over stdio
- Remote: JSON-RPC over Streamable HTTP (via Lambda Function URL)
Why Use mcp_lambda_handler
?
Different Roles from FastMCP
The FastMCP
I used for local MCP registered Python functions as MCP tools and converted JSON-RPC content received via stdio into Python function calls.
Lambda cannot host persistent HTTP servers and is designed to trigger on Lambda-specific event formats. The mcp_lambda_handler
extracts the JSON-RPC portion from Lambda Event format, converts it to Python function calls, and returns the execution results as JSON-RPC that MCP clients can accept. It uses Lambda Function URLs to convert HTTP into Lambda-supported event formats.
Data Flow Comparison
Local MCP Case
Remote MCP Case
Both ultimately resolve to Python function calls, but the intermediate transformation layers differ. The mcp_lambda_handler
nicely abstracts Lambda's quirky event format.
Why Not Use FastMCP's Remote MCP Support Directly?
While FastMCP does support remote MCP, it's designed for persistent servers like FastAPI. Since I wanted to leverage Lambda's free tier with event-driven architecture, I didn't want to run a persistent server. To migrate existing HTTP servers to Lambda, you'd need to wrap them with Lambda Web Adapter, which adds unnecessary layers. Since I only needed to execute about 4 simple CRUD functions, the lightweight mcp_lambda_handler
was optimal.
(When building this, I just searched for sample code and had Claude create it for me, but after thinking through this for the article, I realize it was indeed a good choice.)
Implementation Example
Here's an example of hosting a remote MCP on Lambda that can add memories to DynamoDB and list existing memories. The content is minimal.
# app.py
import boto3
from datetime import datetime
from awslabs.mcp_lambda_handler import MCPLambdaHandler
# Initialize MCP server
mcp_server = MCPLambdaHandler(name="memory-mcp", version="1.0.0")
# Storing memories in DynamoDB
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('mcp-memories')
@mcp_server.tool()
def create_memory(content: str) -> str:
"""Create new user memory""" # This content is passed to LLM as tool description, so it's important
memory_id = f"memory_{datetime.now().strftime('%Y%m%d%H%M%S')}"
table.put_item(Item={
'memory_key': memory_id,
'content': content
})
return f"saved: {memory_id}"
@mcp_server.tool()
def list_memories() -> str:
"""List all saved memories"""
response = table.scan()
items = response.get('Items', [])
if not items:
return "no memory found"
return '\n'.join([f"{item['memory_key']}: {item['content']}" for item in items])
def lambda_handler(event, context):
return mcp_server.handle_request(event, context)
Important Notes
mcp_lambda_handler
is an AWS Labs library, so long-term maintenance isn't guaranteed. However, the implementation is simple enough that you could create equivalent functionality yourself if needed.
For commercial long-term operations, you might want to consider AgentCore Runtime as well.
Deployment and Operations
I'll keep this brief since it's not the main focus.
Setup Tasks
-
Create DynamoDB Table: Table name
mcp-memories
, partition keymemory_key
- Create Lambda Function: Deploy the above code, grant DynamoDB permissions
- Enable Function URL: No authentication, or API key authentication*
*Claude Remote MCP configuration only accepts MCP name and endpoint, so detailed authentication settings aren't possible (OAuth is possible but not what I wanted), and for personal use, I didn't need that level of detail. So I implemented Function URL + simple API key authentication.
For deployment methods, everyone has their preferences, but when I let Claude Code handle it, it became SAM + bash script.
Conclusion
Migrating from local MCP to remote MCP achieved the following benefits:
- Consistent cross-device experience: Access the same memory from Desktop, Web, and Mobile
- Cost efficiency: Operates within the free tier
- Reduced operational overhead: Serverless and event-driven
In actual use, despite changing from local to remote, there was no noticeable latency. All Claude devices can now properly read and write memories, with mobile experience significantly improved. Since there were few implementation examples using mcp_lambda_handler, I hope this article serves as a useful reference.
Related Previous Articles
https://zenn.dev/zhizhiarv/articles/local-memory-mcp-for-claude-desktop
https://zenn.dev/zhizhiarv/articles/use-remote-mcp-on-claude-mobile
Top comments (0)