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:11540

On 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

EndpointDescription
POST /v1/messagesThe Messages API: content blocks, system prompts, tool use, thinking, streaming, and the MCP connector.
POST /v1/messages/count_tokensRuns 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_stop

A 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:11540

Example

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.