Hightower's AI Harness Engineering

Hightower's AI Harness Engineering

Claude Managed Agents VI: Your Agent Lives in a Box. MCP Is How It Reaches Your Billing System.

Part 6: Custom tools make the agent ask your code for data; MCP lets it call your real services directly, and the interesting part is what happens when one of those services goes down.

Rick Hightower's avatar
Rick Hightower
Aug 04, 2026
∙ Paid

Your Agent Lives in a Box. MCP Is How It Reaches Your Billing System.

Custom tools make the agent ask your code for data; MCP lets it call your real services directly, and the interesting part is what happens when one of those services goes down.

Custom tools let an agent ask your code for data. The Model Context Protocol lets it call your real services directly, on its own. Here is how to wire a remote server in, scope which tools it can touch, and survive a server that dies mid-session.

In this article, you will learn how to connect a Claude Managed Agent to an external service over the Model Context Protocol. We cover the two-part declaration that the API enforces, how to scope which server tools the agent may use, why MCP tools ask for confirmation by default, and the failure modes that arrive the moment your agent depends on a service the harness does not control. By the end, you can hand an agent a live connection to your internal systems without the integration becoming a single point of collapse.


Part 6 of the Claude Managed Agents Series

Share


Give an agent a custom tool and watch what actually happens. The agent wants vendor data. It stops, hands your application a structured request, and waits. Your code receives the request, runs the lookup, and sends the answer back. For one tool, that is a clean contract. For an internal billing system with a dozen operations, reading vendors, fetching payment terms, posting reconciliation results, and querying tax records, you are now writing and maintaining a relay function for every single call. That is the exact plumbing an agent framework was supposed to delete.

The Model Context Protocol is the better answer. MCP is a standard way to expose a set of tools over an HTTP endpoint, and Managed Agents speaks it natively. You point the agent at your billing system’s MCP server once, and from then on the agent calls any tool that server exposes directly. The harness executes the call. There is no per-call relay in your code at all.

The distinction is worth holding onto. A custom tool is the agent asking you for something. An MCP tool is the agent reaching out and getting it itself. This article wires a working agent into a real service over MCP, scopes what it is allowed to do there, and then deals honestly with the new failure modes that come with depending on something the harness cannot guarantee.

Two ways an agent gets external data: a custom tool routes every call through your relay code, while an MCP toolset lets the harness call the server directly with no relay.

Code below is shown in Python and TypeScript.

Declaration is two halves that must agree

MCP setup deliberately splits across two moments in an agent’s lifecycle. At agent creation you declare which servers exist, naming them and giving their URLs, with no secrets involved. At session creation you supply the credentials by referencing a vault. That separation is not bureaucracy. It keeps tokens out of your reusable agent definitions, so one agent definition can run for many different users, each with their own credentials.

This article is the declaration half. You declare servers in two places, and the two places have to line up. The mcp_servers array names each server and gives its URL. The tools array adds an mcp_toolset entry that references that server by name. The toolset entry is what actually exposes the server’s tools to the agent. Here is an invoice-reconciliation agent pointed at an internal billing system, in Python:

agent = client.beta.agents.create(
    name="Invoice Reconciler",
    model="claude-opus-4-7",
    system=(
        "You are an invoice-reconciliation agent. Use the billing system's tools "
        "to fetch canonical vendor and ledger data rather than trusting values "
        "printed on invoices."
    ),
    mcp_servers=[
        {
            "type": "url",
            "name": "billing",
            "url": "https://mcp.internal.example.com/billing",
        },
    ],
    tools=[
        {"type": "agent_toolset_20260401"},
        {"type": "mcp_toolset", "mcp_server_name": "billing"},
    ],
)

And in TypeScript:

const agent = await client.beta.agents.create({
  name: "Invoice Reconciler",
  model: "claude-opus-4-7",
  system:
    "You are an invoice-reconciliation agent. Use the billing system's tools to " +
    "fetch canonical vendor and ledger data rather than trusting values printed on invoices.",
  mcp_servers: [
    { type: "url", name: "billing", url: "https://mcp.internal.example.com/billing" },
  ],
  tools: [
    { type: "agent_toolset_20260401" },
    { type: "mcp_toolset", mcp_server_name: "billing" },
  ],
});

The name field is the thread that ties the two halves together. You called the server billing in mcp_servers, and the mcp_toolset references it as mcp_server_name: "billing". That same name shows up on every MCP tool event in the stream, so when you see agent.mcp_tool_use go by, you know exactly which server it came from. The type is always "url", since these are remote servers reached over HTTP.

Here is the gotcha, and the API enforces it strictly. The two halves must agree exactly. Every server you declare in mcp_servers must be referenced by an mcp_toolset, and every mcp_toolset must point at a declared server. Declare a server and forget to add its toolset, or reference a server name you never declared, and the agent definition is rejected outright. There are no dangling halves. If agent creation fails with a complaint about MCP configuration, this mismatch is almost always the reason. One more limit: an agent can declare up to 20 MCP servers, and their names must be unique within that agent.

The two-part MCP declaration: mcp_servers and the mcp_toolset must reference each other by name at agent creation, then vault_ids supply credentials at session creation.

If you are a paid subscriber, thank you. Your support makes this work possible.

If you are a free subscriber and find these articles useful, please consider upgrading. A paid subscription is $80 per year or $8 per month.

Share Hightower's AI Harness Engineering

User's avatar

Continue reading this post for free, courtesy of Rick Hightower.

Or purchase a paid subscription.
© 2026 Rick Hightower · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture