AWS - Dev
This command activates a development session on the specified stage and region. This allows you to run, develop, and test your functions locally while they are being invoked in real-time remotely on AWS Lambda. It establishes a long-running CLI session that connects directly to your Lambda functions, waiting for events to invoke them. This method significantly simplifies the development of your functions locally, eliminating the need for deployment after every change, and allows you to work with real infrastructure without any emulation.
serverless dev
Options
--stageor-sThe stage in your service that you want to activate a development session for.--regionor-rThe region in that stage that you want to active a development session for.--aws-profileThe AWS profile you want to use.--on-exit=removePrompt to remove the deployed service stack when exiting Dev Mode with Ctrl+C.
Note: While it is possible, we do not recommend activating a development session in your prod stage.
Sandboxes (Lambda MicroVMs)
For sandboxes, serverless dev --sandbox <name> runs the sandbox locally as a Docker container — a different mechanism from the Lambda IoT-Core session described above. It builds the sandbox's Dockerfile and starts a local, SDK-compatible AWS Lambda MicroVMs control-plane that launches instances as Docker containers on demand, streams their logs, and hot-reloads on file changes.
serverless dev --sandbox <name> # --sandbox is optional when only one sandbox is defined
serverless dev --mode sandboxes # equivalent; auto-detected when the service only has sandboxes
serverless dev --sandbox <name> --port 9300 # local control-plane endpoint port (default 9100)
Requires a local Docker daemon and a local artifact directory (a sandbox whose artifact is an s3:// zip can't be run with dev). By default the container runs under the sandbox's deployed execution role, so AWS calls use real IAM; pass --no-assume-role to skip that and run with your ambient AWS credentials instead. See the local development section of the sandboxes guide.
MCP servers
serverless dev serves the MCP servers declared under your service's mcp property the same way it serves your functions: requests hit the real deployed endpoint, the deployed function relays each invocation to your machine, and your local server module runs behind the same entry production uses. Edits to your server code — TypeScript or JavaScript — apply on the next request without a redeploy, and the session banner lists each server's endpoint URL under mcp:, as deploy does.
Each request is logged with its JSON-RPC method — and the tool, prompt, or resource it targets — followed by the local run time once it has been answered. A JSON-RPC error carried inside a 200 response is called out on the same line, since the status code alone would hide it:
Functions:
crm: crm-tools-dev-crm (112 kB)
mcp: crm → https://abc123.execute-api.us-east-1.amazonaws.com/dev/crm/mcp
✔ Connected (Ctrl+C to cancel)
→ λ crm ── mcp tools/list
← λ crm (200) 1.2s
→ λ crm ── mcp tools/call get_weather
← λ crm (200) 640ms
→ λ crm ── mcp tools/call noSuchTool
← λ crm (200) 158ms ── error -32602: Tool noSuchTool not found
Only JSON-RPC-level errors get that callout. A failure inside a tool — arguments its input schema rejects, for example — is an MCP tool result carrying isError: true inside a 200 response, so it is logged as a plain (200) line and the reason appears in the result the client receives.
Anything your server logs appears between the two lines. --detailed additionally prints the complete API Gateway event and response envelope for every request.
Access control stays in force during a session: an authorizer still rejects unauthorized requests at the gateway before anything reaches your machine, and authorized requests are served locally like any other (a Lambda authorizer runs through the session too). OAuth discovery documents remain served by API Gateway, and state keys are fetched by the locally running entry using the function's own execution-role credentials, so elicitation round trips work end to end. Each request runs your module fresh, which typically adds a few hundred milliseconds.
Results are delivered buffered: the response body is assembled fully and delivered at once, so progress notifications arrive together at the end of the call. As for all Dev Mode functions, requests or results larger than roughly 125 KB fail with an error explaining the limit; that explanation is printed in the serverless dev terminal, while the MCP client receives an HTTP 502 with no detail — and on the default edge-optimized endpoint, a call that has produced nothing for roughly 30 seconds is dropped downstream with a 504 (the session prints a warning when a local run exceeds that budget). On provider.endpointType: REGIONAL that budget does not apply and no warning is printed — a dev-session tool call runs up to the server's own timeout, 60 seconds by default. Deploy normally to test incremental streaming, long-running tools, or large payloads; running serverless deploy after the session restores normal serving. See the Dev Mode section of the MCP guide for the full behavior.
Supported runtimes
- Node.js (JS & TS)
- Python (coming soon)
- Go (coming soon)
- Ruby (coming soon)
- Java (coming soon)
How it works
To establish a secure connection between your AWS Lambda functions and your local machine, we initiate a WebSocket connection through AWS IoT Core. Each AWS account is equipped with a unique, secure IoT Core endpoint available for immediate use, eliminating the need for deploying any additional infrastructure—unlike WebSocket solutions that rely on AWS API Gateway. Thus, when you execute sls dev, the CLI incorporates a shim into all your lambda functions, routing all events via this WebSocket connection to your local machine. To facilitate this, we must also update the permissions for all lambda functions to access AWS IoT Core by adding the following IAM statement:
Effect: 'Allow',
Action: ['iot:*'],
Resource: '*'
Subsequently, we deploy your service similarly to executing sls deploy, albeit without your service code and with modified configurations. The CLI then maintains a long-running session, awaiting invocation events.
To finalize development and save your changes, you must exit the development session and perform a standard sls deploy.
Environment
When a development session is active, it's set up to listen for invocation events from your functions. Upon receiving such an event, the CLI creates a new child process that closely replicates the environment of the Lambda function that was invoked. This replication includes the same environment variables, IAM permissions, context, and the event itself. The child process then executes your handlers with this comprehensive dataset, outputs all your function logs directly to the local terminal, and sends the response back to Lambda, along with any errors that might have occurred.
Examples
Activate a quick development session in the default dev stage...
serverless dev
Activate a development session in the dev stage, but in the us-east-2 region...
serverless dev --stage dev --region us-east-2
Activate a development session in your own personal stage...
serverless dev --stage austen
Activate a development session in a stage called "local"...
serverless dev --stage local
Maintaining a dedicated local stage is beneficial for quickly activating a development session without needing to modify your infrastructure each time you execute the command.
Troubleshooting
Typescript isn't working for me.
Under the hood Serverless uses ts-node for invoking your functions locally, and does require a tsconfig.json file. Make sure you have a valid config file and try again.
Lambda functions inside a VPC aren't working for me
The dev command does not work out-of-the-box with AWS Lambda functions running inside a VPC. To enable it, you can either temporarily remove the VPC configuration or update your VPC setup to allow connectivity with AWS IoT Core. For detailed instructions, refer to the official AWS documentation on using AWS IoT Core with interface VPC endpoints.