{"ok":true,"site":{"host":"tripcanvas.tillmac.com","url":"https://tripcanvas.tillmac.com/","type":"live","desc":"A live map itinerary a human and a WebMCP browser agent edit together — every agent change reviewable.","tools":[{"name":"get_itinerary","kind":"answer","impl":"imperative","description":"Read the whole trip: each day's ordered stops with arrival times, dwell, leg mode and minutes, lodging per night, candidates (places on no day), and warnings (past-22:00 overflow, legs over 40 min). Every read also lists what the human changed since your last read and which of your edits are still pending review. Call it before editing and again after the human touches the map. Stops are addressed by the [s#]/[c#] ids it prints. Pass day for one day in full detail on long trips.","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"day":{"type":"number","description":"1-based day to read alone in full detail. Omit for the whole trip; trips over 4 days auto-compact to per-day one-liners."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_changes","kind":"answer","impl":"imperative","description":"List every change since a revision: who made it (human or agent), what changed, and the fate of each of your edits — pending, accepted, or reverted. Defaults to everything since your last get_itinerary or get_changes call. Use it after a pause to see what the human did, and before building on your own pending edits. Returns 'No changes since rev N.' when quiet; if the revision is older than kept history it returns the full itinerary instead.","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"since":{"type":"number","minimum":0,"description":"Revision to list changes after (from an earlier result). Default: your last read."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_leg_options","kind":"answer","impl":"imperative","description":"Compare one leg by walk, drive and transit in a single read, before committing to a mode. Name the leg by the stop it departs from ([s#] id; 'lodging' for a day's first leg; the day's last stop names the return to lodging). Transit is fetched live, so this takes a few seconds; '~' marks an estimated number. Nothing changes — the leg keeps its current mode; use set_leg_mode to apply the one you pick.","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"day":{"type":"number","minimum":1,"description":"Day 1..N containing the leg."},"fromStop":{"type":"string","description":"[s#] id the leg departs from ('lodging' = day's first leg; the last stop = return to lodging)."}},"required":["day","fromStop"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"revert_pending","kind":"act","impl":"imperative","description":"Revert your own pending edits — ones the human has not yet accepted or built on. Pass edit ids from get_changes, or all:true for every pending edit of yours. An edit whose stops the human already touched is accepted and stays; the rest of the edit is restored exactly. Never touches human-made changes; ask the human to undo those instead.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"edits":{"type":"array","items":{"type":"string"},"description":"Pending edit ids from get_changes, e.g. ['e12']."},"all":{"type":"boolean","description":"Revert every pending edit of yours."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"plan_trip","kind":"act","impl":"imperative","description":"Plan a whole trip from place names. Give places plus dayCount, or days you grouped yourself (grouping kept; each day is still ordered by travel time). Max 12 names per call including lodging — resolving is rate-limited (~1/s). The page resolves names, assigns days, orders each day from its lodging, and computes a timed schedule. Unresolved names are skipped and listed, never fatal. Everything lands pending until the human reviews it. Overwriting an existing trip needs replace:true.","annotations":{"readOnlyHint":false,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"places":{"type":"array","items":{"type":"string"},"description":"Flat place names, e.g. 'Ghibli Museum, Mitaka'. Use with dayCount, or give days instead. 12 names max incl. lodging."},"days":{"type":"array","items":{"type":"array","items":{"type":"string"}},"description":"Pre-grouped names, one inner array per day. Grouping kept; each day still reordered by travel time."},"dayCount":{"type":"number","minimum":1,"maximum":7,"description":"Number of days, 1-7. Required with places; ignored with days."},"lodging":{"type":"string","description":"Lodging name, applies to all nights. Per-night lodging: set_lodging afterwards."},"dayStart":{"type":"string","description":"HH:MM start for every day. Default 09:00."},"replace":{"type":"boolean","description":"Must be true to overwrite an existing trip."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_place","kind":"act","impl":"imperative","description":"Resolve one free-text place name and add it: to a day at the best position by travel time (or a fixed position), or as a candidate when day is omitted. Takes about 1s for an uncached name. Returns the resolved name — check it matches what you meant; if wrong, move it to candidates and retry with a fuller name like 'Ghibli Museum, Mitaka'. The stop lands pending for the human.","annotations":{"readOnlyHint":false,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Free-text place name; include the city for accuracy."},"day":{"type":"number","minimum":1,"description":"1-based target day; omit to add as a candidate."},"position":{"type":"number","minimum":1,"description":"1-based slot in the day; omit for best insertion by travel time."},"dwellMinutes":{"type":"number","minimum":0,"description":"Minutes at the stop. Default 60."}},"required":["name"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"move_stop","kind":"act","impl":"imperative","description":"Move a stop to another day or position, place a candidate onto a day, or pass day 0 to unassign a stop into candidates (nothing is deleted; candidates keep it recoverable). Omit position for best insertion by travel time. Ids come from get_itinerary. Affected days reschedule immediately; the result reports their new end times and any overflow. Pending until the human accepts or reverts.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"stop":{"type":"string","description":"[s#] or [c#] id from get_itinerary."},"day":{"type":"number","minimum":0,"description":"Target day 1..N, or 0 to send it to candidates."},"position":{"type":"number","minimum":1,"description":"1-based slot; omit for best insertion by travel time."}},"required":["stop","day"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_times","kind":"act","impl":"imperative","description":"Set a day's timing inputs: dayStart (HH:MM) moves when the day leaves its lodging; stop plus dwellMinutes changes minutes spent there; freeMinutesAfter inserts unscheduled time after that stop. The schedule recomputes at once. Use when get_itinerary warns a day overflows past 22:00 — start earlier or trim dwell. Pending until the human accepts.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"day":{"type":"number","minimum":1,"description":"Day 1..N."},"dayStart":{"type":"string","description":"New HH:MM 24h start for the day."},"stop":{"type":"string","description":"[s#] id to retime; required with dwellMinutes or freeMinutesAfter."},"dwellMinutes":{"type":"number","minimum":0,"description":"New minutes spent at the stop."},"freeMinutesAfter":{"type":"number","minimum":0,"description":"Unscheduled minutes after the stop; 0 removes the block."}},"required":["day"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_leg_mode","kind":"act","impl":"imperative","description":"Set how one leg is travelled: walk, drive or transit. Name the leg by the stop it departs from ([s#] id; 'lodging' for a day's first leg; the day's last stop names the return to lodging). Legs default to walk under about 1.2 km and drive above — call this only to override. transit fetches live routes (a few seconds) and returns the steps: lines, headsigns, where to get off. If no transit route exists the leg keeps its old mode and the result says so. Pending.","annotations":{"readOnlyHint":false,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"day":{"type":"number","minimum":1,"description":"Day 1..N containing the leg."},"fromStop":{"type":"string","description":"[s#] id the leg departs from ('lodging' = day's first leg; the last stop = return to lodging)."},"mode":{"type":"string","enum":["walk","drive","transit"],"description":"walk | drive | transit."}},"required":["day","fromStop","mode"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_lodging","kind":"act","impl":"imperative","description":"Resolve a lodging name and anchor nights to it. Night 0 is where Day 1 starts; night N is where day N ends and day N+1 starts. Omit nights to set every night. Day schedules recompute from their anchors; days with no lodging start at their first stop. Returns the resolved name — verify it matches. Pending until the human accepts.","annotations":{"readOnlyHint":false,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Lodging name or address; include the city."},"nights":{"type":"array","items":{"type":"number","minimum":0},"description":"Night numbers to anchor; omit for every night."}},"required":["name"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"arrange_days","kind":"act","impl":"imperative","description":"Regroup and reorder every placed stop across days by travel time: stops cluster into days, each day is ordered from its lodging, schedules recompute — exactly what the human's Arrange days button does. Dwell survives; leg-mode choices survive where the stop pair stays adjacent. Candidates untouched. Pass dayCount to grow or shrink the trip. Use after several adds rather than optimising stop by stop. One pending edit, one-click revert.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"dayCount":{"type":"number","minimum":1,"maximum":7,"description":"Target number of days 1-7; omit to keep the current count."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_planning_guide","kind":"answer","impl":"imperative","description":"Read once before planning or filling a trip: typical minutes to spend at different kinds of places, how many stops make a comfortable day, and when to leave free time for meals. Use it to choose dwellMinutes for add_place and set_times and to decide how much to pack into a day. Static text — the live trip comes from get_itinerary.","annotations":{"readOnlyHint":true,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"Travel & Events","favicon":"/favicons/tripcanvas.tillmac.com.png","apiSurface":"spec","toolCount":12}}