Communication·
advanced
·15 min read·Jul 9, 2026

Multi-Client Agent Orchestration: Implementing SSE-based Remote Connections

Transition your local stdio servers to network-connected remote servers using bi-directional Server-Sent Events (SSE). Support multi-client scaling.

SSEServer-Sent Eventsnetwork architectureHTTPmulti-clientdeployment

Multi-Client Agent Orchestration: SSE-based Connections

While standard input/output (stdio) transports are ideal for local development and single-machine agent setups, they fundamentally cannot handle remote network environments or multi-client communication patterns. To deploy your MCP server to the cloud and connect multiple different LLM clients simultaneously, you must use Server-Sent Events (SSE).

SSE provides a bi-directional communication protocol over standard https:

  • The client listens to server events using a continuous EventSource stream (server-to-client).
  • The client sends commands and tool payloads to the server via standard HTTP POST calls (client-to-server).

Prerequisites

  1. Familiarity with Node.js and the Express framework.
  2. The @modelcontextprotocol/sdk installed in your project.
  3. An understanding of HTTP request lifecycles.

Communication Architecture

code
[Client (e.g. Browser Agent)] --(HTTP POST: JSON-RPC)--> [SSE Server Endpoint]
[Client (e.g. Browser Agent)] <--(Server-Sent Events)--- [SSE Stream Endpoint]

Express-based SSE Transport Implementation

Here is a functional blueprint for setting up an SSE-based MCP server using Express:

typescript
import express from 'express';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import cors from 'cors';

const app = express();
app.use(cors()); // Critical for browser clients
app.use(express.json());

const mcpServer = new Server({ name: 'sse-server', version: '1.0.0' }, { capabilities: {} });

// We must track transports per-session if we support multiple clients. 
// For this simple example, we'll track a single global transport.
let sseTransport: SSEServerTransport | null = null;

app.get('/mcp/events', (req, res) => {
  sseTransport = new SSEServerTransport('/mcp/messages', res);
  mcpServer.connect(sseTransport);
  // The client keeps this connection open indefinitely
});

app.post('/mcp/messages', (req, res) => {
  if (sseTransport) {
    sseTransport.handleMessage(req, res);
  } else {
    res.status(400).send("No active SSE session initialized.");
  }
});

app.listen(3001, () => console.log('SSE MCP Server running on port 3001'));

Best Practices

  • Session Management: The blueprint above uses a single global transport. In production, you must map sessionIds to distinct SSEServerTransport instances so multiple clients don't overwrite each other.
  • CORS Configuration: If your AI client runs in a browser (like a React app), you MUST configure CORS headers on both your /events and /messages endpoints.
  • Reverse Proxies: If you deploy behind Nginx or Cloudflare, ensure you configure them to not buffer SSE responses. (e.g., proxy_buffering off; in Nginx).

Troubleshooting

  • Connection Drops After 60 Seconds: Your load balancer or proxy is likely timing out the idle HTTP connection. Implement server-side keep-alive pings or configure your reverse proxy's timeout settings.
  • CORS Errors on POST: Ensure you are explicitly handling preflight OPTIONS requests if you are sending custom headers like Authorization with your JSON-RPC payloads.

Related Guides