Skip to content

mcpx: capabilities declared to upstreams that nothing answers, and host gates that ignore sub-capabilities #1930

Closed

Description

@dezren39

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 (nil roots).
  • 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 sampling and roots to an upstream only when the corresponding handler actually exists — code matches docs/protocol.md (CAP-02/CAP-04).
  • roots/list is answered from configured or host-provided roots, not unconditionally [].
  • Host-facing gates check sub-capabilities: elicitation form 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

  1. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    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

  2. added
    bugSomething isn't working
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    source/humanFiled directly by a human
    priority/normalOrdinary priority (the default)
    effort/mMedium: expected under 1 day of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 28, 2026
  3. developing-today commented on Oct 28, 2026

    @developing-today
    Contributor
  4. added
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 29, 2026
  5. 96 remaining items

  6. added
    queue/queuedHas a queued task in the Supabase agent queue
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 3, 2026
  7. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up — docs fix in PR

  8. added a commit that references this issue on Nov 3, 2026
  9. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · docs remainder landed — #1930 complete

    • Fix: PR docs(mcpx): protocol.md describes the capability gates as built (#1930) #4993 MERGED (merge 9637e164). pkgs/mcpx/docs/protocol.md now describes the capability gates as built:
      • §3.1 — elicitation read per mode (form key; {} form-only; url key) and sampling per sub-capability (tools refused whole, includeContext dropped), citing internal/mcpserver/conn.go CanElicit/CanSampleTools/CanSampleContext.
      • §4 declared-to-servers row and §4.1 roots/list row — declarations only when a handler is installed and the daemon handler answers; roots relayed to a declaring host, else configured daemon.roots.
      • §6 — the "capabilities declared upstream that nothing answers" gap removed.
    • Verification: go run ./tools/docs-history check docs/*.md → ok (also the change fragment docs/changes/protocol-capability-claims.md); no #210 / "coarser" / "passes none" text remains in protocol.md; docs-only diff.
    • Duplicate: PR docs(mcpx): correct protocol capability claims (#1930) #3689 diffed (nothing unique) and closed as superseded.
    • Code remainder: zero, per triage task 7785 (verdict on this issue 2026-11-03). Acceptance met — closing as implemented.

    Cross-repo propagation to dezren39/nix's mcpx copy remains tracked by the cross-repo set rule (not this task).

  10. removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  11. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    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

  12. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    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

  13. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    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

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

Metadata

Metadata

Assignees

Labels

app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)bugSomething isn't workingeffort/mMedium: expected under 1 day of workkind/bugSomething isn't working (prefixed form of the classic bug label)meta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)queue/queuedHas a queued task in the Supabase agent queuesource/humanFiled directly by a humanstatus/needs-triageNot yet triaged; needs a first looktask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions