Skip to main content

What are Transports?

Transports define how your MCP server communicates with clients. FastMCP supports three transport types:
  • stdio - Standard input/output for local, single-client connections
  • httpStream - HTTP streaming for remote, multi-client connections
  • SSE - Server-Sent Events (automatically enabled with httpStream)
Each transport has different characteristics and use cases.

stdio Transport

The stdio transport uses standard input/output for communication. It’s ideal for local, single-client connections.

Basic Usage

import { FastMCP } from "fastmcp";

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

server.start({
  transportType: "stdio",
});

When to Use stdio

Use stdio when

  • Running locally on the same machine as the client
  • Integrating with IDEs and desktop applications
  • Single client connections
  • Simple deployment scenarios

Avoid stdio when

  • Need remote access
  • Multiple concurrent clients
  • Web-based clients
  • Load balancing required

Configuration

server.start({
  transportType: "stdio",
});
No additional configuration is needed for stdio transport.

HTTP Stream Transport

The HTTP streaming transport provides efficient communication over HTTP. It’s ideal for remote, multi-client scenarios.

Basic Usage

import { FastMCP } from "fastmcp";

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

server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8080,
  },
});
This starts the server on http://localhost:8080/mcp for HTTP streaming and http://localhost:8080/sse for SSE.

Configuration Options

server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8080,
    endpoint: "/mcp",      // Custom endpoint (default: "/mcp")
    stateless: false,      // Enable stateless mode
  },
});

When to Use HTTP Stream

Use httpStream when

  • Remote access needed
  • Multiple concurrent clients
  • Web-based applications
  • Load balancing required
  • Cloud deployment

Consider alternatives when

  • Local-only access needed
  • Single client scenario
  • Maximum simplicity desired

Client Connection

Connect from a client using the HTTP streaming transport:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client(
  {
    name: "example-client",
    version: "1.0.0",
  },
  {
    capabilities: {},
  }
);

const transport = new StreamableHTTPClientTransport(
  new URL("http://localhost:8080/mcp")
);

await client.connect(transport);

SSE Transport

Server-Sent Events are automatically enabled when using HTTP Stream transport.

SSE Endpoint

When you start an HTTP Stream server, SSE is available at /sse:
server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8080,
  },
});
// SSE available at http://localhost:8080/sse

Client Connection

Connect using SSE from a client:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";

const client = new Client(
  {
    name: "example-client",
    version: "1.0.0",
  },
  {
    capabilities: {},
  }
);

const transport = new SSEClientTransport(
  new URL("http://localhost:8080/sse")
);

await client.connect(transport);

HTTPS Support

Secure your HTTP transport with SSL/TLS:
server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8443,
    sslCert: "./path/to/cert.pem",
    sslKey: "./path/to/key.pem",
    sslCa: "./path/to/ca.pem", // Optional: for client certificate authentication
  },
});

SSL Options

OptionDescription
sslCertPath to SSL certificate file
sslKeyPath to SSL private key file
sslCa(Optional) Path to CA certificate for mutual TLS

Generate Test Certificates

For testing, generate self-signed certificates:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
For production, obtain certificates from a trusted CA like Let’s Encrypt.

Stateless Mode

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

Stateless Mode Characteristics

  • No persistent sessions tracked
  • Each request creates a temporary session
  • Reduced memory usage
  • Better scalability
  • Perfect for serverless environments
Stateless mode is only available with HTTP streaming transport. Features that depend on persistent sessions will not be available.

CLI and Environment Variables

Enable stateless mode via CLI or environment:
# Via CLI argument
npx fastmcp dev src/server.ts --transport http-stream --port 8080 --stateless true

# Via environment variable
FASTMCP_STATELESS=true npx fastmcp dev src/server.ts

Transport Comparison

Characteristics:
  • Local connections only
  • Single client
  • No network configuration
  • Fastest for local use
  • IDE integration
Best for:
  • Development tools
  • Desktop applications
  • Local automation
  • Single-user scenarios

Edge Runtime

For edge runtimes like Cloudflare Workers, use EdgeFastMCP:
import { EdgeFastMCP } from "fastmcp/edge";
import { z } from "zod";

const server = new EdgeFastMCP({
  name: "My Edge Server",
  version: "1.0.0",
});

server.addTool({
  name: "greet",
  description: "Greet someone",
  parameters: z.object({
    name: z.string(),
  }),
  execute: async ({ name }) => {
    return `Hello, ${name}! Served from the edge.`;
  },
});

// Export the server (required for Cloudflare Workers)
export default server;

Edge vs Standard FastMCP

FeatureFastMCPEdgeFastMCP
RuntimeNode.jsEdge (V8 isolates)
Start methodserver.start()export default server
Transportstdio, httpStream, SSEHTTP Streamable only
SessionsStateful or statelessStateless only
File systemYesNo

Complete Examples

stdio Example

import { FastMCP } from "fastmcp";
import { z } from "zod";

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

server.addTool({
  name: "add",
  description: "Add two numbers",
  parameters: z.object({
    a: z.number(),
    b: z.number(),
  }),
  execute: async (args) => {
    return String(args.a + args.b);
  },
});

server.start({
  transportType: "stdio",
});

HTTP Stream Example

import { FastMCP } from "fastmcp";
import { z } from "zod";

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

server.addTool({
  name: "greet",
  description: "Greet someone",
  parameters: z.object({
    name: z.string(),
  }),
  execute: async (args) => {
    return `Hello, ${args.name}!`;
  },
});

server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8080,
  },
});

console.log("Server running at:");
console.log("- HTTP Stream: http://localhost:8080/mcp");
console.log("- SSE: http://localhost:8080/sse");

HTTPS Example

import { FastMCP } from "fastmcp";
import { z } from "zod";

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

server.addTool({
  name: "secureGreet",
  description: "Secure greeting",
  parameters: z.object({
    name: z.string(),
  }),
  execute: async (args) => {
    return `Hello, ${args.name}! (via HTTPS)`;
  },
});

server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8443,
    sslCert: "./cert.pem",
    sslKey: "./key.pem",
  },
});

console.log("Secure server running at https://localhost:8443/mcp");

API Reference

StartOptions Type

type StartOptions = {
  transportType: "stdio" | "httpStream";
  httpStream?: {
    port: number;
    endpoint?: string;
    stateless?: boolean;
    sslCert?: string;
    sslKey?: string;
    sslCa?: string;
  };
};

Build docs developers (and LLMs) love