Skip to content

feat(everything): add URL elicitation example (SEP-1036)#3895

Open
JosephDoUrden wants to merge 1 commit intomodelcontextprotocol:mainfrom
JosephDoUrden:feat/url-elicitation-example
Open

feat(everything): add URL elicitation example (SEP-1036)#3895
JosephDoUrden wants to merge 1 commit intomodelcontextprotocol:mainfrom
JosephDoUrden:feat/url-elicitation-example

Conversation

@JosephDoUrden
Copy link
Copy Markdown

Summary

Add a trigger-url-elicitation-request tool to the Everything server that demonstrates SEP-1036 URL Elicitation — the new url mode for secure out-of-band interactions.

Closes #3034

What is URL Elicitation?

SEP-1036 extends MCP elicitation with a url mode for scenarios where sensitive data (credentials, payment info) must not transit through the MCP client:

  • Third-party OAuth authorisation flows
  • Payment/subscription flows (PCI compliance)
  • Sensitive credential collection

The server sends elicitation/create with mode: "url", and the client navigates the user to the specified URL. The actual interaction happens out-of-band in the browser.

Changes

  • src/everything/tools/trigger-url-elicitation-request.ts: New tool that sends a URL elicitation request with an example GitHub OAuth URL
  • src/everything/tools/index.ts: Register the tool in registerConditionalTools (only when client declares elicitation.url capability)

Design

Follows the same pattern as the existing trigger-elicitation-request tool:

  • Conditionally registered based on client capabilities (elicitation.url)
  • Handles all three response actions (accept, decline, cancel)
  • Includes raw result for debugging
  • Uses ElicitResultSchema for response validation

Test plan

  • TypeScript compiles (npx tsc --noEmit)
  • All 95 existing Everything server tests pass (npx vitest run)

AI Disclosure

AI assistance (Claude) was used for issue research and understanding SEP-1036. The implementation was written and reviewed by the author.

Add a trigger-url-elicitation-request tool to the Everything server that
demonstrates SEP-1036 URL Elicitation. The tool sends an
elicitation/create request with mode "url", asking the client to
navigate the user to an external URL for out-of-band interaction (e.g.,
third-party OAuth authorization).

The tool is conditionally registered only when the client declares
elicitation.url capability, consistent with existing elicitation tools.

Closes modelcontextprotocol#3034
Copy link
Copy Markdown
Member

@olaservo olaservo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean implementation — follows the existing elicitation tool pattern exactly. The capability check and conditional registration are correct.

Two suggestions:

  1. Can you verify the elicitationId field is part of the SEP-1036 spec? If it's not a recognized field, it might be worth removing to avoid confusion.
  2. A basic test that verifies the tool is registered when the elicitation.url capability is present (and not registered when absent) would be a nice addition, though not blocking.

This review was assisted by Claude Code.

@cliffhall cliffhall added enhancement New feature or request server-everything Reference implementation for the Everything MCP server - src/everything labels Apr 20, 2026
@cliffhall
Copy link
Copy Markdown
Member

@claude review

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 21, 2026

Claude finished @cliffhall's task in 1m 45s —— View job


PR Review: feat(everything): add URL elicitation example (SEP-1036)

  • Gather context and read changed files
  • Compare with existing elicitation tool pattern
  • Check MCP protocol spec alignment
  • Review code quality and correctness
  • Post full review feedback

Overall this is a clean, correct implementation of SEP-1036 URL elicitation that follows the repo's existing patterns well. A few things to call out:

Spec alignment: elicitationId is correct and required

This addresses the concern raised in the previous review. Per the SEP-1036 spec:

URL mode elicitation requests MUST specify mode: "url" and include these parameters: url, elicitationId, message

elicitationId is a required field. crypto.randomUUID() is the right way to generate it. No change needed here.

Capability check is correct

trigger-url-elicitation-request.ts lines 36–40 correctly check for elicitation.url as a sub-capability — distinct from elicitation.form and consistent with the spec's capability structure. Good.

Missing: notifications/elicitation/complete

Per SEP-1036 (and the spec):

Servers SHOULD send a notifications/elicitation/complete notification when an out-of-band interaction started by URL mode elicitation is completed. The notification MUST include the elicitationId.

This reference implementation handles the accept response but never sends the completion notification. Since the everything server's purpose is to demonstrate MCP features, this omission means clients can't test the full URL elicitation lifecycle. The implementation pattern should be:

  1. Send elicitation/create (done ✓)
  2. Receive accept response (done ✓)
  3. Simulate the out-of-band flow completing → send notifications/elicitation/complete with the elicitationId (missing ✗)

Since this is a demo server and there's no real OAuth flow, a reasonable approach would be to send the completion notification after a short delay when the user accepts, to show clients the full round-trip. Fix this →

Tests need updating

registrations.test.ts line 56 — the mock capabilities for the conditional tools test use elicitation: {} (no url sub-key). This means trigger-url-elicitation-request will NOT be registered in that test scenario, and there is no assertion verifying it. Two things should be addressed:

  1. The test on line 48 should add a case with elicitation: { url: {} } capability and assert trigger-url-elicitation-request is registered.
  2. Conversely, verify it is not registered when only elicitation: {} (form-only) is declared.

This is the test coverage the previous reviewer suggested and it's straightforward to add. Fix this →

Minor nit: args parameter is unused

trigger-url-elicitation-request.ts line 46 — async (args, extra)args is declared but unused (consistent with the existing form elicitation tool, so not a blocker, but a _args prefix would make the intent explicit).

Summary

Spec correctness elicitationId is required and correctly generated
Capability gating ✅ Correctly checks elicitation.url sub-capability
Response handling ✅ All three actions handled correctly
Completion notification ⚠️ SHOULD per spec — missing for full lifecycle demo
Test coverage ⚠️ No tests for the new tool's conditional registration

The implementation is sound and spec-compliant. The completion notification and tests are the main items worth addressing before merge.

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

Labels

enhancement New feature or request server-everything Reference implementation for the Everything MCP server - src/everything

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Example for SEP-1036: URL Elicitation to Everything Server

3 participants