Transport Types

Complete guide to stdio and HTTP transport types, session management, and streaming features.

Transport Overview

OpenAPI MCP Server supports two transport methods to accommodate different integration scenarios. Each transport type is optimized for specific use cases and client requirements.

Feature Stdio Transport HTTP Transport
Use Case AI systems, Claude Desktop Web applications, HTTP clients
Protocol JSON-RPC over stdin/stdout JSON-RPC over HTTP with SSE
Session Management Single persistent session Multiple concurrent sessions
Streaming Bidirectional via stdio Server-Sent Events (SSE)
Network Required No Yes
Security Process isolation HTTP headers, CORS

Stdio Transport

The stdio transport uses standard input and output streams for communication, making it ideal for AI systems like Claude Desktop that manage MCP servers as child processes.

Key Features

🔗 Direct Integration

No network configuration required - communication via stdin/stdout

🔒 Process Isolation

Each server runs as a separate process with built-in security

⚡ Low Latency

Direct process communication without network overhead

🎯 Single Session

One persistent session per server instance

Configuration

# CLI usage (default transport)
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url https://api.example.com \
  --openapi-spec https://api.example.com/openapi.json \
  --transport stdio
// Library usage
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";

const server = new OpenAPIServer({
  apiBaseUrl: "https://api.example.com",
  openApiSpec: "https://api.example.com/openapi.json",
  transportType: "stdio" // Default
});

await server.start();

Claude Desktop Integration

Configure the stdio transport for Claude Desktop:

{
  "mcpServers": {
    "openapi": {
      "command": "npx",
      "args": ["-y", "@lucid-spark/openapi-mcp-server", "openapi-mcp-server"],
      "env": {
        "API_BASE_URL": "https://api.example.com",
        "OPENAPI_SPEC_PATH": "https://api.example.com/openapi.json",
        "API_HEADERS": "Authorization:Bearer token123"
      }
    }
  }
}

Communication Flow

1. Process Start

Claude Desktop starts the MCP server as a child process

2. Initialization

MCP initialization handshake via stdin/stdout

3. Tool Discovery

Client requests available tools

4. Tool Execution

Bidirectional JSON-RPC communication

Message Format

# Client to Server (via stdin)
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

# Server to Client (via stdout)
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "get-users",
        "description": "List all users",
        "inputSchema": { ... }
      }
    ]
  }
}

HTTP Transport

The HTTP transport enables web applications and HTTP clients to interact with the MCP server over HTTP using JSON-RPC with Server-Sent Events for streaming.

Key Features

🌐 Web Compatible

Standard HTTP protocol compatible with web applications

🎯 Multi-Session

Support for multiple concurrent client sessions

📡 Server-Sent Events

Streaming responses using SSE for real-time communication

🔄 Session Management

Automatic session lifecycle with unique session IDs

Configuration

# CLI usage
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url https://api.example.com \
  --openapi-spec https://api.example.com/openapi.json \
  --transport http \
  --port 3000 \
  --host 127.0.0.1 \
  --path /mcp
// Library usage
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";

const server = new OpenAPIServer({
  apiBaseUrl: "https://api.example.com",
  openApiSpec: "https://api.example.com/openapi.json",
  transportType: "http",
  httpPort: 3000,
  httpHost: "0.0.0.0", // Bind to all interfaces
  endpointPath: "/mcp"
});

await server.start();

HTTP Endpoints

Method Path Purpose Headers Required
POST /mcp Send JSON-RPC requests Content-Type: application/json
GET /mcp Receive streaming responses (SSE) Mcp-Session-Id
DELETE /mcp Terminate session Mcp-Session-Id

Session Management

1. Session Initialization

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}'

Server responds with session ID in the Mcp-Session-Id header

2. Open Streaming Connection

curl -N http://localhost:3000/mcp \
  -H "Mcp-Session-Id: your-session-id"

Establishes SSE connection for receiving server responses

3. Send Requests

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: your-session-id" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Send JSON-RPC requests with session ID

4. Session Termination

curl -X DELETE http://localhost:3000/mcp \
  -H "Mcp-Session-Id: your-session-id"

Clean up session resources

Server-Sent Events (SSE)

HTTP transport uses SSE for streaming server responses:

# SSE stream format
data: {"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}

data: {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"API response"}]}}

# Heartbeat to keep connection alive
data: {"type":"heartbeat","timestamp":"2024-01-01T00:00:00.000Z"}

Complete HTTP Client Example

class MCPHttpClient {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
    this.sessionId = null;
    this.eventSource = null;
  }

  async initialize() {
    // Initialize session
    const response = await fetch(`${this.baseUrl}/mcp`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 0,
        method: 'initialize',
        params: {
          protocolVersion: '2025-03-26',
          capabilities: {},
          clientInfo: { name: 'HttpClient', version: '1.0.0' }
        }
      })
    });

    this.sessionId = response.headers.get('Mcp-Session-Id');
    
    // Open SSE connection
    this.eventSource = new EventSource(`${this.baseUrl}/mcp?${new URLSearchParams({
      'Mcp-Session-Id': this.sessionId
    })}`);

    this.eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data);
      this.handleResponse(data);
    };
  }

  async sendRequest(method, params = {}) {
    const response = await fetch(`${this.baseUrl}/mcp`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Mcp-Session-Id': this.sessionId
      },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: Date.now(),
        method,
        params
      })
    });

    // Some responses are immediate (tools/list)
    if (response.headers.get('Content-Type')?.includes('application/json')) {
      return response.json();
    }
  }

  async listTools() {
    return this.sendRequest('tools/list');
  }

  async executeTool(name, arguments) {
    // Response will come via SSE
    this.sendRequest('tools/call', { name, arguments });
  }

  async disconnect() {
    if (this.eventSource) {
      this.eventSource.close();
    }

    await fetch(`${this.baseUrl}/mcp`, {
      method: 'DELETE',
      headers: { 'Mcp-Session-Id': this.sessionId }
    });
  }

  handleResponse(data) {
    // Handle JSON-RPC responses from SSE
    console.log('Received response:', data);
  }
}

Security Considerations

Stdio Transport Security

🔒 Process Isolation

Each server runs as a separate process with OS-level isolation

🎯 Single Client

One-to-one relationship between client and server process

🚫 No Network Exposure

No network ports opened, reducing attack surface

🔐 Environment Variables

Secrets passed via environment variables (not command line)

HTTP Transport Security

🌐 Origin Validation

Origin headers validated to prevent DNS rebinding attacks

🔒 Localhost Binding

Default binding to 127.0.0.1 prevents external access

🎫 Session Management

Unique session IDs prevent cross-session interference

⏰ Session Timeouts

Automatic session cleanup to prevent resource leaks

Production HTTP Security

# Secure HTTP configuration
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --transport http \
  --host 127.0.0.1 \  # Localhost only
  --port 3000 \
  --path /mcp/api \  # Non-obvious path
  # Consider adding reverse proxy with:
  # - HTTPS termination
  # - Rate limiting
  # - Authentication
  # - Request size limits

Performance Considerations

📡 Stdio Transport

  • Latency: Very low (direct process communication)
  • Throughput: High (no network overhead)
  • Scalability: One session per process
  • Memory: Lower overhead

🌐 HTTP Transport

  • Latency: Network dependent
  • Throughput: Good (HTTP/1.1)
  • Scalability: Multiple concurrent sessions
  • Memory: Higher overhead per session

Optimization Tips

🎯 Choose the Right Transport

Use stdio for single-client scenarios, HTTP for multi-client or web integration

🔄 Connection Reuse

Keep HTTP sessions alive and reuse connections for multiple requests

📊 Monitor Sessions

Track active sessions and implement cleanup for abandoned connections

⚡ Tool Filtering

Filter tools to reduce memory usage and improve startup performance

Transport Troubleshooting

Stdio Transport Issues

❌ Process Not Starting

Symptoms: Claude Desktop shows server as unavailable

Solutions:

  • Check Node.js installation and version (≥18.0.0)
  • Verify package installation: npx @lucid-spark/openapi-mcp-server openapi-mcp-server --version
  • Test configuration with debug mode
  • Check environment variables in Claude config

❌ Communication Errors

Symptoms: Tools not appearing or execution failures

Solutions:

  • Enable debug logging to see JSON-RPC messages
  • Verify OpenAPI specification is valid
  • Check API authentication and connectivity
  • Test with simplified configuration

HTTP Transport Issues

❌ Server Not Starting

Symptoms: Connection refused errors

Solutions:

  • Check if port is already in use: lsof -i :3000
  • Verify host binding (use 0.0.0.0 for external access)
  • Check firewall settings
  • Test with different port numbers

❌ Session Issues

Symptoms: Session not found or expired errors

Solutions:

  • Ensure session ID is included in all requests
  • Check session timeout settings
  • Verify SSE connection is maintained
  • Implement proper session cleanup

❌ CORS Errors

Symptoms: Browser blocks requests

Solutions:

  • Use same-origin requests when possible
  • Configure reverse proxy with CORS headers
  • Consider using stdio transport for local clients
  • Implement proper Origin validation

Debug Commands

# Test stdio transport
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url https://httpbin.org \
  --openapi-spec examples/httpbin-openapi.json \
  --transport stdio \
  --debug

# Test HTTP transport
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url https://httpbin.org \
  --openapi-spec examples/httpbin-openapi.json \
  --transport http \
  --port 3000 \
  --debug

# Test HTTP endpoint
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'