Claude (Anthropic)
Claude can interact with any agent.json endpoint using tool use. Define the inbox’s actions as Claude tools, and Claude will call them with structured parameters.
1. Discover the inbox
Section titled “1. Discover the inbox”First, fetch the discovery document to learn what actions are available:
curl https://agent-json.com/.well-known/agent.json2. Define tools from actions
Section titled “2. Define tools from actions”Map each action from the discovery document to a Claude tool definition:
import anthropicimport httpx
# Fetch discovery documentdiscovery = httpx.get("https://agent-json.com/.well-known/agent.json").json()INBOX_URL = discovery["message_endpoint"]TOKEN = "your-bearer-token"
# Convert actions to Claude toolstools = []for action in discovery["actions"]: tools.append({ "name": f"inbox_{action['name']}", "description": f"Send to website inbox: {action['description']}", "input_schema": action["parameters"] })
# Add a generic "send message" tool for free-formtools.append({ "name": "inbox_send_message", "description": "Send a free-form message to the website inbox", "input_schema": { "type": "object", "properties": { "subject": {"type": "string", "description": "Message subject"}, "body": {"type": "string", "description": "Message body"} }, "required": ["subject"] }})3. Handle tool calls
Section titled “3. Handle tool calls”When Claude calls an inbox tool, send the message to the inbox endpoint:
def handle_inbox_tool(tool_name, tool_input, user_email=None): """Send a tool call to the agent.json endpoint.""" if tool_name == "inbox_send_message": payload = { "from": { "agent": "claude-assistant", "on_behalf_of": user_email }, "subject": tool_input["subject"], "body": tool_input.get("body", "") } else: # Structured action call action_name = tool_name.removeprefix("inbox_") payload = { "from": { "agent": "claude-assistant", "on_behalf_of": user_email }, "action": action_name, "parameters": tool_input }
response = httpx.post( INBOX_URL, json=payload, headers={"Authorization": f"Bearer {TOKEN}"} ) return response.json()4. Complete conversation loop
Section titled “4. Complete conversation loop”client = anthropic.Anthropic()
messages = [ {"role": "user", "content": "I need a refund for order #1234, it arrived damaged."}]
# First turn — Claude decides to call the toolresponse = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=messages)
# Process tool callsfor block in response.content: if block.type == "tool_use": result = handle_inbox_tool(block.name, block.input, "customer@example.com")
# Feed result back to Claude messages.append({"role": "assistant", "content": response.content}) messages.append({ "role": "user", "content": [{ "type": "tool_result", "tool_use_id": block.id, "content": str(result) }] })
# Claude summarizes the result for the user final = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=messages ) print(final.content[0].text)5. Poll for responses (optional)
Section titled “5. Poll for responses (optional)”If the website sends a response later, you can poll for it:
def check_for_response(message_id): """Poll the inbox for a response to a previously sent message.""" response = httpx.get( f"{INBOX_URL}/{message_id}", headers={"Authorization": f"Bearer {TOKEN}"} ) data = response.json() if data.get("response"): return data["response"] return NoneWith callbacks
Section titled “With callbacks”For real-time responses without polling, provide a callback_url when sending:
payload = { "from": { "agent": "claude-assistant", "on_behalf_of": "customer@example.com", "callback_url": "https://your-server.com/webhooks/inbox" }, "action": "request_refund", "parameters": {"order_id": "1234", "reason": "damaged"}}See Callbacks for how to verify the HMAC signature on your webhook endpoint.
MCP server
Section titled “MCP server”You can also wrap agent.json as an MCP server to make it available to any MCP-compatible client (Claude Desktop, Cursor, etc.):
// Fetch discovery doc at startup, expose each action as an MCP tool// The MCP server translates tool calls into POST /.agent/inbox requestsThis turns any agent.json endpoint into a tool that Claude can use across all MCP-enabled interfaces.