How to Use the 94 MCP Tools with Scoped Authorization in OmniRoute

The OmniRoute MCP server authorizes all 94 tools by comparing the caller's granted scopes against each tool's required scopes declared in schemas/tools.ts, supporting wildcards and returning missing_scopes errors when access is denied.

The diegosouzapw/OmniRoute repository exposes 94 MCP (Model Context Protocol) tools through a hardened authorization layer that requires explicit scopes for every operation. When AI agents or external clients invoke these tools, the server validates credentials against declarative scope requirements using a multi-stage resolution pipeline defined in open-sse/mcp-server/scopeEnforcement.ts.

Understanding the Scope Enforcement Architecture

Every tool in the OmniRoute MCP ecosystem is protected by default. The authorization flow involves tool registration, scope resolution, and pattern matching before any handler executes.

Tool Registration and Required Scopes

In open-sse/mcp-server/schemas/tools.ts, each of the 94 tools is defined with a scopes array that specifies the exact permissions required for execution. Tools for health checks might require read:health, while combo routing operations need write:combos. This declarative approach ensures that every capability is explicitly permissioned at the schema level.

Scope Resolution and Matching Logic

The scopeEnforcement.ts file implements the core authorization engine through three critical functions:

  • resolveCallerScopeContext: Extracts the caller's scopes from the authInfo object, the _meta field, or environment-based fallbacks
  • evaluateToolScopes: Compares the resolved caller scopes against the tool's required scopes defined in MCP_TOOL_MAP
  • scopeMatches: Performs pattern matching supporting exact strings and wildcard (*) prefixes (lines 61-68)

When a request arrives at open-sse/mcp-server/toolSearch/handler.ts, the dispatcher invokes evaluateToolScopes before running any tool handler.

Authenticating MCP Tool Requests

Callers must supply their authorization context using a structured format that the server can validate against the tool registry.

Constructing the Caller Object

The caller object contains an authInfo property with a clientId and an array of granted scopes. This structure integrates with OAuth 2.0 or custom session providers:

const caller = {
  authInfo: {
    clientId: "my-client-id",
    scopes: ["read:health", "read:combos", "write:combos"]
  },
  sessionId: "optional-session-id",
  _meta: { /* additional metadata */ }
};

HTTP Transport and Header Configuration

The httpTransport.ts module exposes MCP endpoints at /api/mcp/stream (JSON-HTTP) and /api/mcp/sse (Server-Sent Events). The caller serializes their authorization context into the x-omniroute-caller header:

import fetch from "node-fetch";

async function runMcpTool<TInput, TOutput>(
  toolName: string,
  input: TInput,
  caller: any
): Promise<TOutput> {
  const response = await fetch(
    "https://my-omniroute-instance.com/api/mcp/stream",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-omniroute-caller": JSON.stringify(caller)
      },
      body: JSON.stringify({ tool: toolName, input })
    }
  );

  if (!response.ok) {
    const err = await response.json();
    throw new Error(`MCP error: ${err.message}`);
  }
  return (await response.json()) as TOutput;
}

Invoking the 94 MCP Tools with Scoped Credentials

Once authenticated, callers can invoke specific tools by name, provided their scope list intersects with the tool's requirements.

Example: Reading Health Status

The omniroute_get_health tool requires the read:health scope:

const caller = {
  authInfo: {
    clientId: "health-monitor",
    scopes: ["read:health"]
  }
};

runMcpTool("omniroute_get_health", {}, caller)
  .then(health => console.log("System health:", health));

Handling Missing Scope Errors

When a caller lacks the required scopes, the server returns a structured error before executing any business logic. For example, attempting to switch a combo without write:combos:

const switchInput = {
  comboId: "combo-42",
  active: false
};

// Caller only has read:combos, not write:combos
const limitedCaller = {
  authInfo: {
    clientId: "reader-only",
    scopes: ["read:combos"]
  }
};

runMcpTool("omniroute_switch_combo", switchInput, limitedCaller);

This returns a 403-equivalent response:

{
  "allowed": false,
  "required": ["write:combos"],
  "provided": ["read:combos"],
  "missing": ["write:combos"],
  "reason": "missing_scopes"
}

Filtering Tool Access with Tool Cardinality

The open-sse/mcp-server/toolCardinality.ts module filters the full catalog of 94 tools based on the caller's authorized scopes. When clients request the tool list via /api/mcp/tools, the server returns only those tools the caller is permitted to execute:

const response = await fetch(
  "https://my-omniroute-instance.com/api/mcp/tools",
  {
    headers: { "x-omniroute-caller": JSON.stringify(caller) }
  }
);

const accessibleTools = await response.json();
// Returns subset of 94 tools matching the caller's scopes

Implementing Wildcard Scopes for Broad Access

OmniRoute supports wildcard patterns in scope grants to simplify permission management. A scope ending with * grants access to all permissions sharing that prefix:

// Grant all read operations across all tool categories
const adminCaller = {
  authInfo: {
    clientId: "admin-service",
    scopes: ["read:*"]
  }
};

// Now authorized for read:health, read:combos, read:quotas, etc.

The scopeMatches function in scopeEnforcement.ts handles this pattern matching, allowing read:* to satisfy read:health requirements while correctly rejecting write:health requests.

Summary

  • 94 MCP tools are defined in open-sse/mcp-server/schemas/tools.ts, each with explicit required scopes.
  • Authorization occurs via resolveCallerScopeContext and evaluateToolScopes in scopeEnforcement.ts before any tool handler executes.
  • Caller credentials are passed via the x-omniroute-caller header or request body extra field, containing an authInfo object with clientId and scopes.
  • Wildcard support allows granting families of permissions (e.g., read:*) through the scopeMatches function.
  • Error handling returns structured missing_scopes responses detailing exactly which permissions are required but not provided.
  • Tool discovery is filtered by toolCardinality.ts to show only authorized tools when listing capabilities.

Frequently Asked Questions

What are the 94 MCP tools in OmniRoute?

The 94 MCP tools expose OmniRoute functionality—including health monitoring, combo routing, quota management, compression, memory operations, and plugin management—to AI agents via the Model Context Protocol. Each tool is declared with Zod schemas and required scopes in open-sse/mcp-server/schemas/tools.ts.

How do I pass scopes to the OmniRoute MCP server?

Scopes are passed within the authInfo.scopes array inside the x-omniroute-caller HTTP header, or alternatively via the _meta field in the request body. The resolveCallerScopeContext function in scopeEnforcement.ts extracts these values and normalizes them for evaluation.

What happens if I call a tool without the required scope?

The MCP server rejects the request with a missing_scopes error before executing the tool handler. The response includes the required scopes, provided scopes, and the specific missing scopes that blocked execution, enabling precise debugging of permission issues.

Can I use wildcard patterns for MCP tool authorization?

Yes. The scopeMatches function supports wildcard (*) patterns at the end of scope strings. For example, granting read:* authorizes all tools requiring read:health, read:combos, or any other scope beginning with read:, while write:* would cover all write operations.

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 →