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"}}}'