Skip to content

Pi

Pi reads its providers from a single global JSON file rather than environment variables, so opencodex does not launch it. Instead, ocx export serializes the opencodex provider block — base URL, model list, and the env reference Pi interpolates — and you merge it into your own config.

Start the proxy, then print the config:

Terminal window
ocx start
ocx export --client pi

The output leads with the JSON, then prints the destination path, the merge warning, the env export line, and how many models carry authoritative context limits.

{
"providers": {
"opencodex": {
"baseUrl": "http://127.0.0.1:10100/v1",
"api": "openai-completions",
"apiKey": "$OPENCODEX_API_KEY",
"models": [
{
"id": "anthropic/claude-opus-5",
"name": "Claude Opus 5 (anthropic)",
"input": ["text"],
"contextWindow": 200000,
"maxTokens": 32000
}
]
}
}
}

Model ids are the proxy’s canonical selectors, so routed models appear as provider/model (anthropic/claude-opus-5) and native OpenAI slugs stay unprefixed (gpt-5.6-sol). The name suffix — (anthropic), (native), (routed) — is what makes two same-named models from different upstreams distinguishable in Pi’s picker.

Pi’s global model config is:

~/.pi/agent/models.json

The exported block is a static snapshot, not a live view. Re-run ocx export after adding a provider or changing model visibility, and merge the new block over the old one.

Two different keys are easy to confuse here, and only the first one appears in this file:

Key What it is Where it lives
Proxy admission key opencodex’s own credential, generated on the dashboard’s API tab referenced by apiKey as $OPENCODEX_API_KEY; the value stays in your environment
Provider key your Anthropic / OpenAI / OpenRouter key opencodex’s own config, per Providers

The exported config carries only the reference, never a secret. Pi interpolates a bare $NAME, so the variable is:

Terminal window
export OPENCODEX_API_KEY=<your key>

That name is Pi’s alone. opencode uses a different variable (OPENCODEX_OPENCODE_API_KEY, in {env:…} form) — see the opencode guide.

A loopback proxy needs no key at all. opencodex binds 127.0.0.1 by default and authenticates nothing there, so the $OPENCODEX_API_KEY reference is inert and you can leave the variable unset. It matters only when hostname is set beyond loopback, which is also the case where the proxy refuses to start without a token — see Remote access.

contextWindow and maxTokens are emitted only when the catalog reports an authoritative context window. When it does not, both fields are omitted for that model and Pi applies its own defaults; ocx export prints how many rows fell into that case.

maxTokens is a schema-satisfying budget of 32000, clamped down to the context window so a small-context model is never given more output than context. It is not a claim about any specific model’s true maximum.

Two fields are deliberately absent. cost requires all four price fields and opencodex has no price data for routed models — emitting zeros would assert that every model is free. reasoning is a boolean in Pi while the catalog carries an effort ladder, and mapping one onto the other would be a guess.

A running opencodex proxy (ocx start) and Pi installed. ocx export reads the live catalog through the proxy’s management API, so a config can never be emitted with an empty model list.