Skip to main content

Agent HTTP API

Run Claude agents programmatically via HTTP with streaming responses.

Overview

The Agent HTTP API wraps the Claude Agent SDK, exposing it over HTTP with Server-Sent Events (SSE) for real-time streaming. This enables:

  • Remote agent execution from any HTTP client
  • Main agents spawning specialized subagents
  • Integration with non-Python systems
  • Orchestration of multiple agents

Endpoints

POST /chat

Stream an agent conversation.

Request Body:

{
"prompt": "Your task or question",
"system_prompt": "Optional system context",
"model": "claude-sonnet-4-20250514",
"allowed_tools": ["Read", "Write", "Bash"],
"session_id": "optional-session-id-to-resume",
"working_directory": "/path/to/cwd",
"mcp_servers": {
"janus": {
"command": "janus-mcp",
"args": []
}
}
}

Parameters:

FieldTypeRequiredDescription
promptstringYesThe user message or task
system_promptstringNoSystem context for the agent
modelstringNoClaude model (default: claude-sonnet-4-20250514)
allowed_toolsstring[]NoRestrict to specific tools
session_idstringNoResume a previous session
working_directorystringNoSet agent's working directory
mcp_serversobjectNoMCP servers to enable

Response: Server-Sent Events stream

GET /health

Check service health and configuration.

Response:

{
"status": "healthy",
"claude_auth": true,
"mcp_servers": ["janus", "context7"]
}

SSE Event Types

The /chat endpoint streams events as the agent works:

EventDataDescription
init{session_id, mcp_servers}Session started
text{text}Text output from agent
tool_use{tool, tool_id, input}Agent calling a tool
tool_result{tool_id}Tool execution completed
done{session_id, result, num_turns, duration_ms, cost_usd}Conversation complete
error{error}Error occurred

Usage Examples

Python Client

import httpx

async def run_agent(prompt: str):
async with httpx.AsyncClient() as client:
async with client.stream(
"POST",
"http://localhost:8765/chat",
json={"prompt": prompt},
timeout=300.0
) as response:
async for line in response.aiter_lines():
if line.startswith("data: "):
data = json.loads(line[6:])
if data["type"] == "text":
print(data["data"]["text"], end="")
elif data["type"] == "done":
return data["data"]["result"]

curl

curl -N -X POST http://localhost:8765/chat \
-H "Content-Type: application/json" \
-d '{"prompt": "List files in the current directory"}'

With MCP Servers

response = await client.stream(
"POST",
"http://localhost:8765/chat",
json={
"prompt": "Find a button component for my React app",
"mcp_servers": {
"magic": {
"command": "npx",
"args": ["-y", "@anthropic/magic-mcp"]
},
"context7": {
"command": "npx",
"args": ["-y", "@anthropic/context7-mcp"]
}
}
}
)

Session Resumption

Continue a previous conversation by passing the session_id:

# First request
response1 = await run_agent("Create a React component")
session_id = response1["session_id"]

# Continue the conversation
response2 = await run_agent(
"Now add TypeScript types",
session_id=session_id
)

Tool Allowlisting

Restrict what tools the agent can use:

# Read-only agent
response = await run_agent(
"Analyze this codebase",
allowed_tools=["Read", "Glob", "Grep"]
)

# Full access agent
response = await run_agent(
"Fix the bug and commit",
allowed_tools=["Read", "Write", "Edit", "Bash"]
)

Running the Service

# Start the agent API
claudebox-agent --host 0.0.0.0 --port 8765

# Or via systemd
systemctl --user start claudebox-agent
systemctl --user status claudebox-agent

Configuration

Environment variables:

VariableDescriptionDefault
CLAUDEBOX_MCP_COMMANDDefault MCP server commandNone
CLAUDEBOX_DEFAULT_MODELDefault Claude modelclaude-sonnet-4-20250514

Error Handling

Errors are streamed as error events:

{
"type": "error",
"data": {
"error": "Tool execution failed: permission denied"
},
"timestamp": "2025-01-01T12:00:00Z"
}

The client should handle these gracefully and potentially retry or surface to the user.