Skip to content
unlob

Anthropic · Python and TypeScript

Build a research agent with Claude Agent SDK

Build a research agent on the Claude Agent SDK, adding unlob as an MCP server alongside the SDK’s built-in file and shell tools.

What you are building

Your process

query()

The Claude Code harness, as a library

Tools available

Built in

Read, Write, Bash, Grep, Glob

unlob over MCP

11 tools, no wrappers written

Services

Anthropic API

claude-opus-5

unlob

stdio JSON-RPC

Your side of the API. unlob is one HTTPS service among the others — nothing here is specific to how our index works, so this agent survives a change of framework.

Install

Dependenciesbash
pip install claude-agent-sdk

Already have Claude Agent SDK wired up? TheClaude Agent SDK integration pagehas the connection config on its own — this page assumes you have it and gets on with building.

Step by step

  1. Understand what you are installing

    The Claude Agent SDK is a different product from the Tool Runner in the `anthropic` package. The SDK ships built-in tools and the Claude Code harness; the Tool Runner is a helper that loops over tools you define. Both are Anthropic, both are current, and they are frequently confused.

  2. Register unlob as an MCP server

    The Agent SDK speaks MCP natively, so the eleven unlob tools arrive without writing a single wrapper function. This is the shortest path from nothing to an agent that can search the web.

    agent.pypython
    import os
    from claude_agent_sdk import query, ClaudeAgentOptions
    
    options = ClaudeAgentOptions(
        model="claude-opus-5",
        system_prompt=(
            "You are a research assistant. Search before you answer. Prefer claims "
            "carried by several independent sources and say so when one is alone. "
            "Always cite URLs."
        ),
        mcp_servers={
            "unlob": {
                "command": "npx",
                "args": ["-y", "@unlob/mcp"],
                "env": {"UNLOB_API_KEY": os.environ["UNLOB_API_KEY"]},
            }
        },
        # Least privilege: the web tools plus reading, and nothing that writes.
        allowed_tools=[
            "mcp__unlob__web_search",
            "mcp__unlob__assemble_context",
            "mcp__unlob__corroborate",
            "Read",
        ],
    )
  3. Run the query

    query() is an async generator over the agent’s messages. The loop, the tool execution and the context management all happen inside it.

    run.pypython
    import asyncio
    
    async def main():
        async for message in query(
            prompt="What changed in the EU AI Act GPAI rules in 2026? Cite sources.",
            options=options,
        ):
            print(message)
    
    asyncio.run(main())

What happens when it runs

YouAgent SDKClaudeunlob MCPquery(prompt, options)tools/list11 tool schemasprompt + toolstool_use: assemble_contexttools/callpacked passagesstreamed messages
One turn of the loop. Search returns metadata only, so the agent spends a few hundred tokens deciding rather than tens of thousands reading.

The whole thing

Complete and runnable. Set the two environment variables and it works.

research_agent.py — completepython
"""A research agent on the Claude Agent SDK, backed by the unlob web index.

    pip install claude-agent-sdk
    export UNLOB_API_KEY=ulb_...
    export ANTHROPIC_API_KEY=sk-ant-...

Note: this is the Claude Agent SDK (`claude-agent-sdk`), which is Claude Code
as a library. It is NOT the Tool Runner in the `anthropic` package — that is a
different tool for a different job.
"""
import asyncio
import os

from claude_agent_sdk import query, ClaudeAgentOptions

options = ClaudeAgentOptions(
    model="claude-opus-5",
    system_prompt=(
        "You are a research assistant. Search before you answer. Prefer claims "
        "carried by several independent sources and say so when one is alone. "
        "Always cite URLs."
    ),
    mcp_servers={
        "unlob": {
            "command": "npx",
            "args": ["-y", "@unlob/mcp"],
            "env": {"UNLOB_API_KEY": os.environ["UNLOB_API_KEY"]},
        }
    },
    allowed_tools=[
        "mcp__unlob__web_search",
        "mcp__unlob__assemble_context",
        "mcp__unlob__corroborate",
        "Read",
    ],
)


async def main() -> None:
    prompt = "What changed in the EU AI Act GPAI rules in 2026? Cite sources."
    async for message in query(prompt=prompt, options=options):
        print(message)


if __name__ == "__main__":
    asyncio.run(main())

What will go wrong

The failures that cost an afternoon rather than a minute, because they produce something that looks like it is working.

Where this agent can go next

Every result the agent receives is a node in the coverage graph. These are the tools you can add to it without leaving Claude Agent SDK — each is one more entry in the same tools list.

relatedNear-duplicatescorroborateIndependent sourcesauthoritiesAuthoritative hostsdossierThe entity briefpathA second documentassemble_contextA packed context setA search resultwhat your agent has
The two marked in blue are the tools this tutorial wires up. The other four are the same shape.

Frequently asked questions

Is this the same as the Tool Runner?

No, and it is the most common confusion in this area. The Claude Agent SDK (`claude-agent-sdk` / `@anthropic-ai/claude-agent-sdk`) is Claude Code as a library, with built-in file and shell tools and the full harness. The Tool Runner (`client.beta.messages.tool_runner`) lives in the regular `anthropic` SDK and automates the loop over tools you write yourself. Different packages, different jobs.

Do I need to write tool wrappers for unlob?

No. The Agent SDK speaks MCP, and unlob ships an MCP server, so all eleven tools are available once you declare the server. That is the main reason this is the shortest tutorial on the site.

Can I use it from TypeScript?

Yes — `@anthropic-ai/claude-agent-sdk` is the same product with the same options. The MCP server block is identical.

You need a key to run this

10,000 requests a month on the free tier, no card. Enough to build the agent and put a real evaluation set through it.