Repository navigation
Description
Relocated from dezren39/darwin-nix#210 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: #177
Summary
mcpx declares sampling to every upstream because the daemon always installs an elicitation handler, and docs/protocol.md says it is declared only when a handler exists. It declares roots to every upstream and always answers []; the doc says "the configured roots" and the daemon passes nil. Toward hosts, the elicitation gate treats any declared elicitation as form-capable, so a host that declared only url would be sent a form. Sampling is relayed after checking only that sampling is present, not sampling.tools or sampling.context. mcpx never asks its host for roots, which would be the honest source for the roots it answers upstream.
Found while writing the comparison register (pkgs/mcpx/docs/compare/) and checked against the code at 05c78b2. Each row below links its register entry, which carries the value, effort, risk, the specification text and every source.
Register rows
| row | difference | mcpx @ 05c78b2 | effort |
|---|---|---|---|
| CAP-02 | client roots; deprecated to a bare {} in 2026 |
partial — declared to every upstream; always answers an empty list | S |
| CAP-04 | client sampling; structured in 2025-11-25, deprecated in 2026 |
partial — declared to every upstream; only a broker agent answers | S |
| SMP-09 | Client declares sampling only when something can answer |
✗ — declared to every upstream; doc says otherwise | S |
| CAP-08 | client elicitation.form; {} means form only |
partial — form gate ignores a url-only declaration | S |
| SMP-11 | Relaying sampling to a host checks sub-capabilities and revision | ✗ — only sampling presence checked |
S |
| ROOT-04 | Server asks its host for roots | ✗ — never sends roots/list to a host |
M |
Evidence
internal/mcpclient/modern.go:46-58(sampling when a handler exists),internal/daemon/hooks.go:69(always a handler),internal/daemon/server.go:176(nilroots).internal/mcpserver/conn.go:191-211(CanElicit,CanSample).
What to do
Declare sampling only when a sampler is configured; answer roots from configuration or the host (or stop declaring roots); gate form mode on form present or neither key present; check sampling.tools/context before relaying.
Ease · Impact · Related
Ease S · Impact low · Related: #177, #110 (where the model comes from, after Sampling's deprecation)
Acceptance criteria
- mcpx declares
samplingandrootsto an upstream only when the corresponding handler actually exists — code matchesdocs/protocol.md(CAP-02/CAP-04). roots/listis answered from configured or host-provided roots, not unconditionally[].- Host-facing gates check sub-capabilities:
elicitationform vs url,sampling.tools/sampling.context— not merely the parent capability's presence. - mcpx obtains roots from its host where the host offers them, as the honest source for what it answers upstream.
- Tests cover declaration and gating per sub-capability.
Activity
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#210 (verbatim, oldest first):
@dezren39 · 2026-10-28T04:31:21Z
🤖 Intake review — fleet monitor, 2026-10-27 run
pkgs/mcpx/docs/compare/register/capabilities.md; cross-referenced by the register issue 🎨 Palette: Add ARIA labels to theme buttons #222 and conformance matrix test(mcpx): execid tests use testsupport.TempDir (fixes macOS failures, #282) #283.05c78b2(2026-09-30). Re-verify each row against currentmainbefore fixing — a row may have moved since.developing-today commentedon Oct 28, 2026
CODE-856
96 remaining items
dezren39 commentedon Nov 3, 2026
🤖 Agent note · picked up — docs fix in PR
b9e2eaf2; no hard-stop labels.roots/listrow, and the fixed §6 bullet removed; change fragmentdocs/changes/protocol-capability-claims.md.go run ./tools/docs-history check docs/*.md→ ok; no#210/coarser/passes nonematches left.Merge pull request #4993 from developing-today/queue/8151-1930-mcpx-p…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · docs remainder landed — #1930 complete
9637e164).pkgs/mcpx/docs/protocol.mdnow describes the capability gates as built:formkey;{}form-only;urlkey) and sampling per sub-capability (tools refused whole,includeContextdropped), citinginternal/mcpserver/conn.goCanElicit/CanSampleTools/CanSampleContext.roots/listrow — declarations only when a handler is installed and the daemon handler answers; roots relayed to a declaring host, else configureddaemon.roots.go run ./tools/docs-history check docs/*.md→ ok (also the change fragmentdocs/changes/protocol-capability-claims.md); no#210/ "coarser" / "passes none" text remains in protocol.md; docs-only diff.Cross-repo propagation to dezren39/nix's mcpx copy remains tracked by the cross-repo set rule (not this task).
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
developing-today commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03