Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ serverless deploy
| [AWS Serverless Github Webhook Listener example in NodeJS](https://github.com/serverless/examples/tree/v4/aws-node-github-webhook-listener) <br/> This service will listen to github webhooks fired by a given repository. | nodeJS |
| [GraphQL query endpoint in NodeJS on AWS with DynamoDB](https://github.com/serverless/examples/tree/v4/aws-node-graphql-api-with-dynamodb) <br/> A single-module GraphQL endpoint with query and mutation functionality. | nodeJS |
| [AWS Serverless IoT Event example in NodeJS](https://github.com/serverless/examples/tree/v4/aws-node-iot-event) <br/> This example demonstrates how to setup a AWS IoT Rule to send events to a Lambda function. | nodeJS |
| [AWS MCP Server behind API Gateway REST (NodeJS)](https://github.com/serverless/examples/tree/v4/aws-mcp-servers/rest-api) <br/> Run an MCP server built with the official MCP TypeScript SDK on AWS Lambda, with streaming responses through API Gateway REST response streaming. | nodeJS |
| [AWS MCP Server on Lambda Function URL (NodeJS)](https://github.com/serverless/examples/tree/v4/aws-mcp-servers/function-url) <br/> Run an MCP server built with the official MCP TypeScript SDK on a Lambda Function URL with response streaming - no API Gateway. | nodeJS |
| [AWS MCP Server with Hono (NodeJS)](https://github.com/serverless/examples/tree/v4/aws-mcp-servers/hono) <br/> Run an MCP server on AWS Lambda with the official MCP Hono integration and Hono's aws-lambda adapter - no hand-written Lambda glue at all. | nodeJS |
| [AWS MCP Server with Express and Lambda Web Adapter (NodeJS)](https://github.com/serverless/examples/tree/v4/aws-mcp-servers/express-web-adapter) <br/> Run an MCP server as a plain Express app on AWS Lambda with Lambda Web Adapter - zip deployment, streaming through API Gateway REST. | nodeJS |
| [AWS MCP Server with Fastify in a Container Image (NodeJS)](https://github.com/serverless/examples/tree/v4/aws-mcp-servers/fastify-container) <br/> Run an MCP server as a containerized Fastify app on AWS Lambda with Lambda Web Adapter - the same image runs on Fargate or anywhere else. | nodeJS |
| [Node.js AWS Lambda connecting to MongoDB Atlas](https://github.com/serverless/examples/tree/v4/aws-node-mongodb-atlas) <br/> Shows how to connect AWS Lambda to MongoDB Atlas. | nodeJS |
| [Running Puppeteer on AWS Lambda](https://github.com/serverless/examples/tree/v4/aws-node-puppeteer) <br/> This example shows you how to run Puppeteer on AWS Lambda | nodeJS |
| [AWS Recursive Lambda function Invocation example in NodeJS](https://github.com/serverless/examples/tree/v4/aws-node-recursive-function) <br/> This is an example of a function that will recursively call itself. | nodeJS |
Expand Down Expand Up @@ -167,6 +172,7 @@ serverless deploy
| [Bedrock AgentCore: LangGraph Multi-Gateway Agents (JavaScript)](https://github.com/serverless/examples/tree/v4/aws-bedrock-agentcore/javascript/langgraph-multi-gateway) <br/> LangGraph JS agents using separate public and private AgentCore Gateways with different authorization levels. | nodeJS |
| [Bedrock AgentCore: LangGraph Agent with Token Streaming (JavaScript)](https://github.com/serverless/examples/tree/v4/aws-bedrock-agentcore/javascript/langgraph-streaming) <br/> LangGraph JS agent streaming LLM tokens in real time over SSE via BedrockAgentCoreApp. | nodeJS |
| [Bedrock AgentCore: Standalone MCP Server (JavaScript)](https://github.com/serverless/examples/tree/v4/aws-bedrock-agentcore/javascript/mcp-server) <br/> Standalone JavaScript MCP server deployed to AWS Bedrock AgentCore Runtime, consumable by any MCP client. | nodeJS |
| [Bedrock AgentCore: MCP Server from Plain Lambda Functions (JavaScript)](https://github.com/serverless/examples/tree/v4/aws-bedrock-agentcore/javascript/mcp-server-lambda-tools) <br/> MCP server whose tools are plain Lambda functions - no MCP SDK in your code - using Bedrock AgentCore Gateway. | nodeJS |
| [Bedrock AgentCore: Strands Agent with Browser (JavaScript)](https://github.com/serverless/examples/tree/v4/aws-bedrock-agentcore/javascript/strands-browser) <br/> Strands Agents JavaScript agent using AgentCore Browser tools for web automation. | nodeJS |
| [Bedrock AgentCore: LangGraph Basic Agent, Code Deploy (Python)](https://github.com/serverless/examples/tree/v4/aws-bedrock-agentcore/python/langgraph-basic-code) <br/> Minimal LangGraph agent deployed to AWS Bedrock AgentCore using code (zip) deployment. | python |
| [Bedrock AgentCore: LangGraph Basic Agent, Docker Deploy (Python)](https://github.com/serverless/examples/tree/v4/aws-bedrock-agentcore/python/langgraph-basic-docker) <br/> Minimal LangGraph agent deployed to AWS Bedrock AgentCore using Docker/container deployment. | python |
Expand Down
72 changes: 72 additions & 0 deletions aws-bedrock-agentcore/javascript/mcp-server-lambda-tools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!--
title: 'Bedrock AgentCore: MCP Server from Plain Lambda Functions (JavaScript)'
description: Deploy an MCP server whose tools are plain Lambda functions - no MCP SDK in your code - using Bedrock AgentCore Gateway.
layout: Doc
framework: v4
platform: AWS
language: nodeJS
authorLink: 'https://github.com/serverless'
authorName: 'Serverless, Inc.'
authorAvatar: 'https://avatars1.githubusercontent.com/u/13742415?s=200&v=4'
-->

# MCP Server from Plain Lambda Functions

Deploy a fully managed [Model Context Protocol](https://modelcontextprotocol.io) server whose tools are **plain Lambda functions** — no MCP SDK, no HTTP server, and no protocol code anywhere in your project.

The Serverless Framework provisions a [Bedrock AgentCore Gateway](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html), which *is* the MCP server: an AWS-managed `/mcp` endpoint that answers `tools/list` and `server/discover` itself and performs one Lambda invocation per tool call. Your handlers receive the tool arguments as the event and return the bare result:

```js
export const handler = async (event) => event.a + event.b
```

With `supportedVersions: ['2026-07-28', ...]`, the endpoint serves the stateless MCP protocol revision — self-contained requests with no handshake and no sessions — alongside earlier revisions on the same URL.

**How this differs from the [`mcp-server`](../mcp-server) example:** that one deploys *your own* MCP server (built with the MCP SDK, running as a container on AgentCore Runtime) — full control over the protocol, streaming, and sessions, in exchange for owning the server code. This example inverts the trade: AWS runs the MCP server for you and your code shrinks to plain functions, with the tool schema declared in `serverless.yml`. Pick `mcp-server` when you need SDK-level capabilities; pick this one when your tools are simple request/response functions.

## Usage

### Deploy

```bash
serverless deploy
```

The deploy output prints the gateway's MCP endpoint:

```
agents:
mcpServer: https://mcp-server-lambda-tools-mcpserver-....gateway.bedrock-agentcore.us-east-1.amazonaws.com/mcp
```

### Test

The gateway uses AWS_IAM (SigV4) authorization by default. The included test client signs requests with your local AWS credentials:

```bash
npm install
GATEWAY_URL=<endpoint from deploy output> node test-client.mjs
```

It calls `server/discover`, `tools/list`, and `tools/call`:

```
=== tools/call (calculator___add) -> HTTP 200 ===
{"result":{"isError":false,"content":[{"type":"text","text":"42"}],"resultType":"complete"},...}
```

Note that tool names are namespaced by their gateway target: the `add` tool of the `calculator` target is invoked as `calculator___add`.

### Connect MCP clients

MCP clients such as Claude or AI IDEs authenticate with OAuth rather than SigV4. To support them, configure a JWT authorizer on the gateway (see the commented `authorizer` block in `serverless.yml`) with your OpenID Connect provider's discovery URL — for example an Amazon Cognito user pool.

### Add tools

Each entry in `ai.tools` maps a schema to a function. A single `toolSchema` array can declare multiple tools backed by one function — the invoked tool name is available in `context.clientContext.custom['bedrockAgentCoreToolName']`. Beyond Lambda, gateway tools can also wrap OpenAPI definitions (`openapi: ./spec.yml`) or proxy external MCP servers (`mcp: https://example.com/mcp`).

### Cleanup

```bash
serverless remove
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* A plain Lambda handler exposed as an MCP tool through AgentCore Gateway.
*
* The Gateway passes the tool's input arguments as the event and embeds the
* return value as the MCP tool result - return the bare result directly.
*
* When one function backs multiple tools, the invoked tool name arrives in
* context.clientContext.custom['bedrockAgentCoreToolName'] in the form
* `<target>___<tool>` (for example `calculator___add`).
*/
export const handler = async (event, context) => {
const { a, b } = event
if (typeof a !== 'number' || typeof b !== 'number') {
throw new Error('a and b must be numbers')
}
// `<target>___<tool>` - branch on the tool name when one function backs
// several tools:
const tool = context.clientContext?.custom?.bedrockAgentCoreToolName ?? ''
if (tool.endsWith('___multiply')) return a * b
return a + b
}
Loading