Loop
How it worksThe loopWhy LoopPricingDocs
use case restaurant booking agents

Verify before booking.
Report after.

Booking agents fail when they act on stale data — discovering a closed restaurant after routing the user there. Loop gives agents a way to check before acting: verify() re-runs a live observation on the specific record, and report() records the outcome so the next agent gets better data.

the problem

Agents discover stale data too late.

A booking agent searches Google Places or a map API, finds a match, starts navigating the user or attempting a reservation — then discovers the hours were wrong. The restaurant closed early. It doesn’t have outdoor seating. The phone number is disconnected. The user is disappointed.

The root cause: search APIs return data without freshness labels, and they have no mechanism for agents to check a claim before acting on it. Loop solves both: verify() re-checks a specific record live before you commit, and report() feeds back what actually happened so every future search is better.

424
restaurants in Kreuzberg
312
cross-source confirmed
4
steps: search → details → verify → report
the booking flow
Step 1 — search()
// Step 1: search
{
  "name": "search",
  "arguments": {
    "query": "Italian restaurant open tonight, outdoor seating",
    "location": "Kreuzberg, Berlin",
    "filters": { "outdoor_seating": true }
  }
}
Step 2 — get_details()
// Step 2: get_details (issues result_token for report)
{
  "name": "get_details",
  "arguments": {
    "result_id": "osm_node_12345678"
  }
}
// → returns full record + result_token (valid 30 min)
Step 3 — verify()
// Step 3: verify() — re-check a specific claim live
{
  "name": "verify",
  "arguments": {
    "result_id": "osm_node_12345678",
    "claim": "open tonight with outdoor seating"
  }
}
// → response:
{
  "result_id": "osm_node_12345678",
  "name": "Trattoria da Marco",
  "claim": "open tonight with outdoor seating",
  "latest_observation": {
    "type": "recheck",
    "value": {
      "present": true,
      "opening_hours": "Mo-Su 12:00-23:00"
    },
    "source": "osm_recheck",
    "confidence": 0.85,
    "observed_at": "2026-06-12T19:45:00Z"
  },
  "observed_at": "2026-06-12T19:45:00Z",
  "record_confidence": 0.91,
  "availability": { "inferred": true, "status": "likely_open_now" },
  "note": "Re-verified live against OSM — observed_at reflects this check."
}
Step 4 — report() the outcome
// Step 4: report the outcome
// result_token comes from get_details()
{
  "name": "report",
  "arguments": {
    "result_token": "eyJhbGci...",
    "outcome": "correct"
  }
}

// outcome: "correct" | "booked" | "closed" | "wrong" | "other"

Loop is the data and verification layer — not the reservation mechanism. The booking step (OpenTable partner API, browser automation, phone call) happens in your agent after verify() clears the way. report() records what actually happened.

what you get

verify() before you act

Call verify(result_id, claim) before routing, booking, or telling a user a restaurant is open tonight. Catches stale data before the user is disappointed.

📊

report() after the outcome

report(result_token, outcome) records what actually happened — open, closed, wrong details. Each call mutates confidence and freshness for every future agent query.

🕐

Explicit freshness signals

Every record includes observed_at and a confidence score. Availability is labeled inferred: true until verified. Agents can surface this honestly to users.

🔌

MCP native

Add https://stayinloop.dev/mcp to any MCP client. Four tools available instantly: search, get_details, verify, report.

Typed restaurant schema

cuisine[], price_band, outdoor_seating, vegan, vegetarian as typed fields — no string parsing. Build booking filters that actually work.

🔍

Cross-source confirmed

312 of 424 Kreuzberg restaurants confirmed across OpenStreetMap and Foursquare OS Places — flagged in every response so agents can surface higher-confidence results first.

four tools, one endpoint
search()
When: User states a preference or request

Natural-language + filter search across 424 Kreuzberg restaurants. Returns ranked candidates with confidence and freshness. Filter by cuisine, outdoor_seating, vegan, price_band.

get_details()
When: User selects a candidate

Full record: all fields, opening hours, phone, website. Returns a result_token valid 30 minutes — required for report().

verify()
When: Before any booking attempt or user commitment

Re-checks a specific claim live: is it open now? Does it have outdoor seating tonight? Call this before routing the user or attempting a reservation. Do not skip this step.

report()
When: After the agent observes an outcome

outcome: 'correct' (data matched reality), 'booked' (reservation placed), 'closed' (was closed when agent checked), 'wrong' (hours, amenities, or details were wrong), 'other'. Mutates confidence and freshness in the database. Required for the loop to close.

Add Loop to your booking agent.

Add https://stayinloop.dev/mcp as a remote MCP server. Four tools, free tier, no credit card.