Skip to content

feat(elicitation): MCP 2025-06-18 elicitation support - #139

Merged
zoedsoupe merged 3 commits into
mainfrom
feat/elicitation
Apr 27, 2026
Merged

zoedsoupe merged 3 commits into
mainfrom
feat/elicitation

Conversation

@zoedsoupe

Copy link
Copy Markdown
Owner

Problem

Closes #30. The 2025-06-18 MCP spec adds elicitation — server-initiated
requests for structured user input via the client. Anubis already declared
:elicitation as a feature of Protocol.V2025_06_18 but had no wire-level
implementation.

Solution

Mirror the existing sampling/roots architecture end-to-end:

  • Protocol: register elicitation/create method + Peri params schema in
    Anubis.MCP.Message; gate it to v2025-06-18 in the version module.
  • Validator (Anubis.MCP.ElicitationSchema): defschema-based check of the
    restricted JSON Schema subset (flat object, primitive types, formats
    email/uri/date/date-time, enum+enumNames). validate_content/2 converts
    the runtime schema to a Peri schema and validates payloads.
  • Client: new :elicitation capability; register_elicitation_callback/2
    registers a 2-arity callback returning {:accept, map} | :decline | :cancel | {:error, reason}. New Anubis.Client.Elicitation mirrors Sampling.
  • Server: Anubis.Server.send_elicitation_request/3 (validates schema
    synchronously before any wire I/O) + new handle_elicitation/3 callback.
    Session tracks the request alongside sampling/roots and validates response
    content before dispatching to user code.

Tests: 25 schema, 9 client, 5 session — all 693 + 33 doctests pass; credo
strict clean.

Rationale

Elicitation is structurally a third server→client request type alongside
sampling and roots, so reusing the same patterns (capability gating, callback
registration in client State, server_requests tracking on the session,
async dispatch via handle_* callback) keeps the surface area small and
consistent with project conventions. Validation lives in a dedicated module
so both sides can guard the same way: server before sending, client before
returning accept content, server again before calling user code — the spec
asks both parties to validate, and bad data never reaches user callbacks.

Implement server-initiated `elicitation/create` requests and client-side
handling per the 2025-06-18 spec. Mirrors the existing sampling architecture:
clients advertise the `elicitation` capability and register a 2-arity callback
returning `{:accept, content} | :decline | :cancel | {:error, reason}`; servers
call `Anubis.Server.send_elicitation_request/3` and receive responses via the
new `handle_elicitation/3` callback.

Adds `Anubis.MCP.ElicitationSchema` for validating both the restricted JSON
Schema subset (flat object, primitive types, formats: email/uri/date/date-time,
enum + enumNames) and content payloads against a validated schema. Validation
runs synchronously in `send_elicitation_request/3` and again on the client
before returning accept content, and on the server before invoking
`handle_elicitation/3` — bad payloads never reach user code.

Closes #30
@zoedsoupe
zoedsoupe merged commit 8ab36e2 into main Apr 27, 2026
9 checks passed
@zoedsoupe
zoedsoupe deleted the feat/elicitation branch April 27, 2026 23:26
@zoedsoupe zoedsoupe mentioned this pull request Apr 27, 2026
@coderabbitai

coderabbitai Bot commented Apr 27, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@zoedsoupe has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 51 minutes and 15 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d0e9972c-0eaf-4937-9c2d-1674252f4f4d

📥 Commits

Reviewing files that changed from the base of the PR and between b9fde69 and aabbf23.

📒 Files selected for processing (1)
  • lib/anubis/client/elicitation.ex
📝 Walkthrough

Walkthrough

This change implements end-to-end Model Context Protocol (MCP) elicitation support across the Anubis framework. It introduces client-side elicitation callback registration and request handling via a new Anubis.Client.Elicitation module, adds server-side initiation through send_elicitation_request/3 and handle_elicitation/3 callback, implements schema validation for requested schemas and content via Anubis.MCP.ElicitationSchema, extends the MCP message protocol to recognize elicitation/create requests, and adds session-level request tracking with timeout-based cancellation. Comprehensive test coverage validates both client and server flows, including error paths and schema validation scenarios.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding MCP 2025-06-18 elicitation support to the codebase.
Description check ✅ Passed The PR description follows the template, covering Problem (closes #30, context on missing implementation), Solution (detailed breakdown of changes per component), and Rationale (architectural reasoning and consistency).
Linked Issues check ✅ Passed The PR fully addresses #30 by implementing end-to-end elicitation support: capability advertisement, wire protocol, schema validation, client callbacks, server send API, and response handling.
Out of Scope Changes check ✅ Passed All changes are directly scoped to elicitation feature implementation. Minor test fixture updates (stub_server, stub_transport) support the new functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/elicitation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Elicitation plans?

1 participant