Skip to content

Add a perch-cli provider that runs the official Perch CLI, like claude-cli #7306

Open

Description

@scy7796

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 exec and 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_DIR is set, so the adapter expects a file-based sign-in there for now.

Alternatives or workarounds

  • Running perch by 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-cli does: 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-cli is 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-context and account. 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 npx and 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 .cmd shim, 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 readdir order, 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_transport and turn_preparation_stalled failures, is retried once through the shared send budget (transient send 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_iterations or turn_incomplete are 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

  1. added
    enhancementNew feature or request
    providerProvider adapters, OpenAI-compat presets, upstream API quirks
    toolstool_calls, MCP, web-search / sidecar tools
    on Oct 18, 2026
  2. Ingwannu commented on Oct 18, 2026

    @Ingwannu
    Owner

    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.

  3. scy7796 commented on Oct 19, 2026

    @scy7796
    ContributorAuthor

    Provider admission packet for perch-cli

    This 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

    • Package: perchai-cli on 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.
    • npm maintainer: lahar123, contact hello@joinperch.me.
    • License: proprietary ("Perch AI CLI Proprietary License", copyright 2026 Perch AI). It forbids modifying, reverse engineering, or making derivative works except as Perch allows in writing.
    • Official docs: CLI page, docs, Starter plan. The press page lists the CLI as one of three official surfaces (Web, Desktop, CLI), with Node 18 or newer.
    • The flags the adapter uses (--json, --thread, --cwd, --mode, --model, --effort) come from perch run --help. Three inputs aren't in the README: .perch/PERCH.md with .perch/rules/, .perch/skills.json, and PERCH_CLI_AUTH_DIR. I found those by watching the CLI.

    Operator and terms

    • Terms of Service and Privacy Policy, both last updated 2026-09-13.
    • The operator is named only as "Perch AI". Contacts: legal@perchai.app, privacy@perchai.app, support@perchai.app. The terms are governed by Georgia (USA) law, with Georgia courts.
    • I couldn't find a registered entity. The terms, privacy policy, press page, and about page don't give one, and a web search and a USPTO search for "PERCH AI" found nothing. LinkedIn lists "Perch AI" with 2–10 employees and no address. perchai.app was 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.
    • Not checked: the Georgia business registry and OpenCorporates. Both need a manual search. Compare Qoder, where the docs name BRIGHT ZENITH PRIVATE LIMITED. For Perch I can't fill that line in yet.

    Integration basis

    The terms say three things that matter here:

    • §6: unless a plan includes direct API access, Perch-hosted models are available only through Perch AI Web, Desktop, and CLI, and Perch's internal endpoints aren't a public API.
    • §6: "unlimited" usage is subject to fair use and excludes automated bulk processing. Perch may throttle, suspend, or downgrade usage it considers automated.
    • §7: you may not "call, automate, proxy, resell, or expose Perch's internal hosted-model endpoints as an API" without a plan that allows direct API access.

    I've taken the same position the claude-cli row 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 the codebuddy and claude-cli rows were. The provider guide states it in user-facing terms, and the design keeps the exposure small:

    • Turns run through the official CLI, one of the three surfaces §6 allows. OpenCodex never calls Perch's endpoints itself and replays no HTTP identity.
    • The CLI reads its own sign-in. OpenCodex stores, copies, and injects no Perch credential, and a key saved on the row never reaches the CLI.
    • One sign-in serves the whole proxy: the account of the user OpenCodex runs as. There's no pooling and no per-client account.

    There's one difference from claude-cli, and I want it reviewed on its own. The preload runs inside the CLI process and hooks fetch. 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 a free-directory.ts reference 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

    • The registry ships roost-standard, roost-standard-max, and deepseek-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.
    • The adapter logs which model actually served each turn. From my own runs:
      • deepseek-flash-starter: deepseek/deepseek-v4.1-flash, 26 calls on 2026-10-17
      • roost-standard: poolside/laguna-s-2.1, 36 calls on 2026-10-17 and 2026-10-18
      • roost-standard-max: qwen/qwen3.8-flash, 17 calls on 2026-10-17 and 2026-10-18
    • Perch's Starter page lists the current free lineup as Laguna S 2.1, DeepSeek V4.1 Flash, and GLM 5.3 Flash, plus Beam 1.0 until 2026-10-23. Qwen 3.8 Flash isn't on that list, so Roost serves from a wider pool than the published lineup. The page also says the lineup rotates.
    • Context sizes come from the CLI's own tier caps in 2.4.109 (standard 200K, standard max 1M). The 1M tier and the pin are published at 512K for the replay-size reason given in feat(providers): add perch-cli adapter for the official Perch CLI #7311.

    Scope of the evidence

    • Tested: Windows 11, Starter plan, perchai-cli 2.4.109, on 2026-10-17 and 2026-10-18.
    • Not tested: macOS, Linux, and any Pro model or Pro-only feature. The row lists no Pro models and no reasoning efforts. Perch ignores --effort below Pro.

    Maintenance

    I'll maintain this row (@scy7796). Things I expect to change, and what I'll do:

    • The Starter lineup rotates. The registry uses the two Roost tiers plus one pin, so a rotation mostly changes what serves the tiers. If the deepseek-flash-starter pin goes away, I'll remove it.
    • CLI flags, input files, or sign-in can change between releases (107 versions in four months). Breakage shows up in the request log as cli_not_found, perch_cli_failed, or tool_bridge_init_missing.
    • If Perch answers on the terms question, or changes §6–7, I'll update the guide and this row to match.
  4. github-actions commented on Oct 19, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: English.

  5. Ingwannu commented on Oct 19, 2026

    @Ingwannu
    Owner

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestproviderProvider adapters, OpenAI-compat presets, upstream API quirkstoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions