Skip to main content
Glama
jorisc90

omniroute-mcp-bridge

by jorisc90

omniroute-mcp-bridge

A stdio MCP bridge that DSH spawns as a child process (via the dsh-mcp-client plugin, transport: stdio). It proxies tools/list / tools/call to the omniroute streamable-http MCP server at https://llm.claassen.family/api/mcp/stream and exposes only the allow-listed tools to the model.

Why

  • The upstream streamable-http session dies when idle ("Unknown Mcp-Session-Id" 404). The bridge detects that exact failure, tears down the stale client, re-runs the MCP initialize handshake (fresh session id) and retries — so a dead upstream session no longer breaks a tool call.

  • The dsh-mcp-client plugin has no tool-filtering config. This bridge filters tools/list server-side, so only omniroute_web_search is exposed instead of ~70 tools (saves model context; stable serverName: omniroute is kept, so the public name stays mcp__omniroute__omniroute_web_search).

  • The upstream auth header is passed via child env, not argv — the secret never appears in the process list. It lives only in the 0600 cordis.patch.yml of the web profile.

Related MCP server: mcp-http-bridge

Files

file

purpose

bridge.mjs

stdio MCP server entrypoint (spawned by DSH)

upstream.mjs

injectable upstream accessor with dead-session re-init logic

test-bridge.mjs

standalone live test: full MCP handshake + real search call

test-reinit.mjs

deterministic fake-upstream test of the re-init loop

probe.mjs

dumps raw upstream tool names

probe-ttl2.mjs

measures upstream session idle TTL

SDK resolution

package.json pins @modelcontextprotocol/sdk to the exact version the bridge was developed against. Two ways to get it:

  • Standalone: npm install in this directory.

  • Inside the DSH host (this deployment): node_modules is a symlink to /usr/lib/node_modules/@deepseek-ai/dsh/node_modules, so the bridge always uses the same SDK build DSH's own mcp-client plugin uses. The symlink is gitignored — recreate it after cloning in that environment:

    ln -sfn /usr/lib/node_modules/@deepseek-ai/dsh/node_modules node_modules

Config (env, set in ~/.dsh/profiles/web/cordis.patch.yml)

var

meaning

MCP_BRIDGE_UPSTREAM_URL

streamable-http URL (required)

MCP_BRIDGE_UPSTREAM_HEADERS

JSON object of request headers

MCP_BRIDGE_ALLOWED_TOOLS

comma-separated raw tool names (omit = all)

MCP_BRIDGE_LOG

1 = verbose logging on the child's stderr

Tests

Credentials are not committed. Export them first (values from your patch file):

export MCP_BRIDGE_UPSTREAM_URL='https://llm.claassen.family/api/mcp/stream'
export MCP_BRIDGE_UPSTREAM_HEADERS='{"Authorization":"Bearer …","X-Forwarded-For":"127.0.0.1"}'

Then:

node test-reinit.mjs   # deterministic: dead session -> re-init -> success (no network needed)
node test-bridge.mjs   # live: handshake + filtered list + real search
node probe.mjs         # dump the upstream's raw tool names
node probe-ttl2.mjs    # measure upstream session idle TTL

Change the allow-list

Edit MCP_BRIDGE_ALLOWED_TOOLS in the patch file (comma-separated raw names from node probe.mjs). The include-plugin HMR re-applies the patch on file change; the mcp-client plugin respawns the bridge child.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    This server bridges a stdio MCP server to HTTP, allowing MCP clients that communicate over HTTP to use the server's tools. It includes a per-tool allow/deny filter for security.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A deterministic MCP tool-list relay that lets operators filter tools by include/exclude rules and exposes a filtered stdio MCP server to local clients.
    5 npm
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Lets you run a lightweight stdio MCP server in front of an upstream MCP server, exposing only a configured subset of its tools with compact schemas while keeping the full catalog reachable via discover, describe, and call meta-tools.
    -