Repository navigation
Add a perch-cli provider that runs the official Perch CLI, like claude-cli #7306
Description
Area
Provider adapters
What are you trying to accomplish?
I use Codex (both the CLI and the desktop app) through OpenCodex and also have a Perch account. I want Perch as a provider in OpenCodex, so its hosted models show up in the Codex model picker and can drive normal Codex turns. Like claude-cli, the models should call Codex's own tools (exec, file edits, MCP tools) while Codex keeps control of approvals and sandboxing.
My account is on Perch's free Starter plan, so I wired up the Starter models first:
- Roost
standard(200K) - Roost
standard-max(1M) - DeepSeek V4.1 Flash
Nothing in the adapter is specific to these three. Pro models and reasoning-effort settings can go on the same provider entry once someone with a Pro account can test them.
What prevents this today?
Perch doesn't offer an API on consumer plans. Its models are only reachable through Perch's own web, desktop and CLI clients (npm i -g perchai-cli). OpenCodex has no adapter for it, so the only option today is running Perch's CLI in a separate terminal next to Codex, without Codex's tool loop or session history.
What should OpenCodex do?
Add a perch-cli preset that runs the official perch CLI headlessly, once per turn, following the same design as claude-cli:
- Tool calls go through Codex. Perch's models receive Codex's tool catalog and can make single, parallel or multi-step tool calls. When Perch requests tool calls, the turn ends and the calls go back to Codex, which approves and runs them and sends the results in the next turn. If the model calls one of Perch's built-in tools instead, the adapter retries once with a correction and fails with an explicit error if it happens again.
- No credentials in OpenCodex. Sign-in stays in the CLI (
perch login); OpenCodex never stores or forwards Perch credentials. - Isolated turns. Each turn runs in an isolated environment, so the user's local Perch config, MCP servers, skills and account memories don't leak into Codex sessions.
- Streaming and errors. Text and reasoning stream live as Perch produces them. Failures map to the usual status codes: 401 when not signed in, 429 on usage limits, a retryable 503 when Perch is unreachable.
- Images. The models on this path are text-only, so image inputs go through the vision sidecar first.
Example usage or interface
{
"providers": {
"perch-cli": { "adapter": "perch-cli", "baseUrl": "https://app.perchai.app" }
}
}Then select perch-cli/roost-standard, perch-cli/roost-standard-max or perch-cli/deepseek-flash-starter in Codex.
This already works on a branch off current dev (a single commit, ready to open as a PR). I tested it on Windows 11 with perchai-cli 2.4.109 on a Starter account:
- Real Codex tasks on all three Starter models, including multi-step
execand file-edit tool loops, and an image question answered through the vision sidecar. - First output in about 7.5 s once warm (about 12 s on the first turn after a proxy restart), with Codex's full prompt as input.
- All local checks pass: the adapter's tests (offline, no Perch install needed),
typecheck,structure:check,privacy:scan, the registry/layout/docs-count guards, and the docs build. - Not tested on Linux or macOS. On macOS the CLI keeps credentials in the Keychain unless
PERCH_CLI_AUTH_DIRis set, so the adapter expects a file-based sign-in there for now.
Alternatives or workarounds
- Running
perchby hand outside Codex. It can't share Codex's tools or conversation state. - Letting Perch execute tools itself ("delegate" mode). I ruled this out for the same reason
claude-clidoes: Codex would lose ownership of tool execution and the sandbox. - Calling Perch's private HTTP endpoints directly. Perch's terms restrict those endpoints to its own clients, and imitating the client goes against how
claude-cliis built. Running the official CLI avoids that.
Additional context
Going from a first proof of concept to something usable for daily Codex work took a few iterations. Most of the work went into working around how perch run handles MCP tools, startup and prompts.
Tools invisible on the 200K tier. At first, roost-standard never saw the client tools. Once MCP tool schemas pass 10% of the context limit, Perch hides them behind its own loadMcpTools step. Codex's exec schema alone is about 50 KB, so 12 of my first 13 failed turns ended in tool_bridge_init_missing. When the catalog gets close to that threshold, the adapter now cuts each tool to a one-line description and moves the full descriptions into the instructions. I haven't seen the failure since.
Capturing tool calls without killing the CLI. The bridge's MCP server declares no tool annotations, so Perch treats every Codex tool as a write. It reports the whole parallel batch as tool_call_requested and exits cleanly with approval_required on its own; nothing is killed mid-turn.
Keeping the model off Perch's built-in tools. Perch has no flag that disables its built-ins while keeping MCP. Restating the real working directory and the tool rule in the argv prompt took built-in calls on a real Codex task from 2 of 3 runs to 0 of 3. If the model still calls a built-in before any output has streamed, the adapter reruns the turn once with a correction naming the right client tools, and fails closed if that doesn't work either.
First token: about 20 s → about 7.5 s. Most of this comes from a small --import preload loaded into the CLI's Node process:
- The CLI uploads the transcript at the end of every turn, which held the result back for 1.5–12 s. The preload answers those uploads locally.
- The preload caches three startup requests: the public default model,
cli-contextandaccount. The two account-specific entries are keyed by a hash of the sign-in, so the token itself is never written to disk.
Outside the preload, the adapter:
- turns off Perch's seeded CourtListener MCP server, which otherwise starts
npxand adds about 4 s; - disables the built-in skills, saving about 1.7K tokens per request;
- runs the CLI's Node entry point directly. That skips Perch's heap re-exec and the Windows
.cmdshim, which also cut argv at the first newline.
Streaming. perch run --json prints a single JSON document on exit. The preload copies model-call deltas to an extra pipe, so text and reasoning stream as they arrive. The adapter tracks how much of each model call already went out and only sends the rest from the final document, so a tail is never dropped or sent twice.
Passing the conversation. perch run only takes its prompt from argv, so the conversation goes through Perch's project instruction files: .perch/PERCH.md plus up to 40 rule files of 64 KB each.
- History is capped by bytes, using the conversation's own bytes-per-character ratio (CJK text takes about 3 bytes per character). The current turn's input is never cut.
- Perch reads rule files in raw
readdirorder, so each file carries an explicit part number. - If Perch compacts those files during a run, the adapter fails closed instead of letting the model answer from a cut conversation.
Isolation. Every turn gets a fresh --thread ID; otherwise Perch derives the thread from the working directory and replays its own past turns. The CLI also runs with an empty staging home directory, so the user's local Perch config stays out.
Retries and lifecycle:
- One of Perch's startup requests occasionally times out. The run then has no turn ticket and fails with "model is busy". That case, along with
provider_transportandturn_preparation_stalledfailures, is retried once through the shared send budget (transientsend class), but only if nothing has streamed yet. Perch's own error codes, such as quota or context limits, take precedence and are never retried. - Token usage is summed across attempts and reported on whatever ends the turn, errors included.
- An abort returns 499, also between attempts.
- Runs stopped by
max_iterationsorturn_incompleteare marked as truncated, so Codex doesn't treat a partial answer as complete. - On Windows the CLI's process tree is cleaned up with the shared runner's helper.
- Error messages are stripped of bearer tokens, JWTs and token fields.
Known limitations (also in the docs):
- Perch always prepends its own operator persona, and the CLI can't replace it. Codex's instructions come right after it and win out for tool use, but the model occasionally still introduces itself by Perch's persona name.
- Each request carries about 22K tokens of Perch's own system prompt and built-in tool schemas.
- Perch's built-in read tools (web search, web fetch) can run inside Perch before the adapter sees the call, so they bypass the client's network sandbox.
- Conversation history has to fit in those 40 rule files, so the 1M-context models are advertised at 512K and Codex compacts before hitting the cap.
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
Ingwannu commentedon Oct 18, 2026
Implementation is now tracked in Draft #7311; leaving this issue open until that work is reviewed and lands. For the provider-admission packet, please link the official CLI distribution/documentation, operating entity/terms and the supported integration basis, with a verification date and an ongoing maintainer. Running the official CLI is useful provenance but does not alone establish every hosted-model or subscription integration claim. Keep Windows Starter evidence distinct from unverified Linux/macOS/Pro models. Tool capture must demonstrably leave execution/approval with the originating client, including unticketed/native-tool attempts, cancellation and process cleanup. No new provider sponsorship or merge approval is implied here.
scy7796 commentedon Oct 19, 2026
Provider admission packet for
perch-cliThis is the packet you asked for in the intake on #7306 and #7311. It covers the provider itself. The Windows execution evidence stays in #7311 and isn't repeated here. Everything below was checked on 2026-10-19 unless a line says otherwise.
Distribution and documentation
perchai-clion npm. First published 2026-06-09, 107 versions in all. The latest is 2.4.111 (published 2026-10-19). I tested 2.4.109.lahar123, contact hello@joinperch.me.--json,--thread,--cwd,--mode,--model,--effort) come fromperch run --help. Three inputs aren't in the README:.perch/PERCH.mdwith.perch/rules/,.perch/skills.json, andPERCH_CLI_AUTH_DIR. I found those by watching the CLI.Operator and terms
perchai.appwas registered on 2026-05-19 through Name.com with the registrant redacted. The GitHub org the site links to (Perch-Terminal-AI) returns 404 from the GitHub API. The npm maintainer's email domain,joinperch.me, hosts a separate "Perch Capital" site whose terms name no entity either.Integration basis
The terms say three things that matter here:
I've taken the same position the
claude-clirow took in #5712. Whether a vendor's sign-in may be driven through a proxy for a third-party agent is the vendor's call, not this repository's. So I'm flagging it for maintainer review the way thecodebuddyandclaude-clirows were. The provider guide states it in user-facing terms, and the design keeps the exposure small:There's one difference from
claude-cli, and I want it reviewed on its own. The preload runs inside the CLI process and hooksfetch. It reads the CLI's authorization header, only to hash it into a cache key. It answers three lookups locally and drops the CLI's end-of-turn transcript uploads (cli-turn,cli-learning). The turn ticket and the model calls, where Perch admits and meters a turn, pass through unchanged. It doesn't modify any CLI file, but it does change what the CLI sends. Given the license and §7, that's the part most likely to be a problem. I also haven't checked whether those uploads feed the Starter Data Program (terms §8). If you'd rather not take that on, there are two fallbacks: drop the caches and the upload filter and keep only the stream mirror, or turn the row into afree-directory.tsreference entry.Two more risks fall on the user, and the provider guide states the first: Perch could treat a proxied CLI as automated use under §6–7 and throttle or suspend the account. And on Starter, the Starter Data Program is on by default (terms §8). Eligible Starter activity, which here includes Codex prompts, code, and tool calls, can be turned into deidentified training data that Perch may license or sell. Users can turn it off in Settings → Privacy. The guide doesn't mention this yet. I'll add it to #7311.
Model provenance
roost-standard,roost-standard-max, anddeepseek-flash-starter. The first two are Perch's Roost routing tiers (--model standard,--model standard max). Roost picks a backend per task and can race providers, so the tier name doesn't fix the model. The third is an exact pin.deepseek-flash-starter:deepseek/deepseek-v4.1-flash, 26 calls on 2026-10-17roost-standard:poolside/laguna-s-2.1, 36 calls on 2026-10-17 and 2026-10-18roost-standard-max:qwen/qwen3.8-flash, 17 calls on 2026-10-17 and 2026-10-18Scope of the evidence
perchai-cli2.4.109, on 2026-10-17 and 2026-10-18.--effortbelow Pro.Maintenance
I'll maintain this row (@scy7796). Things I expect to change, and what I'll do:
deepseek-flash-starterpin goes away, I'll remove it.cli_not_found,perch_cli_failed, ortool_bridge_init_missing.github-actions commentedon Oct 19, 2026
Automated translation bookkeeping — detected language: English.
Ingwannu commentedon Oct 19, 2026
The admission packet is useful, and I independently checked the official CLI page, terms §§6–8 and privacy policy §4 on 2026-10-19. The pages establish CLI availability, restrict internal-endpoint automation/proxying without appropriate permission, and describe default-on eligible Starter training-data participation after notice/acknowledgement. They do not themselves establish permission for this preload's caching/upload suppression or supply the missing registered-operator evidence.
Before promoting this as a canonical preset, please resolve the integration basis for the injected fetch hook and dropped end-of-turn uploads, and add the Starter data-program/opt-out disclosure to the guide. Removing caches/upload suppression or using an inert directory reference are reviewable alternatives; neither should be portrayed as already approved. No CLI install, license acceptance, provider contact/login or external model call was performed here. Keeping the admission/owner review hold separate from your Windows execution receipt.