check_koko_status
ChatGPTReport how far along one of the user's Koko lists or plans is in its background build. send_to_koko returns before the build finishes: geocoding and the ratings/photos pass continue in the background, and this tool reports where that has got to. Returns a staged message (received → locating → enriching → ready) with a step number and the view link; step == total means the build is complete. ALSO the status of an update_koko that answered it was rebuilding: it says while the update is still rebuilding, then that it is in (with any stop that didn't map) or that it failed (nothing changed).
discover_koko
ChatGPTFind up to ten free public Koko trips by title or destination. No purchases or pricing.
get_koko
ChatGPTRetrieve ONE of the user's Koko lists or plans as an EDITABLE structure so you can modify it and push it back with update_koko. Get the id from my_koko. Returns JSON in the same shape send_to_koko uses: {job_id, kind, title, region, description, and either places (a list) or days (a plan — arrays of stops, each with dwell_min; free-time blocks appear as {free_time:true, duration_min, neighborhood}, and a travel leg as the same block tagged transport_mode with its own transport_start/transport_end/transport_note)}. A plan also carries mode/day_start/start_date. A stop that didn't make the schedule rides the trailing day with an unscheduled_reason (place closed / hours conflict / ran out of time) — relay that if the user asks about a missing stop. A stop the user has written a side note on carries it as note (only their OWN notes come back — a note written by the creator of a list they bought is shown in the app but is not theirs to rewrite). EVERY LOCATED STOP ALSO CARRIES resolved — {lat, lng, address, source} — which is WHERE THE PIN ACTUALLY LANDED, not what you asked for. CHECK IT when travel times look wrong: an address in the wrong city or ward is a mis-geocode, not a routing bug, and it is the usual cause of an absurd leg (a Ginza restaurant once resolved 56km away and showed a 3-hour drive). resolved is READ-ONLY — send a better query to move a pin. A stop with no resolved has no pin at all and is not on the map. A PLAN STOP AFTER THE FIRST ONE OF ITS DAY ALSO CARRIES travel — {mode, minutes, source, distance_km, walk_minutes, transit_minutes, car_minutes, note} — HOW THE HOP INTO IT IS BEING TRAVELLED, so you can check the routing and not just the pins. mode is what the plan shows ('walk' | 'transit' | 'car'), minutes is the gap the schedule left for it, and the per-mode minutes are OUR estimates. source is "engine" (our guess) or "you" (a transport already set here, which we no longer re-decide). UNLIKE resolved, THIS BLOCK IS WRITABLE — see update_koko's travel. transit_minutes: null means our station index found no rail route between those pins; in greater Tokyo that usually means the index is thin (no geo for JR or any private railway), not that there is no train. Edit the structure, then call update_koko with the FULL new version.
import_koko_link
ChatGPTImport one public Instagram, TikTok, YouTube, Threads, or Google Maps list link the user supplied into their Koko account. This uses one monthly link import allowance and starts an asynchronous build. Returns a task id for checking progress.
import_koko_status
ChatGPTCheck the status and resulting trip id of the user's link import.
koko_account
ChatGPTWho the connected Koko account is: display name, username, email, whether it is an operator account, the creator storefront it publishes to (if any), how many lists and plans it holds, and — critically — whether sends AUTO-PUBLISH to the public Discover shelf. Call this when the user asks who they are logged in as, when a send is about to go somewhere public, or when anything about the account is ambiguous. Returns only the caller's own account.
my_koko
ChatGPTList the lists and plans in the user's Koko account (title, kind, place count, id).
my_travel_type
ChatGPTRead the signed-in user's saved Koko travel type, if they took the quiz.
open_koko
ChatGPTOpen the signed-in user's saved Koko trip library or one trip's compact map and day view.
read_koko_settings
ChatGPTRead Koko's planning preference schema and current values.
refresh_details
ChatGPTManually re-pull Google ratings/reviews/hours + photos on an EXISTING Koko list or plan. This happens automatically on send_to_koko, so ONLY call it when the user explicitly asks to refresh an existing list. confirm=false estimates the cost; confirm=true spends and starts the refresh in the background (it returns at once; the data lands over a minute or two).
search_koko_mentions
ChatGPTSearch the signed-in user's saved trips for the composer picker.
send_to_koko
ChatGPTSave what you just made to the user's Koko account — a LIST or a PLAN, decided automatically from the shape. A PLAN has a schedule (stops with times grouped into days) → pass days. A LIST is just places in rank order → pass places. Pass EXACTLY ONE. region = 'City, Country'. Whenever the plan includes FREE TIME (a break, downtime, 'explore on your own'), encode that stop as a free-time block ({free_time: true, duration_min, neighborhood?}) — never as a place. Any SIDE NOTE the user gives about a particular stop ('Thursdays only', 'book the counter seat') goes in that stop's note — it is kept per-stop and shown on the stop itself, and is a different field from reason, which is the one-line pitch on the card. Geocoding is free; ratings/photos fill in afterward. Returns a quick ack + a view link.
update_koko
ChatGPTUpdate an EXISTING Koko list or plan — a FULL REPLACE of its contents from the edited structure you got from get_koko. Pass the WHOLE new version, not a diff: stops you omit are removed, new ones are added, and the order/notes/durations you send win. The list's link and id stay the same; unchanged places keep their pins & photos (only new names are geocoded). TO CORRECT A WRONG PIN, send that stop a more specific query (exact name + ward/neighbourhood + city + country): a query that differs from the one the stop was resolved with re-geocodes it, and the old pin is kept only if nothing better is found. Changing name or reason does NOT move a pin. Drop the resolved block or send it back untouched — it is ignored either way. Pass places for a list or days for a plan (match the kind from get_koko). Keep free-time blocks as {free_time: true, duration_min, neighborhood?} stops — and a JOURNEY (a flight, a train leg) as the one get_koko gave you, transport_mode and its transport_start/transport_end/transport_note intact: drop those and the leg comes back as anonymous downtime. KEEP EACH STOP'S note — this call re-creates every stop, so a note you drop from the payload is deleted from the list. Send back the note get_koko gave you (edited if the user asked), and add one to any stop they just told you something about. title/region/description/start_date/day_start are optional — omitted ones keep their current values. A plan stop can carry travel — the transport into it from the stop before. SEND IT WHENEVER YOU KNOW BETTER THAN A HEURISTIC: our estimate has no timetable and no geo for JR or any private railway, so it mis-routes real journeys and will sometimes choose a car over an obvious train. A travel you send is used as given and survives every later edit; get_koko marks those legs source: "you". The expected input is the structure get_koko returns for this job_id with the edits applied, so that the replacement is built from the current version. ATOMIC, AND ASYNCHRONOUS WHEN BIG: the payload is validated first (an error changes nothing), and the new version is built off to the side and swapped in whole. A rebuild that takes more than ~20 s (a long trip, many new places) answers that it is still rebuilding: poll check_koko_status with this job_id until it says the update is in, and send nothing else to this job meanwhile.
update_koko_settings
ChatGPTSet the signed-in user's default transport for new plans.
whoami
ChatGPTIdentify the authenticated Koko account: returns JSON with username (stable), email, name, username, is_operator, auto_publish_as and creator_handle. No arguments. Call it to confirm which account this connection acts on — e.g. before a send, or when the user asks who they are logged in as. koko_account is the same information as prose.