How to Integrate OmniRoute with Other Systems: A Complete Guide to HTTP API, MCP, and A2A Integration

OmniRoute integrates with external systems through three primary surfaces: an OpenAI-compatible HTTP API for direct client connections, an MCP server with 104 built-in tools for autonomous agents, and an A2A server for agent-to-agent orchestration.

The OmniRoute universal AI gateway (diegosouzapw/OmniRoute) is designed for maximum interoperability. Whether you're connecting IDE plugins, autonomous agents, or multi-service AI pipelines, OmniRoute exposes standardized interfaces that abstract away provider complexity. All integration surfaces share the same core pipeline: authentication, routing, compression, execution, and response translation.

All requests flow through a unified architecture before reaching upstream providers. The combo router in open-sse/services/combo.ts implements 19 routing strategies with millisecond fallback across four tiers (subscription → API-key → cheap → free). The compression pipeline in open-sse/compression/engines/registry.ts can reduce token usage by up to 95% using RTK, Caveman, and LLMLingua-2 engines.

HTTP API Integration: OpenAI-Compatible Endpoints

Quick Start with the REST API

Point any OpenAI-compatible client to http://localhost:20128/v1. The entry point at src/app/api/v1/chat/completions/route.ts accepts standard OpenAI, Anthropic, Gemini, and Responses formats.


# Basic chat completion with curl

curl -X POST http://localhost:20128/v1/chat/completions \
  -H "Authorization: Bearer $OMNIROUTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "auto",
        "messages": [{"role":"user","content":"Write a Node.js hello-world"}]
      }'

Routing Transparency Headers

OmniRoute injects diagnostic headers into every response. These are generated in open-sse/handlers/chat.ts after the combo router completes its selection:

Header Purpose
X-OmniRoute-Decision Selected provider and routing strategy
X-OmniRoute-Compression Compression ratio achieved
X-OmniRoute-Cost Estimated cost in USD

These headers enable downstream observability without parsing response bodies.

Python SDK Integration

import os
import requests

def query_omniroute(messages, model="auto"):
    """Drop-in replacement for OpenAI client."""
    return requests.post(
        "http://localhost:20128/v1/chat/completions",
        headers={
            "Authorization": f"Bearer {os.getenv('OMNIROUTE_API_KEY')}",
            "Content-Type": "application/json"
        },
        json={
            "model": model,
            "messages": messages,
            "temperature": 0.7
        }
    )

# Usage matches standard OpenAI patterns

response = query_omniroute([
    {"role": "system", "content": "You are a helpful assistant"},
    {"role": "user", "content": "Explain quantum computing"}
])

MCP Server Integration: Tool-Based Agent Control

The MCP (Multicall Protocol) server exposes 104 built-in tools for programmatic router management. Located in open-sse/mcp-server/server.ts, it supports three transports: STDIO, SSE, and HTTP.

Starting the MCP Server


# Local agent integration (STDIO)

omniroute --mcp

# Remote agent access (HTTP transport)

omniroute --mcp --http

# Server-Sent Events for streaming

omniroute --mcp --sse

Available Tool Categories

Tools are registered dynamically and include:

  • Routing tools: list_combos, update_combo, set_fallback_chain
  • Cache tools: cache_get, cache_set, cache_invalidate
  • Memory tools: memory_search, memory_store, memory_delete
  • Skill tools: skill_invokd, skill_list, skill_deploy
  • Stats tools: get_metrics, export_logs, run_eval

JSON-RPC Request Format

{
  "jsonrpc": "2.0",
  "method": "list_combos",
  "params": {
    "filter": "active",
    "include_stats": true
  },
  "id": "req-001"
}

The server validates requests against schemas in src/shared/validation/ before dispatching to internal handlers. Full tool reference: docs/frameworks/MCP-SERVER.md.

Python MCP Client Example

import json
import socket

class OmniRouteMCPClient:
    def __init__(self, host="localhost", port=20129):
        self.address = (host, port)
    
    def call(self, method, params=None, msg_id=None):
        sock = socket.create_connection(self.address)
        payload = {
            "jsonrpc": "2.0",
            "method": method,
            "params": params or {},
            "id": msg_id or "auto"
        }
        sock.sendall((json.dumps(payload) + "\n").encode())
        return json.loads(sock.recv(8192).decode())

client = OmniRouteMCPClient()

# Query current routing configuration

combos = client.call("list_combos")
print(f"Active providers: {len(combos['result'])}")

# Trigger a memory search

results = client.call("memory_search", {
    "query": "API authentication patterns",
    "limit": 5
})

A2A Server Integration: Agent-to-Agent Orchestration

The A2A (Agent-to-Agent) server enables higher-level orchestration where AI services call each other asynchronously. The implementation in src/lib/a2a/server.ts provides task-based execution with sandboxed skill isolation.

Starting the A2A Daemon

omniroute a2a start

This binds to /a2a with full JSON-RPC 2.0 compliance.

Task-Based Async Execution

Unlike synchronous MCP calls, A2A operations return task IDs for polling:

{
  "jsonrpc": "2.0",
  "method": "memory_search",
  "params": {
    "query": "latest pricing info",
    "priority": "high"
  },
  "id": "task-42"
}

Response:

{
  "jsonrpc": "2.0",
  "result": {
    "task_id": "a2a-7f3d-9e2a",
    "status": "queued",
    "estimated_completion": "2s"
  },
  "id": "task-42"
}

Poll for completion via tasks/get_status or subscribe to webhooks.

Skill Engine Sandboxing

A2A skills run in isolated contexts defined in src/lib/a2a/skills/. Built-in skills include:

  • memory_search / memory_store: Semantic search across conversation history
  • code_execute: Sandboxed code execution with resource limits
  • web_fetch: Cached HTTP retrieval with content extraction
  • eval_runner: Automated benchmark execution

Custom skills follow the interface defined in src/shared/types/a2a.ts.

Remote Mode: CLI-to-VPS Deployment

For production deployments, Remote Mode lets you run OmniRoute on a VPS while maintaining local CLI ergonomics.

Server Setup


# On remote VPS

omniroute token create --name "laptop-dev" --scope "admin"

# Returns: or-live-xxxxxxxx

Local Configuration

omniroute remote connect \
  --url https://router.internal.company.com \
  --token $REMOTE_TOKEN \
  --set-default

# All subsequent commands target remote instance

omniroute providers list
omniroute combos status

The CLI entry point in src/cli/index.ts handles command forwarding transparently. Local caching of remote state reduces latency for read-heavy operations.

Core Pipeline: How Integration Surfaces Connect

Understanding the shared architecture helps debug integration issues:

Stage File Responsibility
HTTP/MCP/A2A ingress src/app/api/v1/*/route.ts, open-sse/mcp-server/server.ts, src/lib/a2a/server.ts Protocol parsing, auth extraction
Handler core open-sse/handlers/chat.ts Rate limiting, request validation
Combo router open-sse/services/combo.ts Provider selection, fallback logic
Executor open-sse/executors/default.ts HTTP building, retry policies
Provider registry src/shared/constants/providers.ts Provider metadata, model lists

Provider Execution Flow

The executor in open-sse/executors/default.ts constructs provider-specific requests:

  1. Map OmniRoute model names to provider-native names
  2. Apply authentication (header injection or signature generation)
  3. Transform request body format (OpenAI ↔ Anthropic ↔ Gemini)
  4. Execute with exponential backoff
  5. Translate response to canonical format

Production Integration Patterns

Pattern 1: IDE Plugin Backend


# VS Code extension configuration

omniroute:
  endpoint: http://localhost:20128/v1
  model: auto
  features:
    - inline_completion
    - chat_panel
    - code_explanation

The plugin sends standard OpenAI requests; OmniRoute handles provider rotation and compression transparently.

Pattern 2: CI/CD Pipeline Agent


# GitHub Actions workflow

- name: Generate Release Notes
  run: |
    curl -s http://omniroute:20128/v1/chat/completions \
      -H "Authorization: Bearer ${{ secrets.OMNIROUTE_KEY }}" \
      -d '{"model":"auto","messages":[{"role":"user","content":"Summarize commits since last tag"}]}' \
      | jq -r '.choices[0].message.content' >> RELEASE_NOTES.md

Pattern 3: Multi-Agent System


┌─────────────┐     A2A      ┌─────────────┐     MCP      ┌─────────────┐
│  Planner    │ ───────────→ │  OmniRoute  │ ←──────────→ │  Skills DB  │
│   Agent     │  async tasks │   Gateway   │  tool calls  │  (vector)   │
└─────────────┘              └─────────────┘              └─────────────┘
       ↓                           ↓
┌─────────────┐              ┌─────────────┐
│   Memory    │              │  Provider   │
│   Service   │              │   Pool      │
└─────────────┘              └─────────────┘

The planner uses A2A for long-running tasks, while OmniRoute's MCP tools manage provider health and routing optimization.

Complete Multi-Surface Example

#!/bin/bash

# startup.sh - Full OmniRoute deployment

# Start main gateway (HTTP API)

omniroute start --port 20128 &

# Start MCP server for automation

omniroute --mcp --http --port 20129 &

# Start A2A server for agent coordination

omniroute a2a start --port 20130 &

wait
#!/usr/bin/env python3

# client_demo.py - Using all three surfaces

import os
import json
import socket
import requests

OMNI_HTTP = "http://localhost:20128"
OMNI_MCP = ("localhost", 20129)

# 1. HTTP API: Standard completion

def chat_completion(messages):
    return requests.post(
        f"{OMNI_HTTP}/v1/chat/completions",
        headers={"Authorization": f"Bearer {os.getenv('OMNIROUTE_API_KEY')}"},
        json={"model": "auto", "messages": messages}
    ).json()

# 2. MCP: Get routing diagnostics

def get_combo_stats():
    sock = socket.create_connection(OMNI_MCP)
    req = json.dumps({
        "jsonrpc": "2.0",
        "method": "get_metrics",
        "params": {"timespan": "1h"},
        "id": "demo-1"
    }) + "\n"
    sock.sendall(req.encode())
    return json.loads(sock.recv(4096).decode())

if __name__ == "__main__":
    # Use HTTP for normal operations

    result = chat_completion([
        {"role": "user", "content": "What providers are available?"}
    ])
    print(f"Response from: {result.get('provider', 'unknown')}")
    
    # Use MCP for operational insight

    stats = get_combo_stats()
    print(f"Success rate: {stats['result']['success_rate']:.1%}")

Summary

  • HTTP API (/v1/*) provides drop-in OpenAI compatibility with automatic routing and compression—ideal for existing clients and SDKs.
  • MCP server exposes 104 tools for programmatic control of routing, caching, memory, and skills—designed for autonomous agents.
  • A2A server (/a2a) enables async, task-based agent orchestration with sandboxed skill execution.
  • Remote Mode maintains local CLI experience while running OmniRoute on production infrastructure.
  • All surfaces share the pipeline in open-sse/handlers/chat.ts, open-sse/services/combo.ts, and open-sse/executors/default.ts.

Frequently Asked Questions

What authentication methods does OmniRoute support for external integrations?

OmniRoute uses Bearer token authentication for all integration surfaces. Generate tokens via omniroute token create with configurable scopes. The validation logic in open-sse/handlers/chat.ts checks tokens against the configured secret before routing requests. For production, set OMNIROUTE_API_KEY as an environment variable and rotate tokens regularly.

Can I use OmniRoute as a drop-in replacement for the OpenAI API?

Yes. OmniRoute's /v1/chat/completions endpoint in src/app/api/v1/chat/completions/route.ts accepts identical request bodies. Change only the base URL and authorization header. Response formats match OpenAI's schema, including streaming (stream: true) support. The model parameter accepts "auto" for dynamic routing or specific provider-prefixed names like "openai:gpt-4o".

How does the MCP server differ from the A2A server?

MCP operates synchronously with immediate JSON-RPC responses, designed for direct tool invocation by agents that need real-time results. A2A operates asynchronously with task IDs and polling, designed for multi-step workflows where agents delegate work and continue processing. MCP tools control the router itself; A2A skills execute user-defined operations in sandboxes. Both are implemented in open-sse/mcp-server/server.ts and src/lib/a2a/server.ts respectively.

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 →