# OmniRoute MCP Server Architecture and Transport Options: A Deep Dive

> Explore OmniRoute MCP server architecture, including its three-layer design and supported transport options like JSON-RPC via stdio and HTTP/SSE. Learn about session management and scope enforcement.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: deep-dive
- Published: 2026-07-12

---

**The OmniRoute MCP server implements a three-layer architecture—server core, transport adapters, and runtime support—exposing JSON-RPC tooling via stdio (CLI) and HTTP/SSE transports with built-in session management and scope enforcement.**

The OmniRoute MCP (Model Context Protocol) server is a self-contained, modular component that exposes the platform's full tooling suite through a JSON-RPC interface. Understanding its **MCP server architecture** is essential for developers integrating OmniRoute's health monitoring, routing, and plugin systems into their own applications. The architecture separates concerns into distinct layers for tool registration, transport adaptation, and runtime observability, as implemented in the `diegosouzapw/OmniRoute` repository.

## MCP Server Core Architecture

The server core in [`open-sse/mcp-server/server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/server.ts) acts as the central dispatcher for all MCP functionality. It instantiates the server, registers built-in tools, and applies middleware for security and accessibility.

### Server Instantiation and Tool Registration

The entry point `createMcpServer()` initializes a new `McpServer` instance configured with the name `"omniroute"` and the current version. This function dynamically registers eight distinct tool categories:

- **Core tools** (health, routing, quota)
- **Memory and skill tools**
- **Plugin and compression tools**
- **Pool and gamification tools**
- **Notion/Obsidian integrations**
- **Dynamic skill tools**

Each registration wraps the handler with `withScopeEnforcement()` to ensure proper authorization. The server also reads optional database flags for **description compression** and **accessibility filtering** to optimize payload size and usability.

```typescript
server.registerTool(
  "omniroute_get_health",
  { description: "Returns OmniRoute health status …", inputSchema: getHealthInput },
  withScopeEnforcement("omniroute_get_health", async (args) => {
    getHealthInput.parse(args ?? {});
    return handleGetHealth();
  })
);

```

### Scope Enforcement and Optional Features

The `withScopeEnforcement()` wrapper (applied at lines 90-94 and 101-107 in [`server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/server.ts)) validates MCP scopes before executing any tool handler. This ensures that callers possess the necessary permissions for operations like web searches or quota modifications. Optional features include **description compression** to reduce token usage and **accessibility filtering** to modify tool descriptions based on user needs.

## Transport Options: Stdio vs HTTP

The architecture abstracts transport specifics through adapter layers, allowing the same toolset to expose itself over multiple I/O channels.

### Stdio Transport for CLI Integration

The **stdio transport** serves CLI clients through the `startMcpStdio()` function (lines 32-65 in [`server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/server.ts)). When users invoke `omniroute --mcp`, the system:

1. Calls `createMcpServer()` to initialize the tool registry
2. Instantiates `StdioServerTransport` from `@modelcontextprotocol/sdk/server/stdio.js`
3. Connects the server to stdin/stdout pipes
4. Activates a heartbeat monitor for health tracking

**Usage:**

```bash
omniroute --mcp

```

This mode is ideal for local integrations where the MCP client runs as a subprocess, communicating via standard streams.

### HTTP Transport with SSE and Streamable-HTTP

The HTTP transport in [`open-sse/mcp-server/httpTransport.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/httpTransport.ts) supports two distinct modes for web dashboard and HTTP client integration:

**SSE Mode** uses a shared `WebStandardStreamableHTTPServerTransport` instance (`_sseServer`) serving:
- `GET /api/mcp/sse` for the event stream
- `POST /api/mcp/sse` for JSON-RPC messages

**Streamable-HTTP Mode** creates isolated sessions via:
- `POST /api/mcp/stream` for message submission
- `GET /api/mcp/stream` for SSE streams
- `DELETE /api/mcp/stream` for session termination

Each streamable session receives a unique UUID and auto-closes after 5 minutes of inactivity. The transport injects an `mcp-session-id` header into every response (lines 52-63) and automatically reinitializes sessions if a client sends an `initialize` request with an unknown session ID (lines 71-84).

**Initializing a streamable HTTP session:**

```typescript
import fetch from "node-fetch";

async function initMcpSession() {
  const initResp = await fetch("http://localhost:3000/api/mcp/stream", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ jsonrpc: "2.0", method: "initialize", id: 1, params: {} })
  });
  const sessionId = initResp.headers.get("mcp-session-id");
  
  const healthResp = await fetch("http://localhost:3000/api/mcp/stream", {
    method: "POST",
    headers: { "Content-Type": "application/json", "mcp-session-id": sessionId! },
    body: JSON.stringify({
      jsonrpc: "2.0",
      method: "omniroute_get_health",
      id: 2,
      params: {}
    })
  });
  const health = await healthResp.json();
  console.log("Health:", health.result);
}

```

**Subscribing to SSE events:**

```typescript
const evtSource = new EventSource("http://localhost:3000/api/mcp/sse");
evtSource.onmessage = (e) => console.log("MCP event:", e.data);
evtSource.onerror = (e) => console.error("MCP SSE error", e);

```

## Runtime Support and Observability

The runtime layer handles cross-cutting concerns without polluting the core business logic.

### Authentication and Context Propagation

The [`httpAuthContext.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/httpAuthContext.ts) module extracts caller identity from HTTP headers and propagates it through tool invocations using `withMcpHttpAuthContext`. This enables per-user scope validation and audit trails without requiring each tool to handle auth logic manually.

### Health Monitoring and Audit Logging

- **Heartbeat**: [`runtimeHeartbeat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/runtimeHeartbeat.ts) periodically logs server metrics including tool counts, active scopes, and version information
- **Audit**: [`audit.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/audit.ts) records every tool invocation with timestamps, parameters, and errors to a persistent store for compliance and debugging

## Summary

- The **MCP server core** in [`server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/server.ts) centralizes tool registration and enforces scopes through middleware wrappers
- **Two transport adapters** expose identical functionality: **stdio** for CLI subprocesses and **HTTP** (with SSE and streamable-HTTP modes) for web clients
- **Session management** in HTTP mode isolates clients via UUIDs with automatic cleanup after 5 minutes of inactivity
- **Runtime support** provides authentication context, heartbeat monitoring, and comprehensive audit logging without requiring changes to tool implementations
- **Extensibility** allows new tool categories (skills, plugins, gamification) to register dynamically without modifying the server core

## Frequently Asked Questions

### What transports does the OmniRoute MCP server support?

The OmniRoute MCP server supports **stdio** (standard input/output) for CLI integration and **HTTP** for web clients. The HTTP transport further subdivides into **SSE (Server-Sent Events)** mode for shared streaming and **streamable-HTTP** mode for isolated per-session transports, as implemented in [`open-sse/mcp-server/httpTransport.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/httpTransport.ts).

### How does session management work in the HTTP transport?

Session management differs by HTTP mode. **SSE mode** uses a single shared server instance for all clients, while **streamable-HTTP** creates a unique `StreamableSession` with a UUID for each client. Sessions automatically terminate after 5 minutes of inactivity through an idle sweep mechanism (lines 34-43 in [`httpTransport.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/httpTransport.ts)), and each response includes an `mcp-session-id` header for stateful communication.

### What is the purpose of the `withScopeEnforcement` wrapper?

The `withScopeEnforcement()` function acts as a middleware layer that validates MCP scopes before executing tool handlers. It wraps every registered tool in [`server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/server.ts) (lines 90-107) to ensure callers possess proper authorization for operations like health checks, routing queries, or plugin management, preventing unauthorized access to sensitive functionality.

### How do I start the MCP server from the command line?

Invoke the stdio transport by running `omniroute --mcp` in your terminal. This executes `startMcpStdio()` in [`open-sse/mcp-server/server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/server.ts), which initializes the `McpServer`, connects it to `StdioServerTransport` from the Model Context Protocol SDK, and begins listening for JSON-RPC messages on stdin/stdout with automatic heartbeat monitoring.