Docs
Roadbook MCP API
See what is included in Premium
Roadbook exposes a Model Context Protocol(MCP) server so an AI agent can plan and manage trips on a user's behalf. The endpoint speaks JSON-RPC 2.0 over a single route.
Endpoint
POST /mcp accepts a JSON-RPC 2.0 request (or a batch array of up to 50) and dispatches on the methodfield - initialize,tools/list, andtools/call are the ones an MCP client needs. The machine-readable request/response envelope is published as OpenAPI at/openapi.json. Every tool and its input fields are listed under Tools.
Authentication
Every request needs a bearer token in the Authorization header. Two ways to get one:
- OAuth 2.0 - discover the authorization server at/.well-known/oauth-authorization-server(RFC 8414) and the protected-resource metadata at/.well-known/oauth-protected-resource(RFC 9728). Dynamic client registration, PKCE (S256), and the
authorization_codeandrefresh_tokengrants are supported. - Personal token - a signed-in user can mint a long-lived token from their account settings for scripting or local MCP clients that don't support OAuth.
Access
Connecting and listing tools is free. Every tool call needs an active premium subscription. Any authenticated, non-banned Roadbook account can run initialize and tools/list. The premium check runs at tools/call time, not at connection time.
Tools
29 tools, generated from the server's own tools/list response, so every field below is one a client sees. Each badge says what a tool does to your data, not which plan can call it. The badge comes from the tool's MCP annotations: Read-only never changes data, Writes adds or edits, and Destructive can remove data.
list_tripsRead-only
List trips
List the trips you own (id, name, slug, visibility).
| Field | Type | Required | Notes |
|---|---|---|---|
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
read_tripRead-only
Read trip
Read one of your trips with its stops in order, each with name/city/state, nights, and public place coordinates only (never planner-only coordinates), plus trip.startDate and trip.endDate. Call this FIRST before saving a trip transcript to the logbook: match each place named in the transcript to a stop by its public identity (name/city/state - never coordinates), then derive each matched stop's date as trip.startDate plus the cumulative nights of every earlier stop (or the transcript's stated date when it gives one). File the resulting entries with create_journal_entries.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
create_tripWrites
Create trip
Create a new private trip. Provide a name; optionally a startDate and endDate (YYYY-MM-DD).
| Field | Type | Required | Notes |
|---|---|---|---|
| name | string | Required | Trip name |
| startDate | string | Optional | ISO date YYYY-MM-DD (optional) |
| endDate | string | Optional | ISO date YYYY-MM-DD (optional) |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
search_placesRead-only
Search places
Search for real places by name. Give a destination name or query only - never coordinates. The server resolves it to a real place. Returns candidate matches to confirm before adding.
| Field | Type | Required | Notes |
|---|---|---|---|
| query | string | Required | Destination name or query |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
add_stopWrites
Add stop
Add a stop to a trip by destination name/query. Give a destination name or query only - never coordinates. The server resolves it to a real place. On an ambiguous match nothing is created and each returned candidate carries a "ref" - call add_stop again with tripId and candidateRef (query not required) to add the exact one meant. Optionally place it precisely: set beforeWaypointId to an existing top-level stop id (from read_trip) to insert the new stop immediately before it; omit beforeWaypointId to append at the end, as before. If you're repeating this call to resolve an ambiguous match with candidateRef, pass beforeWaypointId again too - it is not remembered from the first call. Optionally record lodging for this stop in the same call: set lodgingName (required once any lodging field is set) plus any of lodgingType, checkIn/checkOut, cost, currency, reservationRef, lodgingNotes.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| query | string | Optional | Destination name or query |
| candidateRef | string | Optional | A "ref" from a previous ambiguous add_stop result - use instead of query to add that exact candidate |
| role | string | Optional | departure | stop | destination (default stop) |
| beforeWaypointId | string | Optional | Insert the new stop immediately before this existing top-level stop id (from read_trip). Omit - or send an empty string - to append at the end. |
| lodgingName | string | null | Optional | |
| lodgingType | "campground" | "hotel" | "motel" | "inn" | "rental" | "dispersed" | "other" | null | Optional | Type of lodging: campground, hotel, motel, inn, rental, dispersed, other |
| checkIn | string | null | Optional | |
| checkOut | string | null | Optional | |
| cost | number | null | Optional | Cost of the stay |
| currency | string | null | Optional | |
| reservationRef | string | null | Optional | |
| lodgingNotes | string | null | Optional | |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
update_stopWrites
Update stop
Update a stop on your trip: its role, number of nights, and/or its lodging booking (lodgingName, lodgingType, checkIn/checkOut, cost, currency, reservationRef, lodgingNotes). lodgingName is required the first time lodging is recorded for this stop; once set it cannot be cleared. Pass null (or an empty string) on any other lodging field to clear it, or omit a field to leave it unchanged. To detach a booking from this stop entirely, use remove_stop_lodging.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| role | string | Optional | departure | stop | destination |
| nights | integer | Optional | Nights at this stop |
| lodgingName | string | null | Optional | |
| lodgingType | "campground" | "hotel" | "motel" | "inn" | "rental" | "dispersed" | "other" | null | Optional | Type of lodging: campground, hotel, motel, inn, rental, dispersed, other |
| checkIn | string | null | Optional | |
| checkOut | string | null | Optional | |
| cost | number | null | Optional | Cost of the stay |
| currency | string | null | Optional | |
| reservationRef | string | null | Optional | |
| lodgingNotes | string | null | Optional | |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
remove_stopDestructive
Remove stop
Remove a stop from your trip.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
remove_stop_lodgingDestructive
Remove stop lodging
Remove one lodging record from a stop on your trip, without removing the stop. The stop keeps its place, position, nights, charging report and every logbook entry tagged to it. Pass the lodgingId from read_trip to name the exact record. Omit lodgingId only when the stop has a single lodging record; if the stop has none this reports that there was nothing to remove, and if it has several it asks you to name one. Deletion cannot be undone.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| lodgingId | string | Optional | Id of the lodging record to remove, from read_trip (optional when the stop has exactly one) |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
reorder_stopsWrites
Reorder stops
Reorder all stops on your trip. Pass every stop id in the new order.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointIds | string[] | Required | All stop ids, in the new order |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
list_journal_entriesRead-only
List logbook entries
Operates on the PRIVATE LOGBOOK, never the public journal body. Lists the private logbook entries for one of your trips. Each entry includes its visibility ('private' or 'public').
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
create_journal_entryWrites
Create logbook entry
Operates on the PRIVATE LOGBOOK, never the public journal body. Add a single private dated logbook entry (markdown). Optionally tag it to a stop. A note about the drive itself belongs on the arrival stop with scope: 'drive'. Entries are private by default. Only set visibility: 'public' when the user has explicitly asked for that entry to be public - never infer it. When splitting a whole trip transcript across multiple stops, use create_journal_entries instead so you file one entry per matched stop in a single call. Changing the logbook marks a published journal stale. The response echoes the tagged stop's recorded lodging as lodging (name, type, charger type). Compare it against the entry text you just wrote. If they disagree, tell the user which entry looks misfiled and which stop it probably belongs to instead of silently re-filing it. An entry with no stop tag comes back with a warnings entry saying it could not be checked - relay that to the user too.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| body | string | Required | Markdown note |
| entryDate | string | Required | ISO date YYYY-MM-DD |
| waypointId | string | Optional | Stop id to tag (optional) |
| scope | "stay" | "drive" | Optional | stay = about the time at the tagged stop (default); drive = about the leg that arrived at it (requires waypointId, and the first stop has no inbound drive) |
| visibility | "private" | "public" | Optional | private (default) = never leaves your view; public = eligible to appear publicly, and only ever when the trip itself is public. Set 'public' only when the user explicitly asks. |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
create_journal_entriesWrites
Create logbook entries (batch)
Operates on the PRIVATE LOGBOOK, never the public journal body. Add multiple private dated logbook entries (markdown) in one call - e.g. splitting an entire trip transcript into per-stop notes. Before calling, use read_trip to get the trip's stops (name/city/state, nights) and startDate. Match each transcript place to a real stop by public identity (name/city/state - never coordinates) and set that entry's waypointId; create at most one entry per matched stop, consolidating repeated mentions into it. Date each entry from the transcript when it states one, otherwise use the stop's planned date (startDate plus the cumulative nights of every earlier stop), formatted YYYY-MM-DD. Never create a stop or an entry for a transcript place that is not already a stop on this trip - report those unmatched places back to the user instead of guessing. Entries are private by default. Only set an entry's visibility: 'public' when the user has explicitly asked for that entry to be public - never infer it, and never mark a whole transcript public. Each entry may optionally tag a stop, and a note about the drive itself belongs on the arrival stop with scope: 'drive'. Validation is per-entry: the response reports each entry's outcome (created id, or its error) instead of failing the whole call. Max 50 entries per call. Changing the logbook marks a published journal stale. Each created entry's result carries its own lodging (the tagged stop's recorded booking name, type, charger type). Compare each entry's text against its lodging and, on a disagreement, tell the user which entry looks misfiled and which stop it probably belongs to instead of silently re-filing it. An entry with no stop tag carries a warnings entry saying it could not be checked - relay that too.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| entries | object[] | Required | Entries to create, in order (max 50) |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
update_journal_entryWrites
Update logbook entry
Operates on the PRIVATE LOGBOOK, never the public journal body. Edit a private logbook entry (body, entryDate, scope, waypointId, and/or visibility). Pass waypointId to set/change the stop tag, or waypointId: null to clear it; omit waypointId entirely to leave the current tag untouched. Pass visibility to promote ('public') or demote ('private') an entry; a public entry is only ever exposed publicly when its trip is also public, and this tool renders nothing. Changing the logbook marks a published journal stale. The response echoes the entry's (post-update) tagged stop's recorded lodging as lodging (name, type, charger type). Compare it against the entry text and, on a disagreement, tell the user which entry looks misfiled and which stop it probably belongs to instead of silently re-filing it. An entry with no stop tag comes back with a warnings entry saying it could not be checked - relay that to the user too.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| entryId | string | Required | Entry id |
| body | string | Optional | Markdown note |
| entryDate | string | Optional | ISO date YYYY-MM-DD |
| waypointId | string | Optional | Stop id to tag, or null to clear the tag (omit to leave the tag unchanged) |
| scope | "stay" | "drive" | Optional | stay = about the time at the tagged stop (default); drive = about the leg that arrived at it (requires waypointId, and the first stop has no inbound drive) |
| visibility | "private" | "public" | Optional | private (default) = never leaves your view; public = eligible to appear publicly, and only ever when the trip itself is public. Set 'public' only when the user explicitly asks. |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
delete_journal_entryDestructive
Delete logbook entry
Operates on the PRIVATE LOGBOOK, never the public journal body. Delete a private logbook entry. Changing the logbook marks a published journal stale.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| entryId | string | Required | Entry id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
read_journalRead-only
Read journal
Operates on the PUBLIC JOURNAL BODY, never the private logbook. Read the public trip journal state: body, draftBody, publishedAt, lastPublishedAt, source, style, stale, and changedEntryCount. `draftBody` is the pending private working draft written by write_journal (never public) - compare it against the live `body` to preview a draft before publishing. `stale` means the private logbook has changed since the body was last published, for any source (human, ai_preset, ai_assistant). `lastPublishedAt` is a sticky anchor set on every publish and never cleared on unpublish (null if never published). `changedEntryCount` is the number of logbook entries created or edited since `lastPublishedAt` (0 when never published) - a lower-bound scoping hint for a regeneration; a delete cannot be counted this way, so `stale` remains the authoritative change trigger.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
write_journalWrites
Draft journal
Operates on the PUBLIC JOURNAL BODY, never the private logbook. Write a draft of the public trip journal body (markdown). The draft is private and never touches the live published body or publish state, even when a journal is already published - it is safe to call any time. Read the draft back alongside the live body with read_journal, revise by calling this again (each call replaces the whole draft, no merge), then call publish_journal to promote the draft to the live public body.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| body | string | Required | Markdown journal body |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
publish_journalWrites
Publish journal
Operates on the PUBLIC JOURNAL BODY, never the private logbook. Publish the pending draft: promotes journalDraftBody to the live public body, sets publishedAt and the sticky lastPublishedAt anchor, clears the draft, and marks the body no longer stale. This is the explicit owner-directed act that makes AI-authored content public - throws if there is no draft to publish (write one with write_journal first).
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
unpublish_journalWrites
Unpublish journal
Operates on the PUBLIC JOURNAL BODY, never the private logbook. Take the public trip journal offline: clears publishedAt only. Leaves the sticky lastPublishedAt anchor, the live body, and any pending draft unchanged, and never touches private logbook entries. Idempotent - calling this when already unpublished is a no-op that returns the current state, not an error.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
read_logbook_coverageRead-only
Read logbook coverage
Operates on the PRIVATE LOGBOOK, never the public journal body. Mechanically counts words/characters across one of your trips' logbook entries and returns trip-wide totals, per-day averages, and a per-overnight-stop words-per-night ranking (thinnest first) - no AI judgement of quality, sentiment, or style, and no suggestions for what to write. The per-day denominator is the trip's full planned span (nights + 1 across top-level stops), not elapsed time, so an in-progress trip's half-written logbook correctly reads as thin. Stops with 0 nights are excluded from the ranking (a per-night ratio is undefined for them) but still count toward totals.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
record_stop_chargingWrites
Record stop charging
Record EV charging attributes for a stop you own, as a community camp-and-charge report on that stop's place. chargingAvailable is required: false records the explicit negative (charging not permitted) and must not carry any other charging detail; true may optionally include chargingCost (free|paid|included), chargingPowerKw, chargingConnectorCount, chargingConnectorTypes, and chargingNotes. visitMonth defaults to the current month. Re-recording the same stop/month overwrites the previous report. Read it back via read_trip's per-stop chargingReport field. The stop must either be a place that accepts camp-and-charge reports (national park, state park, campground, hotel/lodge) or have lodging recorded on it.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| chargingAvailable | boolean | Required | Whether EV charging is available/permitted at this stop |
| chargingCost | "free" | "paid" | "included" | Optional | How charging is billed: free, paid, included |
| chargingPowerKw | number | Optional | Charging power in kW (> 0, <= 1000) |
| chargingConnectorCount | integer | Optional | Number of connectors at this stop (1-100) |
| chargingConnectorTypes | ("j1772" | "nacs" | "ccs" | "chademo" | "nema-14-50" | "nema-14-30" | "nema-tt-30" | "nema-5-15" | "nema-5-20")[] | Optional | Connector types present, from: j1772, nacs, ccs, chademo, nema-14-50, nema-14-30, nema-tt-30, nema-5-15, nema-5-20 |
| chargingNotes | string | Optional | Free-form notes about charging (max 500 chars) |
| visitMonth | string | Optional | YYYY-MM the report is for (optional, defaults to the current month) |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
submit_placeWrites
Submit a place
Submit a place that's missing from search into a moderation queue for a human to review. Does NOT create a live, searchable place - it returns a pending-submission id. Required: name, type (campground|hotel|motel|inn|rental|dispersed|park|trailhead|viewpoint|charger|restaurant|other), city, state. Optional: address, notes. If the place already exists or an identical submission is already pending, nothing is queued and the existing match is returned. Fails with a tool error if you already have 10 submissions awaiting moderation.
| Field | Type | Required | Notes |
|---|---|---|---|
| name | string | Required | Place name |
| type | "campground" | "hotel" | "motel" | "inn" | "rental" | "dispersed" | "park" | "trailhead" | "viewpoint" | "charger" | "restaurant" | "other" | Required | Type of place: campground, hotel, motel, inn, rental, dispersed, park, trailhead, viewpoint, charger, restaurant, other |
| city | string | Required | City |
| state | string | Required | State |
| address | string | Optional | Street address (optional, admin-only informational metadata - never published as a precise coordinate) |
| notes | string | Optional | Free-form notes for the reviewing admin (optional) |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
list_itinerary_itemsRead-only
List itinerary items
List the day-view itinerary items (activities, dining, sightseeing, notes, etc.) on one of your stops, ordered by day then order within day. Returns items: [] (not an error) for a zero-night stop, since day-view items only make sense on a stop with at least one overnight stay.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
read_trip_itineraryRead-only
Read trip itinerary
Consolidated day-view itinerary across every top-level stop on a trip, in one call - each stop's basic info (name, city, state, nights, dates, canAddItems) alongside its items, avoiding one list_itinerary_items call per stop. Narrow with fromWaypointId/toWaypointId (both inclusive; omit either to run to the start/end of the trip) and/or upcomingOnly (stops not yet arrived at). A filter matching zero stops is a normal empty result (stops: [], itemCount: 0), never an error. When the trip has no startDate, dates can't be derived: all stops in range are returned and upcomingBasis is 'no-start-date' rather than filtering anything out. Sub-stops are not included here - use list_itinerary_items for those. Note: the arrived/upcoming boundary uses the server's UTC calendar day, not your local timezone, so it can be off by up to a day around midnight.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| fromWaypointId | string | Optional | Optional: only stops from this stop id onward (inclusive, by trip order). Omit to start from the first stop. |
| toWaypointId | string | Optional | Optional: only stops through this stop id (inclusive, by trip order). Omit to run through the last stop. |
| upcomingOnly | boolean | Optional | Optional: only stops not yet arrived at (default false). |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
create_itinerary_itemWrites
Create itinerary item
Add a day-view itinerary item (activity, dining, sightseeing, etc.) to one of your stops. Rejects a zero-night stop - day-view items only make sense on a stop with at least one overnight stay - and rejects an invalid dayOffset/type/title with the app's own validation message text. Never accepts a coordinate.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| dayOffset | integer | Required | Day of the stay this item falls on, 0-indexed from arrival (0-365). |
| type | "sightseeing" | "dining" | "activity" | "lodging" | "charging" | "transit" | "other" | Required | Item type: sightseeing, dining, activity, lodging, charging, transit, other |
| title | string | Required | Short title for the item |
| description | string | Optional | Optional longer description |
| timeOfDay | string | Optional | Optional free-form time, e.g. "9:00am" or "morning" |
| url | string | Optional | Optional link (e.g. a listing or reservation page) |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
update_itinerary_itemWrites
Update itinerary item
Edit a day-view itinerary item on one of your stops: title, description, url, timeOfDay, type, and/or dayOffset. waypointId names the stop the item is currently on - this tool never moves an item to a different stop (use move_itinerary_item for that). Only the fields you set are changed; omit a field to leave it unchanged, or pass null on description/url to explicitly clear it. Changing dayOffset moves the item to a different day on the SAME stop and leaves its order-within-day position as-is. Rejects an empty patch, and rejects an invalid value with the app's own validation message text.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| itemId | string | Required | Item id |
| waypointId | string | Required | Stop the item is currently on |
| title | string | Optional | Short title for the item |
| description | string | Optional | Optional longer description |
| url | string | Optional | Optional link (e.g. a listing or reservation page) |
| timeOfDay | string | Optional | Optional free-form time, e.g. "9:00am" or "morning" |
| type | "sightseeing" | "dining" | "activity" | "lodging" | "charging" | "transit" | "other" | Optional | Item type: sightseeing, dining, activity, lodging, charging, transit, other |
| dayOffset | integer | Optional | Day of the stay this item falls on, 0-indexed from arrival (0-365). |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
move_itinerary_itemWrites
Move itinerary item
Reassign a day-view itinerary item to a different stop on the SAME trip. waypointId is the DESTINATION stop - the source stop is read from the item itself. Optionally set dayOffset for its day on the new stop; omit it to keep the item's current dayOffset. Rejects moving an item to the stop it is already on (use update_itinerary_item to change its day instead), and rejects a zero-night source or destination stop. The item is appended to the end of the destination day, and its approval status and who added it are preserved verbatim - a move never approves a pending suggestion. There is no in-place move in the database: this recreates the item on the destination stop and deletes the original, so the moved item gets a NEW id (returned as item.id) and the old id is returned as previousItemId. If the recreate succeeds but the delete fails, the tool errors and a duplicate item is left behind for you to remove - it is never silently lost.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| itemId | string | Required | Item id to move |
| waypointId | string | Required | Destination stop id |
| dayOffset | integer | Optional | Optional: day of the stay on the destination stop (0-365). Defaults to the item's current dayOffset. |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
delete_itinerary_itemDestructive
Delete itinerary item
Remove a day-view itinerary item from one of your stops. The stop must still have at least one overnight stay for the delete to be allowed - the same rule the app enforces today, even for a delete.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| itemId | string | Required | Item id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
request_waypoint_photo_uploadWrites
Request waypoint photo upload URL
Step 1 of 2 for attaching a photo to one of your own stops. Returns a one-time uploadUrl valid for 15 minutes: PUT the raw image bytes (jpeg/png/webp/heic, up to 10 MB) directly to that URL with a matching Content-Type header - do NOT send image data through this tool call or any other tool call. After the PUT succeeds, call finalize_waypoint_photo_upload with the returned uploadId to actually attach and store the photo. Call read_trip FIRST to get the trip's ordered stops (name, city/state, nights, public place coordinates, and the trip's startDate) - the stored photo has its embedded date/location metadata stripped as a privacy guarantee, so match the photo to the correct stop using its own metadata before you upload it. On an ambiguous match, confirm with the user rather than guessing - never invent a stop.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |
finalize_waypoint_photo_uploadWrites
Finalize waypoint photo upload
Step 2 of 2: call this AFTER you have successfully PUT the image bytes to the uploadUrl returned by request_waypoint_photo_upload. Attaches the uploaded photo to the stop. The photo is transcoded to WebP and stripped of metadata before storage, exactly like the in-app upload: images over 10 MB (decoded), an unrecognized image type, or a caption over 280 characters are all rejected. caption is optional and entirely your own words (e.g. from looking at the photo before it was stripped) - the server never generates one, and it doubles as the photo's accessible text description. uploadId expires 15 minutes after request_waypoint_photo_upload was called and can only be redeemed once.
| Field | Type | Required | Notes |
|---|---|---|---|
| tripId | string | Required | Trip id |
| waypointId | string | Required | Stop id |
| uploadId | string | Required | uploadId returned by request_waypoint_photo_upload |
| caption | string | Optional | Optional short caption (up to 280 characters), written by you from the photo itself - never generated by the server. |
| session_id | string | Optional | Groups this call with others in the same task. |
| agent_id | string | Optional | Distinguishes this agent from others running in parallel. |
| intent | string | Optional | Why you are calling this tool. |