How to Set Up and Use the MCP Server with OmniRoute: Complete 2024 Guide
OmniRoute bundles a production-ready MCP (Multi-Channel Provider) server with 104 built-in tools, three transport modes (SSE, stdio, HTTP), and fine-grained scope enforcement—all accessible via createMcpServer() in open-sse/mcp-server/server.ts.
The Model Context Protocol (MCP) server in OmniRoute turns the framework into a tool-capable backend that LLMs and agents can invoke through standardized endpoints. Whether you're exposing health checks, routing logic, or custom business operations, the server ships with everything needed for secure, scoped tool execution.
Creating the MCP Server Instance
Every OmniRoute MCP deployment starts with createMcpServer() in open-sse/mcp-server/server.ts (line 618). This factory function builds a McpServer instance, automatically registers all 104 base tools from MCP_TOOLS, and prepares the internal router for incoming requests.
import { createMcpServer } from "@omniroute/open-sse/mcp-server/server.ts";
const server = createMcpServer(); // ← initializes tool registry + handlers
The tool catalog itself is assembled in open-sse/mcp-server/schemas/tools.ts from several specialized subsets:
CCR_MCP_TOOLS— core routing and CCR operationsmemoryTools— memory persistence and retrievalskillTools— skill execution utilitiesagentSkillTools— A2A (agent-to-agent) capabilitiespoolTools— resource pool management
// schemas/tools.ts — master tool aggregation
export const MCP_TOOLS = [
...CCR_MCP_TOOLS,
...memoryTools,
...skillTools,
...agentSkillTools,
...poolTools,
// …additional tool categories
];
The server also maintains MCP_TOOL_MAP for O(1) name-based lookups and splits tools into Phase 1 (essential) and Phase 2 (advanced) categories for progressive capability exposure.
Starting the MCP Server: Three Transport Options
OmniRoute supports three transport modes for different integration scenarios. Each wraps the same McpServer core but exposes it through different protocols.
stdio Transport (CLI Quick Start)
The fastest way to launch the MCP server for local LLM integrations:
npx omniroute --mcp
Behind the scenes, this executes startMcpStdio(createMcpServer()) from open-sse/mcp-server/index.ts. The stdio transport is ideal for Claude Desktop, Cursor, and other MCP clients that communicate over standard input/output streams.
HTTP Transport (Programmatic Servers)
For remote deployments or web-facing APIs, instantiate HttpTransport directly:
import { createMcpServer } from "@omniroute/open-sse/mcp-server/server.ts";
import { HttpTransport } from "@omniroute/open-sse/mcp-server/httpTransport.ts";
const server = createMcpServer();
const http = new HttpTransport(server);
http.listen(3001, () => {
console.log("MCP HTTP server listening on port 3001");
});
The HttpTransport constructor (line 13 in httpTransport.ts) internally calls createMcpServer() and binds request handling to the specified port.
SSE Transport (Server-Sent Events)
For real-time streaming tool outputs, the SSE transport enables push-based updates to connected clients. Configure this through the same transport pattern by selecting the SSE variant in your server bootstrap.
Scope Enforcement and Security
Before any tool executes, open-sse/mcp-server/scopeEnforcement.ts validates the caller's permissions. The middleware checks the OMNIROUTE_MCP_SCOPES claim in the request context against each tool's scopes array in its definition.
Permission flow:
- Incoming request carries scope claims (JWT, headers, or context)
- Scope enforcement middleware intersects claims with
tool.scopes - Execution proceeds only if at least one required scope matches
// Example tool definition with scoped access
{
name: "omniroute_admin_clear_cache",
scopes: ["admin.cache", "superuser"], // requires either scope
handler: async (args) => { /* ... */ }
}
Tools without explicit scopes default to open access, though production deployments should always restrict sensitive operations.
Discovering Available Tools
Clients can introspect the server's capabilities at runtime via the discovery endpoint implemented in src/app/api/mcp/tools/route.ts:
curl http://localhost:3000/api/mcp/tools
Response includes tool names, descriptions, required scopes, and phase classifications:
{
"tools": [
{
"name": "omniroute_get_health",
"phase": 1,
"scopes": [],
"description": "Returns server health status and version"
},
{
"name": "omniroute_list_routes",
"phase": 1,
"scopes": ["routes.read"],
"description": "Lists all registered routes"
}
],
"total": 104,
"phases": { "essential": 42, "advanced": 62 }
}
Invoking Tools Programmatically
Direct tool execution bypasses transport layers for internal use:
import { createMcpServer } from "@omniroute/open-sse/mcp-server/server.ts";
const server = createMcpServer();
// Synchronous invocation with typed results
const health = await server.invokeTool("omniroute_get_health", {});
console.log(health); // → { status: "ok", version: "v3.8.50", uptime: 3600 }
// Tools accepting arguments
const routes = await server.invokeTool("omniroute_list_routes", {
filter: "api/v1/*",
includeInactive: false
});
The invokeTool method on McpServer handles argument validation, scope checking, and error wrapping automatically.
Adding Custom Tools to the MCP Server
Extend the base catalog with domain-specific operations by implementing McpToolDefinition:
import { McpToolDefinition } from "@omniroute/open-sse/mcp-server/schemas/toolDefinition.ts";
import { createMcpServer } from "@omniroute/open-sse/mcp-server/server.ts";
const validateWebhookSignature: McpToolDefinition = {
name: "stripe_validate_signature",
description: "Verifies Stripe webhook payload authenticity",
phase: 2,
scopes: ["payments.webhooks"],
inputSchema: {
type: "object",
properties: {
payload: { type: "string" },
signature: { type: "string" },
secret: { type: "string" }
},
required: ["payload", "signature"]
},
handler: async ({ payload, signature, secret }) => {
const crypto = await import("node:crypto");
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return {
valid: crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
};
}
};
const server = createMcpServer();
server.registerTool(validateWebhookSignature); // merges into MCP_TOOLS + MCP_TOOL_MAP
registerTool() automatically updates both the master tool list and the lookup map, ensuring immediate availability through all transports.
Key Files Reference
| File | Purpose |
|---|---|
open-sse/mcp-server/server.ts |
Core createMcpServer() factory and McpServer class |
open-sse/mcp-server/index.ts |
Public exports and stdio starter |
open-sse/mcp-server/httpTransport.ts |
HTTP transport with listen() binding |
open-sse/mcp-server/schemas/tools.ts |
MCP_TOOLS aggregation and phase splitting |
open-sse/mcp-server/scopeEnforcement.ts |
Permission validation middleware |
src/app/api/mcp/tools/route.ts |
Runtime tool discovery API |
skills/omni-mcp/SKILL.md |
CLI skill documentation |
Summary
- Initialize with
createMcpServer()inopen-sse/mcp-server/server.ts(line 618) to load 104 built-in tools - Select transport:
npx omniroute --mcpfor stdio,HttpTransportfor HTTP, or SSE for streaming - Enforce security through
OMNIROUTE_MCP_SCOPESclaims validated byscopeEnforcement.ts - Discover tools via
GET /api/mcp/toolsor introspectMCP_TOOL_MAPprogrammatically - Extend with
registerTool()usingMcpToolDefinitionschemas for custom operations
Frequently Asked Questions
What is the MCP server in OmniRoute used for?
The MCP server exposes OmniRoute's internal capabilities—routing, caching, health monitoring, agent skills—as callable tools that conform to the Model Context Protocol. LLM clients like Claude, Cursor, and custom agents can invoke these tools through standardized transports without writing HTTP client code.
How do I choose between stdio, HTTP, and SSE transports?
stdio suits local desktop integrations where the LLM spawns OmniRoute as a subprocess. HTTP works best for production deployments with remote clients or load balancers. SSE is optimal when tools stream partial results or progress updates back to the caller.
Where are the 104 built-in tools defined?
The master list lives in open-sse/mcp-server/schemas/tools.ts, assembled from categorized subsets (CCR_MCP_TOOLS, memoryTools, skillTools, etc.). Each tool's handler, schema, and scope requirements are co-located in dedicated files under open-sse/mcp-server/tools/.
How does scope enforcement protect sensitive tools?
scopeEnforcement.ts intercepts every tool invocation and compares the caller's OMNIROUTE_MCP_SCOPES against the tool's scopes array. Only requests with matching scopes proceed; others receive a 403-equivalent error before the handler executes.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →