MCP server demo β tickets, schema discovery, auth, and PII gating. stdio + HTTP.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
One-click editor setup isnβt available for this listing yet β we donβt have a confirmed install command, and weβd rather show nothing than point your editor at the wrong package or host. Follow the projectβs own setup instructions, linked above.
A production-shaped MCP server you can run in under five minutes. Ships with 10 tools, 3 resources, 5 prompts, three auth modes, API key management, per-tool gates, rate limiting, a live observability dashboard, and a VS Code / Bob / Cursor / Windsurf control-plane extension.
Use it to learn MCP, test IDE integrations, run live demos, or as a reference implementation when building your own server.
Companion to MCP as a Platform: What I Learned Building a Portfolio of MCP Servers Β· MCP Dev Summit Toronto Β· 5 October 2026 Β· Talk slides β
| MCP server | npm install mcp-ticket-demo |
| VS Code extension | VS Code Marketplace Β· Open VSX |
| Talk slides | markusvankempen.github.io/linuxfoundation-mcp-dev-summit |
Personal open-source project. Not an IBM product.
Most MCP examples stop at "here is a tool that returns a string." This one goes further:
| Feature | What you learn |
|---|---|
| 10 tools with intent-named descriptions | Naming is the interface β not request(path, method) |
3 resources (ticket://, tickets://open, schema://) | resources/list enumerates instances; reads use the same gate() as the matching tool |
| 5 MCP prompts | User-facing prompts vs agent-facing tools |
Tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint: false) | Client confirm/retry UX |
| Server instructions | The README the model actually reads |
isError: true on every failure | Clients don't need to parse ok: false |
Attribution scar β create_ticket without requester_email | 201 is not done. The bot owns the ticket. |
Schema discovery β list_schemas β get_schema β run_query | One query tool beats a pile of query_* names |
| 0 tools discovered β hand a laptop path to a cloud runner | The silent failure with no error and no warning |
| stdio + SSE + Streamable HTTP from one codebase | Two transports, same 10 tools |
Auth modes (off / write / all) + per-tool gate + per-tool auth lock | Security is an operator concern |
tools/list_changed broadcast when admin flips a gate | SSE and Streamable HTTP sessions refresh; one-shot curl does not |
Rate limiting with retry_after_seconds in the error | Stop the model retrying in a loop |
PII redaction on lookup_customer | Scope-gated field visibility |
/health vs /test | Alive β works. Public /test is read-only; cwd stays off public /health |
Live observability β /log page with counters, error log, call trace | See what the model is actually doing |
Then open in a browser:
| URL | What it shows |
|---|---|
| http://127.0.0.1:8787/health | Is the process alive? (cwd only on localhost) |
| http://127.0.0.1:8787/test | Read-only smoke (search / get / schemas / query) |
| http://127.0.0.1:8787/admin | Auth mode, API keys, tool gates, observability |
| http://127.0.0.1:8787/log | Call counters, error log, full call trace |
| http://127.0.0.1:8787/tools | Tool inventory with scope and auth status |


Laptop login: demo / demo. On a public bind (HOST=0.0.0.0, container, Code Engine) set ADMIN_PASSWORD β the default is disabled. Write smoke is /test?write=1 after admin sign-in.
VS Code / GitHub Copilot β .vscode/mcp.json:
Bob / Cursor / Windsurf β .bob/mcp.json / .cursor/mcp.json / .windsurf/mcp.json:
Or install the extension and click Register server with all IDEs β it writes all four configs at once: VS Code Marketplace Β· Open VSX

| Tool | Scope | When to use | Lesson |
|---|---|---|---|
describe_server | open | First call, and after any denial | Discovery beats guessing |
search_tickets | read | Find by status / requester / keyword | Intent name, not an HTTP wrapper |
get_ticket | read | You already have a TCK-β¦ id | Instance fetch |
create_ticket | write | Open a ticket β always pass requester_email | Omit it β 201 + bot owns the ticket |
add_comment | write | Comment on a known ticket | Write tool; gated |
close_ticket | write | Resolve a ticket, optionally add resolution note | destructiveHint: true, idempotentHint: true |
list_schemas | read | Before any query | Discover the shape |
get_schema | read | After list, before query | Fields + filterable keys |
run_query | read | The one query tool | Replaces query_tickets / query_assets / β¦ |
lookup_customer | pii | Customer record β phone is PII | Redacted without pii scope |

Resources are addressable and pinnable β clients can subscribe and refresh. Tools are for agent loops.
| URI | What it returns | Same gate as |
|---|---|---|
ticket://TCK-1001 | One ticket by id | get_ticket |
tickets://open | Live open ticket list (top 25) | search_tickets |
schema://tickets | Query schema shape (also customers, assets) | get_schema / list_schemas |
Call resources/list to browse β you do not need to know a URI ahead of time. A denied read is a JSON-RPC error (not a fake ticket document you can pin).
User-facing prompts β the user picks these, the model executes them.
| Prompt | Lesson it teaches |
|---|---|
search-open-tickets | Find service-account scars in the live data |
attribution-scar | Create without requester_email β explain what broke |
schema-discovery | list_schemas β get_schema β run_query walkthrough |
close-ticket-flow | add_comment then close_ticket in sequence |
diagnose-server | describe_server β auth mode, scopes, available tools |
Credentials: Authorization: Bearer <api key> over HTTP Β· MCP_API_KEY env var over stdio.
Issue keys, set modes, toggle per-tool gates, and lock individual tools on /admin.
A change broadcasts notifications/tools/list_changed to connected SSE and Streamable HTTP sessions (Cursor/Bob after initialize). One-shot POST /mcp (curl) has no session β it sees the new list on the next call.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/mcp-ticket-demo)<a href="https://allmcps.com/mcp/mcp-ticket-demo"><img src="https://allmcps.com/api/badge/mcp-ticket-demo?style=directory" alt="MCP Ticket Demo on AllMCPs" /></a>