关于 mcp-ticket-demo
mcp-ticket-demo 是用于学习 MCP、测试 IDE 集成和演示的参考服务器,提供票务工具及服务运维功能。它涵盖多种传输方式、认证、权限门控和 PII 脱敏,并配有可观测性界面。
主要功能
- 0119 个票务与管理工具
- 02stdio、SSE 和 Streamable HTTP
- 03多种认证模式与工具门控
- 04PII 脱敏和速率限制
- 05资源、提示词与调用追踪
适用场景
- 01学习 MCP 服务的设计与运维
- 02测试 IDE 的 MCP 集成
- 03演示认证和 PII 权限控制
MCP 相关
作为 MCP 服务,它向客户端提供工具、资源和提示词,可通过 stdio、SSE 或 Streamable HTTP 连接。票务和管理能力均通过 MCP 接口提供。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y mcp-ticket-demoMCP_API_KEY密钥API key for authenticated tool calls. Issue one on /admin → API Keys. Required when AUTH_MODE=write or AUTH_MODE=all.AUTH_MODE密钥Authentication mode: off (default), write (write+pii tools gated), all (every tool gated).MCP_USERS密钥Extra username/password users: 'alice:secret:read,write'. Comma-separated, colon-delimited.RATE_LIMITMax tool calls per window per caller. Default 60.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
10收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | 返回的最大行数。默认值为 10,最大值为 25。 |
| query | string | 否 | 可选关键词,用于匹配主题和正文,例如 hostname 或 mcp.json。 |
| status | enum | 否 | 生命周期筛选条件。默认值为 open。搜索结果为空时使用 all。open | pending | solved | all |
| requester_email | string | 否 | 可选的精确客户邮箱,例如 [email protected]。如果不确定工单是否仍处于打开状态,请与 status=all 组合使用。 |
详细介绍
MCP Ticket Demo — 全栈 MCP 参考服务
一个贴近生产环境的 MCP 服务,不到 5 分钟即可运行。内置 19 个工具、3 个资源、5 个提示词、三种身份验证模式、API 密钥管理、按工具设置的访问控制、速率限制、实时可观测性仪表板,以及 VS Code / Bob / Cursor / Windsurf 控制平面扩展。
可用于学习 MCP、测试 IDE 集成、进行现场演示,或在构建自己的服务时作为参考实现。
配套演讲:MCP as a Platform:构建 MCP 服务组合的心得 · MCP Dev Summit Toronto · 2026 年 10 月 5 日 · 演讲幻灯片 →
| MCP 服务(3.0.1) | npm install mcp-ticket-demo |
| VS Code 扩展(1.16.0) | VS Code Marketplace · Open VSX |
| 演讲幻灯片 | markusvankempen.github.io/linuxfoundation-mcp-dev-summit |
个人开源项目。
除了 hello-world 示例之外,它还能带来什么
大多数 MCP 示例都止步于“这是一个会返回字符串的工具”。这个示例更进一步:
| 特性 | 你将了解什么 |
|---|---|
| 19 个采用意图命名描述的工具 | 名词放在架构中,动词保留为工具——而不是 request(path, method) |
3 个资源(ticket://、tickets://open、schema://) | resources/list 会枚举实例;读取时使用与对应工具相同的 gate() |
| 5 个 MCP 提示词 | 面向用户的提示词与面向 Agent 的工具有何不同 |
工具注解(readOnlyHint、destructiveHint、idempotentHint、openWorldHint: false) | 客户端的确认/重试体验 |
| 服务端说明 | 模型实际读取的 README |
每次失败都设置 isError: true | 客户端无需解析 ok: false |
归属缺失的后果——调用 create_ticket 时不传 requester_email | 返回 201 并不代表完成。工单归机器人所有。 |
架构发现——get_schema → run_query | 一个查询工具胜过一堆 query_* 名称 |
| 发现到 0 个工具——把笔记本电脑上的路径交给云端运行器 | 没有错误、没有警告的静默失败 |
| stdio + SSE + Streamable HTTP,来自同一代码库 | 三种传输方式,相同的 19 个工具 |
身份验证模式(off / write / all)+ 单工具门控 + 单工具身份验证锁 | 安全是运维人员需要考虑的问题 |
管理员切换门控时广播 tools/list_changed | SSE 和 Streamable HTTP 会话都会刷新;一次性 curl 请求不会 |
速率限制,错误中包含 retry_after_seconds | 阻止模型陷入循环重试 |
对 run_query 的 schema=customers 进行 PII 脱敏 | 同一工具、同一端点;没有 pii 范围时,phone 字段会显示为 REDACTED |
/health 与 /test 的区别 | 存活 ≠ 正常工作。公开的 /test 只读;公开的 /health 不会暴露 cwd |
实时可观测性——带计数器、错误日志和调用追踪的 /log 页面 | 查看模型实际在做什么 |
通过 MCP 进行运维——设置(通过单个 update_settings 补丁更新)、用户、API 密钥和设置导入都是工具;设置导出使用 run_query schema=settings;即使身份验证为 off,其中大多数操作仍需要 admin 范围 | 控制平面是服务的一部分,而不是旁门 |
运维同一服务的三种方式——/admin 远程配置、扩展的远程配置标签页,以及 mcp-ticket-demo 命令行 | 步骤相同,Demo 设置相同,并且会相互核验 |
快速开始——五分钟
# Run directly from npm — no clone needed
npx mcp-ticket-demo # stdio (IDE spawns this)
MCP_MODE=http npx mcp-ticket-demo # HTTP — opens /health /test /admin /mcp
# Or clone and run
git clone https://github.com/markusvankempen/mcp-ticket-demo
cd mcp-ticket-demo/server && npm install && npm run http
然后在浏览器中打开:
| URL | 显示内容 |
|---|---|
| http://127.0.0.1:8787/health | 进程是否存活?(cwd 仅在 localhost 上显示) |
| http://127.0.0.1:8787/test | 只读冒烟测试:种子工单、架构和 run_query |
| http://127.0.0.1:8787/admin | 身份验证模式、API 密钥、工具门控、可观测性 |
| http://127.0.0.1:8787/log | 调用计数器、错误日志、完整调用追踪 |
| http://127.0.0.1:8787/tools | 工具清单,包含范围和身份验证状态 |
在终端中使用
同一个 mcp-ticket-demo 命令也可以作为客户端,连接正在运行的本地或已部署服务。不带参数时,它仍是 MCP 服务,因此下方的 IDE 配置仍可正常使用。
npx mcp-ticket-demo status # http://127.0.0.1:8787/mcp by default
npx mcp-ticket-demo call run_query schema=tickets 'filter={"status":"open"}' limit=5 # any tool, values typed from its schema
npx mcp-ticket-demo demo apply --user demo --password demo # users, keys, auth write, 30 calls / 60 s
npx mcp-ticket-demo demo check --user demo --password demo # acts as each role and as nobody
npx mcp-ticket-demo status --url https://my-host.example.com # a deployed server
--json 会为脚本打印单个文档;退出码分别为 0 已完成 · 1 已拒绝 · 2 用法错误 · 3 无法连接。执行删除或重新配置的命令会先征求确认。所有命令、选项和示例都在 server/README.md 中;运行中的服务还提供了可直接复制粘贴的页面 /clients/cli.html。demo apply 会更改实际设置,请只在自己拥有的服务上使用。


笔记本电脑登录凭据:demo / demo。在公开绑定(HOST=0.0.0.0、容器、Code Engine)上,请设置 ADMIN_PASSWORD——默认情况下,管理员密码处于禁用状态。管理员登录后,可通过 /test?write=1 执行写入冒烟测试。
添加到 IDE(单行配置)
VS Code / GitHub Copilot — .vscode/mcp.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:
{
"mcpServers": {
"mcp-ticket-demo": {
"command": "npx",
"args": ["mcp-ticket-demo"],
"env": { "MCP_MODE": "stdio" }
}
}
}
或者安装扩展并点击 Register server with all IDEs — 它会一次性写入全部四个配置: VS Code Marketplace · Open VSX

工具
该服务有 19 个工具。下方介绍其中 6 个工单台工具。另外 8 个用于操作服务本身:update_settings(每个设置都是一次补丁:身份验证模式、速率限制、调用跟踪、工单台登录、传输方式、事件、门控、锁和作用域)、set_mqtt、用户、API 密钥、import_settings 和示例流量。其中大多数即使在身份验证为 off 时也需要 admin 作用域;server/README.md 列出了每项操作所需的作用域。还有 3 个计时器工具:start_timer、stop_timer 和 push_timer,没有 get_timer(push_timer 也会将计时器作为事件流式传输;参见事件):你可以通过 schema 读取计时器,使用 run_query 并设置 schema=timers(server/README.md)。push_log 会将一条日志作为事件发送,而 watch_system 会以 system.info 的形式发布机器信息,包括容器的 cgroup 限制。普通列表本身不是工具:run_query 可读取 settings(已保存的设置,可按原样导入)、system(机器)、events(已发送的事件);使用 admin 凭据时,还可读取 users、api_keys、trace、errors 和 counters。/clients/dashboard.html 页面会显示这些内容。每个工具只声明一次,其余内容均由该定义生成。
工单台(6 个)
| 工具 | 作用域 | 使用时机 | 说明 |
|---|---|---|---|
describe_server | read | 首次调用,以及任何拒绝后 | 探索优于猜测 |
create_ticket | write | 创建工单 — 始终传入 requester_email | 不传入时 → 返回 201,且工单归机器人所有 |
add_comment | write | 对已知工单发表评论 | 写入工具;受门控限制 |
close_ticket | write | 解决工单,可选择添加解决说明 | destructiveHint: true, idempotentHint: true |
get_schema | read | 任何查询前 | 不传入 name 时,会列出所有名称及其类型(data、query、tool);传入 name 时,会返回对应结构或参数 |
run_query | read | 唯一的查询工具:schema=tickets(按 status / requester_email / query 查找,或使用 id 查询单个工单及其正文和评论)、schema=customers(没有 pii 作用域时,电话号码会显示为 REDACTED),以及 assets、timers、system、settings、events(admin 还可查询 users、api_keys、trace、errors、counters) | schema 中使用名词,工具中使用动词。取代 query_tickets / query_assets / … |

3 个资源
资源可寻址且可固定 — 客户端可以订阅并刷新。工具则用于 Agent 循环。
| URI | 返回内容 | 使用相同门控的工具 |
|---|---|---|
ticket://TCK-1001 | 按 id 查询单个工单 | run_query |
tickets://open | 实时未结工单列表(前 25 条) | run_query |
schema://tickets | 查询 schema 结构(也包括 customers、assets) | get_schema |
调用 resources/list 浏览资源 — 无需提前知道 URI。被拒绝的读取会返回 JSON-RPC 错误(而不是可固定的伪工单文档)。
5 个提示词
面向用户的提示词——由用户选择,模型执行。
| 提示词 | 传达的经验 |
|---|---|
search-open-tickets | 在实时数据中查找服务账户留下的问题 |
attribution-scar | 不提供 requester_email 创建记录 → 说明出了什么问题 |
schema-discovery | get_schema(不带名称)→ get_schema(带名称)→ run_query 操作演示 |
close-ticket-flow | 依次执行 add_comment 和 close_ticket |
diagnose-server | describe_server — 身份验证模式、作用域、可用工具 |
身份验证模型
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.
凭据:通过 HTTP 使用 Authorization: Bearer <api key> · 通过 stdio 使用 MCP_API_KEY 环境变量。
在 /admin 中签发密钥、设置模式、切换各工具的访问限制,并锁定单个工具。
更改会向已连接的 SSE 和 Streamable HTTP 会话广播 notifications/tools/list_changed(Cursor/Bob 在 initialize 之后)。一次性的 POST /mcp(curl)没有会话——它会在下一次调用时看到新列表。
仓库布局
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/README.md | 这些指南的索引,适用于服务器 3.0.1 和扩展 1.16.0 |
| docs/DEMO.md | 端到端演示指南 — 16 个实时 curl 演示、涵盖每条经验、包含真实捕获的输出 |
| docs/LESSONS-LEARNED.md | 构建真实 MCP 服务的 15 条经验 — 实战故事 + 发布前检查清单 |
| docs/LOCAL.md | 本地 stdio + HTTP 操作演示 |
| docs/REMOTE.md | Code Engine 部署 + 0 个工具被发现的复现步骤 |
| docs/ADMIN-AND-SECURITY.md | 身份验证模式、API 密钥、工具访问限制 |
| docs/BOB.md | IBM Bob 专属设置 |
| docs/PUBLISHING.md | npm + MCP Registry + VS Code Marketplace 发布步骤 |
| docs/EXTENSION.md | VS Code / Cursor / Bob 扩展 — 标签页、远程配置、命令 |
| server/README.md | 每个端点的完整 curl 参考,以及命令行客户端 |
环境变量
| 变量 | 默认值 | 作用 |
|---|---|---|
MCP_MODE | stdio | stdio 或 http |
PORT | 8080 | 仅用于 HTTP。npm run http 使用 8787 |
HOST | 127.0.0.1 | 容器内为 0.0.0.0(自动设置) |
AUTH_MODE | off | off · write · all |
ADMIN_USER / ADMIN_PASSWORD | demo / demo | /admin 登录。公开绑定时默认禁用,直到设置 ADMIN_PASSWORD |
CORS_ORIGINS | 未设置 | 允许访问 /mcp 的额外 Origin 值。始终允许 localhost 和同主机来源 |
API_KEY / API_KEY_SCOPES | 未设置 | 启动时注册一个密钥 |
MCP_API_KEY | 未设置 | stdio 凭据。命令行客户端会将其作为 bearer 密钥发送 |
MCP_USERNAME / MCP_PASSWORD | 未设置 | stdio 基本身份验证。命令行客户端会将其作为 HTTP Basic 凭据发送 |
MCP_URL | http://127.0.0.1:8787/mcp | 仅供命令行客户端使用:要连接的服务 |
MCP_USERS | 未设置 | 额外登录账户,格式为 "alice:secret:read,write" |
RATE_LIMIT / RATE_LIMIT_WINDOW_MS | 60 / 60000 | 每个调用者在每个时间窗口内的调用次数 |
TENANT_ID | 未设置 | 如果设置,写入操作需要 x-tenant-id 标头 |
明确的限制
- 工单存储在内存中——新容器会从种子数据开始。
- 管理员身份验证使用会话 Cookie,而非 SSO。Cookie 为
HttpOnly(HTTPS 下还会设置Secure)。 /health显示正常,不代表工单已发送给正确的人。- 公共
/test不会创建或关闭工单。管理员登录后,请使用/test?write=1。 - 远程配置、扩展的「远程配置」选项卡和命令行会更改你所指向的服务器上的实际设置(身份验证模式、用户、密钥、速率限制)。演示配置仅供你自己的服务器使用。
作者: Markus van Kempen · [email protected] · markusvankempen.github.io · MCP Dev Summit Toronto 演讲 · 演讲幻灯片 · npm · VS Code Marketplace · Open VSX
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。
