Repository navigation
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't suggested before. Related issues were found but all were auto-closed by the stale bot without official resolution — see "Related issues" below.
Describe the enhancement you want to request
While porting a quota-aware retry plugin (429 handling with unlimited round continuation) to the opencode 2.0 plugin API, we hit two platform gaps in the same area: plugins cannot manage session messages (revert), and plugins cannot discover the HTTP API of the server instance they run inside.
1. session.revert is not exposed to plugins
The capability exists end-to-end except at the plugin boundary:
- Core service: revert
stage/clear/commitare implemented (packages/core/src/session.ts~:451-454) - HTTP API:
POST /api/session/:id/revert/stage,DELETE .../revert,POST .../revert/commit(packages/protocol/src/groups/session.ts) - Plugin Host session domain (
packages/core/src/plugin/host.ts~:518-546) and the promise adapter (packages/plugin/src/promise/adapter.ts) bridge create/get/prompt/synthetic/interrupt/update/move/wait/context — but not revert. Same for the effect-form session domain (packages/plugin/src/effect/session.ts).
Use case: when a provider quota exhausts mid-turn, our plugin re-drives execution via ctx.session.synthetic (works great). To keep the transcript clean we would like to remove the failed assistant message and the previous internal marker — currently impossible from a plugin, forcing either HTTP self-calls (with server port/password configuration) or accepting a growing list of failed messages.
Request: bridge revert.stage/clear/commit (or at minimum a remove(messageID)) into the plugin session domain.
2. Plugins cannot discover their own server's HTTP endpoint
Plugins run in-process with the server, yet there is no way to learn which server instance they belong to:
ctx.apponly exposes name/version/channel- No
url/port/auth anywhere in the plugin context - The official discovery file (
~/.local/state/opencode/service.json, written only inservicemode) containsurl/pid/password, but a plugin reading it cannot safely assume it maps to its own instance (multi-instance machines), andservemode does not write it at all
Request: expose the server's own endpoint + auth (e.g. ctx.app.server = { url, password } or similar) so plugins can call their own instance's HTTP API without user configuration.
Related issues
- [FEATURE]: Expose the ability to modify the chat messages thread via a plugin #7034 — plugins modifying chat history / going back to an earlier message (v1 era, auto-closed by stale bot; this issue is its 2.0-specific subset: bridge the existing revert into the plugin session domain)
- [FEATURE]: add ensureServer() to PluginInput for plugins that need an HTTP server #31821 —
ensureServer()for plugins needing an HTTP server (auto-closed by stale bot; complementary: we ask for discovery of the already-running server, not spinning one up) - [FEATURE]: Export actual server URL as environment variable #9099 — export actual server URL as env var (auto-closed by stale bot; env var helps child processes, but a first-class plugin-context field is cleaner and covers plugins specifically)
- [FEATURE] Desktop: persist sidecar server URL/credentials to disk (XDG_STATE_HOME) so companion tools can auto-discover #47206 — Desktop sidecar URL/credentials persisted to disk for companion tools (open, but scoped to the Desktop sidecar scenario; ours targets the plugin API on any deployment)
Environment
opencode 2.0.15 (linux/arm64 binary + packages/core source). Plugin form: promise (define/{id, setup}).
Activity
[-]Plugin API: expose session revert, and server self-endpoint discovery for plugins[/-][+][FEATURE]: Plugin API: bridge session revert, and expose server self-endpoint to plugins[/+]github-actions commentedon Sep 27, 2026
Thanks for updating the issue with the required feature verification checkbox and [FEATURE]: title prefix!
Shalin-Shah-2002 commentedon Sep 27, 2026
Implementation PR opened: #51601. It adds plugin session revert operations and instance-specific
ctx.app.serverendpoint credentials. The PR targetsv2, includes focused validation, and usesFixes #51599for automatic tracking.Shalin-Shah-2002 commentedon Sep 27, 2026
PR #51601 was rebased onto
v2to remove unrelated pre-existing worktree history. It now contains only the focused implementation commit and nine issue-related files.opencodejr commentedon Oct 28, 2026
Thanks for the detailed request! You're asking for two additions to the v2 plugin API:
stage/clear/commit, or a simplerremove(messageID)) into the plugin session domain, so a plugin can remove failed assistant messages.I checked the current code. The promise and effect plugin session domains bridge
synthetic,interruptand other methods, but not revert, and the plugin context has no server URL or credentials. Neither of these can be worked around inside a plugin right now. Maintainers will consider the request.Related issues:
serverUrlgiven to plugins was fabricated under the in-process transport, which matters for any server-URL fieldOpeOginni commentedon Nov 6, 2026
Another use case for the server self-endpoint request is a server plugin that moves the current session to a remote OpenCode server. This cannot work with
--standalonewithout a change in OpenCode.Problem and use case
This needs
session.exporton the local server,session.importon the remote,session.form.create/get/cancelfor user confirmation, andsession.activeplussession.inbox.listto check that the local session is idle. The plugin context'ssessiondomain exposes none of these.ctx.rpconly reaches plugin-registered methods, not the server's own API.What we tried
A plugin can build an
OpenCode.makeclient usingService.discover()or explicitly configured server credentials. Butopencode --standalonestarts a privateopencode serve --stdio --port 0with a random port. Plugins receive no address, and the server deletesOPENCODE_SERVER_PASSWORDfrom its environment after reading it. Discovery finds the background service instead, which is not hosting the session. The private URL cannot be configured ahead of time.The only workaround today is
opencode serve --port 4096, attach withopencode --server http://127.0.0.1:4096, and configure the plugin to use that address.Verified with OpenCode 2.2.5,
@opencode/plugin2.0.30, and@opencode/client2.2.1.Proposal
ctx.client, anOpenCodeClientscoped to that plugin. It should work in service, standalone, andservemodes without discovery, ports, or passwords.export,import,formwith create/get/cancel,active, andinbox.listto the pluginsessiondomain.We're happy to send a PR if maintainers say which option they prefer.