Inspiration In Vietnam's mountain towns, small homestays run on chat messages, paper ledgers and the owner's memory. Goods reach them through chains of wholesalers, each adding a margin, and money moves on trust. Sapalens already digitizes these operations as SOPs. What was missing was a way to just say what needs to happen and have it done safely, and to see where both the goods and the money went.

What it does The Sapalens AI Operator is an Alexa+-ready MCP server, shown in MCP Inspector. It turns one sentence into a governed operation and acts only as the signed-in person.

Agentic workflows across six services: identity, Reception SOPs, partner supply, logistics, finance clearing and the trace ledger. Context-aware. One passport, many positions: the tools follow the position, not the prompt. Purchasing with a human in the loop. After the owner approves, the platform places B2B supply orders at the source distribution point, and in split mode the money is split and traceable. "Four guests are arriving tomorrow: check the booking, check supplies and request anything missing."

Who am I operating as? It verifies the person's Sapalens passport and the Homestay Operator position, and reports each condition with its evidence. Booking and supplies. It finds the booking and computes what four guests need from the property's own norms, so it knows what is short. Source locally. It finds the nearest distribution point that holds the goods: a local shop selling a local producer's consigned stock. Request, never spend. It creates a replenishment request that waits for the owner. Only after the owner approves are supply orders placed at that point. Every step returns an input → process → output receipt. Approval happens in the owner's Sapalens app (maker–checker); the voice assistant can propose but never approve.

What the offline demo answers (fictional data; excerpts of the tool replies its tests check, "…" marks omitted text):

Owner: "I have four guests arriving at 3 PM tomorrow. Check the booking, prepare the room, check supplies, and create a replenishment request for anything missing."

Operator: "Booking found. … Supplies checked for 4 guests: 3 bath towels missing. Everything else is sufficient. … Replenishment request REQ-… created …, waiting for owner approval. From “Sapa Linen Co-op (demo)” via “Sapa Center Mart (demo)” … supplied straight from that point once the owner approves (no intermediate warehouse)."

Behind it are two flows:

Goods: producers keep ownership on consignment, shops hold the goods against a deposit, and a signed agreement binds both. Money: in split mode, a paid order is split by a published, versioned fee policy: a platform fee set by that policy (5 % of the selling price on the demo, as published by maker–checker: one admin proposes, another approves; adjustable, an increase is announced 30 days ahead, a decrease applies immediately), a point fee set in each signed agreement, and no buyer fee. Each split is hashed onto a tamper-evident trace ledger, where a signed-in party can verify it. The split engine runs on the demo environment shown in the video; switching production over is gated on the release deploy and two-admin fee publication. A staff-only Treasury AI proposes treasury actions that a second person must approve. No AI can approve, post or move money.

How we built it MCP specification 2025-11-25 over Streamable HTTP (official MCP TypeScript SDK 1.32.x) on Node.js and Express; a test asserts that initialize answers protocol version 2025-11-25. The server is stateless; each caller gets a server bound to their verified passport. 20 intent-level tools on the hosted platform (13 for a homestay owner, the set the offline evaluation mode shows; the rest belong to the regional-coordinator and finance-staff positions) across homestay, supply, money and trace, treasury, and Forge Store modules, with strict Zod schemas. A capability allowlist decides which tools exist for whom; OAuth scopes can only narrow it. Every tool carries MCP annotations (readOnlyHint, destructiveHint: false, openWorldHint: false) and returns structuredContent with its receipt. An adapter, not a second system. The Operator owns no data. It calls the Sapalens services through the gateway as the signed-in person (RFC 8693 token exchange), so tenant scope, authorization and audit stay where the data lives. OAuth 2.1: Authorization Code + PKCE (S256), audience-bound tokens, rotating refresh tokens, RFC 9728 protected-resource metadata. Staff reached through a voice assistant keep only context.read, and results drop contact details, ID documents, addresses, birth dates, bank, card and tax identifiers, including in receipts and errors. Money: a split engine and a double-entry clearing ledger in PostgreSQL (Prisma), maker–checker approvals, and a SHA-256 hash chain sealed into Merkle batches, anchorable with OpenTimestamps. Natural-language runner: uses Azure OpenAI function calling over the same governed tools when Azure OpenAI is configured; otherwise (the offline demo needs no model), or if the model fails, it follows the deterministic SOP plan for a guest-arrival request and changes nothing for any other. Demo environment: the same Docker images as production behind Caddy, with its own fictitious data. A demo-world builder in the Sapalens platform repository (not part of the Operator repository shared with the judges) builds that data through the real HTTP APIs and writes a gap report of every step that did not work. What we built during the hackathon The Operator MCP server (platform/operator-service) was written from 8 October 2026 (first commit c7c63b786). What it calls (the passport, Reception SOPs, partner supply, finance and the trace ledger) runs on the Sapalens platform, whose marketplace, partner, finance, identity and logistics services existed before the hackathon. During the hackathon we wrote the Operator and extended the platform (dates from the commit history):

The Operator service and its MCP server (from 8 Oct): stateless Streamable HTTP, spec 2025-11-25, official MCP TypeScript SDK, a protocol-version test, 20 intent-level tools with a capability allowlist, receipts and personal-data minimisation, and the natural-language runner. Delegated sign-in (8 Oct): an OAuth 2.1 authorization server in the identity service with RFC 8693 token exchange, plus the Operator's RFC 9728 resource metadata and MCP Inspector support. Replenishment with supply orders (8 Oct): AI-raised requests wait for the owner; once approved, supply orders are placed at the source point. Tamper-evident trace ledger (14 Oct, #201): SHA-256 hash chain sealed into Merkle batches. Clearing hub ledger (14 Oct, #206) and the split engine with a versioned fee policy (14 Oct, #225). Demo environment (15 Oct, #240) and the demo-world builder with its gap report (16 Oct, #247). Offline mode for judges (17 Oct, #403): contract emulators so the tests and a local demo run without any Sapalens host. Challenges we ran into Making "AI agent" and "least privilege" coexist. Scope comes only from the passport and position, and schemas are strict, so the model cannot widen its own reach. Idempotency for voice. A retry must never create a second request, so the server derives the key itself. Being honest about money. While building we found and closed real weaknesses: manual money endpoints, payouts without separation of duties, refunds executed on request, a spoofable tenant header. Fees and taxes moved into dated, versioned configuration; tax rates stay unverified until an accountant signs them off. Showing only what is real. We dropped a simulated month from the demo and built a separate demo environment, filled through the real APIs, with a gap report instead of staged screens. Accomplishments that we're proud of An end-to-end homestay operation on real platform code, with receipts a human can audit, and no purchase without the owner. Money that a signed-in party can verify on the trace ledger once an order settles in split mode: a record's hash, its Merkle path and the batch root. A demo world built by fictitious people joining the platform the way a real person would, with every broken step listed in a gap report rather than hidden. What we learned MCP works best as a capability boundary, not an API dump. Designing tools as intents, each mapped to an SOP step and each leaving a receipt, made both the model and the auditors happier.

Potential impact Sapalens serves the people who keep a mountain tourism economy running: producer co-ops in Sa Pa, the shops and kiosks that become consignment points, the homestays that need supplies before guests arrive, and the travellers who buy local.

The model removes the usual failure points. In a 2019 survey of vegetable chains in Bến Tre, more than 75% of volume passed through three intermediaries (Hoang Viet, 2021, Modern Short Food Supply Chain, Good Agricultural Practices, and Sustainability, Agronomy 11(12):2408, doi:10.3390/agronomy11122408), and in one FAO textbook example fresh-tomato growers receive about 40% of the consumer price (FAO, Agricultural and Food Marketing Management, ch. 12). In the Sapalens chain the goods go producer → point → buyer with no reseller: the point sells on consignment and the producer keeps ownership. On the demo tea order in the video (120,000 VND, a simulated payment capture, no real money), the split pays the point 11,160 VND, the platform 6,000 VND (5%), withholds 2,640 VND of tax, and pays the tea house 100,200 VND. That is the tea house's revenue, not its profit: from it the tea house pays its own costs, shown line by line in its price worksheet (the leaves 40,000, transport 8,000, batch testing 3,000, an assurance-fund contribution 2,500 and fixed costs 745), and keeps 45,955 VND (38.3%) as profit. There is no fixed share: the partner sets the price, every line is visible, and the advisor only suggests. On fictional demo data, the logistics service proposes one consolidated restock tour of 71 km in place of ten separate trips totalling 144.6 km.

Working today on the demo environment (real service code, fictional data, no real users or revenue yet): signed consignment agreements, deposit-capped shelves, sourcing from the nearest point, supply orders, batch and lot tracing with one-tier recalls, and splits set by the signed agreement. Multi-tier tracing and production records are code-complete, not yet deployed. The split engine runs on the demo environment shown in the video; switching production over is gated on the release deploy and two-admin fee publication. The Sa Pa pilot measures time per pre-arrival check, stock-outs at check-in, and the producer's share of each sale — recorded per order by the clearing hub — plus the kilometres driven.

Next steps: (1) run the Sa Pa pilot with real co-ops, points and homestays; (2) switch production settlement to the split engine once the owner approves; (3) move origin disclosure from declared to verified.

What's next Alexa+ with real owners: use the self-hosted MCP server from Alexa+ and tune voice-length answers with homestay owners. Production switches to split settlement after the demo environment has run it. More skills from the Sapalens Forge Store: tools registered from a module manifest, with consent, an allowlist, receipts and revenue share for the local builder. Tax withholding deducted from payouts only after an accountant signs off the rates (today it is computed and shown). The Sa Pa pilot, where we measure real prices and distances before claiming any savings. Try it now The hosted demo environment is temporarily offline while our cloud subscription is paused. The repository runs offline on fictional data (npm install && npm test && npm run demo, then MCP Inspector on http://localhost:3045/mcp), and the video shows the full platform running on the demo environment.

Built With

Share this project:

Updates

Submission history