Repository navigation
Description
Relocated from dezren39/darwin-nix#47 on 2026-10-28 (placement audit): mcpx's single source lives in developing-today/code (pkgs/mcpx); re-home tracked at #309. Original body below; issue references inside it are historical (dezren39/nix numbering).
Parent: #181
Backlog. Findings: pkgs/mcpx/docs/opencode-plugin.md §2 and §4.
v1 plugins do not load in opencode v2 — no shim, no fallback (packages/core/src/plugin/module.ts:60-73). v2 needs a rewrite against {id, setup}, not a port.
What changes, each better than the v1 equivalent:
| v1 today | v2 |
|---|---|
shell.env per command (carries sessionID) |
shell.create.before has no sessionID → use PUT /api/experimental/session/:id/environment once per session |
experimental.chat.system.transform |
session.hook("context") → event.system (or a budgeted catalog in event.tools, diffed between turns) |
tool map, un-namespaced |
tool.transform(e => e.add(...)) with a namespace |
tool.execute.after sees success only |
union on status — record failures too |
| state file for the remembered daemon | ctx.storage |
| no way to answer MCP sampling | ctx.generate.text — the plugin can answer mcpx's sampling questions |
$ for the CLI |
gone — and nothing is lost: since #53 (closes #44) the plugin reaches the daemon over the unix socket and spawns mcpx --json status only as rung 4, the last fallback (plugin/opencode/README.md:83-110, plugin/opencode/mcpx/daemon.ts); backend: v1 never spawns and bin: "" forbids it. In v2, drop rung 4 or keep it through node:child_process, which daemon.ts already imports |
| subdirectory to hide helpers from the loader | unnecessary; only default is read |
Also new in v2 and worth using: mcp.transform (register a filtered server set per session), permission.hook("evaluate") (real, unlike v1's dead permission.ask), promise-based TUI select() for the daemon picker.
Also: opencode v2's MCP client sends _meta["ai.opencode/sessionID"] on tool calls (packages/core/src/mcp/client.ts:278). When opencode v2 talks to mcpx as an MCP server, mcpx should read that for session attribution and leasing — no environment injection needed at all on that path.
Depends on: #44 (closed, fixed in #53 — the binary-free core exists).
Since this was filed (checked at 05c78b2):
- Phase 2: delegated Manage cannot add members #171's guard covers a v2 port automatically.
TestThePluginReadsNoUndeclaredSetting
(internal/settings/consumed_test.go:209-236) scans everyplugin/**/*.ts(x)except tests
(pluginSources,:288-320), so a v2 plugin anywhere underplugin/must honour only variables declared in
pluginSettings()(internal/settings/plugin.go:18). Phase 2: delegated Manage cannot add members #171 also wiredplugin.discoveryRetryand declared
plugin.remember/plugin.annotate; the v2 port keeps all three. - The dead
permission.askhook is recorded among the "declared but did nothing" incidents
(docs/declared-but-unread.md:8-12, Update Rust crate proc-macro2 to 1.0.81 - autoclosed #75's PR body); nothing in the v1 plugin is built on it
(docs/plugin-discovery.md:144-145). v2'spermission.hook("evaluate")is the real one. - The opencode-side line references above (
packages/core/src/plugin/module.ts:60-73,
packages/core/src/mcp/client.ts:278) are against opencode'sv2branch and were not re-checked in this pass.
No real choice: v1 plugins do not load in v2, so the only question is when. The table above is the design.
Ease · Impact · Related
Ease L (a rewrite against {id, setup}, not a port) · Impact med-high — nil while v1 is what runs,
total once v2 is (the v1 plugin does not load at all).
Related: #48 (the harness-free core this adapter sits on), #80 and #82 (the extension side; the same /v1
back-channel), #87 (ctx.storage replaces the remembered-daemon file; its lifetime follows #87's rule).
Security/auth deferred; see tracker.
Activity
developing-today commentedon Oct 28, 2026
CODE-785
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#47 (verbatim, oldest first):
@dezren39 · 2026-09-30T07:28:39Z
Integration pass. This issue has no category tracker -- it predates the build-out and is a dependency of several parts of it. Placed in the proposed order at #181.
@dezren39 · 2026-09-30T12:12:01Z
Issues pass (2026-09-30, at 05c78b2).
Parent: #181, a footer (Ease L, Impact med-high) and Related links.$row said the core "must already be binary-free (Bump rustls-webpki from 0.100.1 to 0.100.2 in /sources/pavex/examples/realworld #44)". chore(deps): bump build/buck/preludes/buck2-prelude fromd956689to880be56#53 closed Bump rustls-webpki from 0.100.1 to 0.100.2 in /sources/pavex/examples/realworld #44: the plugin uses the unix socket and spawnsmcpx --json statusonly as rung 4, the last fallback (plugin/opencode/README.md:83-110,daemon.ts).Depends on: #44is now marked closed.TestThePluginReadsNoUndeclaredSettingscans all ofplugin/**/*.ts(x), so a v2 port is covered and any variable it honours must be declared ininternal/settings/plugin.go. Also noted the deadpermission.askhook (docs/declared-but-unread.md).implementlabel.@dezren39 · 2026-10-28T20:40:37Z
Triage verdict (lane A, task 2037, 2026-10-28): CONFIRMED at current HEAD — a rewrite, routed code-side; kept open under #181.
Evidence (owning repo developing-today/code @ bfcfc15; the mcpx source left dezren39/nix on 2026-10-19, #468):
pkgs/mcpx/plugin/opencode/mcpx-session.ts:737still hooks the v1 API:"experimental.chat.system.transform": async (_input, output) => {.pkgs/mcpx/plugin/opencode/README.mdstill describes v1 loading semantics (everyplugin/*.tsexport called as a plugin) and install by copying into~/.config/opencode/plugin.{id, setup}export, nosession.hook("context")— the port has not happened.Routing: no follow-up packet from this triage. This is explicitly a rewrite, not a
small_fix, and the code lives in developing-today/code; backlog re-homing is tracked by #309 (OPEN). No counterpart for #47 exists there yet, so #47 stays open under tracker #181 until the re-home lands; the v1→v2 mapping table in this issue body is the spec for whoever picks it up there.dezren39 commentedon Oct 29, 2026
🤖 Agent note · picked up
dezren39 commentedon Oct 29, 2026
🤖 Agent note · done — triage verdict: scope CONFIRMED (a rewrite, as the issue says); dedupe settled — #730 and #1932 are neighbours, not duplicates; core rewrite routed as queue task 3068, v2-only wins recorded as SET-REMAINDER
.opencode/plugin/mcpx-session.ts(repo config, under the opencode migration tracker) — a different artifact from the shipped product plugin atpkgs/mcpx/plugin/opencode/that this issue covers. Both need doing; neither subsumes the other. A cross-note is posted on OpenCode 2: validate .opencode config against the v2 schema and port the v1 plugins #730 so the two ports share one shape instead of diverging._meta["ai.opencode/sessionID"]), not the daemon's pid #1932 already owns the server-side half of this issue's "Also" paragraph (_meta["ai.opencode/sessionID"]session attribution) — excluded from the follow-up packet.82b019a0(2026-10-29, via GitHub API): the shipped plugin is still purely v1 —pkgs/mcpx/plugin/opencode/mcpx-session.tsimports{ tool, type Plugin }from@opencode-ai/plugin, exports a single default, and hides helpers in themcpx/subdirectory precisely because the v1 loader globsplugin/*.ts(its own header comment) — the idiom this issue says v2 abolishes. No v2 tree exists. The daemon core it must reuse (mcpx/daemon.ts,ops.gen.ts) is present, and the settings guard (TestThePluginReadsNoUndeclaredSettingoverplugin/**/*.ts(x)) will cover a v2 tree automatically, as the issue records. One caution carried into the packet: this issue's opencode-side line references were taken against opencode'sv2branch and never re-checked — the implementer verifies v2 API facts against the pinned v2 indocs/opencode-plugin.md(reports 2.0.3) and the migration guide, not against those refs.hidden_files/packet-1858-fix.json), scoped to the core rewrite:{id, setup}shape, session-environment API, context hook, namespacedtool.transformregistration, status-uniontool.execute.after,ctx.storageremembered daemon, v1 plugin untouched beside it.ctx.generate.text,mcp.transformfiltered per-session registration,permission.hook("evaluate"), promise-based TUIselect()daemon picker. All four are specified in this issue's table._meta["ai.opencode/sessionID"]), not the daemon's pid #1932 · core substrate mcpx: a harness-free plugin core, with adapters for codex, claude code, pi, manus #1861 · follow-up queue task 3068111 remaining items
dezren39 commentedon Nov 3, 2026
🤖 Agent note · triaged (issue stays open as the set tracker)
triaged, no code change{id,setup}+ mcpx v2 plugin: permission gate for daemon_select (#1858 item (2)) #3018 item (2) permission evaluate) and mapped row-by-row topkgs/mcpx/plugin/opencode/v2/*at1e3763faf; remaining set = mcpx opencode v2 plugin: implement the #1858 SET-REMAINDER items (1)-(5) #2841 items (4)ctx.generate.text(feasible, pinned API confirmed), (3) TUI select (absent from pinned promise API — needs disposition), (1)mcp.transformper-session filter (not implementable as written:Transform<Input>is location-wide/synchronous,promise/registration.ts:21,promise/mcp.ts:6-16— same finding as task 3997), (5) retire v1 files (last)dezren39 commentedon Nov 3, 2026
🤖 Agent note · done
ctx.generate.text, returning a CreateMessageResult. Recorded deviation: sampling requests carrying tools/toolChoice are left for another answerer — the pinned generate surface has no tool use. Items (1), (3), (5) of the set remain open on issue mcpx opencode v2 plugin: implement the #1858 SET-REMAINDER items (1)-(5) #2841.dezren39 commentedon Nov 3, 2026
agent-note:v1
state: triaged (set update from task 8566, lane code-p)
Set tracker update for the #2841 SET-REMAINDER, verified fresh 2026-11-03: item (2) DONE (PR #3018 merged); item (4) implemented in PR #4997 (open, checks pass) — shepherd enqueued as task 8795; item (1) dispositioned as a recorded deviation (per-session mcp.transform is not implementable on the pinned v2 surface — synchronous, location-wide, no session ID): the accepted equivalent, session context-hook filtering of model-visible mcpx tools, is filed as issue #5122 and enqueued as task 8797 (small_fix). Items (3) and (5) of #2841 remain, sequenced after (1)/(4). Full verdict table is on #2841.
dezren39 commentedon Nov 3, 2026
SET-REMAINDER update — 2026-11-03
Item (4), answering mcpx sampling requests via OpenCode v2 ctx.generate.text, is now landed: PR #4997 merged at e425b6a. Tests rerun locally after merge: v2 plugin suite 48 passed; full plugin suite 101 passed, 5 skipped. The basic production-line check passed. The PR-specific mcpx test matrix did not run because this PR base predates #5151, which added the pull_request trigger to mcpx-test.yml.
The set remains open and tracked in #2841: item (1) has a recorded deviation/follow-up in #5122; items (3) and (5) remain.
dezren39 commentedon Nov 4, 2026
🤖 Agent note · done
f486f2aab6a98cf709a4b37659441f318eafa0f8); per-session tool filtering shipped via the session context hook as scoped on issue mcpx opencode v2 plugin: item (1) of #2841 — per-session tool filtering via session context hook (mcp.transform deviation) #5122;bun test plugin/opencode/v2/61 pass / 0 fail verified on the merged head tree. Issue mcpx opencode v2 plugin: item (1) of #2841 — per-session tool filtering via session context hook (mcp.transform deviation) #5122 is closed with the full note. Items (3) and (5) remain as scoped there.dezren39 commentedon Nov 4, 2026
agent-note:v1
state: picked-up
queue: repo-health-code-pilot
task: 8103 (triage, worker repo-worker-code, lane 262eb403-3347-4a7c-ba6b-e7bc263ca853), attempt 1
by: openchamber-scheduled-lane
at: 2026-11-04T01:46:32Z
Claimed to revalidate the set tracker. Fresh issue view: #1858 remains OPEN with no hard-stop labels; its latest recorded update says #5122's item (1) landed in #5170 and items (3) and (5) remain under #2841. I will verify the current tracker and whether the remaining scope is already owned before recording the triage verdict; no implementation in this task. Claim labels synced: work/assigned, queue/claimed, status/in-progress added; queue/queued and status/needs-triage removed.
dezren39 commentedon Nov 4, 2026
agent-note:v1
state: triaged
queue: repo-health-code-pilot
task: 8103 (triage, worker repo-worker-code, lane 262eb403-3347-4a7c-ba6b-e7bc263ca853)
by: openchamber-scheduled-lane
at: 2026-11-04T01:50:50Z
Verdict: still live only as the set tracker; keep #1858 open
Fresh revalidation: #1858 remains OPEN with no hard-stop labels. The core v2 rewrite is already landed (#2489, #3018); item (4) sampling is landed in #4997; item (1)'s accepted deviation is implemented in #5170 (merged 2026-11-04T00:36Z). #2841 is still OPEN as the canonical SET-REMAINDER implementation tracker. Its latest note confirms items (3) and (5) remain. Current main contains the v2 plugin tree and still has legacy paths pkgs/mcpx/plugin/opencode/mcpx-session.ts, mcpx-tui.tsx, and mcpx/. No open PR matches #1858 or #2841.
Routing: no duplicate fix packet created. The remaining items stay tracked under #2841, whose acceptance already sequences item (3) before retiring v1 files in item (5). #1858 deliberately remains OPEN as the set tracker until those are landed or explicitly waived. This task performed triage only; no code changed.