Before your agent dispatches a delivery, it needs to know the restaurant is actually open. Loop's verify() upgrades stale availability labels to live observations. report() feeds outcomes back — every closed-restaurant signal improves the data for the next agent.
Restaurant hours change without notice. A delivery agent relying on static place data will occasionally dispatch to a closed restaurant — a bad outcome for the user and a wasted signal. Loop's verify() re-checks availability live before the agent acts, and report() writes the outcome back so the next agent starts with fresher data.
search()Find restaurants matching the delivery request — natural language, typed filters{ "name": "search", "arguments": { "query": "pizza, quick delivery, open now", "location": "Kreuzberg, Berlin", "filters": { "price_band": "€€" } } } // → typed results: // { // "result_id": "osm_node_98765432", // "name": "Pizzeria da Marco", // "cuisine": ["italian", "pizza"], // "price_band": "€€", // "observed_at": "2026-06-12T...", // "confidence": 0.91, // "cross_source_confirmed": true, // "availability": { "status": "likely_open_now", "inferred": true } // }
get_details()Fetch phone, address, and hours for the top candidate{ "name": "get_details", "arguments": { "result_id": "osm_node_98765432" } } // → full record: // { // "name": "Pizzeria da Marco", // "address": "Oranienstraße 12, 10999 Berlin", // "phone": "+49 30 ...", // "opening_hours": "Mo-Su 11:00-23:00", // "location": { "lat": 52.499, "lng": 13.418 }, // "result_token": "eyJ...", // required for report() — expires 30 min // "confidence": 0.91 // }
verify()Confirm the restaurant is open before dispatching the order{ "name": "verify", "arguments": { "result_id": "osm_node_98765432", "claim": "open now" } } // → live observation: // { // "verified": true, // "latest_observation": { // "status": "open", // "observed_at": "2026-06-12T19:42:00Z", // "inferred": false // ← upgraded from inferred to observed // }, // "confidence": 0.94 // }
report()Close the feedback loop after the delivery outcome is known{ "name": "report", "arguments": { "result_token": "eyJ...", "outcome": "correct" } } // outcome enum: // "correct" — data matched reality (restaurant was open, order placed) // "wrong" — hours or details were inaccurate // "closed" — restaurant was closed at dispatch time // "booked" — order was placed and confirmed // "other" — any other outcome // → { "recorded": true, "confidence_delta": +0.02 }
| Without Loop verify() | With Loop verify() |
|---|---|
| Availability from static tags (inferred) | Live re-check, freshness timestamp |
| No signal when restaurant is closed | report('closed') updates confidence score |
| Next agent repeats the same failed lookup | Next agent gets upgraded confidence from reports |
| Stale hours silently accepted | inferred: true label always surfaced to agent |
Yes. Call search(query, location, filters) — for example "pizza, open now" in "Kreuzberg, Berlin". Results include cuisine[], price_band, observed_at, and confidence. Use get_details() to get opening_hours and phone.
Before dispatching, call verify(result_id, "open now"). Loop re-checks the record live and returns a latest_observation with an inferred: false flag. Availability in search results is always inferred: true until verify() confirms it.
Call report(result_token, "closed")to signal the closure. Loop updates the record's confidence score and freshness timestamp. Then fall back to the next result from search(). Each closure report makes the data better for subsequent delivery agents.
No. The free tier accepts unauthenticated connections to https://stayinloop.dev/mcp. For higher-volume delivery pipelines, apply for a key at stayinloop.dev/#pricing.