Skip to content

Research spike: elicitation-based confirmation #33

Open

Description

@roborourke

Research only. Do not start implementation until this has been reviewed.

Confirmation guidance in tool descriptions (#30) is advisory — a model can ignore it. Elicitation is the MCP mechanism for a real prompt: the server asks the client to confirm before a call proceeds. Claude Code supports it. MCP Adapter v0.6.1 does not implement it.

Upstream discussion: WordPress/mcp-adapter#176. What it establishes:

  • mcp_adapter_pre_tool_call already exists (adapter v0.5.0). A plugin can rewrite arguments or return a WP_Error to block a call. That's a hard stop, not a prompt — it can't ask the user anything.
  • A custom pending/approved/rejected envelope was proposed and turned down. That vocabulary isn't part of the MCP protocol, so a generic client only sees text and doesn't know to poll. This also rules out a home-grown "preview then confirm" convention as a general fix.
  • Elicitation needs a server-to-client channel, which over HTTP means SSE. The adapter has no SSE transport, and the maintainer doesn't expect one soon — an open stream pins a PHP worker, and WordPress runs on hosts with aggressive timeouts.
  • McpTransportInterface is frozen public API. A plugin can register its own transport (the STDIO one already does), so an SSE transport with elicitation-based approval could be proven outside the adapter first. The maintainer explicitly asked for a runnable proof over more design discussion.

Write up:

  1. Whether hm-rest-ability is the right home for an SSE transport, or whether it belongs in a separate plugin.
  2. The hosting cost — a pinned PHP worker per open session is a real constraint on Altis/VIP and most managed hosts. This may be the thing that rules it out.
  3. Which clients support elicitation today, and whether that's enough coverage to justify the work.
  4. Prior art: ibrahimhajjaj/abilityguard (ability-layer approval, snapshot, rollback) and the merged Automattic/agents-api#234.
  5. Related upstream issue Audit hook for tool calls (post-execution complement to #176) WordPress/mcp-adapter#228 — a mcp_adapter_tool_executed action for audit logging. Independent of approval, may be worth supporting either way.

A conclusion of "not yet, hosting cost is too high" is a valid outcome. Write it down so the decision doesn't get re-litigated.

Part of #28.

Activity

  1. roborourke commented on Sep 15, 2026

    @roborourke
    CollaboratorAuthor

    1. Where an SSE transport should live

    Not this plugin. hm-rest-ability's job is exposing REST routes as abilities. An SSE transport is a generic MCP Adapter concern — any plugin registering abilities would want elicitation, not just this one. Building it here couples a narrow-purpose plugin to a long-lived connection it has no other reason to hold open, and makes this plugin harder to audit. It belongs in its own plugin, proven there first, per the maintainer's ask in #176 — and is a better upstream contribution once proven than something HM keeps forking-and-maintaining alone.

    2. Hosting cost

    WP Engine's shared and mid tiers cap PHP workers between 2 and 8 total, across all traffic on the site. A pinned worker per open elicitation session competes directly with that pool. A handful of concurrent AI sessions waiting on a human to confirm could exhaust it and start 503ing real visitors. This is a hard blocker on HM's typical managed tiers, not a tuning problem. It would need a design that doesn't hold a PHP worker open for the wait — a queue with polling, or a relay outside PHP-FPM — before it's viable on shared hosting.

    3. Client coverage

    Claude Code CLI supports elicitation. Claude Desktop does not yet (open feature request). Cursor added it recently. Coverage is partial and inconsistent across the clients people actually use. Building an SSE transport now would serve a minority of clients while adding real hosting risk to every install, including sites whose users are on a client that ignores it entirely.

    4. Prior art

    ibrahimhajjaj/abilityguard is a developer library, not a drop-in fix. Ability authors opt in per-ability with a safety key (snapshot, audit, approval, rollback) on wp_register_ability(), and it works across REST, MCP, CLI, and internal calls. It's a useful reference for the registration pattern — snapshot before, diff after, rollback on demand — but it's v1.2.0 with a single star, so treat it as a design reference, not a dependency to pull in.

    Automattic/agents-api#234 (merged) implements the in-process version of this: a filter that returns a "pending action" envelope, and a loop that halts and surfaces status: approval_required. It works because the consumer is Automattic's own agent loop, which understands that vocabulary. This is exactly the case the mcp-adapter maintainer flagged in #176 as not porting to MCP — a generic external client only sees text and has no vocabulary to poll against. It confirms rather than changes that conclusion.

    5. #228 status

    Open, two comments, not merged. Proposes a mcp_adapter_audit_tool_call action fired on every call outcome, including denied and blocked calls the current mcp_adapter_tool_call_result filter misses. Independent of approval — audit logging works whether or not elicitation ever lands. Worth watching, not blocking on.

    Recommendation

    Wait. Client coverage is too thin (Claude Desktop lacks elicitation entirely) and the hosting cost is a real blocker on HM's typical tiers, not a hypothetical one. Revisit once elicitation support is broader across clients and once a non-worker-pinning transport design exists to prove out separately from this plugin.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions