⚡ New — Kimi K3 is live: bring your own Moonshot key →
Documentation

Agents

An agent is just a chat-completions loop that calls tools. BharatRouter gives that loop a single, governed endpoint — so your routing rules, India residencyand per-key budgets apply to every step an autonomous agent takes, not just the first. There are two ways in.

ApproachUse when
Point the agent's model client at the gatewayYou control the agent code (LangChain, your own loop, an SDK) — just swap the base URL.
Connect over MCPThe agent host speaks MCP (Claude Code, Cursor, …) — no code change, declare the server.

The tool-calling loop

Standard OpenAI tools / tool_calls — the only change is the base URL, plus data_policy pinned so the agent can't leak data offshore mid-run.

import json
from openai import OpenAI

client = OpenAI(base_url="https://api.bharatrouter.com/v1", api_key="br-...")

tools = [{
    "type": "function",
    "function": {
        "name": "get_pincode_city",
        "description": "Return the city for an Indian PIN code",
        "parameters": {
            "type": "object",
            "properties": {"pincode": {"type": "string"}},
            "required": ["pincode"],
        },
    },
}]

def get_pincode_city(pincode): return {"560095": "Bengaluru"}.get(pincode, "Unknown")

messages = [{"role": "user", "content": "Which city is PIN 560095?"}]

while True:
    r = client.chat.completions.create(
        model="gemma-4-e4b-it",
        messages=messages,
        tools=tools,
        extra_body={"data_policy": "india_only"},   # residency on every step
    )
    msg = r.choices[0].message
    messages.append(msg)
    if not msg.tool_calls:
        print(msg.content)
        break
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = get_pincode_city(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result),
        })

Connect over MCP

BharatRouter ships an MCP server over streamable HTTP with bearer auth, so an MCP host can discover and call the gateway with no code. Add it to Claude Code:

claude mcp add --transport http bharatrouter \
  https://api.bharatrouter.com/mcp \
  --header "Authorization: Bearer br-..."

Or declare it in a project .mcp.json:

{
  "mcpServers": {
    "bharatrouter": {
      "type": "http",
      "url": "https://api.bharatrouter.com/mcp",
      "headers": { "Authorization": "Bearer br-..." }
    }
  }
}

Discover the server programmatically from its card:

curl -s https://api.bharatrouter.com/.well-known/mcp/server-card.json

Full details — tools exposed, auth, streaming — on the MCP for agents page.

Residency for agents

An autonomous agent can fire dozens of calls you never see. Pin data_policy: "india_only"on each call (or as the key's default) so every step stays on India-resident routes andfails closed rather than leaking. Cap spend with a per-key monthly ₹ budget so a runaway loop can't drain credit — see API keys & limits.

Recipe: wire Claude Code to the gateway. Building a plain app instead? See Client SDKs.