> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arcium.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Coding agents

> Run Claude Code on Blackthorn's sealed engine with `blackthorn claude`, and why Codex does not work with it yet.

`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):

```bash theme={null}
v=$(curl -fsS https://bin.arcium.com/download/blackthorn/latest)
curl -fsSLo blackthorn "https://bin.arcium.com/download/blackthorn/blackthorn_$(uname -m | sed s/arm64/aarch64/)_$(uname -s | tr A-Z a-z | sed s/darwin/macos/)_$v"
chmod +x blackthorn && sudo mv blackthorn /usr/local/bin/
blackthorn --version
```

**2. Log in and check the engine**

```bash theme={null}
blackthorn login     # paste your API key (it is not echoed)
blackthorn status    # fails unless every MPC party vouches for the GPU's attested session
```

**3. Start the server**

```bash theme={null}
blackthorn serve     # OpenAI's API on http://127.0.0.1:8000/v1, Anthropic's on http://127.0.0.1:8000
```

Leave it running while the agent works. Add `--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 `blackthorn serve` running, in another terminal:

```bash theme={null}
blackthorn claude
```

Arguments after `--` go to `claude`. For one prompt:

```bash theme={null}
blackthorn claude -- -p "What does this repository do?"
```

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

```bash theme={null}
blackthorn claude -- --bare --tools "Read" -p "Use the Read tool on ./notes.txt, then tell me the launch code."
```

If `serve` listens on another port, pass the same `--port` to `blackthorn claude`.

`blackthorn claude` sets up Claude Code for the engine:

* **API:** `ANTHROPIC_BASE_URL` points at `serve`, with a placeholder token. `serve` accepts 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 (`awaySummaryEnabled` and `promptSuggestionEnabled`).

A session recap, which is on by default, starts a few minutes after you leave the terminal. It sends the whole conversation plus an instruction to summarize it. The engine would extend the conversation's session with the recap and cannot take it back out, so your next message would match no open session, and the engine would read the whole conversation again.

Your own Claude Code setup still applies: settings, `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](#shared-prompt-prefix) saves reading Claude Code's tools.

`serve --verbose` prints a line per request, for example:

```text theme={null}
[serve] prompt 11705 tokens (11674 held, 0 prefilled, 31 sent), answer 14 tokens, 0 tool call(s), 0.9s
```

`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.

> [!NOTE]
>
> 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 your `CLAUDE.md` and 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 `-p` prompts 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

> [!WARNING]
>
> Codex does not work with `serve` yet.

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:

```text theme={null}
ERROR: unexpected status 404 Not Found: not found, url: http://127.0.0.1:8000/v1/responses
```

## Other agents

An agent that speaks either API can use `serve` directly, with any API key:

* **OpenAI's Chat Completions API:** base URL `http://127.0.0.1:8000/v1`. `system`, `tools`, assistant `tool_calls` and `tool` messages work as in OpenAI's API. `tool_choice` may only be `auto` or `none`, there are no images, and `frequency_penalty`, `presence_penalty`, `logprobs` and `n > 1` are 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_choice` `any` or `tool` is taken as `auto`.

An omitted `temperature` is `0` (greedy) in both. The [Quickstart](https://docs.arcium.com/blackthorn/quickstart.md) has examples for both APIs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.