The scraping trap
When developers first wire an AI agent into a travel workflow, the instinct is to point it at a hotel website and let it scrape. It seems pragmatic - the data is right there on the page. But scraping hotel websites for booking is a trap that closes the moment you try to go to production.
The DOM is an implementation detail. A redesign - or even a minor A/B test on a call-to-action button - silently breaks every selector the agent relies on. There is no typed contract, no schema, no versioning. You are parsing human intent encoded as HTML for a human reader, and that encoding changes whenever marketing feels like it.
Payment is the deeper problem. A scraping agent can fill in a form, but it cannot hold a verified payment credential. Most hotel booking systems require 3DS authentication, a browser-verified card vault, or at minimum a session token tied to an authenticated user. None of those are accessible to a headless scraper without building a full browser-automation stack that defeats the security controls the hotel put there deliberately.
Finally, there is the legal dimension. Most major travel platforms explicitly prohibit automated access in their terms of service. robots.txt exists for a reason, and a booking agent that ignores it is one cease-and-desist letter away from shutdown.
What an agent actually needs
Strip the problem back to first principles. A hotel-booking agent needs four things that scraping cannot provide reliably:
- A typed contract - what actions exist, what inputs they accept, what they return, and what they cost. Machine-readable, versioned, and authoritative.
- Scoped authorization - a credential that says "this agent may book rooms up to €500 per night, for these guests, on behalf of this principal." Not a username and password; a mandate with explicit scope and a hard spend cap.
- Payment rails - a way to commit funds that is verifiable by the provider and auditable by the principal, without re-implementing card vaulting or PSD2 step-up in every integration.
- An audit trail - a tamper-evident record of every action taken so the principal can see exactly what their agent did and reverse it if needed.
These requirements describe a protocol, not a scraper. They are exactly what Sgovr is built around.
The agent-native flow
Sgovr exposes hotel providers (and any other transactional service) through a structured capability spec. An agent interacts with a provider in five explicit, verifiable steps:
Step 1 - Discover
The agent queries the Sgovr registry in natural language: "luxury hotels in Paris with free cancellation." The registry blends semantic (pgvector) and full-text search over provider-published specs and returns ranked, verified results. No URL guessing, no link-following, no HTML parsing.
Step 2 - Read the spec
The agent fetches the provider's capability spec - a JSON document that lists every available action with its input/output schema, pricing model, auth scopes, and rate limits. The spec for book_room tells the agent exactly what fields are required, what currency and pricing structure to expect, and what the idempotency semantics are. It also carries the merchant identifier and action SKU the agent will need to mint credentials in the next step.
Step 3 - Sign an IntentMandate
Before touching the provider, the agent signs a short-lived IntentMandate with its local private key. The mandate names the exact merchant and action from the spec, embeds the allowed scopes, and expires in 60 seconds. This is the agent declaring: "I am authorised to proceed with this specific action, and I am doing so right now." The private key never leaves the agent's wallet; the gateway verifies the signature against the principal's published public key.
Step 4 - Get a provider-signed quote
The agent calls the gateway's quote endpoint, passing the IntentMandate as the bearer. The gateway authenticates the request and proxies it to the provider, which responds with a CartMandate - a signed JWT containing the exact price, line items, and a short expiry window. The price the agent sees at quote time is the price it pays. No bait-and-switch, no surprise currency conversions.
Step 5 - Invoke with payment confirmation
The agent signs a PaymentMandate confirming the quoted total, then invokes the action with all three credentials: the IntentMandate as the bearer, the provider-signed CartMandate, and the PaymentMandate as confirmation. The Sgovr gateway verifies all three atomically, enforces the agent's spend cap, runs the fraud score, settles the payment, and proxies the call to the provider. The response includes a confirmation number and a tamper-evident audit record.
Idempotency built in
Running it with the SDK
The TypeScript SDK and Python SDK each ship a Wallet class that holds your private key and signs mandates locally - only the signed JWTs leave the process. The full five-step flow is covered end to end in both SDK guides, with a runnable example against the included demo provider. Start there if you prefer to work directly against the API.
Running it through MCP
If your agent runs in an MCP host - Claude Desktop, Claude Code, Cursor, or any other compatible host - you register two servers side by side. The first is the Sgovr SSE server at mcp.sgovr.eu/sse, which handles discovery, spec fetching, quotes, and invocations against the gateway. The second is a local wallet sidecar that holds your private key and signs mandates on demand; it makes no outbound network calls of its own.
Once both servers are registered, the model chains the tools automatically: it signs an IntentMandate, calls the quote endpoint, signs a PaymentMandate, and invokes - all in a single conversation turn, with the same spend-cap and policy enforcement from the gateway that SDK calls receive. The MCP server guide covers the exact registration steps for Claude Code and Claude Desktop.
Two servers, one reason
Safety by design, not afterthought
The five-step flow is not ceremony. Each step exists because agent transactions have failure modes that human-facing UIs can handle interactively but agents cannot.
- Spend caps - the agent's mandate carries a hard ceiling. The gateway rejects any invoke that would breach it, regardless of what the provider charges. The principal sets this once and trusts it absolutely.
- Fraud scoring - every request passes through an ML-backed anomaly scorer. An agent that books 40 rooms in 10 minutes trips a velocity limit. An action that looks nothing like the agent's established pattern gets flagged for human review before the funds move.
- Policy gates - large bookings (above a configurable threshold) route to a human-approval queue before execution. The agent waits; the principal approves or rejects via webhook.
- Tamper-evident audit - every invocation writes a hash-chained audit record that can be mirrored to WORM storage. The principal can prove what their agent did, or did not do, without relying on the agent's own logs.
Beyond hotels: any transactional workflow
The same flow works for any provider that publishes a capability spec: restaurant reservations, flight upgrades, software licence renewals, logistics bookings, procurement, financial settlements. The protocol is domain-agnostic. Once your agent knows how to interact with Sgovr, it can transact safely with any registered provider without new integration work.
This is the architectural difference between an agent that can use tools and one that can safely transact. Tools are about capability. Sgovr is about trust - the mandate that proves the principal authorised this specific action, the audit trail that proves it happened, and the payment rails that make sure the money moved correctly.
Provider? Register your spec
Try it yourself
The full hotel booking demo ships with the Sgovr source. The demo provider exposes a "Lux Hotels" adapter with search and booking actions. Run it locally and step through the entire flow - discovery, spec read, quote, payment mandate, invoke, audit - in under ten minutes:
- TypeScript SDK guide - full runnable example with the client SDK.
- Python SDK guide - the same flow, stdlib-only.
- MCP server guide - wire Sgovr into Claude Desktop or Claude Code.