inhold Book a call

Claude Agent SDK

How do I connect a Claude Agent SDK agent to Inhold?

Inhold connects to the Claude Agent SDK as an HTTP MCP server in ClaudeAgentOptions. Production sign-in on AWS for Claude agents is not built yet.

Last checked 31 Oct 2026, written by Vivek

Inhold is being built. No customers yet. Repo goes public 9 Nov 2026.

The part you copy

One MCP server entry

Everything else in the example file is the demo.

headers = {"Authorization": "Bearer <token>", "Inhold-Purpose": "billing"}
ClaudeAgentOptions(mcp_servers={"inhold": {"type": "http", "url": url, "headers": headers}})

Start a local gateway

From the repo root, with Inhold installed. It makes a fresh database, seeds one billing note and one clinical note, and serves MCP at http://127.0.0.1:8700/mcp.

python examples/gateway.py

Run the Claude Agent SDK example

In a second terminal. Each SDK gets its own virtualenv because their MCP client versions disagree.

python -m venv .venv-claude && .venv-claude/bin/pip install -r examples/requirements-claude.txt
ANTHROPIC_API_KEY=... .venv-claude/bin/python examples/with_claude_agent_sdk.py

Read the output

The billing agent gets the billing note and a refusal for the clinical one. Then the script reads the log the way the hospital's security team would.

context_get ctx_a4fc2fea0a10 -> Payer Northwind rejects claims without modifier 25; resubmit within 30 days.
context_get ctx_1c79d9bf86eb -> REFUSED: Error executing tool context_get: not readable; do not retry

audit rows written during this run:
  #5 billing-agent read ctx_a4fc2fea0a10 purpose=billing -> ALLOW (purpose 'billing' may read internal)
  #6 billing-agent read ctx_1c79d9bf86eb purpose=billing -> DENY (purpose 'billing' may not read items written under 'prior_auth')

The Claude Agent SDK only calls tools when Claude asks, so there is no run without a model. The two audit rows look the same as in the other guides. Output from our run on main 478aded, 31 Oct 2026; ids differ on each run.

Worth knowing

Four things the example shows

The purpose is a header

It sits in your config. The model never sees it and no tool takes it as an argument, so a prompt injection cannot talk its way into another purpose.

A refusal is a normal tool error

The SDK hands it back to the model and the run carries on. The message is the same for a forbidden note and a missing one, so the agent cannot probe. The real reason is only in the audit row.

Hiding tools is your hygiene

The example offers the model only the read tools. The hospital's control is the policy on the gateway, which decides every call either way.

Sign-in in a real install

The Claude Agent SDK takes fixed headers only, and a signed AWS request lasts 60 seconds, so there is no production sign-in for Claude agents on AWS yet. The planned fix is a short-lived bearer token for agents. Until it ships, use the bearer token on a laptop only. The SDK does run on Bedrock (CLAUDE_CODE_USE_BEDROCK=1), which keeps the model in the hospital's account.