Fastify

Run an xmcp MCP server on Fastify. Works on any Node.js deployment target including AWS Lambda.

For the complete documentation index, see llms.txt. Markdown variants of every page are available by appending .md to the URL.

Installation

xmcp can work on top of your existing Fastify project. To get started, run the following command in your project directory:

Code
npx init-xmcp@latest

After setting up the project, your build command should look like this:

Code
{
  "scripts": {
    "build": "xmcp build && tsc"
  }
}

xmcp build bundles your tools into .xmcp/adapter.

Usage

Install Fastify and register the MCP handler on your server:

Code
npm install fastify
Code
import Fastify from "fastify";
import { xmcpHandler } from "@xmcp/adapter";

const app = Fastify({ logger: false });

app.post("/mcp", xmcpHandler);
app.get("/mcp", xmcpHandler); // required for SSE / streaming clients

await app.listen({ port: 3000 });

AWS Lambda

Use @fastify/aws-lambda as the Lambda bridge:

Code
npm install fastify @fastify/aws-lambda
Code
import Fastify from "fastify";
import awsLambdaFastify from "@fastify/aws-lambda";
import { xmcpHandler } from "@xmcp/adapter";

const app = Fastify({ logger: false });

app.post("/mcp", xmcpHandler);

export const handler = awsLambdaFastify(app);

The default buffered form (awsLambdaFastify(app)) works for all JSON-RPC POST requests (initialize, tools/call, etc.). GET/SSE is not supported in buffered mode — see the streaming form below.

SSE support on Lambda

To support SSE via GET /mcp, use a Lambda Function URL with InvokeMode: RESPONSE_STREAM and switch to the streaming form:

Code
import Fastify from "fastify";
import awsLambdaFastify from "@fastify/aws-lambda";
import { xmcpHandler } from "@xmcp/adapter";
import { promisify } from "node:util";
import stream from "node:stream";

const pipeline = promisify(stream.pipeline);
const app = Fastify({ logger: false });

app.post("/mcp", xmcpHandler);
app.get("/mcp", xmcpHandler);

const proxy = awsLambdaFastify(app, { payloadAsStream: true });

export const handler = awslambda.streamifyResponse(
  async (event, responseStream, context) => {
    const { meta, stream: bodyStream } = await proxy(event, context);
    responseStream = awslambda.HttpResponseStream.from(responseStream, meta);
    await pipeline(bodyStream, responseStream);
  }
);

xmcp.config.ts

Code
import type { XmcpConfig } from "xmcp";

const config: XmcpConfig = {
  http: true,
  experimental: {
    adapter: "fastify",
  },
};

export default config;