Add live web search to a Composio agent
Composio gives AI agents a unified tool layer — 250+ pre-built integrations (GitHub, Slack, Gmail, Notion…) in one standardized format, plus managed auth, all usable from whatever framework you run (OpenAI, LangChain, CrewAI, Claude, AutoGen, LangGraph). What Composio's catalog can't do is search the live web. This guide registers Superhighway as a Composio custom tool so your agent gets real-time web search, news, image search, page reading, and one-call research sitting right alongside GitHub and Slack in the same toolset.
How this fits together
Superhighway is a plain JSON REST API. Composio's custom-tool API wraps any function — including one that calls an external HTTP API — into a tool the agent's model can invoke. So you write a small Python function that hits https://superhighway.walls.sh/search, decorate it, register it on a Composio session, and hand the resulting tools to your LLM. From the model's point of view it's indistinguishable from any of Composio's managed integrations.
A note on MCP: Composio's MCP feature runs one direction — it exposes Composio's own tools as an MCP server for clients like Cursor; it does not consume external stdio MCP servers. So the native way to bring Superhighway into Composio is the custom tool below. (If you'd rather load all five Superhighway tools over MCP directly — no Composio in the loop — point any MCP client at npx -y superhighway-mcp; see the MCP guide.)
Get a free API key
Create a free-tier key at superhighway.walls.sh — email only, no card. Export it next to your model provider key:
export SUPERHIGHWAY_API_KEY=sk_... # from /pricing
export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY, etc.
export COMPOSIO_API_KEY=... # from app.composio.dev
1. Install
Install the Composio core SDK plus the provider package for whichever framework you use. For OpenAI Chat Completions:
pip install composio composio_openai openai requests
Swap the provider package for your stack: composio_langchain, composio_crewai, composio_gemini, composio_autogen, composio_langgraph — same custom-tool code, different provider.
2. Register Superhighway as a custom tool
A Composio custom tool is a decorated function whose first argument is a Pydantic model (its fields become the input schema the model sees) and whose docstring becomes the tool description. Inside the function you're free to make a normal HTTP request — Superhighway authenticates with a bearer token, so no Composio-managed auth is needed.
import os, requests
from pydantic import BaseModel, Field
from composio import Composio
from composio_openai import OpenAIProvider
composio = Composio(provider=OpenAIProvider())
class WebSearchInput(BaseModel):
query: str = Field(description="The search query")
limit: int = Field(default=5, description="Max results to return")
@composio.experimental.tool()
def superhighway_web_search(input: WebSearchInput, ctx):
"""Search the live web for current, real-time information.
Returns ranked results with title, URL, and description."""
resp = requests.get(
"https://superhighway.walls.sh/search",
params={"q": input.query, "limit": input.limit},
headers={"Authorization": f"Bearer {os.environ['SUPERHIGHWAY_API_KEY']}"},
)
resp.raise_for_status()
return resp.json()
The function name becomes the tool slug, prefixed by Composio (e.g. LOCAL_SUPERHIGHWAY_WEB_SEARCH). That's it — Superhighway is now a Composio tool.
3. Give the tool to your agent
Register the custom tool when you create the session, fetch the tools in the provider's format, and run the standard tool loop. This example uses the OpenAI provider; the only Composio-specific lines are the session and handle_tool_calls.
import json
from openai import OpenAI
client = OpenAI()
session = composio.create(
user_id="default",
experimental={"custom_tools": [superhighway_web_search]},
)
tools = session.tools() # OpenAI-format tool schemas, incl. our custom tool
messages = [{"role": "user",
"content": "What are the newest open-source AI agent frameworks this month?"}]
response = client.chat.completions.create(
model="gpt-4o", tools=tools, messages=messages,
)
# Agentic loop: execute tool calls until the model answers in text
while response.choices[0].message.tool_calls:
results = composio.provider.handle_tool_calls(response=response, user_id="default")
messages.append(response.choices[0].message)
for i, tc in enumerate(response.choices[0].message.tool_calls):
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": json.dumps(results[i]),
})
response = client.chat.completions.create(
model="gpt-4o", tools=tools, messages=messages,
)
print(response.choices[0].message.content)
The model decides when the question needs live data, calls superhighway_web_search, Composio runs your function, and the fresh results flow back into the answer. Because Superhighway lives in the same session as Composio's managed tools, the same agent can search the web and open a GitHub issue or send a Slack message in one run.
4. All five tools (web, news, images, scrape, research)
Register one custom tool per Superhighway endpoint and the model picks the right one per turn. Same pattern — each is a decorated function calling a different path:
def _get(path, params):
r = requests.get(
f"https://superhighway.walls.sh{path}", params=params,
headers={"Authorization": f"Bearer {os.environ['SUPERHIGHWAY_API_KEY']}"},
)
r.raise_for_status()
return r.json()
class Query(BaseModel):
query: str = Field(description="The search query")
limit: int = Field(default=5, description="Max results")
class Url(BaseModel):
url: str = Field(description="The page URL to read")
@composio.experimental.tool()
def superhighway_news_search(input: Query, ctx):
"""Search recent news with published dates."""
return _get("/news", {"q": input.query, "limit": input.limit})
@composio.experimental.tool()
def superhighway_image_search(input: Query, ctx):
"""Search for images — direct URLs, thumbnails, source pages."""
return _get("/images", {"q": input.query, "limit": input.limit})
@composio.experimental.tool()
def superhighway_scrape_page(input: Url, ctx):
"""Read any web page as clean markdown text."""
return _get("/scrape", {"url": input.url})
@composio.experimental.tool()
def superhighway_research(input: Query, ctx):
"""Search the web AND read the top pages in one call."""
return _get("/research", {"q": input.query})
session = composio.create(
user_id="default",
experimental={"custom_tools": [
superhighway_web_search, superhighway_news_search,
superhighway_image_search, superhighway_scrape_page,
superhighway_research,
]},
)
tools = session.tools()
Any framework Composio supports
The custom-tool definitions above are framework-agnostic. To target a different stack, change only the provider you pass to Composio(...) and consume session.tools() the way that framework expects:
| Framework | Provider package |
|---|---|
| OpenAI / OpenAI Agents | composio_openai |
| LangChain / LangGraph | composio_langchain / composio_langgraph |
| CrewAI | composio_crewai |
| Claude (Anthropic) | composio_anthropic |
| Gemini | composio_gemini |
| AutoGen | composio_autogen |
On Anthropic, the tools are Claude tool-use schemas; on LangChain they're StructuredTool objects you drop into an agent — Composio handles the translation. The Superhighway function never changes.
Legacy SDK (ComposioToolSet / @action)
If you're on the older composio-core 0.x line, the equivalent is the @action decorator plus ComposioToolSet:
from composio import action, ComposioToolSet
@action(toolname="superhighway", requires=["requests"])
def web_search(query: str, limit: int = 5) -> dict:
"""Search the live web for real-time information."""
import os, requests
return requests.get(
"https://superhighway.walls.sh/search", params={"q": query, "limit": limit},
headers={"Authorization": f"Bearer {os.environ['SUPERHIGHWAY_API_KEY']}"},
).json()
toolset = ComposioToolSet()
tools = toolset.get_tools(actions=[web_search])
New projects should prefer the v3 SDK shown above.
Which tools are available
| Tool / endpoint | What it returns | Price |
|---|---|---|
web_search / /search | Ranked web results — title, URL, description | $0.001 |
news_search / /news | Recent news with published dates | $0.001 |
image_search / /images | Image URLs, thumbnails, source pages | $0.001 |
scrape_page / /scrape | Any URL → clean markdown text | $0.002 |
research / /research | Search + read top pages in one call | $0.005 |
Prefer pay-per-call with no API key? Superhighway also speaks x402 — settle each call in USDC on Base from inside the same custom-tool function. Full API reference: /openapi.json. Get a free API key.