Add live web search to any OpenRouter model

Superhighway guides

OpenRouter gives you one API key and one OpenAI-compatible endpoint in front of 300+ models — GPT-4o, Claude, Gemini, Llama, Mistral, DeepSeek, and a whole free tier. What it doesn't give any of those models is access to the live web. Wire in Superhighway and you close that gap once: every model OpenRouter routes to can now search real-time web results. No separate account per provider, no separate search vendor — one setup, any LLM, fresh web content.

Why OpenRouter + Superhighway

OpenRouter handles model routing; Superhighway handles live web search. The division of labour is clean: you keep a single LLM key and a single search key, and you can swap which model answers a query — Claude today, a free Llama tomorrow — without touching the search plumbing. Two paths below: function calling with a free key (one tool, full control, works against every model), or the MCP server (all five tools, less code) for any OpenRouter-powered agent that speaks MCP.

Two paths

PathBest forWhat you need
Function calling + RESTOne tool (web search), explicit control, switch models with one lineA free Superhighway key + an OpenRouter key
MCP serverAll five tools auto-loaded; any MCP-aware agent; optional x402 walletnpx + a free key (or a funded Base wallet)

Get your keys

Grab a free-tier Superhighway key at superhighway.walls.sh (no credit card) and an OpenRouter key at openrouter.ai. Export both:

export OPENROUTER_API_KEY=sk-or-...
export SUPERHIGHWAY_API_KEY=sk_...   # from /pricing

Path 1 — function calling (REST API + free key)

OpenRouter is OpenAI-compatible, so the standard openai Python SDK works — just point its base_url at OpenRouter. Define the web-search tool once in OpenAI's tool schema; every model on OpenRouter understands it.

pip install openai requests
import json
import os
import requests
from openai import OpenAI

# Point the OpenAI SDK at OpenRouter
client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key=os.environ["OPENROUTER_API_KEY"],
)

def web_search(query: str, limit: int = 5) -> dict:
    """Call Superhighway search."""
    resp = requests.get(
        "https://superhighway.walls.sh/search",
        params={"q": query, "limit": limit},
        headers={"Authorization": f"Bearer {os.environ['SUPERHIGHWAY_API_KEY']}"},
    )
    resp.raise_for_status()
    return resp.json()

# Define the tool in OpenAI format — works with ANY OpenRouter model
tools = [{
    "type": "function",
    "function": {
        "name": "web_search",
        "description": "Search the live web for real-time information. "
                       "Returns ranked results with title, URL, and description.",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "The search query"},
                "limit": {"type": "integer", "description": "Max results (default 5)"},
            },
            "required": ["query"],
        },
    },
}]

Now run the standard two-call tool loop: ask the model with tools=[...], run any tool call it returns, append the result as a tool message, and call again so it can answer from live data.

PROMPT = "What are the latest developments in AI agents?"
MODEL = "anthropic/claude-opus-4-8"  # one line away from any other model

messages = [{"role": "user", "content": PROMPT}]
response = client.chat.completions.create(
    model=MODEL,
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

msg = response.choices[0].message
if msg.tool_calls:
    messages.append(msg)  # the assistant turn that requested the tool
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = web_search(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result),
        })
    # Second call: the model reads the results and writes the answer
    final = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
    print(final.choices[0].message.content)
else:
    print(msg.content)

Switch models by changing one line

This is the OpenRouter payoff: the tool definition, the search call, and the loop never change. Only the MODEL string moves — across frontier models, a free-tier Llama, or a cheap DeepSeek — and your web search works against all of them.

MODELS = [
    "anthropic/claude-opus-4-8",
    "openai/gpt-4o",
    "google/gemini-2.0-flash",
    "meta-llama/llama-3.3-70b-instruct:free",  # free tier
    "deepseek/deepseek-chat",
]

for model in MODELS:
    print(f"=== {model} ===")
    # ...run the same tool loop above with MODEL = model...

Pick a frontier model for hard reasoning, a :free model for cheap high-volume runs — the live-web capability rides along regardless.

Path 2 — MCP server (all five tools, less code)

Superhighway also ships an MCP server that exposes all five tools — web_search, news_search, image_search, scrape, and research — in one command. Any OpenRouter-powered agent that speaks MCP (a framework MCP client, Claude Code, Cursor, or a custom loop) can load them with no per-tool schema to write:

npx -y superhighway-mcp

Add it to your MCP client's config and pass the same free key:

{
  "mcpServers": {
    "superhighway": {
      "command": "npx",
      "args": ["-y", "superhighway-mcp"],
      "env": { "SUPERHIGHWAY_API_KEY": "sk_..." }
    }
  }
}

The agent — running on whatever model you've pointed OpenRouter at — now discovers all five tools and picks the right one per turn.

x402 pay-per-call. To let an autonomous agent pay per call with no API key, swap the env for a funded Base wallet:

      "env": { "AGENT_PRIVATE_KEY": "0x...", "X402_NETWORK": "base" }

Each call then settles automatically in USDC on Base — $0.001 a search — via the x402 protocol. No signup, no key, no human in the loop.

Which tools are available

Tool / endpointWhat it returnsPrice
web_search / /searchRanked web results — title, URL, description$0.001
news_search / /newsRecent news with published dates$0.001
image_search / /imagesImage URLs, thumbnails, source pages$0.001
scrape / /scrapeAny URL → clean markdown text$0.002
research / /researchSearch + read top pages in one call$0.005

Full API reference: /openapi.json. Get a free API key or learn the x402 wallet flow.