How to Set Up MCP Server with Scoped Tool Permissions in OmniRoute

Configure the OMNIROUTE_MCP_SCOPES environment variable to map tools to required permission scopes, then deploy the MCP server with the scopeEnforcement.ts middleware to authorize every incoming request against the caller's JWT or API key claims.

The OmniRoute MCP (Multi-Channel Proxy) server exposes over 100 tools via HTTP, SSE, or stdio transports, but production deployments require strict access control. By setting up MCP server with scoped tool permissions, you can restrict which tools each client is allowed to invoke based on granular permission scopes defined in src/shared/constants/mcpScopes.ts.

Core Components of the Permission System

The permission model relies on three interconnected pieces that govern tool access from declaration to enforcement.

MCP_TOOL_SCOPES Mapping

The MCP_TOOL_SCOPES constant in src/shared/constants/mcpScopes.ts serves as the authoritative registry that lists every available tool alongside the specific scopes required to invoke it. When a tool is registered, the server consults this mapping to determine what permissions an incoming request must possess.

Scope Enforcement Middleware

Located at open-sse/mcp-server/scopeEnforcement.ts, this middleware runs on every inbound request and performs the actual authorization check. It extracts the caller's scopes from JWT claims (using the scp key) or API key metadata, then validates them against the requirements defined in MCP_TOOL_SCOPES. Failed validations return a 403 Forbidden response before the tool executes.

Declarative Scope Presets

The same constants file exports MCP_SCOPE_PRESETS, which provides pre-configured bundles like default (all tools), readOnly (safe read operations), and manage (administrative functions). These presets simplify configuration by grouping common permission patterns into single identifiers.

Step-by-Step Setup Guide

1. Install and Build the Server

Begin by installing dependencies and compiling the production bundle that includes the MCP server entry point.

npm ci
npm run build:release

The compiled entry point resides at open-sse/mcp-server/index.ts, which handles environment parsing and server initialization.

2. Configure Scoped Permissions

Choose between using a preset or defining a custom tool-to-scope mapping via the OMNIROUTE_MCP_SCOPES environment variable.

Option A: Use a Preset

OMNIROUTE_MCP_SCOPES=readOnly

Option B: Provide Custom JSON

OMNIROUTE_MCP_SCOPES='{
  "omniroute_web_fetch": ["execute:search"],
  "omniroute_memory_add": ["memory:write"]
}'

The server parses this JSON at startup (as implemented in open-sse/mcp-server/index.ts) to build the active permission matrix.

3. Start the MCP Server

Launch the server using the compiled output. By default, it listens on http://127.0.0.1:3000, configurable via MCP_SERVER_PORT.

node --import tsx/esm open-sse/mcp-server/index.js

4. Issue Scoped Client Tokens

For API Key Authentication: Add a scopes claim to the key's metadata using the OmniRoute dashboard or CLI (omniroute keys create).

For JWT Authentication: Include a scp claim listing the scopes the bearer possesses:

{
  "sub": "user-123",
  "scp": ["execute:search", "memory:write"]
}

5. Invoke Tools with Automatic Validation

When calling a tool endpoint, the scopeEnforcement.ts middleware automatically verifies the token against the tool's required scopes. Requests lacking authorization receive an immediate rejection.

Practical Implementation Examples

Running with a Custom Scope Map

Configure the environment to allow only web search and memory write operations:

export OMNIROUTE_MCP_SCOPES='{
  "omniroute_web_fetch": ["execute:search"],
  "omniroute_memory_add": ["memory:write"]
}'

Start the server:

node --import tsx/esm open-sse/mcp-server/index.js

Attempting Unauthorized Tool Access

If a client presents a JWT without the required scope:

{
  "sub": "user-123",
  "scp": ["memory:write"]
}

And attempts to call omniroute_web_fetch (which requires execute:search), the server responds:

{
  "error": "Forbidden",
  "message": "Missing required scope for tool omniroute_web_fetch"
}

Deploying a Read-Only Environment

Restrict clients to safe, non-destructive operations using the built-in preset:

OMNIROUTE_MCP_SCOPES=readOnly

This preset, defined in src/shared/constants/mcpScopes.ts, grants access only to tools like list_models_catalog and search while blocking any write or execute operations.

Summary

  • The OmniRoute MCP server exposes tools through open-sse/mcp-server/index.ts with permission enforcement handled by scopeEnforcement.ts.
  • Tool permissions are declared in src/shared/constants/mcpScopes.ts via the MCP_TOOL_SCOPES mapping and MCP_SCOPE_PRESETS.
  • Configure scope restrictions using the OMNIROUTE_MCP_SCOPES environment variable, accepting either preset names or custom JSON mappings.
  • Client authentication requires JWT tokens with an scp claim or API keys with embedded scope metadata.
  • Failed scope validation results in a 403 Forbidden response, preventing unauthorized tool execution.

Frequently Asked Questions

How do I restrict a client to read-only tools?

Set OMNIROUTE_MCP_SCOPES=readOnly in your environment configuration. This preset, defined in src/shared/constants/mcpScopes.ts, automatically restricts access to safe read operations like list_models_catalog while blocking write and execute tools.

What HTTP status code is returned for insufficient permissions?

The scopeEnforcement.ts middleware returns a 403 Forbidden status with a JSON error message indicating the missing scope. This occurs before the tool handler executes, ensuring no unauthorized side effects.

Can I use both presets and custom scope mappings simultaneously?

No, the configuration accepts either a preset identifier (like default or readOnly) or a custom JSON object via OMNIROUTE_MCP_SCOPES. You must choose one approach per deployment as implemented in open-sse/mcp-server/index.ts.

Where is the scope validation logic implemented?

Scope validation resides in open-sse/mcp-server/scopeEnforcement.ts, which acts as middleware on every request. This file extracts scopes from the JWT scp claim or API key metadata and validates them against the MCP_TOOL_SCOPES mapping from src/shared/constants/mcpScopes.ts.

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 →