MCP Elicitation LAB
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
MCP Elicitation LAB
An MCP server in the middle of a tool call needs more from the person, and asks the client for it in form mode or URL mode. This lab runs 19 scenarios against a mock server and a mock client that follows the spec's rules, shows the raw JSON-RPC of every message, builds the dialog a compliant client must show, and reports findings when a server breaks a MUST or SHOULD.
Tier: Tester Repo: https://github.com/curtismu7/mcp-elicitation-LAB Catalog: D37
Catalog D37 ("MCP elicitation lab") is an existing row of the demo catalog, not a placeholder. The catalog lists its kind as Demo; this README declares Tester because the app probes and scores a server's behaviour against the spec rather than telling a customer story.
Spec basis. MCP revision 2025-11-25, plus the current draft as a labelled difference. Both elicitation pages were read in full on 2026-10-22. basic/security_best_practices, basic/authorization and basic/patterns/mrtr were NOT read, so anything about them is UNVERIFIED. Real clients (do they implement URL mode?) were not probed. See docs/safety.md.
What is simulated
Mock mode (the only mode). The MCP server and the MCP client are both mocks written for this lab, running inside one process. Nothing is fetched, opened or sent anywhere: a URL in a scenario is analysed and shown, never requested, and a netguard refuses every non-loopback socket, DNS lookup, fetch and UDP send or connect. "Opens the URL in a secure browser view" is narration, not behaviour. The phishing scenarios model the attack the spec describes with a mock identity check; they exploit nothing.
Live mode (not available). There is no real MCP server or client to connect to, so the header's Live button answers with a message and the lab stays on Mock. Setting MEL_LAB_MODE=live makes the server refuse to start, with the same message. If Live is ever added it will be owner-run.
What it shows:
Form mode: accept, decline, cancel, client-side validation before anything is sent, and an empty capability meaning form only.
URL mode: a secret goes to the server's own page and not through the client,
-32042 URLElicitationRequiredthen a retry, declining consent, a client that did not declare URL mode, a stray completion notification.Servers that break rules, on purpose: a password in a form, a nested schema, a link in a form, a URL with a credential and a token, a Punycode host over http, a mode the client never declared, a malformed
-32042.Phishing: Alice triggers the elicitation, Bob opens the link. A server that does not verify the person binds Bob's account to Alice's session; one that does, refuses.
Diagram: ReactFlow, drawn from diagram-studio/1 data loaded by name: movable boxes, Simulate again, speed, Reset (restores box positions).
Talk track and presenter mode:
docs/talk-track.md, the page and the presenter notes are all rendered from one data file.
What is the lab's own behaviour (the spec does not define it) is labelled "lab behaviour" on screen: cancelling a form the client cannot render, and ending a malformed -32042.
Related MCP server: mcp_auth_server
Run from a clone
Prerequisites: Node 26 or newer. Docker only if you use the Docker form. Mock mode needs no setup at all: no tenant, no credentials, no settings file.
git clone https://github.com/curtismu7/mcp-elicitation-LAB.git
cd mcp-elicitation-LAB
npm ci
npm run build
npm startOpen http://127.0.0.1:6800/ . For development with hot reload: npm run dev (the API on 6800, the Vite dev server on http://127.0.0.1:6801/).
Settings file
All standalone apps read one optional settings file, ~/Development/.env (mode 600). Set STANDALONE_ENV to use another path. This lab takes one key from it and ignores everything else (it parses the file with util.parseEnv and copies only its own key); no value is ever printed:
MEL_LAB_MODE(optional):mock(the default).liveis refused with a message. A bareMODEis never read.
The shared file holds no PORT. Run-time knobs go in the shell, not in the file: PORT (see below) and MEL_LAB_BIND (loopback unless you set it on purpose; the container does). LAB_ALLOWED_HOSTS is a comma list of host names (no ports) the lab answers to besides loopback, as <name>:<PORT>; unset means loopback only. Docker defaults it to the name the family lab-proxy sends in Host (see docker-compose.yml), and on that Host only a write whose Origin equals X-Forwarded-Proto://X-Forwarded-Host counts as same-origin. The lab holds no credentials for anything, so no secret belongs in the file.
Ports, and what to do if the port is taken
Ports: MCP Elicitation LAB listens on 6800 (set with PORT, default 6800). The Vite dev server uses 6801 (set with VITE_PORT). The Docker host port is HOST_PORT, default 6800. Port range for this app: 6800-6849.
If the port is taken:
Find what is using it: lsof -iTCP:6800 -sTCP:LISTEN -n -P
If it is an old copy of this app, stop that process: kill .
If it is something else, either stop it or start this app on another port: PORT= npm start
Do not use 8080, 5173, 3000, 4000, 4400, 4510, 4600-4601, 18080, 19080 or 19090. Those are taken by other demos or other tools.
The server refuses a PORT outside 6800-6849 or on that reserved list.
Mock and live modes
The header has a Mock | Live toggle on the page, with the current mode beside it ("Mode: mock") and the same mode named in the banner, which also shows in presenter mode. Mock is on. Clicking Live shows why it is not available and changes nothing: no request is made and the banner still says MOCK. The server answers GET /api/info with mode: "mock" and the reason Live is refused.
Health, doctor and reset
npm run doctor # Node, mode, bind, port range, every scenario behaves as declared, citations, diagram data, talk track, netguard, one real HTTP run, port free
npm run reset # forgets every run in the default workspace; settings are kept
npm run smoke # drives every scenario through a RUNNING lab over HTTP (BASE_URL=http://127.0.0.1:6800)The app answers GET /api/health with demo-health/1 (public, GET only, no detail; the state comes from the same checks as the doctor). Reset in the header does the same as the script for your own workspace, and also puts the diagram boxes back where the data says. Each browser tab has its own workspace (X-Workspace, default default), so one tab's Reset never touches another's.
Docker (optional)
HOST_PORT=6800 docker compose up --build -dPublishes to 127.0.0.1 only (a test pins it). The container is read-only, drops all capabilities, runs as a non-root user and needs nothing else. Docker on OrbStack, never Docker Desktop.
Tests
npm testRuns the server (vitest), the web UI (vitest) and the repo checks (node --test scripts/*.test.mjs). On Node 26, 103 pass: 59 server, 17 web and 27 repo checks. The browser logs the deliberate 4xx answers a negative scenario provokes as console messages; that is expected. Also by hand, with the family's shared standards kit: its check-drift.sh . and check-css.sh ., and its conformance.mjs . --new (not yet run in CI; rule 18 warns because the SE k8s build is deferred).
Troubleshooting
The port is taken: see "Ports, and what to do if the port is taken" above.
refusing to start: mode:MEL_LAB_MODEis set tolive(or something else). This lab has only Mock; unset it.The page says "Could not load" or the diagram is empty: the API is not running, or you opened the Vite dev server without the API. Run
npm startand open port 6800, ornpm run dev.A request is refused with 403
bad_hostorcross_origin: the lab only answers a loopback Host (or aLAB_ALLOWED_HOSTSname, which is how the family lab-proxy reaches it) and same-origin writes. Open it as http://127.0.0.1:6800/ or through the family launcher, and do not put any other proxy in front.Docker health stays "starting": run
docker compose logs; the container needs port 6800 free inside andHOST_PORTfree on the host.
Ownership
Owner: the Ping SE demo family owner (see the repo settings).
License: MIT (see
LICENSE).Found a problem? Open an issue on the repo.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
Related MCP Connectors
Demo banking MCP server: accounts, transactions and payments. OAuth 2.1 with DPoP.
Prove real MCP clients can connect: 5-client x 3-IdP OAuth matrix with shim fixes.
Experimental MCP server for current empirical verification of explicit public HTTPS endpoint claims.
MEOK MCP Test MCP — golden-file + schema-drift + tool-failure tests for any MCP server. Drop-in
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA comprehensive reference implementation demonstrating all features of the Model Context Protocol (MCP) specification, serving as documentation, learning resource, and testing tool for MCP implementations.1MIT
- FlicenseNot gradedqualityDmaintenanceA proof-of-concept MCP server implementing OAuth 2.1 authorization with CIMD client registration and PKCE, demonstrating protected resource access and step-up authentication.-
- FlicenseNot gradedqualityDmaintenanceA zero-dependency Node.js playground for debugging how MCP clients authenticate to an MCP server over HTTP.-
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to interact with a fictional bank through remote tools, including mock banking operations, OAuth 2.1 authentication, and a live X-ray dashboard for observing session activity.MIT