# How to Set Up an MCP Server with OmniRoute: Configuring Tools and Scope Permissions

> Learn to set up an MCP server with OmniRoute. Configure tools and scope permissions using environment variables for secure AI agent access. Follow our guide to limit access effectively.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-07-04

---

**Configure the OmniRoute MCP server by setting the `OMNIROUTE_MCP_SCOPES` environment variable to limit tool access, then launch the Node process from [`open-sse/mcp-server/server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/server.ts) to expose only the permitted tools to AI agents.**

The diegosouzapw/OmniRoute repository ships with a built-in **Model Context Protocol (MCP)** server that exposes 37 tools for AI agent integration. By configuring scope permissions through environment variables, you can restrict agent access to specific subsets of tools—such as limiting a coding assistant to only essential utilities with narrow permissions—while maintaining security through the built-in scope enforcement layer.

## Core Architecture of the OmniRoute MCP Server

The MCP server operates as a standalone Node process that bridges AI agents and the OmniRoute gateway. In [`open-sse/mcp-server/server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/server.ts), the server initializes stdio or HTTP transport and registers all tool handlers from the catalog.

**Scope enforcement** is implemented in [`open-sse/mcp-server/scopeEnforcement.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/scopeEnforcement.ts). This module parses the `OMNIROUTE_MCP_SCOPES` environment variable at startup and validates every incoming tool call against the required scopes defined in the tool definitions. Unauthorized calls are rejected before reaching the gateway.

All tool definitions reside in [`open-sse/mcp-server/catalog.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/catalog.ts), which aggregates schemas from [`open-sse/mcp-server/schemas/tools.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/schemas/tools.ts) and implementations from the `open-sse/mcp-server/tools/` directory. Each tool invocation is logged to an SQLite audit database via [`open-sse/mcp-server/audit.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/audit.ts) with SHA-256 hashing of inputs for privacy.

## Selecting Tools and Configuring Scope Permissions

### Understanding the 37-Tool Catalog

The server exposes 37 tools across categories including core routing, memory, compression, and monitoring. Rather than exposing the full catalog, you select tools by granting the specific scopes they require. For example, a minimal coding assistant configuration might use these nine tools:

- **`omniroute_get_health`** — Requires `read:health` scope; checks gateway status
- **`omniroute_list_combos`** — Requires `read:combos` scope; discovers available model combinations
- **`omniroute_route_request`** — Requires `execute:completions` scope; sends completion requests
- **`omniroute_check_quota`** — Requires `read:quota` scope; verifies provider limits
- **`omniroute_cost_report`** — Requires `read:usage` scope; monitors billing
- **`omniroute_set_budget_guard`** — Requires `write:budget` scope; enforces spending limits
- **`omniroute_switch_combo`** — Requires `write:combos` scope; activates model combinations
- **`omniroute_cache_stats`** — Requires `read:cache` scope; inspects cache performance
- **`omniroute_compression_status`** — Requires `read:compression` scope; views compression settings

### Defining Scope Permissions

Scopes are granted as comma-separated values in the `OMNIROUTE_MCP_SCOPES` environment variable. To enable the nine tools listed above, you would grant three scope groups:

```bash
export OMNIROUTE_MCP_SCOPES="read:health,read:combos,execute:completions"

```

You can also use wildcards for broader access, such as `read:*` to grant all read permissions. The `OMNIROUTE_MCP_ENFORCE_SCOPES` flag must be set to `"true"` to activate enforcement; otherwise, the server runs in open mode.

## Step-by-Step Setup Guide

### 1. Export Environment Variables

Configure the server by setting these four required variables before launching the process:

```bash
export OMNIROUTE_BASE_URL="http://localhost:20128"
export OMNIROUTE_API_KEY="your-gateway-api-key"
export OMNIROUTE_MCP_ENFORCE_SCOPES="true"
export OMNIROUTE_MCP_SCOPES="read:health,read:combos,execute:completions"

```

The `OMNIROUTE_BASE_URL` points to your OmniRoute gateway address (default port 20128). The `OMNIROUTE_API_KEY` is required only if your gateway enforces authentication.

### 2. Launch the MCP Server

Start the server using the TypeScript executor or the OmniRoute CLI:

```bash

# Direct launch with stdio transport

npx tsx open-sse/mcp-server/server.ts

# Or via the built-in CLI

omniroute --mcp

```

By default, the server communicates over stdin/stdout. For HTTP transport, use the implementation in [`open-sse/mcp-server/httpTransport.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/httpTransport.ts).

### 3. Configure Your AI Agent

Connect Claude Desktop, Cursor, VS Code, or custom agents by pointing them to the server process. For VS Code, add this configuration to your settings:

```json
{
  "mcp": {
    "servers": {
      "omniroute": {
        "command": "npx",
        "args": ["tsx", "open-sse/mcp-server/server.ts"],
        "env": {
          "OMNIROUTE_BASE_URL": "http://localhost:20128",
          "OMNIROUTE_MCP_ENFORCE_SCOPES": "true",
          "OMNIROUTE_MCP_SCOPES": "read:health,read:combos,execute:completions"
        }
      }
    }
  }
}

```

## Implementation Examples

### Bash Environment Configuration

Set up the environment for a shell-based launch:

```bash

# Base configuration

export OMNIROUTE_BASE_URL="http://localhost:20128"
export OMNIROUTE_API_KEY="my-secret-key"

# Enable scope enforcement with three specific permissions

export OMNIROUTE_MCP_ENFORCE_SCOPES="true"
export OMNIROUTE_MCP_SCOPES="read:health,read:combos,execute:completions"

# Launch the server

npx tsx open-sse/mcp-server/server.ts

```

### TypeScript Programmatic Launch

Spawn the MCP server from a parent Node process:

```typescript
import { spawn } from "child_process";

const proc = spawn("npx", ["tsx", "open-sse/mcp-server/server.ts"], {
  env: {
    ...process.env,
    OMNIROUTE_BASE_URL: "http://localhost:20128",
    OMNIROUTE_MCP_ENFORCE_SCOPES: "true",
    OMNIROUTE_MCP_SCOPES: "read:health,read:combos,execute:completions",
  },
});

proc.stdout.pipe(process.stdout);
proc.stderr.pipe(process.stderr);

```

### Python MCP Client Integration

Use the MCP SDK to connect with limited scope permissions:

```python
import asyncio
from mcp import ClientSession, StdioServerParameters

async def main():
    server = StdioServerParameters(
        command="npx",
        args=["tsx", "open-sse/mcp-server/server.ts"],
        env={
            "OMNIROUTE_BASE_URL": "http://localhost:20128",
            "OMNIROUTE_MCP_ENFORCE_SCOPES": "true",
            "OMNIROUTE_MCP_SCOPES": "read:health,read:combos,execute:completions",
        },
    )

    async with ClientSession(*await server.start()) as session:
        await session.initialize()
        
        # Valid calls with granted scopes

        health = await session.call_tool("omniroute_get_health", {})
        print("Health:", health.content[0].text)
        
        # This will fail without write:budget scope

        try:
            await session.call_tool("omniroute_set_budget_guard", {"limit": 100})
        except Exception as e:
            print("Scope enforcement blocked:", e)

asyncio.run(main())

```

### Direct HTTP API Access (Go)

Bypass the MCP protocol and call the OmniRoute gateway directly:

```go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    base := "http://localhost:20128"

    // Health check equivalent to omniroute_get_health
    resp, _ := http.Get(base + "/api/monitoring/health")
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    fmt.Println("Health:", string(body))

    // Completion request equivalent to omniroute_route_request
    payload := map[string]any{
        "model": "claude-sonnet-4",
        "messages": []map[string]string{
            {"role": "user", "content": "Hello from Go"},
        },
    }
    data, _ := json.Marshal(payload)
    r, _ := http.Post(base+"/v1/chat/completions", "application/json", bytes.NewReader(data))
    defer r.Body.Close()
    out, _ := io.ReadAll(r.Body)
    fmt.Println("Completion:", string(out))
}

```

## Summary

- The **OmniRoute MCP server** is located in `open-sse/mcp-server/` and exposes 37 tools through the Model Context Protocol.
- **Scope enforcement** is controlled by `OMNIROUTE_MCP_SCOPES` and validated in [`open-sse/mcp-server/scopeEnforcement.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/scopeEnforcement.ts), allowing you to restrict agents to specific tool subsets.
- Set `OMNIROUTE_MCP_ENFORCE_SCOPES="true"` to activate permission checking; without this flag, the server operates in open mode.
- All tool calls are audited via [`open-sse/mcp-server/audit.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/audit.ts) with SHA-256 hashed inputs for privacy compliance.
- The server supports both **stdio** (default) and **HTTP** transports, configurable via [`server.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/server.ts) or [`httpTransport.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/httpTransport.ts).

## Frequently Asked Questions

### How many tools does the OmniRoute MCP server expose?

The server ships with **37 tools** covering core routing, memory management, compression, and advanced monitoring functions. While the full catalog is loaded from [`open-sse/mcp-server/catalog.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/catalog.ts), you can restrict access to any subset by configuring the appropriate scope permissions in `OMNIROUTE_MCP_SCOPES`.

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

The call is rejected by the scope enforcement layer in [`open-sse/mcp-server/scopeEnforcement.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/scopeEnforcement.ts) before it reaches the OmniRoute gateway. The server returns an authorization error indicating which scope is required to invoke the specific tool, preventing unauthorized access to sensitive operations like budget modifications or combo switching.

### Can I run the MCP server without scope restrictions?

Yes. If you omit the `OMNIROUTE_MCP_ENFORCE_SCOPES` environment variable or set it to `"false"`, the server runs in **open mode** and exposes all 37 tools to connecting agents. However, for production deployments, diegosouzapw/OmniRoute recommends enabling enforcement to maintain security boundaries between AI agents and the gateway.

### How do I verify which scopes are required for specific tools?

Tool definitions in [`open-sse/mcp-server/schemas/tools.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/schemas/tools.ts) and the implementation files in `open-sse/mcp-server/tools/` document the required scopes for each operation. The MCP README in [`open-sse/mcp-server/README.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/mcp-server/README.md) contains a comprehensive table mapping every tool to its required scope permissions, allowing you to audit capabilities before granting access.