expert-booking-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@expert-booking-mcpFind available expert slots for a data science consultation this Friday."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Expert Booking MCP Server
一个面向 AI Agent、支持渐进式工具发现的专家预约 MCP Server。默认端点采用 Streamable HTTP 和 MCP 2026-07-28 modern era 的 server/discover;为保证终态响应时间可验证,旧版 stateless/SSE fallback 会被明确拒绝,不做静默降级。
一条命令验证
npm install && npm test测试会真实启动 Streamable HTTP MCP 端点,用官方 Client 完成能力发现、工具发现与工具调用,并覆盖预约状态机。完整可重复 Demo:
npm run demo启动持久化服务:
cp .env.example .env
set -a; source .env; set +a
npm run dev
# MCP endpoint: http://127.0.0.1:3000/mcp生产构建使用 npm run build && npm start。服务默认仅绑定 localhost,并启用 Host/Origin 校验;远程暴露前必须另加认证。
设计动机、现实风险和未覆盖范围见 NOTES.md。
给本地 Agent 的安装提示词
把下面内容复制给需要安装 MCP 的编码 Agent:
请在当前仓库安装并接入 expert-booking-mcp:
1. 确认 Node.js >= 22,运行 npm ci。
2. 运行 cp .env.example .env && npm run dev,MCP 地址是 http://127.0.0.1:3000/mcp。
3. 按当前 MCP Host 的配置方式添加这个 Streamable HTTP Server,不要改成 stdio。客户端请求需复用 src/temporal-http.ts 的 createTemporalClientFetch,以附带服务要求的动态时间字段。
4. 连接后确认 tools/list 能发现 tool_catalog.search、tool_catalog.read、tool_catalog.call,并通过目录工具搜索、读取和调用 booking 工具。
5. 运行 npm test 验证安装;需要查看完整预约流程时运行 npm run demo。付款由用户在 Agent 外完成,不要实现或代替付款。
如果失败,请保留原始错误并定位原因,不要通过关闭参数校验、时间校验或 Host/Origin 校验来绕过问题。最后告诉我 MCP 配置位置、实际运行的命令和验证结果。Agent 使用流程
默认 tools/list 只返回三个稳定、低上下文成本的 MCP Tool:
MCP Tool | 用途 |
| 检索式预筛选;返回标题、 |
| 通过 |
| 以未经转换的 |
目录中的四个固定逻辑工具是:
逻辑工具 | 关键输入 | 结果 |
|
| 结构化时段候选、总数、下一页游标 |
|
| 五分钟独占预约、支付页、完整快照和 Server 签发的 |
|
| intent 与支付双重校验后的完整确认快照 |
|
| 当前完整预约快照 |
推荐 Host 轨迹:
server/discover:发现 MCP 能力与协议版本。tools/list:仅加载上述三个目录工具。tool_catalog.search:搜索相关逻辑工具;状态栏只保留返回的工具名。tool_catalog.read:按需读 schema;读完整后将 schema 一次追加到上下文尾部,此后留在原历史位置以命中前缀缓存。tool_catalog.call:把用户/Agent 给出的业务参数原样送入严格校验和执行。
第 3–5 步是服务提供的协议能力;“把 schema 放到对话历史的哪个位置”最终由 MCP Host 控制,Server 通过 instructions、固定 schema 和分页元数据给出可执行约定。
状态机与事务
AVAILABLE SLOT
│ hold (SQLite IMMEDIATE transaction)
▼
HELD / payment=PENDING ───── expiresAt reached ────▶ EXPIRED
│
├── queryPayment=PENDING ─────────────────────▶ HELD
├── queryPayment=FAILED ─────────────────────▶ PAYMENT_FAILED
├── queryPayment=CLOSED ─────────────────────▶ PAYMENT_CLOSED
└── fresh human approval + exact PAID match ──▶ CONFIRMEDone_active_booking_per_slot部分唯一索引从存储层保证每个时段最多一个HELD/CONFIRMED预约。临时预约的
expiresAt = heldAt + 5 分钟。每次相关读写前在同一事务中清理过期预约,因此进程重启后也不会丢失释放动作。本地状态变更全部位于 SQLite 事务内;异常会回滚整个本地变更。只读支付查询在事务外执行,返回后重新读取版本并在一个事务中提交最终状态,避免持锁等待外部网络。
支付初始状态只能是
PENDING,确认只允许本地PENDING → PAID。bookingId同时是不可变、唯一的payment.queryId,重复确认查询同一个支付对象。expectedVersion提供乐观并发控制。Hold 与 Confirm 各自要求 UUID 幂等键;同键同参返回原结果,同键异参返回IDEMPOTENCY_CONFLICT。FAILED/CLOSED会事务性释放时段。支付已经成功但预约在外部查询完成前过期时,服务拒绝确认;退款/人工对账按题目范围留给外围系统。
参数保真与错误契约
逻辑工具由 AJV 严格校验:coerceTypes=false、useDefaults=false、removeAdditional=false、所有对象 additionalProperties=false。例如邮箱不会转小写,数字字符串不会转换为数字,未知字段不会被丢弃。业务参数与调用上下文分开传递,日志上下文不会注入业务参数。
所有执行结果都是机器可读 envelope。写操作返回完整的变更后预约,而非空 200 OK:
{
"ok": false,
"error": {
"code": "PAYMENT_PENDING",
"message": "Payment has not completed; the booking remains held until expiresAt.",
"retryable": true,
"details": { "bookingId": "booking-..." },
"recovery": { "action": "Ask the user to finish payment, then retry confirmation before expiry." }
},
"meta": {
"traceId": "32 lowercase hex characters",
"spanId": "16 lowercase hex characters",
"operationId": "UUID",
"clientSentAt": "RFC 3339",
"serverReceivedAt": "RFC 3339",
"serverResultCreatedAt": "RFC 3339",
"cache": "BYPASS"
}
}输入 schema 错误由 MCP SDK 或 INVALID_ARGUMENTS 返回;可预期业务错误不会泄露堆栈。主要错误包括 SLOT_UNAVAILABLE、BOOKING_EXPIRED、VERSION_CONFLICT、PAYMENT_PENDING、PAYMENT_MISMATCH、HUMAN_APPROVAL_EXPIRED、APPROVAL_INTENT_HASH_MISMATCH、APPROVAL_INTENT_MISMATCH 和 IDEMPOTENCY_CONFLICT。
Human in the loop
临时预约是可自动重试、会自动释放的动作。最终确认必须携带:
{
"humanApproval": {
"approvalId": "UUID",
"decision": "APPROVE",
"approvedAt": "2026-08-26T09:30:00.000Z",
"intent": {
"bookingId": "booking-...",
"slotId": "slot-ai-001",
"startsAt": "2030-09-02T02:00:00.000Z",
"amount": "500.00",
"currency": "CNY",
"version": 1
},
"intentHash": "sha256:<64 lowercase hex>"
}
}hold_slot 和处于 HELD/PENDING 的 get_booking 会返回 confirmationIntent。Host 必须向用户展示对应的 booking、专家、时段、金额、币种和版本,并把其中的 intent、intentHash 原样复制到批准对象;不要由 Agent 重建或修改。Server 先重新计算 hash,再把六个字段与当前 booking 精确比较,任一不一致都不会查询支付。
v1 canonical intent 是按 key 升序排列的无空白 UTF-8 JSON:amount, bookingId, currency, slotId, startsAt, version。intentHash 是 sha256: 加该字节串的 64 位小写十六进制 SHA-256。Server 返回 hash,因此一般 Client 只需原样传递。这个无密钥 hash 绑定内容完整性,但不是对批准者身份的数字签名;需要抵御不可信 Host 时,应把 v1 binding 升级为 Server HMAC 或签名 challenge。
批准有效期为 120 秒,允许 5 秒时钟偏差;缺失、过期、未来时间、缺少 binding 或 binding 不匹配的默认行为都是 不查询支付、不确认预约。确认成功后 confirmationIntent 变为 null,避免把旧 intent 当成可再次批准的 challenge。
支付依赖 seam
预约模块只依赖下面的只读 port:
interface PaymentQueryPort {
queryPayment(bookingId: string, trace: TraceContext): Promise<PaymentResult>;
}生产 adapter 对 PAYMENT_QUERY_BASE_URL/payments/{bookingId} 发 GET,请求超时 3 秒并传递 traceparent。测试和 Demo 注入 Stub;仓库没有实现支付服务或支付动作。支付结果必须精确匹配 bookingId、金额字符串和币种,PAID 还必须有 paidAt。
按需加载、分页与缓存
Tool 搜索和时段搜索都返回结构化候选,不拼接全文。
游标是与原查询绑定的不透明 token;跨查询复用会返回
INVALID_CURSOR。tool_catalog.read以 0-basedoffset和显式limit读取,返回totalLines、truncated、omittedLines、next和人类可读继续方式。固定 Tool 目录的 search/read 结果可永久安全复用;可预约时段查询缓存 5 秒,任何预约写入或过期释放都会使其失效。
SQLite WAL 允许多个只读感知调用安全并发;写入由数据库事务和唯一索引串行化。
可观测性
每个目录动作和逻辑工具动作都向 stderr 输出 JSON Lines,包含 source、RFC 3339 timestamp、caller、动作、耗时、trace_id、span_id、operation_id。支付查询创建子 span 并通过 W3C traceparent 传播。
调用方显式传入 UUID requestSpanId;服务用它确定性派生 128-bit trace_id,每次动作生成新的 64-bit span_id。OpenTelemetry 标准要求 span_id 是 16 个十六进制字符而不是 UUID,因此另行生成 UUID operation_id,没有伪造不兼容的 trace context。代码同时调用 OpenTelemetry API;部署方可注册 exporter。
所有 MCP HTTP 请求必须由显式 client adapter 在真正发送边界加入 x-mcp-client-sent-at,并在 params._meta 写入同值;Server 不会替 Client 猜测或注入该时间。Server 在入口和响应边界分别加入 x-mcp-server-received-at、x-mcp-server-responded-at,JSON-RPC result._meta 同样携带三段时间;Tool envelope 另以 serverResultCreatedAt 标识业务结果生成时刻。因此 Agent 可验证:
clientSentAt ≤ serverReceivedAt ≤ serverResultCreatedAt ≤ serverRespondedAt ≤ clientReceivedAt缺失或非法 RFC 3339 客户端时间会得到 HTTP 400 / MISSING_CLIENT_TIMESTAMP,响应不会伪造客户端时间,并回显 JSON-RPC request id。支付查询这个 Server 发出的外部 GET 也携带 x-mcp-server-request-sent-at;依赖响应的发送时间(若对方提供)及本地接收时间进入结构化日志。当前工具响应均为 JSON;未来启用 SSE 进度/Server-initiated MCP request 前,需要为每个事件补独立发送时间,而不能只沿用建流 Header。
最重要的测试场景
竞争与过期释放:先验证第二位用户无法占用,再推进时钟超过五分钟并验证其可预约。这直接覆盖“同一时段仅一人”和“过期后重新开放”两个核心不变量。
先查后做的支付确认:
PENDING保持预约不变,随后同一支付查询 ID 返回PAID,只发生一次本地PENDING → PAID/CONFIRMED。这是外部付款与本地事务交界处风险最高的路径。金额/身份不匹配回滚:支付返回
PAID但金额错误,本地仍保持HELD/PENDING/version=1,证明外部查询无法造成部分提交。幂等重放与参数漂移:同键同参得到同一预约;同键异参明确冲突,防止 Agent 重试制造重复副作用。
Human approval 超时:过期批准不会调用支付依赖,验证默认拒绝行为。
真实 MCP modern discovery:官方 Client 通过 Streamable HTTP 协商到
modern,发现三项稳定工具,再检索和调用逻辑工具。独立进程时序黑盒:测试先构建,再
spawn生产入口,用官方 Client 验证每次 wire request/response、Tool envelope 与日志的时间顺序,并确保子进程和临时数据库被清理。
假设与范围
预置三位专家和六个 2030 年 UTC 时段;不实现专家管理。
所有时间通过 RFC 3339 传输,存储为 UTC ISO 字符串;服务不静默转换调用参数。
跨机器时序比较假设 Client、预约服务和支付服务通过 NTP 保持时钟同步;生产告警应配置允许偏差。Server 不根据偏差静默改写调用方时间。
金额用两位小数字符串,币种用三位大写代码,避免浮点误差。
最小实现没有账户认证;localhost 运行且 booking ID 不可猜。生产环境必须在 MCP handler 前验证身份,并按 caller 限制预约读取。
付款页 URL 仅由配置基址和 booking ID 组成;本仓库不提供页面。
退款、通知、后台、已付款但过期后的自动对账,以及云部署不在范围内。
项目结构
src/
booking-service.ts 深预约模块:状态机、幂等、事务、缓存
database.ts SQLite schema、约束与预置数据
tool-catalog.ts 固定逻辑 schema、检索、分片读取、严格分发
mcp-server.ts 三个稳定 MCP Tool 与 Streamable HTTP handler
payment.ts 只读支付 HTTP adapter
observability.ts OTel hooks 与结构化日志
temporal-http.ts MCP Client/Server wire 时间契约
test/ 状态机与真实 HTTP MCP 集成测试
scripts/demo.ts 可重复端到端演示
NOTES.md 设计动机、现实风险、取舍与明确未覆盖范围实现对齐官方 MCP TypeScript SDK HTTP Guide、MCP Tools Guide、Streamable HTTP 2026-07-28 规范 与 MCP Pagination 规范。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Dante-dan/expert-booking-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server