Mcp Ticket Demo

io.github.markusvankempen由 GitHub 帳號 markusvankempen 發布v1.9.0更新於 Oct 27, 2026

MCP server demo — tickets, schema discovery, auth, and PII gating. stdio + HTTP.

發布方自己的服務:demo.st

已驗證STDIO僅桌面效率與工作流開發者工具

概覽

AI 產生的概覽

用來學習與示範 MCP 的參考工單伺服器,內含 19 個工具、資源、提示詞、驗證模式、PII 遮蔽與流量限制。

可以做什麼
  • 探索伺服器能力與查詢 schema,再用單一查詢工具讀取工單、客戶、資產、計時器、設定與事件
  • 建立、留言與關閉工單,未具備 pii 權限時客戶電話等欄位會被遮蔽
  • 讀取可定址資源:單張工單、未結案工單清單與 schema 結構,並使用五個面向使用者的提示詞進行引導式演練
  • 維運伺服器本身:修改設定、管理使用者與 API 金鑰、匯入設定、啟停計時器、推送日誌列與發布系統資訊
  • 以本機 stdio 程序或 HTTP 服務執行,提供健康檢查、測試、管理、日誌與工具清單頁面
適用情境
適合想了解 MCP 伺服器如何運作、用貼近實務的伺服器測試 IDE 或代理整合、進行現場示範,或作為自建伺服器的參考實作。它是示範專案,並非正式工單系統。
執行需求
需要 Node.js,可透過 npx 或複製儲存庫執行;預設為 stdio,也可用 HTTP 模式並指定連接埠與主機。選用設定包括 AUTH_MODE、用於 stdio 憑證的 MCP_API_KEY、額外登入的 MCP_USERS、RATE_LIMIT,以及管理頁面的 ADMIN_USER/ADMIN_PASSWORD。不需要外部帳號或服務。
安裝前請注意
驗證預設關閉,所有工具皆開放,需自行設定 AUTH_MODE。管理登入預設為 demo/demo,在公開綁定前必須以 ADMIN_PASSWORD 變更。設定、使用者與 API 金鑰類工具會變更所指伺服器的實際設定,部分工具即使驗證關閉也需 admin 權限。工單存於記憶體,重新啟動即重設。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Mcp Ticket Demo,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

[MCP as a Platform — MCP Dev Summit Toronto 2026]

MCP Ticket Demo — A Full-Stack MCP Reference Server

[npm] [npm downloads] [VS Code] [Open VSX] [License] [Node.js] [MCP] [IBM Cloud] [Linux Foundation]

A production-shaped MCP server you can run in under five minutes. Ships with 19 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 →

Personal open-source project.


What makes this useful beyond a hello-world

Most MCP examples stop at "here is a tool that returns a string." This one goes further:

FeatureWhat you learn
19 tools with intent-named descriptionsNouns live in a schema, verbs stay as tools — 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 promptsUser-facing prompts vs agent-facing tools
Tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint: false)Client confirm/retry UX
Server instructionsThe README the model actually reads
isError: true on every failureClients don't need to parse ok: false
Attribution scar — create_ticket without requester_email201 is not done. The bot owns the ticket.
Schema discovery — get_schema → run_queryOne query tool beats a pile of query_* names
0 tools discovered — hand a laptop path to a cloud runnerThe silent failure with no error and no warning
stdio + SSE + Streamable HTTP from one codebaseThree transports, same 19 tools
Auth modes (off / write / all) + per-tool gate + per-tool auth lockSecurity is an operator concern
tools/list_changed broadcast when admin flips a gateSSE and Streamable HTTP sessions refresh; one-shot curl does not
Rate limiting with retry_after_seconds in the errorStop the model retrying in a loop
PII redaction on run_query schema=customersSame tool, same endpoint; the phone field is REDACTED without the pii scope
/health vs /testAlive ≠ works. Public /test is read-only; cwd stays off public /health
Live observability — /log page with counters, error log, call traceSee what the model is actually doing
Operate it over MCP — settings (one update_settings patch), users, API keys and settings import are tools, settings export is run_query schema=settings, and most need the admin scope even when auth is offThe control plane is part of the server, not a side door
Three ways to operate one server — /admin Remote config, the extension's Remote config tab, and the mcp-ticket-demo command lineSame steps, same Demo setup, checked against each other

Quickstart — five minutes

bash
# Run directly from npm — no clone needednpx mcp-ticket-demo           # stdio (IDE spawns this)MCP_MODE=http npx mcp-ticket-demo  # HTTP — opens /health /test /admin /mcp
# Or clone and rungit clone https://github.com/markusvankempen/mcp-ticket-democd mcp-ticket-demo/server && npm install && npm run http

Then open in a browser:

URLWhat it shows
http://127.0.0.1:8787/healthIs the process alive? (cwd only on localhost)
http://127.0.0.1:8787/testRead-only smoke: seed tickets, schemas, and run_query
http://127.0.0.1:8787/adminAuth mode, API keys, tool gates, observability
http://127.0.0.1:8787/logCall counters, error log, full call trace
http://127.0.0.1:8787/toolsTool inventory with scope and auth status

From a terminal

The same mcp-ticket-demo command is also a client for a running server, local or deployed. With no arguments it is still the MCP server, so the IDE configs below keep working.

bash
npx mcp-ticket-demo status                                    # http://127.0.0.1:8787/mcp by defaultnpx mcp-ticket-demo call run_query schema=tickets 'filter={"status":"open"}' limit=5   # any tool, values typed from its schemanpx mcp-ticket-demo demo apply --user demo --password demo    # users, keys, auth write, 30 calls / 60 snpx mcp-ticket-demo demo check --user demo --password demo    # acts as each role and as nobodynpx mcp-ticket-demo status --url https://my-host.example.com  # a deployed server

--json prints one document for scripts, and exit codes are 0 done · 1 refused · 2 usage · 3 unreachable. Commands that delete or reconfigure ask first. Every command, option and example is in server/README.md, and a copy-paste page is at /clients/cli.html on a running desk. demo apply changes real settings, so use it on a server you own.

[/health — liveness check with version, tool count, and cwd]

[/test — read-only smoke test: seed tickets, schemas, and run_query]

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.


Add to your IDE (one line)

VS Code / GitHub Copilot — .vscode/mcp.json:

json
{  "servers": {    "mcp-ticket-demo": {      "type": "stdio",      "command": "npx",      "args": ["mcp-ticket-demo"],      "env": { "MCP_MODE": "stdio" }    }  }}

Bob / Cursor / Windsurf — .bob/mcp.json / .cursor/mcp.json / .windsurf/mcp.json:

json
{  "mcpServers": {    "mcp-ticket-demo": {      "command": "npx",      "args": ["mcp-ticket-demo"],      "env": { "MCP_MODE": "stdio" }    }  }}

Or install the extension and click Register server with all IDEs — it writes all four configs at once: VS Code Marketplace · Open VSX

[Extension diagnostics panel — all steps passing, server confirmed healthy]


Tools

The server has 19 tools. Six are the ticket desk, below. Eight operate the server itself: update_settings (every setting is one patch: auth mode, rate limit, call trace, desk sign-in, transports, events, gates, locks and scopes), set_mqtt, users, API keys, import_settings and sample traffic. Most of those need the admin scope even while auth is off; server/README.md lists the scope of each. Three are timers, start_timer, stop_timer and push_timer, with no get_timer (push_timer also streams the timer as events; see Events): you read a timer through the schema, run_query with schema=timers (server/README.md). push_log sends a log line as an event, and watch_system publishes the machine as system.info, including a container's cgroup limit. Plain lists are not tools of their own: run_query reads settings (the saved settings, importable as they are), system (the machine), events (the events already sent), and, with an admin credential, users, api_keys, trace, errors and counters. The page at /clients/dashboard.html draws them. Each of these tools is declared once and everything else is generated from that definition.

The ticket desk (6)

ToolScopeWhen to useLesson
describe_serverreadFirst call, and after any denialDiscovery beats guessing
create_ticketwriteOpen a ticket — always pass requester_emailOmit it → 201 + bot owns the ticket
add_commentwriteComment on a known ticketWrite tool; gated
close_ticketwriteResolve a ticket, optionally add resolution notedestructiveHint: true, idempotentHint: true
get_schemareadBefore any queryNo name lists every name with its kind (data, query, tool); a name gives that shape or those arguments
run_queryreadThe one query tool: schema=tickets (find by status / requester_email / query, or one ticket by id with body and comments), schema=customers (phone is REDACTED without the pii scope), plus assets, timers, system, settings, events (and, for an admin, users, api_keys, trace, errors, counters)Nouns in a schema, verbs as tools. Replaces query_tickets / query_assets / …

[Chat tab — AI calls MCP tools to create and query tickets live]


3 Resources

Resources are addressable and pinnable — clients can subscribe and refresh. Tools are for agent loops.

URIWhat it returnsSame gate as
ticket://TCK-1001One ticket by idrun_query
tickets://openLive open ticket list (top 25)run_query
schema://ticketsQuery schema shape (also customers, assets)get_schema

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).


5 Prompts

User-facing prompts — the user picks these, the model executes them.

PromptLesson it teaches
search-open-ticketsFind service-account scars in the live data
attribution-scarCreate without requester_email → explain what broke
schema-discoveryget_schema (no name) → get_schema (name) → run_query walkthrough
close-ticket-flowadd_comment then close_ticket in sequence
diagnose-serverdescribe_server — auth mode, scopes, available tools

Auth model

off    All tools open. No credential needed. Default for local dev.write  Read tools open. Write tools need a credential. The customer phone shows only with a `pii` credential.all    Every tool call requires a credential.

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.


Repo layout

mcp-ticket-demo/  server/       MCP server — tools, resources, prompts, auth, HTTP pages    src/cli/    The command line client (mcp-ticket-demo <command>)    clients/    Copy-paste setup pages served at /clients/ (editors, browser, CLI, settings)  extension/    VS Code / Bob / Cursor / Windsurf control-plane extension (packs a copy of server/)  docs/         Walkthroughs, lessons learned, publishing guide  Dockerfile    node:20-bookworm-slim, non-root USER node, WORKDIR /app

Docs

DocWhat's in it
docs/README.mdIndex of these guides, for server 3.0.1 and extension 1.16.0
docs/DEMO.mdEnd-to-end demo guide — 16 live curl demos, every lesson, real captured output
docs/LESSONS-LEARNED.md15 lessons building a real MCP server — war stories + pre-publish checklist
docs/LOCAL.mdLocal stdio + HTTP walkthrough
docs/REMOTE.mdCode Engine deploy + the 0-tools-discovered repro
docs/ADMIN-AND-SECURITY.mdAuth modes, API keys, tool gates
docs/BOB.mdIBM Bob specific setup
docs/PUBLISHING.mdnpm + MCP Registry + VS Code Marketplace publish steps
docs/EXTENSION.mdThe VS Code / Cursor / Bob extension — tabs, Remote config, commands
server/README.mdFull curl reference for every endpoint, and the command line client

Environment variables

VariableDefaultWhat it does
MCP_MODEstdiostdio or http
PORT8080HTTP only. npm run http uses 8787
HOST127.0.0.10.0.0.0 inside container (set automatically)
AUTH_MODEoffoff · write · all
ADMIN_USER / ADMIN_PASSWORDdemo / demo/admin login. Default disabled on a public bind until ADMIN_PASSWORD is set
CORS_ORIGINSunsetExtra Origin values allowed on /mcp. Localhost and same-host are always allowed
API_KEY / API_KEY_SCOPESunsetRegister one key at boot
MCP_API_KEYunsetstdio credential. The command line client sends it as a bearer key
MCP_USERNAME / MCP_PASSWORDunsetstdio basic auth. The command line client sends them as HTTP Basic
MCP_URLhttp://127.0.0.1:8787/mcpCommand line client only: the server to talk to
MCP_USERSunset"alice:secret:read,write" extra logins
RATE_LIMIT / RATE_LIMIT_WINDOW_MS60 / 60000Calls per window per caller
TENANT_IDunsetIf set, writes need x-tenant-id header

Honest limits

  • Tickets live in memory — a new container starts from seed data.
  • Admin auth is a session cookie, not SSO. Cookie is HttpOnly (+ Secure on HTTPS).
  • /health being green does not mean the ticket went to the right person.
  • Public /test does not create or close tickets. Use /test?write=1 after admin sign-in.
  • Remote config, the extension's Remote config tab and the command line change real settings (auth mode, users, keys, rate limit) on whatever server you point them at. Demo setup is for a server you own.

Author: Markus van Kempen · [email protected] · markusvankempen.github.io · MCP Dev Summit Toronto talk · Talk slides · npm · VS Code Marketplace · Open VSX

來源:README.md,提交 80edabd

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

2
  1. v1.9.0最新Sep 24, 2026
  2. v1.0.4Sep 18, 2026

評分

已滿足適用檢查項的 40%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

    請在儲存庫或註冊中心條目中宣告授權條款。

其他 Demo 整合