Anthropic API
Paddock implements the Anthropic Messages API on /v1/messages, so Anthropic SDK clients, Claude Code among them, can point at a local model.
Base URL and Authentication
The Anthropic SDKs append /v1/messages to their base URL themselves, so the base URL is the server root, without /v1:
http://localhost:11540On the default loopback bind no key is required. When a key is configured (or auto-generated for a non-loopback bind), send it as Authorization: Bearer <key>; Paddock authenticates /v1 requests through that header. Errors use the Anthropic envelope:
{ "type": "error", "error": { "type": "invalid_request_error", "message": "..." } }Endpoints
| Endpoint | Description |
|---|---|
POST /v1/messages | The Messages API: content blocks, system prompts, tool use, thinking, streaming, and the MCP connector. |
POST /v1/messages/count_tokens | Runs the same conversion and template-render pipeline without generating; returns input_tokens. |
Request Surface
model, max_tokens (required, per the Anthropic API), and messages are the core fields. Also supported: system (a string or text blocks), tools, tool_choice (auto, any, tool, none, with disable_parallel_tool_use), stop_sequences, temperature, top_p, thinking, stream, metadata, and mcp_servers. top_k, min_p, and seed are local extensions. Unknown fields are rejected with a 400 that names the field, matching the Anthropic API's own behavior.
Responses
Replies are content-block arrays: text, thinking, and tool_use blocks, with stop_reason set to end_turn, max_tokens, stop_sequence, or tool_use. Usage reports input_tokens and output_tokens.
Streaming
The streaming path speaks the strict Anthropic event protocol that the SDK accumulator enforces:
message_start
ping
content_block_start / content_block_delta / content_block_stop (per block)
message_delta
message_stopA keep-alive ping event follows message_start, as on the live API.
Thinking
Reasoning text is returned as thinking content blocks. thinking.type accepts enabled, disabled, and adaptive (treated as enabled), and thinking.display accepts summarized and omitted: with omitted, thinking blocks come back with an empty thinking field and no thinking deltas.
Three behaviors differ from Anthropic's service: thinking.budget_tokens is accepted but not enforced (thinking length is model-driven), gpt-oss models reason unconditionally and return thinking blocks even without thinking: enabled, and thinking blocks carry an empty signature.
Tool Use
Tools are declared as name, description, and input_schema. The model's calls come back as tool_use blocks, and your tool_result blocks in the next user message feed results back in the standard round trip. Tool definitions are converted to the served model's own chat-template format, so tool use works across model families.
Vision and PDF Input
With a vision model served, image content blocks with base64 sources are accepted. URL image sources are rejected; the server does not fetch remote URLs. PDF document blocks (base64 source, application/pdf media type) are rasterized into page images server-side when a pdfium_lib is configured, with a page cap and reported truncation.
Web Search
The Anthropic server web-search tool (web_search_20250305) is supported, including max_uses. Searches run server-side through the provider you configure in the Studio (Exa or Tavily, your own API key) and are reported as server_tool_use and web_search_tool_result content blocks, with usage.server_tool_use.web_search_requests counting the calls.
MCP Connector
The mcp_servers request field (the Anthropic MCP connector, current beta mcp-client-2025-11-20) makes Paddock connect to remote MCP servers and execute the model's tool calls server-side, emitting mcp_tool_use and mcp_tool_result blocks. Per-server tool configuration comes through mcp_toolset entries in tools (allowlists, denylists, and deferred loading through the search tools); the deprecated tool_configuration shape from mcp-client-2025-04-04 still works. See the MCP page for the full surface.
Claude Code and the Anthropic SDKs
Because /v1/messages follows the Messages spec, including the strict streaming protocol, Anthropic SDK clients and Claude Code work by changing the base URL:
export ANTHROPIC_BASE_URL=http://localhost:11540Example
curl http://localhost:11540/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.5-9b",
"max_tokens": 512,
"system": "You are a concise assistant.",
"messages": [{"role": "user", "content": "What does continuous batching mean?"}]
}'For throughput and latency measurements, see the benchmarks.