{"ok":true,"site":{"host":"agentrep-app.vercel.app","url":"https://agentrep-app.vercel.app/","type":"live","desc":"A representation protocol: discover who can do the job, hold the plan as a composition, gate the booking.","tools":[{"name":"discover_sites","kind":"answer","impl":"imperative","description":"Find WebMCP-enabled websites that can actually perform part of the user's goal. Search engines answer 'where can I read about X'; this answers 'which site can do X for me'. Call it once per capability you need — one call for venues, another for catering, another for cake, another for entertainment — rather than one broad call, because it ranks by keyword overlap and a broad query dilutes the match. Never skip this and guess URLs. Returns each site's URL, the tools it exposes, why it matched, and what slot it fills. Re-run it later when the user's needs change: the set of indexed sites is not fixed. If they ask for themed entertainment after a site is indexed, call this again — a capability that was missing may exist now.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"What needs doing, in plain words, e.g. \"children's birthday venue in Delhi\" or \"themed entertainer for a party\"."},"limit":{"type":"integer","minimum":1,"maximum":8,"default":5}},"required":["query"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_site_capabilities","kind":"answer","impl":"imperative","description":"List exactly which WebMCP tools one site exposes and what each is for, without visiting it. Use to decide whether a site is worth opening before you navigate, and to know which tool to reach for when you get there.","inputSchema":{"type":"object","properties":{"domain":{"type":"string","description":"Domain or brand name from discover_sites."}},"required":["domain"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_plan_state","kind":"answer","impl":"imperative","description":"Read the plan board: event details, every slot, all candidates gathered so far, what is selected, the running total and any outstanding violations. Call this at the start of a planning turn and again whenever the user says they changed something — they can select and clear items on the board by hand, so your last known state may be stale. Compare stateVersion with the value from your previous call to detect that.","inputSchema":{"type":"object","properties":{"includeCandidates":{"type":"boolean","default":true,"description":"Set false for a cheap totals-only check."},"slots":{"type":"array","items":{"type":"string","enum":["venue","food","cake","entertainment"]},"description":"Restrict to specific slots. Omit for the whole board."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_event_details","kind":"answer","impl":"imperative","description":"Set the parameters of the event: budget, date, guest count, the child's age, theme and city. Call this as soon as the user states their goal, and again whenever they revise a constraint — 'make it under ₹12,000', 'five more kids are coming'. Changing these re-runs validation, so the reply tells you immediately whether the current plan still fits. Send only the fields that changed.","inputSchema":{"type":"object","properties":{"occasion":{"type":"string"},"budgetInPaise":{"type":"integer","minimum":0,"description":"Total budget in paise. ₹15,000 = 1500000. Always integer paise, never rupees, never a decimal."},"date":{"type":"string","format":"date","description":"ISO date, e.g. 2026-09-12."},"guestCount":{"type":"integer","minimum":1,"maximum":500},"childAge":{"type":"integer","minimum":0,"maximum":21},"theme":{"type":"string","description":"e.g. \"Pokémon\". Drives theme-match warnings."},"city":{"type":"string","description":"Event city, e.g. \"Delhi\" or \"Noida\". Changing city drops venue options that are not in that city. Delhi does not include Noida or Gurugram."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_candidates","kind":"act","impl":"imperative","description":"Put options you found on a provider site onto the board. This does NOT select them — candidates sit side by side so the user can see what you considered, and so later swaps have somewhere to go. Add every option from the provider search, including premium ones, not just the cheapest or your favourite: find_savings can only work with what is on the board, and a plan with one candidate per slot cannot be cut down. Send them in one call per slot rather than one per item.","inputSchema":{"type":"object","properties":{"slot":{"type":"string","enum":["venue","food","cake","entertainment"]},"candidates":{"type":"array","minItems":1,"maxItems":12,"items":{"type":"object","properties":{"id":{"type":"string","description":"Stable id as \"<Provider>:<itemId>\", e.g. \"PartyHub:venue-fun-arena\". Re-sending the same id updates that candidate instead of duplicating it, so retries are safe."},"provider":{"type":"string"},"providerDomain":{"type":"string"},"name":{"type":"string"},"priceInPaise":{"type":"integer","minimum":0},"attributes":{"type":"object","description":"Comparable facts. Use the SAME keys across candidates in one slot so the board can render a comparison and explain_tradeoff can diff them. Venue: capacity, rating, indoor. Cake: servings, flavour, eggless. Food: includedGuests, courses.","additionalProperties":{"type":["string","number","boolean"]}},"sourceTool":{"type":"string","description":"Provider tool that returned this, e.g. \"search_venues\"."}},"required":["id","provider","name","priceInPaise"],"additionalProperties":false}}},"required":["slot","candidates"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"select_candidate","kind":"act","impl":"imperative","description":"Commit one candidate as the choice for its slot, replacing any previous selection. This is what moves money onto the running total. It books nothing — booking happens only after request_approval and commit_plan — so call it freely while exploring. The event budget is a ceiling, not a target: do not minimise spend unless the user asked. Prefer theme and date fit among options already on the board. Selecting anything invalidates a previous approval, by design.","inputSchema":{"type":"object","properties":{"candidateId":{"type":"string"},"reason":{"type":"string","description":"One short line on why this one. Shown on the board beside the selection so the user sees your reasoning without asking."}},"required":["candidateId"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"find_savings","kind":"answer","impl":"imperative","description":"Given a target total, search every combination of candidates already on the board and return the cheapest ways to reach it, ranked by how little quality is given up. Use this the moment the user asks to cut the budget. Do not guess at swaps yourself and do not go back to the provider sites first — this is exhaustive over what you have already gathered, so it will find combinations you would miss. Each option lists the exact swaps, the new total and what is lost. An empty result means the target is unreachable from current candidates, which is your signal to go search providers for cheaper items and then retry.","inputSchema":{"type":"object","properties":{"targetTotalInPaise":{"type":"integer","minimum":0},"protectedSlots":{"type":"array","items":{"type":"string","enum":["venue","food","cake","entertainment"]},"description":"Slots the user said not to touch. Respected strictly."},"maxOptions":{"type":"integer","minimum":1,"maximum":5,"default":3}},"required":["targetTotalInPaise"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"explain_tradeoff","kind":"act","impl":"imperative","description":"Diff two candidates in the same slot across price and every shared attribute. Call this before recommending a downgrade so you can tell the user precisely what they give up, rather than saying 'a cheaper option'. Returns a field-by-field comparison, not prose.","inputSchema":{"type":"object","properties":{"candidateIdA":{"type":"string"},"candidateIdB":{"type":"string"}},"required":["candidateIdA","candidateIdB"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"check_plan","kind":"answer","impl":"imperative","description":"Validate the whole plan and return every violation: over budget, empty required slots, missing date, venue capacity below the guest count, cake servings below the guest count, theme mismatches. Call this before request_approval, always — blocking violations prevent approval and you will waste the user's attention asking for it.","inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"highlight","kind":"act","impl":"imperative","description":"Draw the user's attention to parts of the board while you explain something. Call it immediately BEFORE the sentence it refers to, so they are looking at the right place as you speak — highlight the food and cake rows, then say 'these two are what push us over budget'. This is how you point at things. Use it often. It costs nothing and it is what makes the board feel shared rather than something you operate behind the user's back.","inputSchema":{"type":"object","properties":{"targets":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"object","properties":{"kind":{"type":"string","enum":["slot","candidate","total","violation"]},"id":{"type":"string","description":"Slot id, candidate id, or violation code. Omit for kind 'total'."}},"required":["kind"],"additionalProperties":false}},"intent":{"type":"string","enum":["attention","problem","improvement","removed"],"default":"attention","description":"Colours the highlight: neutral, red for a problem, green for something you are proposing, grey for something being dropped."},"note":{"type":"string","maxLength":80,"description":"Optional short label drawn on the highlight."}},"required":["targets"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"request_approval","kind":"act","impl":"imperative","description":"Render the approval panel on the board — full line items, total, and which provider each booking goes to — and WAIT for the user to press approve or reject. This call blocks until they decide or it times out. It is the only way to get the approvalToken that commit_plan requires. Never tell the user anything is booked before this returns approved. If they edit the board while the panel is open the request is invalidated and you must check and ask again.","inputSchema":{"type":"object","properties":{"message":{"type":"string","maxLength":240,"description":"What you are asking them to approve, in your own words. Shown above the line items."},"timeoutSeconds":{"type":"integer","minimum":15,"maximum":180,"default":90}},"required":["message"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"commit_plan","kind":"act","impl":"imperative","description":"Exchange an approval token for the list of booking actions the user authorised. AgentRep does not book anything itself — it returns, for each slot, which provider site to open and which tool to call with which arguments. You then go and make those calls. This separation is deliberate: the board holds the decision, the provider owns the transaction. The token is single-use and bound to the exact plan the user saw, so it is refused if anything changed.","inputSchema":{"type":"object","properties":{"approvalToken":{"type":"string"}},"required":["approvalToken"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"record_booking","kind":"transact","impl":"imperative","description":"Write a provider's confirmation reference back onto the board after you have actually booked. Call this once per slot, immediately after the provider's booking tool returns, so the board reflects reality rather than intent. Without it the user sees an approved plan with no confirmations and cannot tell what went through.","inputSchema":{"type":"object","properties":{"slot":{"type":"string","enum":["venue","food","cake","entertainment"]},"reference":{"type":"string","description":"The reference the provider returned, e.g. \"PART-3K9XA\"."}},"required":["slot","reference"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"undo_last_change","kind":"act","impl":"imperative","description":"Revert the most recent selection change on the board. Use when the user says that was wrong, or to back out of a swap they disliked. Cannot undo a recorded booking.","inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"AI & Agents","apiSurface":"spec","toolCount":14}}