Skip to the page

Claude Agent SDK

Give an agent built with the Claude Agent SDK the SpecStream tools. It searches the web, reads pages, and asks for live web data in plain words, on your SpecStream account, with paid runs approved in your own code.

SpecStream for Claude Agent SDKAgent frameworks & builders

What you need

  • Python 3.10 or newer and the Claude Agent SDK.
  • A SpecStream account. New accounts get $10 of credit on sign-up, no card.
  • A SpecStream API key with a spending limit. The SDK runs no sign-in flow of its own, so the key goes in a header.
  1. 1. Install the SDK

    Install the package. It brings the Claude Code CLI with it, so there is nothing else to install.

    Terminal
    pip install claude-agent-sdk
  2. 2. Create an API key

    In your SpecStream workspace, open Agents & API, choose API keys, then Create API key. Give it only the projects, operations, and spending limit the agent needs.

    Keep it in an environment variable where the agent runs:

    Terminal
    export SPECSTREAM_API_KEY="YOUR_SPECSTREAM_API_KEY"
  3. 3. Connect SpecStream

    Add SpecStream to mcp_servers in ClaudeAgentOptions with "type": "http", the address https://api.specstream.ai/mcp, and the key as a Bearer header. Its tools take the names mcp__specstream__<tool>, and a tool runs without a prompt only when allowed_tools lists it.

    disallowed_tools takes the built-in WebSearch and WebFetch out of Claude's toolset, so every search and page read goes through SpecStream. The agent can search, read, and price a request, and paid work waits for the last step.

    agent.py
    import asyncio
    import os
    from claude_agent_sdk import ClaudeAgentOptions, ResultMessage, SystemMessage, query
    options = ClaudeAgentOptions(
    mcp_servers={
    "specstream": {
    "type": "http",
    "url": "https://api.specstream.ai/mcp",
    "headers": {"Authorization": f"Bearer {os.environ['SPECSTREAM_API_KEY']}"},
    }
    },
    allowed_tools=[
    "mcp__specstream__search_web",
    "mcp__specstream__read_pages",
    "mcp__specstream__compile",
    "mcp__specstream__quote_capacity_work",
    "mcp__specstream__get_find",
    "mcp__specstream__list_find_rows",
    ],
    disallowed_tools=["WebSearch", "WebFetch"],
    )
    async def main():
    async for message in query(prompt="Who maintains the Python requests library today? Give the source pages.", options=options):
    if isinstance(message, SystemMessage) and message.subtype == "init":
    print("MCP servers:", message.data.get("mcp_servers"))
    if isinstance(message, ResultMessage) and message.subtype == "success":
    print(message.result)
    asyncio.run(main())
  4. 4. Ask for the data

    Run the agent with a question for a quick answer, or with a request for many records that names the details to bring back on each one. For example:

    Request
    Find EV charging companies in Germany that raised a funding round in 2026, with the amount, the lead investor, and the source.
  5. 5. Approve paid runs in your code

    authorize_capacity_work is the one call that starts paid work, and it is left out of allowed_tools on purpose. Pass a can_use_tool callback to ClaudeSDKClient and allow the call only when confirm_max_cents is within the limit you set. This example also refuses every other tool that is not on the list.

    approve.py
    import asyncio
    import os
    from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient, ResultMessage
    from claude_agent_sdk.types import PermissionResultAllow, PermissionResultDeny
    MAX_CENTS = 500 # the most one run may cost: $5
    async def approve(tool_name, input_data, context):
    if tool_name == "mcp__specstream__authorize_capacity_work":
    if input_data.get("confirm_max_cents", MAX_CENTS + 1) <= MAX_CENTS:
    return PermissionResultAllow(updated_input=input_data)
    return PermissionResultDeny(message="The quote is over the approved maximum.")
    return PermissionResultDeny(message="This agent does not use that tool.")
    options = ClaudeAgentOptions(
    mcp_servers={
    "specstream": {
    "type": "http",
    "url": "https://api.specstream.ai/mcp",
    "headers": {"Authorization": f"Bearer {os.environ['SPECSTREAM_API_KEY']}"},
    }
    },
    allowed_tools=[
    "mcp__specstream__search_web",
    "mcp__specstream__read_pages",
    "mcp__specstream__compile",
    "mcp__specstream__quote_capacity_work",
    "mcp__specstream__get_find",
    "mcp__specstream__list_find_rows",
    ],
    disallowed_tools=["WebSearch", "WebFetch"],
    can_use_tool=approve,
    )
    async def main():
    async with ClaudeSDKClient(options=options) as client:
    await client.query("Find EV charging companies in Germany that raised a funding round in 2026, with the amount, the lead investor, and the source.")
    async for message in client.receive_response():
    if isinstance(message, ResultMessage):
    print(message.result)
    asyncio.run(main())

Check the connection

The first SystemMessage with subtype init lists each server in mcp_servers with its status. connected means the key works. needs-auth or failed means the key is missing or wrong, so check SPECSTREAM_API_KEY. A run goes on without a server that did not connect, so check the status before you trust the answer.

What the agent calls

The tools the agent uses most, in the order a request moves through them:

  • search_web answers a question from the live web, at $5 per 1,000 searches of up to 10 results.
  • read_pages returns the main text of up to 20 pages, at $0.80 per 1,000 pages. A page with no text is not charged.
  • compile reads a request for many records back as editable parts, and quote_capacity_work prices it. Both cost nothing.
  • authorize_capacity_work starts the run with the approved maximum in confirm_max_cents. get_find follows progress, and list_find_rows reads the rows, with the source URL and read time on every value.

Cost

Searches and page reads come out of your balance with no quote. Each row of a run costs 5¢, 15¢ or $1, depending on how much the row needs, plus 5¢ for a person's email and 15¢ for a phone, and never more than the maximum you approved. A quote lasts 30 minutes, and a run that finds nothing costs nothing. How quotes and billing work

Spending limits

The key's own limits hold on every call: total, per run, monthly, and the operations it allows. A search over a limit stops with 402 or 403, and nothing is charged for it.

TypeScript

The TypeScript SDK, @anthropic-ai/claude-agent-sdk, takes the same server in mcpServers with type: "http", and the same tool names in allowedTools and disallowedTools. Its canUseTool option takes the approval callback.

Remove

Take the specstream entry out of mcp_servers and its names out of allowed_tools. To stop the key working everywhere, revoke it in Agents & API. Results already delivered stay in your workspace. Other ways to build with SpecStream are in agent frameworks, and the agent guide covers every tool. Questions go to [email protected].

More

SpecStream for Claude Agent SDK covers what it does in Claude Agent SDK on one page. Every other tool has its guide in Connect your tools. You see the most a request can cost before it starts, and the matches are paid from your balance. Billing has the details. For help, email [email protected].