Skip to main content
FastMCP’s stateless mode makes it ideal for serverless deployments where each request is handled independently without maintaining persistent sessions.

Stateless Mode

Enable stateless mode for serverless environments:
server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8080,
    stateless: true,
  },
});

Why Stateless Mode?

In stateless mode:
  • No sessions tracked - Each request creates a temporary session discarded after response
  • Reduced memory usage - Better scalability and lower costs
  • No session state - Perfect for serverless environments that don’t guarantee instance persistence
  • Independent requests - Each invocation is completely isolated
Stateless mode is only available with HTTP streaming transport. Features depending on persistent sessions will not be available.

Configuration Methods

Enable stateless mode in three ways:
server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8080,
    stateless: true,
  },
});

AWS Lambda Deployment

1

Create Lambda Handler

Create a handler that wraps your FastMCP server:
src/lambda.ts
import { FastMCP } from "fastmcp";
import { z } from "zod";
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";

const server = new FastMCP({
  name: "Lambda MCP Server",
  version: "1.0.0",
});

server.addTool({
  name: "process_data",
  description: "Process data in Lambda",
  parameters: z.object({
    input: z.string(),
  }),
  execute: async ({ input }) => {
    return `Processed: ${input}`;
  },
});

// Start in stateless mode
let serverStarted = false;
const startServer = async () => {
  if (!serverStarted) {
    await server.start({
      transportType: "httpStream",
      httpStream: {
        port: 0, // Port not used in Lambda
        stateless: true,
      },
    });
    serverStarted = true;
  }
};

export const handler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  await startServer();

  // Convert API Gateway event to Request
  const request = new Request(
    `https://${event.headers.Host}${event.path}`,
    {
      method: event.httpMethod,
      headers: event.headers,
      body: event.body,
    }
  );

  // Handle with FastMCP internal handler
  // Note: This requires accessing internal methods
  // For production, consider using a middleware adapter

  return {
    statusCode: 200,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ message: "Success" }),
  };
};
2

Configure SAM or Serverless Framework

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MCPFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: dist/lambda.handler
      Runtime: nodejs20.x
      MemorySize: 512
      Timeout: 30
      Environment:
        Variables:
          NODE_ENV: production
          FASTMCP_STATELESS: 'true'
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
3

Deploy

# Build TypeScript
npm run build

# Deploy with SAM
sam build && sam deploy --guided

# Or deploy with Serverless Framework
serverless deploy

Google Cloud Functions

1

Create HTTP Function

src/index.ts
import { FastMCP } from "fastmcp";
import { z } from "zod";
import { Request, Response } from "@google-cloud/functions-framework";

const server = new FastMCP({
  name: "GCP MCP Server",
  version: "1.0.0",
});

server.addTool({
  name: "cloud_process",
  description: "Process data in Google Cloud",
  parameters: z.object({
    data: z.string(),
  }),
  execute: async ({ data }) => {
    return `Processed in GCP: ${data}`;
  },
});

let initialized = false;

export const mcpHandler = async (req: Request, res: Response) => {
  if (!initialized) {
    await server.start({
      transportType: "httpStream",
      httpStream: {
        port: 0,
        stateless: true,
      },
    });
    initialized = true;
  }

  // Handle request with FastMCP
  res.status(200).json({ message: "Success" });
};
2

Deploy to Google Cloud

gcloud functions deploy mcp-server \
  --runtime nodejs20 \
  --trigger-http \
  --allow-unauthenticated \
  --entry-point mcpHandler \
  --memory 512MB \
  --timeout 60s \
  --set-env-vars FASTMCP_STATELESS=true

Azure Functions

1

Create HTTP Trigger Function

src/functions/mcp.ts
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
import { FastMCP } from "fastmcp";
import { z } from "zod";

const server = new FastMCP({
  name: "Azure MCP Server",
  version: "1.0.0",
});

server.addTool({
  name: "azure_process",
  description: "Process data in Azure",
  parameters: z.object({
    input: z.string(),
  }),
  execute: async ({ input }) => {
    return `Processed in Azure: ${input}`;
  },
});

let started = false;

export async function mcpHandler(
  request: HttpRequest,
  context: InvocationContext
): Promise<HttpResponseInit> {
  if (!started) {
    await server.start({
      transportType: "httpStream",
      httpStream: {
        port: 0,
        stateless: true,
      },
    });
    started = true;
  }

  return {
    status: 200,
    jsonBody: { message: "Success" },
  };
}

app.http("mcp", {
  methods: ["GET", "POST"],
  authLevel: "anonymous",
  handler: mcpHandler,
});
2

Configure host.json

host.json
{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  },
  "functionTimeout": "00:01:00"
}
3

Deploy to Azure

# Create Function App
az functionapp create \
  --name fastmcp-server \
  --resource-group myResourceGroup \
  --consumption-plan-location eastus \
  --runtime node \
  --runtime-version 20 \
  --functions-version 4

# Deploy
func azure functionapp publish fastmcp-server

Best Practices

Environment Variables

Manage configuration across environments:
const server = new FastMCP({
  name: process.env.MCP_SERVER_NAME || "MCP Server",
  version: process.env.MCP_VERSION || "1.0.0",
});

server.addTool({
  name: "api_call",
  description: "Call external API",
  execute: async () => {
    const apiKey = process.env.API_KEY;
    const endpoint = process.env.API_ENDPOINT;
    
    if (!apiKey || !endpoint) {
      throw new Error("Missing required environment variables");
    }

    const response = await fetch(endpoint, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    return response.text();
  },
});

Cold Start Optimization

Minimize cold start times:
// Initialize server outside handler (reused across warm starts)
const server = new FastMCP({
  name: "Optimized Server",
  version: "1.0.0",
});

// Add tools during initialization
server.addTool({
  name: "quick_tool",
  description: "Fast tool execution",
  execute: async () => "Quick response",
});

// Lazy-load heavy dependencies
let heavyDependency: any = null;
const getHeavyDependency = async () => {
  if (!heavyDependency) {
    heavyDependency = await import("heavy-package");
  }
  return heavyDependency;
};

Error Handling

Implement robust error handling:
import { UserError } from "fastmcp";

server.addTool({
  name: "safe_operation",
  description: "Operation with error handling",
  execute: async ({ input }) => {
    try {
      // Validation
      if (!input) {
        throw new UserError("Input is required");
      }

      // External API call
      const response = await fetch("https://api.example.com/data");
      
      if (!response.ok) {
        throw new UserError(`API error: ${response.statusText}`);
      }

      return await response.text();
    } catch (error) {
      if (error instanceof UserError) {
        throw error; // User-facing error
      }
      // Log internal errors, show generic message
      console.error("Internal error:", error);
      throw new UserError("An unexpected error occurred");
    }
  },
});

Health Checks

The /ready endpoint reports stateless mode status:
curl https://your-function.cloud/ready
{
  "mode": "stateless",
  "ready": 1,
  "status": "ready",
  "total": 1
}

Monitoring

Each platform provides monitoring tools:
# View Lambda logs
aws logs tail /aws/lambda/mcp-function --follow

# View metrics
aws cloudwatch get-metric-statistics \
  --namespace AWS/Lambda \
  --metric-name Duration \
  --dimensions Name=FunctionName,Value=mcp-function \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-02T00:00:00Z \
  --period 3600 \
  --statistics Average

Performance Considerations

  • Memory allocation: Increase for complex operations (512MB-1GB recommended)
  • Timeout settings: Set appropriate timeouts (30-60s for most operations)
  • Connection pooling: Reuse HTTP clients across invocations
  • Async operations: Use async/await for all I/O operations
  • Bundle size: Minimize dependencies to reduce cold start time
Stateless mode means each request is independent. Do not rely on in-memory state between requests.

Next Steps

Build docs developers (and LLMs) love