Lodging Decision MCP
Agent-facing tool that ranks lodging candidates with a deterministic, evidence-backed recommendation.
Documentation
Lodging Decision MCP Server (alpha)
Narrow, agent-facing MCP server wrapping PR #25's (Scenic-Stay/staygraph, branch
agent/scenicgraph-lodging-decision-api) lodging-decision kernel unmodified. Governed by
gauntlet/projects/decision-intelligence-v0.1/WORK-ORDERS.yaml
(DI-001-A) in Scenic-Stay/scenic-intelligence. Read that Work Order before changing scope.
Live: https://di-001-a-lodging-decision-mcp.scenicstay.workers.dev/mcp
Extracted from Scenic-Stay/staygraph (services/di-001-a-mcp-decision-server/, branch
agent/di-001-a-mcp-decision-server, commits 8c8f4c7/f7df7b3) into its own public repo so
GitHub-based MCP discovery (the Official MCP Registry, Glama's crawler) can find it without
exposing the rest of staygraph's code. That branch is preserved as historical record; deploy
from this repo going forward.
What this is
One MCP tool, lodging_decision. Callers supply a traveler profile, trip context, and
a list of candidate listings; the tool returns a deterministic, evidence-backed
recommendation with score breakdown, tradeoffs, risk flags, missing information, and
confidence. It does not search inventory, book, transact, or persist anything.
Scope
Non-sensitive categories only: budget, location, amenities, quality/reviews,
cancellation policy, fees, remote-work/family/business/relocation/event trip framing,
and stated accessibility needs. No Safety & Belonging, Medical Recovery, or
protected-characteristic-adjacent input is accepted — see src/guard.ts, a
defense-in-depth denylist that rejects (does not silently strip) free-text fields
referencing a protected characteristic or discriminatory steering criterion, on top of
the fact that the underlying kernel has no such fields to begin with.
Structure
src/kernel/— PR #25's contracts, scorer, validation, and fixtures, copied byte-for-byte (test/kernel-parity.test.tsproves this against PR #25's own six tests and committed example fixtures).src/guard.ts— the denylist guard described above.src/worker.ts— Cloudflare Worker entrypoint: MCPWebStandardStreamableHTTPServerTransportatPOST /mcp, plus a KV-backed soft daily request ceiling and a/healthcheck.test/— kernel parity tests, guard tests.
Local development
npm install
npm test # kernel parity + guard tests
npm run typecheck
npm run dev # wrangler dev, serves http://127.0.0.1:8787/mcp
Deploy
npm run deploy # wrangler deploy
Requires the DI_001_A_ABUSE_CEILING KV namespace bound in wrangler.jsonc (already
provisioned; see the Work Order's execution_result for the namespace ID and actual
Cloudflare cost recorded at deploy time).
Known limitations (carried over from PR #25, unresolved here)
Unauthenticated, unversioned, no rate limiting beyond the soft daily ceiling, not calibrated against real human booking decisions. Do not expose to untrusted high-volume traffic without a further hardening decision — see the Work Order's circuit breakers for the manual kill-switch (pull the Worker; delist from all directories) if abuse signals appear.