How the OmniRoute MCP Server Functions with Tools, Scopes, and Transports

The OmniRoute MCP (Model Context Protocol) server centralizes tool execution by separating tool cataloging, scope-based access control, and multi-transport communication into three independent layers.

This architecture allows the diegosouzapw/OmniRoute repository to expose a unified toolset across HTTP, STDIO, and streaming interfaces while enforcing strict security boundaries. Every tool is discoverable via a generated catalog, protected by scope checks, and reachable through any supported transport without code changes.

Tool Catalog and Signatures

All OmniRoute MCP tools reside in open-sse/mcp-server/tools/ and follow a standardized registration pattern.

The catalog is built at server startup in catalog.ts, which aggregates tool definitions from individual modules like skillTools.ts, memoryTools.ts, and pluginTools.ts. Each tool provides:

  • A Zod schema defined in schemas/tools.ts for input validation
  • A signature exported from toolSearch/signature.ts describing parameters, return types, and metadata
  • A concrete implementation exported from its tool module

Tool resolution happens through toolSearch/search.ts, which indexes tools for fast lookup by name or partial match.

// HTTP client call to invoke a tool via JSON-RPC 2.0
import fetch from 'node-fetch';

const response = await fetch('http://localhost:20128/api/mcp', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'pickFastestModel',
    params: { models: ['gpt-4', 'claude-v2'] },
  }),
});

const result = await response.json();

Scope Enforcement Architecture

Before any tool executes, OmniRoute validates the caller's privileges through scopeEnforcement.ts. This security layer prevents unauthorized access to sensitive operations.

Identity Extraction

The mcpCallerIdentity.ts module extracts authentication context from incoming requests—whether from HTTP headers, STDIO environment variables, or stream metadata.

Scope Checking

Scopes are logical domains grouping related capabilities:

  • skill — Invoke AI skills and model routing
  • plugin — Install and manage plugins
  • memory — Access vector stores and embeddings
  • github — Repository operations
  • obsidian — Knowledge base integration

Scopes can be further restricted to specific transports or client types. The enforceScope(caller, requiredScope) function in scopeEnforcement.ts throws a standardized error via buildErrorBody() on authorization failure.

// Tool implementation with mandatory scope check
import { enforceScope } from './scopeEnforcement';
import { getCallerIdentity } from './mcpCallerIdentity';

export async function pickFastestModel(params, ctx) {
  const caller = await getCallerIdentity(ctx);
  
  // 'combo' scope required for model comparison tools
  enforceScope(caller, 'combo');
  
  // Tool logic executes only after authorization
  const fastest = await benchmarkModels(params.models);
  return { model: fastest.name, latency: fastest.latencyMs };
}

Supported Transports

OmniRoute MCP abstracts transport details behind a common request-handler interface, allowing tools to remain transport-agnostic.

HTTP Transport

The primary transport for browser clients and external APIs, implemented in httpTransport.ts. Handles standard JSON-RPC 2.0 over HTTP/HTTPS with full streaming support for large payloads.

STDIO Transport

Used by the CLI in src/bin/, this transport pipes JSON-RPC messages over stdin/stdout. Enables shell scripts and subprocess invocations without network dependencies.

Streamable HTTP Transport

An enhanced HTTP mode using chunked transfer encoding for real-time streaming of embeddings, file uploads, and long-running operations. Implemented as extensions in httpTransport.ts with dedicated streaming helpers.

// Custom WebSocket transport implementation
import { createTransport } from '@omniroute/open-sse/mcp-server';

export const wsTransport = createTransport({
  send: (msg) => ws.send(JSON.stringify(msg)),
  receive: (handler) => ws.on('message', (data) => handler(JSON.parse(data))),
});

Request Processing Flow

A complete OmniRoute MCP request travels through this pipeline:

  1. Client initiates via HTTP, STDIO, or streamable connection
  2. Transport layer deserializes JSON-RPC and normalizes context
  3. mcpCallerIdentity.ts extracts authentication identity
  4. scopeEnforcement.ts verifies required scopes against caller permissions
  5. toolSearch/catalog.ts resolves the tool by name
  6. Tool implementation executes business logic
  7. Response serializes through the same transport to client

This linear flow ensures consistent security and error handling regardless of entry point.

Runtime Observability

The OmniRoute MCP server maintains operational visibility through two dedicated systems:

  • runtimeHeartbeat.ts — Periodic health-check reporting with version, loaded tool count, and transport status
  • audit.ts — Centralized logging of all tool invocations, including caller identity, parameters (sanitized), execution time, and errors

These modules support rate limiting and compliance requirements without polluting core tool logic.

Key Source Files

File Purpose
open-sse/mcp-server/server.ts Entry point wiring transports, catalog, and request handlers
open-sse/mcp-server/catalog.ts Tool catalog construction from module discovery
open-sse/mcp-server/scopeEnforcement.ts Access control and privilege validation
open-sse/mcp-server/httpTransport.ts HTTP and streaming HTTP implementations
open-sse/mcp-server/toolSearch/search.ts Tool resolution and signature matching
open-sse/mcp-server/tools/skillTools.ts Skill invocation tool implementations
open-sse/mcp-server/runtimeHeartbeat.ts Health monitoring and status reporting
open-sse/mcp-server/audit.ts Usage logging and audit trail generation

Summary

  • Tool cataloging: Dynamic discovery from tools/ modules with Zod schemas and searchable signatures
  • Scope enforcement: Domain-based access control (skill, plugin, memory, etc.) validated via scopeEnforcement.ts
  • Multi-transport support: HTTP, STDIO, and streamable HTTP share a unified interface in httpTransport.ts
  • Security-first design: Identity extraction precedes authorization precedes tool execution in all cases
  • Operational transparency: Heartbeats and audit logging without tool-side instrumentation

Frequently Asked Questions

What MCP protocol version does OmniRoute implement?

OmniRoute implements JSON-RPC 2.0 as the message framing protocol across all transports. The server accepts standard JSON-RPC requests with method specifying the tool name and params containing validated arguments. Responses follow standard JSON-RPC success/error formats.

Can custom scopes be added without modifying core files?

Yes. Scope definitions reside in configuration consumed by scopeEnforcement.ts. New scopes can be declared in tool signatures and enforced through the same enforceScope() API without changing the enforcement logic itself. The scope-to-transport mapping is also externally configurable.

How does the STDIO transport handle authentication?

The STDIO transport extracts identity from environment variables set by the parent process, as implemented in mcpCallerIdentity.ts. This allows CLI wrappers to inject tokens while keeping the transport implementation stateless. The same scope checks apply regardless of transport origin.

What happens when a tool exceeds streaming bandwidth limits?

The streamable HTTP transport in httpTransport.ts applies chunked transfer encoding with backpressure handling. If limits are exceeded, the transport emits an error response mid-stream rather than buffering indefinitely, preventing memory exhaustion on the server side.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →