blackthorn serve runs an API on your own machine that speaks both OpenAI’s Chat Completions API and Anthropic’s Messages API. It seals each prompt there, so only the engine inside the GPU can read it, and the host and the network see ciphertext. A coding agent uses that local API as its model.
bt-api-h3 serves Qwen3.5-9B (qwen3.5-9b-bllm).
Set up blackthorn serve
1
Install the CLI
blackthorn claude and the shared prompt prefix need blackthorn 0.3.0 or newer. Download the prebuilt binary (x86_64 or aarch64, Linux or macOS):2
Log in and check the engine
3
Start the server
--verbose to log each request’s size, how much of it the engine already held, and how long it took.Claude Code
serve speaks Anthropic’s Messages API (/v1/messages and /v1/messages/count_tokens), so Claude Code talks to it directly, with no translating proxy. blackthorn claude starts Claude Code pointed at it.
1
Install Claude Code
blackthorn claude runs the claude on your PATH.2
Run it
With Arguments after If
blackthorn serve running, in another terminal:-- go to claude. For one prompt:--bare skips Claude Code’s own system prompt, and --tools limits the tools. --tools takes every argument after it as a tool name, so put the prompt right after -p:serve listens on another port, pass the same --port to blackthorn claude.blackthorn claude sets up Claude Code for the engine:
- API:
ANTHROPIC_BASE_URLpoints atserve, with a placeholder token.serveaccepts requests only from this machine and seals them with your Blackthorn API key. - Model: the engine’s model for every task, including subagents and small background tasks.
- Limits: a 32k context (
CLAUDE_CODE_MAX_CONTEXT_TOKENS=32768), answers of at most 4,096 tokens, short Bash output (BASH_MAX_OUTPUT_LENGTH=1500), a 10-minute request timeout, and no nonessential traffic. Your environment overrides any of these. - Background requests: off (
awaySummaryEnabledandpromptSuggestionEnabled).
CLAUDE.md, memory, skills, plugins, agents, MCP servers and output style.
What to expect
The engine keeps each conversation open. Each step sends only the tokens that are new since the last step, so only the first step of a conversation is slow: the engine reads the whole prompt then. Your setup adds to that prompt:CLAUDE.md, the memory index, the skill and agent lists, and an output style all go into it. --bare keeps it short, and the shared prompt prefix saves reading Claude Code’s tools.
serve --verbose prints a line per request, for example:
held counts the tokens the engine already had from the earlier steps. When a request starts a new conversation although one was open, --verbose says where the prompt parted from the closest open conversation.
The context is 32,768 tokens, prompt and answer together, so a long Claude Code session runs out of room sooner than with Anthropic’s models. Keeping Bash output short leaves more room for the conversation. Qwen3.5-9B handles simple agent steps, such as reading a file to answer a question, but it is far smaller than the models Claude Code is built for.
Shared prompt prefix
Claude Code’s tool definitions come first in its prompt: about 8,600 tokens interactively, 7,600 with-p. They are the same in every conversation of a Claude Code release, whatever its output style, agents, skills or MCP servers. The engine keeps one shared copy of them. A new conversation starts from that copy instead of reading the tools again. The first conversation to find no copy reads them and publishes them for the next.
- What is shared: only the prompts built into
blackthorn, one per Claude Code release, matched on your machine against your own tokens. Another Claude Code release, or a setup that changes the tool list (such as--disallowedTools, or tool search turned off), shares nothing, and the conversation reads its whole prompt as before. Everything after the tools, including yourCLAUDE.mdand memory, is always read per conversation. - What the host learns: never what the copy holds, but which conversations started from it, so it can tell that you run Claude Code.
- One copy: interactive and
-pprompts have different tools, so they replace each other’s copy. - Turning it off:
blackthorn serve --no-shared-prefix.
serve --verbose names the shared prompt when a conversation forks the copy (forked Claude Code 2.1.318 (interactive): tools) or publishes it (published …).
Codex
Codex speaks only OpenAI’s Responses API (/v1/responses) and no longer accepts wire_api = "chat". serve offers Chat Completions and Anthropic’s Messages API, not the Responses API. A Codex provider pointed at serve fails with:
Other agents
An agent that speaks either API can useserve directly, with any API key:
- OpenAI’s Chat Completions API: base URL
http://127.0.0.1:8000/v1.system,tools, assistanttool_callsandtoolmessages work as in OpenAI’s API.tool_choicemay only beautoornone, there are no images, andfrequency_penalty,presence_penalty,logprobsandn > 1are not supported. - Anthropic’s Messages API: base URL
http://127.0.0.1:8000. Tools and system messages work, including system messages between turns. What a text-only model cannot take is left out rather than refused: an image becomes a note that it was left out, earlier thinking blocks are dropped, and so are tools Anthropic runs itself, such as web search.tool_choiceanyortoolis taken asauto.
temperature is 0 (greedy) in both. The Quickstart has examples for both APIs.