← All guides

Locus product guide · Updated

Pydantic AI MCP tools: MCPToolset with a spend cap

Pydantic AI uses MCP servers as toolsets. Create an MCPToolset with the Locus Pro URL https://api.paywithlocus.com/api/credits/mcp and auth set to an agent key, then pass it to Agent(toolsets=[...]). A process_tool_call hook can force a max_credits ceiling onto every paid call. A Hunter email lookup through Locus Pro costs 1 to 10.1 credits, at most about $0.01.

Setup, step by step

  1. Step 1

    Create an agent key

    In the Locus Pro dashboard, open Connect, then API keys, then An agent. Choose the tools, a credit cap per call and an expiry. Store the lcac_ key in your secret manager.

    export LOCUS_AGENT_CONNECTION="lcac_..."   # agent key, from your secret store
    export LOCUS_MCP_URL="https://api.paywithlocus.com/api/credits/mcp"
  2. Step 2

    Install Pydantic AI with MCP support

    Install pydantic-ai, or pydantic-ai-slim with the mcp group. The mcp group installs FastMCP 4, which is built on httpx2, so build any custom auth or HTTP client objects with httpx2.

    pip install "pydantic-ai-slim[mcp]"
  3. Step 3

    Connect with a price ceiling on every paid call

    auth takes a bearer token string. process_tool_call runs before each call, so it can rewrite execute arguments. Here it caps max_credits at 15 whatever the model asked for. tool_error_behavior="failed" records a refused call as a failed result instead of asking the model to retry.

    import os
    from typing import Any
    
    from pydantic_ai import Agent, RunContext
    from pydantic_ai.mcp import CallToolFunc, MCPToolset, ToolResult
    
    CAP = 15  # credits
    
    async def cap_paid_calls(
        ctx: RunContext[None], call_tool: CallToolFunc, name: str, tool_args: dict[str, Any]
    ) -> ToolResult:
        if name == "execute":
            asked = float(tool_args.get("max_credits") or CAP)
            tool_args = {**tool_args, "max_credits": min(asked, CAP)}
        return await call_tool(name, tool_args)
    
    locus = MCPToolset(
        os.environ["LOCUS_MCP_URL"],
        auth=os.environ["LOCUS_AGENT_CONNECTION"],
        process_tool_call=cap_paid_calls,
        tool_error_behavior="failed",
    )
    agent = Agent("openai:gpt-6.1-sol", toolsets=[locus])
  4. Step 4

    Run a first paid call

    Use any model string your Pydantic AI setup supports in place of the one shown. The execute result reports credits_charged and credits_balance.

    result = await agent.run(
        "Find the work email for Tim Cook at apple.com with hunter/email-finder and report the credits charged."
    )
    print(result.output)
  5. Step 5

    Check the balance for free

    get_balance and catalog searches cost nothing, so a balance check is a safe way to prove the connection before any paid call.

    result = await agent.run("What is my Locus balance?")

MCPToolset or the MCP capability: which should I use?

Pydantic AI recommends the MCP capability for most cases. It takes a URL, runs the connection in your process by default and can switch to the model provider’s native MCP support with native=True. With native MCP, the provider calls Locus, so your key goes to the provider.

Use MCPToolset when you want the process_tool_call hook, a shared toolset across agents, or direct control of the client. This guide uses it because the hook is the cleanest way to force a ceiling on paid calls.

MCPToolset or the MCP capability: which should I use?
OptionWhere the connection runsWho sees your keyBest for
MCPToolsetYour processLocus onlyHooks, shared toolsets, custom clients
MCP('url')Your process by defaultLocus, unless native is onMost agents, per-run credentials
MCP('url', native=True)The model provider, where supportedThe provider and LocusLetting the provider run the tool calls

How do I force a price ceiling on every paid call?

The max_credits argument on execute is written by the model, so a model can raise it. The process_tool_call hook above sits between the model and the server and rewrites the argument before the call leaves your process. A call priced above the ceiling fails with nothing charged.

Keep the agent key’s per-call cap as well. Locus enforces it on its side, so it still holds if the hook has a bug. A call over that cap fails with agent_connection_call_limit_exceeded.

Should a refused Locus call retry, fail or raise?

tool_error_behavior sets one behavior for every server-reported error on a toolset. retry is the default and sends the error back to the model as a retry. failed records a tool result with outcome failed and lets the model decide. error raises the MCP exception and ends the run.

For paid calls, retry invites the model to resend with a higher ceiling or the same arguments. failed suits paid tools better: the model sees the refusal once and decides what to tell the user. Structured error content reaches the model as JSON, so Locus hints such as retryAfter stay readable.

Should a refused Locus call retry, fail or raise?
Locus errorMeaningWhat to do
charge_ceiling_exceededPrice above max_credits; nothing chargedLet the model report it, which failed allows
tenant_rate_limitedPlan limit hit: 5 paid calls a minute on Free, 15 on PlusWait retryAfter seconds, then resend
Insufficient creditsBalance below the priceStop and add credits from your code
credential_endpoint_deniedEndpoint not on the key’s listAdd the endpoint to the agent key

How do I give each user of my app their own Locus credential?

Pass a function as auth. Pydantic AI calls it with the run context at the start of each run, so it can read a per-user key from the run’s dependencies. Each run then opens its own MCP session, so users never share one.

Do not share one MCPToolset with a fixed auth across concurrent runs for different users. On the Enterprise plan, create an agent key per customer and bill each customer from their own balance at base price plus your markup.

What does lead enrichment cost through Locus Pro?

Prices come from the Locus catalog; 1,000 credits equal $1. Prices checked November 10, 2026.

Enriching 500 leads with 1 email lookup and 1 company lookup each costs at most 500 x 10.1 + 500 x 10.1 = 10,100 credits, about $10.10. With the 15-credit cap from the hook, no single call can cost more than $0.015.

What does lead enrichment cost through Locus Pro?
EndpointLocus priceReturns
hunter/email-finder1 to 10.1 credits, by requestThe likely email for a name and domain
hunter/company-enrichment10.1 credits ($0.0101)Company data from a domain
hunter/combined-enrichment20.2 credits ($0.0202)Person and company data together
apollo/people-search2 credits ($0.00202)People by title and company

When does Locus Pro make sense for a Pydantic AI agent?

It makes sense when the agent calls several paid providers and you want one key, one balance and a hard ceiling per call. It also fits uneven workloads, since purchased credits do not expire and there is no plan minimum.

It is the wrong choice when one provider covers the job at steady volume, since that provider can cost less per call with your own account and API key. For logic in your own code, a plain Pydantic AI function tool is simpler.

Frequently asked questions

Can I load the Locus server from an mcp_config.json file?

Yes. load_mcp_toolsets reads url and headers for HTTP servers and expands ${VAR} references, so the Authorization header can read the key from the environment. You lose the per-toolset hook unless you build that toolset in code.

Do Locus tools get a name prefix in Pydantic AI?

Not by default. Wrap the toolset with prefixed, for example prefixed with locus, to get names like locus_execute when another server also has an execute tool.

Does Pydantic AI need FastMCP for MCP?

Yes. MCPToolset wraps the FastMCP client and supports FastMCP 3 and 4. The mcp install group pulls in FastMCP 4.

Implementation references

Use these first-party references for current request contracts and account requirements. Tool availability, prices, and negotiated terms can change.

Sources

Third-party details were checked on November 10, 2026. Vendors change pricing and features often, so confirm on their site before you decide.

Related guides