TL;DR: Go to this repo for the SAM template
TL;DR: Go to this repo for a CLI to start with your next serverless MCP server
Hey devs 👋, if you saw my first two post in this series about building a minimal Model Context Protocol server with AWS Lambda using the Serverless Framework, this is the natural follow-up for those who prefer using AWS Serverless Application Model (SAM).
The post on how to deploy an MCP server in a serverless environment was particularly well received and even got featured in two outstanding newsletters: Serverless Developer Advocate #33 by Lee Gilmore and Ready, Set, Cloud #160 by Allen Helton. I highly recommend subscribing to both as they’re packed with insights and inspiration for serverless enthusiasts!
Also the. second post of this series was cited in Serverless Developer Advocate #34 by Lee Gilmore. I can't be happier about this community feedback.
Why SAM?
In my latest post I've shown to you this omparison table between Serverless Framework
, AWS SAM
and AWS CKD
. Again: read it carefully before choosing your preferred way to do IaC in your project.
Feature / Tool | Serverless Framework | AWS SAM (Serverless Application Model) | AWS CDK (Cloud Development Kit) |
---|---|---|---|
Ownership | V3 independent (deprecated), V4 enterprise, OSS alternative to V4 | AWS | AWS |
Abstraction Level | High-level | Medium-level | Low to medium-level |
Language | YAML + plugins (JavaScript/TS) | YAML + some scripting | TypeScript, Python, Java, C#, Go |
Cloud Provider Support | Multi-cloud (AWS, Azure, GCP, etc) | AWS only | AWS only |
Template Syntax | Custom syntax (serverless.yml) | CloudFormation-compatible YAML | Imperative (code-based) |
Local Development | Good support via plugins | Good (via sam local ) |
Limited, depends on constructs |
Deployment | CLI-driven | CLI-driven (sam deploy ) |
CLI-driven (cdk deploy ) |
State Management | Built-in via .serverless folder |
CloudFormation | CloudFormation |
Extensibility | High (plugins, hooks) | Moderate (some hooks/plugins) | High (custom constructs, reusable code) |
Maturity | Very mature | Mature | Rapidly growing |
Best For | Multi-cloud serverless apps | Simple AWS Lambda apps | Complex infrastructure-as-code on AWS |
Learning Curve | Low to moderate | Low | Moderate to high |
Testing/Debugging | Plugin-based | sam local invoke/start-api |
Manual / unit tests on code |
CI/CD Integration | Easy (via plugins or custom) | Easy (via CodePipeline or custom) | Easy (via CodePipeline or custom) |
Cost | V3 Free, V4 pricing | Free | Free |
So, why pick AWS SAM over Serverless Framework and CDK?
- SAM is built and maintained by AWS. That means native integration for services like Lambda, API Gateway, DynamoDB, and integrations with CloudFormation, CloudWatch, and CodeDeploy out of the box. No need for external plugins or workarounds to make things “just work.”
- Designed only for serverless, unlike CDK, which is general purpose infrastructure as code. As an example: In CDK, to create an API Gateway connected to a Lambda function, you’ll write TypeScript or Python code that explicitly defines routes, integrations, permissions, and deploy stages, in SAM this is really simple with a couple of line of code.
- Local dev & testing is very powerful: SAM CLI lets you run Lambda functions locally and mock API Gateway events. This feels more like traditional dev workflows, which is something CDKdon’t handle as smoothly, while Serverless Framework require serverless offline plugin.
- Simpler learning curve than CDK, as CDK is powerful but verbose. You’re writing imperative code to describe declarative infrastructure. That’s cool, but not always necessary for serverless apps. SAM keeps things simple, YAML based, and readable across different teams: devs, ops, or whoever knows it.
So if you're building pure serverless apps on AWS: SAM it’s native, lightweight, and focused on serverless. CDK shines when you’re managing AWS infrastructure, but when your app is 90% serverless API based on Lambda, SAM is just way faster to learn.
📦 What’s Inside the Repo
This project spins up as the previous one:
- An
AWS Lambda
function hosting a serverless MCP server - An
Amazon API Gateway
with aPOST
/mcp
route
🛠️ Features
Our goal is always to have a skeleton to deploy our MCP server in a serverless environment, but using AWS SAM
.
- Simple MCP server with just a few lines of code
- Runs in a single AWS Lambda function
- HTTP POST endpoint at /mcp
- Local development
- Comes with a basic “add” tool (yeps, just adds two numbers via JSON-RPC: here you should put your endpoint logic!)
📦 Project Structure
We add template.yml
, samconfig.toml
and buildspec.yml
respectively as our resource template, configuration (useful for deploy) and CI/CD pipiline build phase.
sam-serverless-mcp-server/
├── __tests__/ # Jest tests
├── src/ # Source code
│ └── index.js # MCP server handler
├── .gitignore # Git ignore file
├── buildspec.yml # Buildspec file for AWS CodeBuild and CodePipeline (CI/CD)
├── jest.config.mjs # Jest config file
├── package.json # Project dependencies
├── package-lock.json # Project lock file
├── README.md # This documentation file
├── samconfig.toml # Serverless Application Model config
└── template.yml # Serverless Application Model template
🏗️ SAM code
You can easily read the code following comments in the template file:
- set a timeout
- use
nodejs22.x
as runtime - spin up an
AWS::Serverless::Function
giving the proper handler path - create an API Gateway with a
POST
route on/mcp
path, all automatically setting inEvents
attribute an event of typeApi
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: serverless-mcp-server
Globals:
Function:
Timeout: 29
Runtime: nodejs22.x
Resources:
McpServerFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/index.handler
Events:
McpApi:
Type: Api
Properties:
Path: /mcp
Method: post
Tips: if you want to switch to API Gateway V2, just change the type to HttpApi
and you're good to go.
🚀 Getting Started
To get it up and running follow those steps.
- Install dependencies:
npm install
- Run Locally with SAM
sam local start-api
Local endpoint will be available at:
POST http://localhost:3000/mcp
🧪 Test with jest
There are some basic tests included in the __tests__
folder. You can run them with:
npm run test
📡 Deploy to AWS
Follow those steps.
Build with SAM
sam build
And finally deploy (before that you should configure AWS Credentials with aws-cli)
sam deploy --guided
After deployment, the MCP server will be live at the URL output by the command.
🧪 Locally or once deployed, test also with curl requests
List tools
Change your-endpoint
with the one noted after deploy or with localhost:3000
.
curl --location 'https://your-endpoint/dev/mcp' \
--header 'content-type: application/json' \
--header 'accept: application/json' \
--header 'jsonrpc: 2.0' \
--data '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}'
➕ Use the add Tool
Change your-endpoint
with the one noted.
curl --location 'https://your-endpoint/dev/mcp' \
--header 'content-type: application/json' \
--header 'accept: application/json' \
--header 'jsonrpc: 2.0' \
--data '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "add",
"arguments": {
"a": 5,
"b": 3
}
}
}'
💎 Kickstart your next serverless MCP project with a handy CLI
A little gem to help you kickstart your next MCP serverless projects on AWS: I created a CLI that lets you choose between the three boilerplates from this series (Serverless Framework, AWS CDK, or AWS SAM). It’s built with oclif and is easy to install.
It allows you to choose the framework with just a command "serverless-mcp-cli init
" and automatically installs the dependencies so you are ready to go.
⏭️ Next Step
I'm planning to continue this series:
- integrate authentication
- integrate state management
🙋 Who am I
I'm D. De Sio and I work as a Head of Software Engineering in Eleva.
I'm currently (Apr 2025) an AWS Certified Solution Architect Professional and AWS Certified DevOps Engineer Professional, but also a User Group Leader (in Pavia), an AWS Community Builder and, last but not least, a #serverless enthusiast.
My work in this field is to advocate about serverless and help as more dev teams to adopt it, as well as customers break their monolith into API and micro-services using it.