Imports
Pull bookings from Gmail and places from TikTok / Xiaohongshu URLs.
yumo exposes two import pipelines over MCP: email imports (Gmail-backed, booking confirmations → flight/hotel/transport/event candidates) and link imports (TikTok and Xiaohongshu URLs → place candidates).
Both pipelines stage candidates into a review queue rather than writing to a trip directly. The typical flow is the same in either case:
- Kick off a sync / parse (
sync_gmail_now,search_email_bookings,parse_link_url, …). list_*the pending candidates.get_*_candidateto inspect details and confidence.confirm_*_candidateinto a trip / bucket list / vision board, orreject_*_candidate.
Always ask the user which trip to confirm into — do not guess the target.
Email (Gmail)
get_gmail_import_status
Returns { connected, email, scopeHasGmail }. Call this before any sync tool so you can prompt the user to connect Gmail in the app's Account page if connected is false.
{}sync_gmail_now
Pulls recent booking emails across the user's entire inbox, restricted to a vetted sender allowlist (airlines, hotel chains, OTAs, rail). Runs each matching email through the LLM parser and returns { fetched, ingested, deduped, skippedSender, candidatesAdded, parseErrors }.
{ "newerThanDays": 365, "maxMessages": 200 }sync_gmail_for_trip
Same pipeline as sync_gmail_now, narrowed to a date window around a specific trip (≈ 6 months before start to 2 weeks after end).
{ "tripId": "trp_...", "maxMessages": 25 }search_email_bookings
Targeted Gmail search with a free-text query, always ANDed with the sender allowlist. Supports Gmail operators like subject:, after:, before:.
{ "query": "tokyo hotel", "newerThanDays": 365, "maxMessages": 50 }list_pending_imports
Returns every email-import candidate awaiting review (across all trips). Each candidate has id, entityKind (flight | hotel | transport | event), parsed reservation data, suggestedTripId, and the originating email's sender/subject/receivedAt.
{}list_trip_imports
Returns only the pending candidates whose suggestedTripId matches a given trip.
{ "tripId": "trp_..." }get_import_candidate
Full details for one candidate — complete parsed reservation, confidence score, and source email metadata.
{ "id": "imp_..." }confirm_import_candidate
Materializes the candidate into the target trip as the corresponding flight / hotel / transport / event row. Confirm the target trip with the user before calling.
{ "id": "imp_...", "targetTripId": "trp_..." }reject_import_candidate
Removes the candidate from the pending list. Optional reason is stored for diagnostics.
{ "id": "imp_...", "reason": "duplicate" }Link imports (TikTok, Xiaohongshu)
parse_link_url
Parses a URL into one or more place candidates. TikTok (including vm.tiktok.com shortlinks) and Xiaohongshu are supported; Instagram and YouTube return unsupported_provider for now. Returns { linkImportId, candidates[], deduped, emptyExtraction }.
Pass suggestedTripId or suggestedBoardId to seed context — these flow onto the candidate as the default confirm target.
{
"url": "https://www.tiktok.com/@user/video/123...",
"suggestedTripId": "trp_..."
}list_link_imports_for_trip
Pending link-import candidates staged against a trip.
{ "tripId": "trp_..." }list_link_imports_for_board
Pending link-import candidates staged against a vision board.
{ "boardId": "vb_..." }get_link_import_candidate
Full details for a single candidate — extracted place, source thumbnail, author, confidence.
{ "id": "lic_..." }confirm_link_import_candidate
Materializes the candidate into either a trip's bucket list or a vision board as a location card. placeEdit is optional — use it when the user has corrected an extracted field before confirming.
{
"id": "lic_...",
"target": {
"kind": "bucket_list",
"tripId": "trp_..."
}
}For a vision board target:
{
"id": "lic_...",
"target": {
"kind": "vision_board",
"boardId": "vb_...",
"x": 320,
"y": 180
}
}reject_link_import_candidate
Marks the candidate as rejected. Optional reason is kept for diagnostics.
{ "id": "lic_...", "reason": "wrong city" }Need help or found a bug?
Join the yumo community on Discord. We answer questions, take feature requests, and triage bug reports there.
Join the Discord