npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@tylercoles/mcp-transport-http

v0.2.2

Published

HTTP transport with SSE support for MCP servers

Readme

@tylercoles/mcp-transport-http

HTTP transport with Server-Sent Events (SSE) support for MCP servers. This transport provides a full-featured HTTP server with session management, authentication integration, and support for the latest MCP Streamable HTTP specification.

Features

  • 🌐 Modern HTTP Transport - Implements MCP Streamable HTTP (2025-06-18)
  • 🔒 Authentication Ready - Seamless integration with auth providers
  • 📡 Server-Sent Events - Real-time server-to-client communication
  • 🛡️ Security Built-in - DNS rebinding protection, CORS, Helmet
  • Session Management - Stateful sessions with unique session IDs
  • 🔧 Express Integration - Full Express.js compatibility for custom routes

Installation

npm install @tylercoles/mcp-transport-http

Quick Start

import { MCPServer } from '@tylercoles/mcp-server';
import { HttpTransport } from '@tylercoles/mcp-transport-http';

const server = new MCPServer({
  name: 'my-mcp-server',
  version: '1.0.0'
});

// Add some tools
server.registerTool('hello', {
  description: 'Say hello',
  inputSchema: { name: z.string() }
}, async ({ name }) => ({
  content: [{ type: 'text', text: `Hello, ${name}!` }]
}));

// Create HTTP transport
const transport = new HttpTransport({
  port: 3000,
  host: '127.0.0.1'
});

server.useTransport(transport);
await server.start();

console.log('MCP server running on http://127.0.0.1:3000/mcp');

Configuration

Basic Configuration

const transport = new HttpTransport({
  port: 3000,                              // Port to listen on
  host: '127.0.0.1',                       // Host to bind to
  basePath: '/mcp',                        // Base path for MCP endpoints
  trustProxy: false,                       // Trust proxy headers
  externalDomain: 'https://mcp.example.com' // External domain for OAuth
});

Security Configuration

const transport = new HttpTransport({
  port: 3000,
  enableDnsRebindingProtection: true,      // Prevent DNS rebinding attacks
  allowedHosts: ['127.0.0.1', 'localhost'], // Allowed hosts
  helmetOptions: {                         // Helmet security headers
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        styleSrc: ["'self'", "'unsafe-inline'"]
      }
    }
  }
});

CORS Configuration

const transport = new HttpTransport({
  port: 3000,
  cors: {
    origin: ['https://claude.ai', 'https://example.com'],
    credentials: true,
    methods: ['GET', 'POST', 'DELETE'],
    allowedHeaders: ['Content-Type', 'Authorization', 'mcp-session-id']
  }
});

Authentication Integration

import { DevAuth } from '@tylercoles/mcp-auth';

const transport = new HttpTransport({
  port: 3000,
  auth: new DevAuth({
    id: 'dev-user',
    username: 'developer',
    email: '[email protected]'
  })
});

MCP Streamable HTTP Protocol

This transport implements the latest MCP Streamable HTTP specification:

Endpoints

  • POST /mcp - Client-to-server messages (requests, responses, notifications)
  • GET /mcp - Server-sent events stream for server-to-client messages
  • DELETE /mcp - Session termination
  • GET /health - Health check endpoint

Session Management

// Sessions are automatically managed
// Client receives session ID in Mcp-Session-Id header
// All subsequent requests must include this header

// Example client request:
POST /mcp
Content-Type: application/json
Mcp-Session-Id: 550e8400-e29b-41d4-a716-446655440000

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

Server-Sent Events

For real-time server-to-client communication:

// Client opens SSE connection
GET /mcp
Accept: text/event-stream
Mcp-Session-Id: 550e8400-e29b-41d4-a716-446655440000

// Server sends events
data: {"jsonrpc":"2.0","method":"notifications/tools/list_changed"}

data: {"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}

Express Integration

Access the underlying Express app for custom routes:

const transport = new HttpTransport({ port: 3000 });
await transport.start(server);

const app = transport.getApp();
if (app) {
  // Add custom routes
  app.get('/custom', (req, res) => {
    res.json({ message: 'Custom endpoint' });
  });
  
  // Add middleware
  app.use('/api', express.json());
}

Router Registration

Register routers with optional authentication:

// Public router
const publicRouter = transport.createRouter(false);
publicRouter.get('/status', (req, res) => {
  res.json({ status: 'ok' });
});
transport.registerRouter('/api/public', publicRouter);

// Protected router (requires auth)
const protectedRouter = transport.createRouter(true);
protectedRouter.get('/user-data', (req, res) => {
  const user = transport.getAuthenticatedUser(req);
  res.json({ user });
});
transport.registerRouter('/api/protected', protectedRouter);

Authentication Middleware

Built-in Auth Support

import { BearerTokenAuth } from '@tylercoles/mcp-auth';

class APIKeyAuth extends BearerTokenAuth {
  async verifyToken(token: string) {
    // Verify against your API key database
    return await getUserByApiKey(token);
  }
}

const transport = new HttpTransport({
  port: 3000,
  auth: new APIKeyAuth()
});

Manual Auth Middleware

const authMiddleware = transport.getAuthMiddleware();
if (authMiddleware) {
  app.use('/protected', authMiddleware);
}

// Or check authentication manually
app.get('/api/user', (req, res) => {
  const user = transport.getAuthenticatedUser(req);
  if (!user) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  res.json({ user });
});

Health Monitoring

Built-in health endpoint:

// GET /health
{
  "status": "ok",
  "transport": "streamableHttp",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "sessions": 3
}

Monitor server status:

const sessionCount = transport.getSessionCount();
const port = transport.getPort();
console.log(`Server running on port ${port} with ${sessionCount} active sessions`);

Error Handling

HTTP Errors

// 401 Unauthorized - Authentication required
{
  "error": "Authentication required"
}

// 400 Bad Request - Invalid MCP message
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32600,
    "message": "Invalid Request"
  },
  "id": null
}

// 500 Internal Server Error - Server error
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32603,
    "message": "Internal server error"
  },
  "id": 1
}

Connection Errors

transport.on('error', (error) => {
  console.error('Transport error:', error);
});

transport.on('session_error', (sessionId, error) => {
  console.error(`Session ${sessionId} error:`, error);
});

Advanced Usage

Custom Session Management

const transport = new HttpTransport({
  port: 3000,
  sessionConfig: {
    secret: 'custom-session-secret',
    maxAge: 24 * 60 * 60 * 1000, // 24 hours
    secure: true,                 // HTTPS only
    sameSite: 'strict'           // CSRF protection
  }
});

Multi-Transport Setup

// Run multiple transports on different ports
const httpTransport = new HttpTransport({ port: 3000 });
const stdioTransport = new StdioTransport();

server.useTransports(httpTransport, stdioTransport);
await server.start();

WebSocket Alternative

For environments requiring WebSocket-like behavior:

// Client keeps SSE connection open
const eventSource = new EventSource('/mcp', {
  headers: { 'Mcp-Session-Id': sessionId }
});

eventSource.onmessage = (event) => {
  const message = JSON.parse(event.data);
  handleServerMessage(message);
};

// Send messages via POST
fetch('/mcp', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Mcp-Session-Id': sessionId
  },
  body: JSON.stringify(mcpRequest)
});

Security Considerations

DNS Rebinding Protection

const transport = new HttpTransport({
  port: 3000,
  enableDnsRebindingProtection: true,
  allowedHosts: ['127.0.0.1', 'localhost', 'mcp.example.com']
});

CORS Security

const transport = new HttpTransport({
  port: 3000,
  cors: {
    origin: (origin, callback) => {
      // Custom origin validation
      const allowed = ['https://claude.ai', 'https://app.example.com'];
      callback(null, allowed.includes(origin || ''));
    },
    credentials: true
  }
});

Rate Limiting

import rateLimit from 'express-rate-limit';

const transport = new HttpTransport({ port: 3000 });
await transport.start(server);

const app = transport.getApp();
if (app) {
  app.use('/mcp', rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100                   // limit each IP to 100 requests per windowMs
  }));
}

Performance Optimization

Connection Pooling

// Keep SSE connections alive
const transport = new HttpTransport({
  port: 3000,
  keepAliveTimeout: 30000,    // 30 seconds
  headersTimeout: 35000       // 35 seconds
});

Compression

import compression from 'compression';

const app = transport.getApp();
if (app) {
  app.use(compression());
}

Debugging

Enable Debug Logging

process.env.DEBUG = 'mcp-transport-http:*';

const transport = new HttpTransport({
  port: 3000,
  // Debug mode provides verbose logging
});

Request Logging

import morgan from 'morgan';

const app = transport.getApp();
if (app) {
  app.use(morgan('combined'));
}

Compatibility

  • MCP Protocol: 2025-06-18 (Streamable HTTP)
  • Node.js: 18.0.0+
  • Express: 4.x
  • TypeScript: 5.x

Migration from SSE Transport

If migrating from the legacy SSE transport:

// Old SSE transport
import { SSETransport } from '@tylercoles/mcp-transport-sse';

// New HTTP transport (drop-in replacement)
import { HttpTransport } from '@tylercoles/mcp-transport-http';

// Configuration is similar
const transport = new HttpTransport({
  port: 3000,
  // Same configuration options
});

License

MIT