Remote MCP Servers with Streamable HTTP

A
Author
10 Jul, 2026 1 min read 227 views

Stdio servers run on the user's machine. A remote MCP server runs on your infrastructure and is reached over HTTP, which is how SaaS products expose their tools to AI apps. The current HTTP transport is Streamable HTTP: one endpoint that accepts JSON-RPC over POST and can stream responses.

A stateless server with Express

import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { z } from 'zod';

function buildServer() {
  const server = new McpServer({ name: 'status-page', version: '1.0.0' });
  server.registerTool(
    'get_service_status',
    { description: 'Current status of a service', inputSchema: { service: z.enum(['api', 'web', 'db']) } },
    async ({ service }) => ({ content: [{ type: 'text', text: await statusOf(service) }] })
  );
  return server;
}

const app = express();
app.use(express.json());

app.post('/mcp', async (req, res) => {
  // Stateless mode: a fresh server and transport per request
  const server = buildServer();
  const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
  res.on('close', () => {
    transport.close();
    server.close();
  });
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});

app.listen(3333, () => console.log('MCP server on http://localhost:3333/mcp'));

Stateless vs stateful

  • Stateless (above) scales horizontally behind a load balancer and suits simple tool servers.
  • Stateful sessions use an Mcp-Session-Id header and are needed for features such as server-initiated notifications. Pass a sessionIdGenerator and keep transports in a map keyed by session id.

Before you deploy

  • Authentication - the MCP spec uses OAuth 2.1 for remote servers. At minimum require a bearer token.
  • HTTPS only in production.
  • Validate the Origin header and bind local development servers to 127.0.0.1 to prevent DNS-rebinding attacks.
  • Per-user authorisation in every tool: the token identifies the user, and the tool checks what they may access.
  • Rate limits and logging like any public API.
Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.