Asking about scope before opening a pull request, because the answer decides whether it is worth reviewing.
The idea
A Bot that speaks the Agent Client Protocol over stdio, so a coworker can run on a coding harness a person already has a subscription to (Cursor, Grok Build, opencode, Codex) instead of on an API key the deployment bills.
The reason I think this is template-level rather than vendor-level: it is one process per protocol, not one per vendor. ACP is the seam. agent-acp spawns whichever harness a run names via x-openbot-agent-harness, and the shipped catalogue is a data table, not a branch per vendor. Cursor is merely the first thing that speaks it.
The generalisation is made explicit rather than implied: an admin screen lets a deployment define a harness of its own, a binary and its arguments, so adding one needs no change to this repository. That is off by default behind OPENBOT_CUSTOM_HARNESS_ENABLED, admin-only, and audited with the command, because a row there names a program executed on the Bot's host.
Nothing here holds a model credential. Each harness authenticates by the CLI login already on its host.
Why I am asking first
I have read the three that were closed as out of scope: the Hermes bridge (#232), Grok Build OIDC (#258), and the ADK consent card (#279). I would rather not add a fourth. My reading of those closures is that the objection is to a one-vendor shim, and that the acceptable shape is the protocol-level one: "a protocol-level event (ADK merely one emitter)", as #279 put it. That is the shape I have tried to build. But I would rather hear that from you than assume it.
Two things I have already cut on that basis:
- A second Bot on the Claude Agent SDK. It is genuinely useful, because the SDK accepts
tools: [], so a harness's own file and shell tools are gone rather than refused one at a time, which ACP cannot do. But it fronts one vendor, so it is not in this proposal. Happy to raise it separately if the protocol-level half lands.
- Anything that would make Cursor special. It is one row in the catalogue.
The honest limits
Worth stating up front, because they are the reason to say no:
- ACP cannot take a harness's tools away. A harness arrives with its own file and shell tools loaded. Three levers exist: a read-only session mode where the harness publishes one (Cursor's
ask is real, and with it applied whoami is refused by the harness itself), refusing every session/request_permission for a native tool, and the workspace it starts in.
- None of them stop reading. Cursor in
ask mode read /etc/hosts, an absolute path outside its workspace, and asked nobody, so there was no permission request to refuse. Assume any ACP harness can read any file the process can reach. The boundary has to come from the OS, and the Dockerfile is where I have put it.
- Replica question. The create-a-Bot screen probes each managed endpoint for what it can run rather than reading a compiled list, and caches per process with a 30s TTL. An admin defining a harness invalidates the cache on the replica that served them; others converge within the TTL. Nothing is written, so replicas cannot disagree about a change, only about its age. If that window is not acceptable I would do the
LISTEN/NOTIFY invalidation computer/policy-store.ts already documents. Say so and I will.
Size
Around 9,500 lines: the Bot, the harness definition type shared by server and Bot, a harness_definitions table and its migration, the admin screen, and the endpoint probe replacing three lists that were compiled into the server and keyed on localhost ports (the same Bot behind a service on 443 matched none of them and offered no model choice at all).
I know that is large for a first contribution here. If it is in scope but too big as one change, tell me how you would like it cut and I will cut it that way. The probe rewrite, the ACP Bot, and the custom-harness screen are separable, in that order.
Asking about scope before opening a pull request, because the answer decides whether it is worth reviewing.
The idea
A Bot that speaks the Agent Client Protocol over stdio, so a coworker can run on a coding harness a person already has a subscription to (Cursor, Grok Build, opencode, Codex) instead of on an API key the deployment bills.
The reason I think this is template-level rather than vendor-level: it is one process per protocol, not one per vendor. ACP is the seam.
agent-acpspawns whichever harness a run names viax-openbot-agent-harness, and the shipped catalogue is a data table, not a branch per vendor. Cursor is merely the first thing that speaks it.The generalisation is made explicit rather than implied: an admin screen lets a deployment define a harness of its own, a binary and its arguments, so adding one needs no change to this repository. That is off by default behind
OPENBOT_CUSTOM_HARNESS_ENABLED, admin-only, and audited with the command, because a row there names a program executed on the Bot's host.Nothing here holds a model credential. Each harness authenticates by the CLI login already on its host.
Why I am asking first
I have read the three that were closed as out of scope: the Hermes bridge (#232), Grok Build OIDC (#258), and the ADK consent card (#279). I would rather not add a fourth. My reading of those closures is that the objection is to a one-vendor shim, and that the acceptable shape is the protocol-level one: "a protocol-level event (ADK merely one emitter)", as #279 put it. That is the shape I have tried to build. But I would rather hear that from you than assume it.
Two things I have already cut on that basis:
tools: [], so a harness's own file and shell tools are gone rather than refused one at a time, which ACP cannot do. But it fronts one vendor, so it is not in this proposal. Happy to raise it separately if the protocol-level half lands.The honest limits
Worth stating up front, because they are the reason to say no:
askis real, and with it appliedwhoamiis refused by the harness itself), refusing everysession/request_permissionfor a native tool, and the workspace it starts in.askmode read/etc/hosts, an absolute path outside its workspace, and asked nobody, so there was no permission request to refuse. Assume any ACP harness can read any file the process can reach. The boundary has to come from the OS, and the Dockerfile is where I have put it.LISTEN/NOTIFYinvalidationcomputer/policy-store.tsalready documents. Say so and I will.Size
Around 9,500 lines: the Bot, the harness definition type shared by server and Bot, a
harness_definitionstable and its migration, the admin screen, and the endpoint probe replacing three lists that were compiled into the server and keyed on localhost ports (the same Bot behind a service on 443 matched none of them and offered no model choice at all).I know that is large for a first contribution here. If it is in scope but too big as one change, tell me how you would like it cut and I will cut it that way. The probe rewrite, the ACP Bot, and the custom-harness screen are separable, in that order.