> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stardrift.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools

> The public Stardrift MCP tools, their permissions, and how to read and correct your travel plans.

Connect to `https://stardrift.ai/mcp` to use these tools. The [API reference](/api-reference/mcp-server/list-trips) documents the underlying HTTP operations; tool names and HTTP routes are not always the same. The API enforces authentication, permissions, and ownership. The MCP wrapper also validates inputs and filters place candidates.

## Trips and itineraries

| Tool                     | Scope          | What it does                                                                                                                              |
| ------------------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `list_trips`             | `guides:read`  | List your trips with `id`, title, slug, and visibility. Match a title to get a `trip_id`.                                                 |
| `create_trip`            | `guides:write` | Create a draft with `num_days` blank days. The returned `id` is the `trip_id`.                                                            |
| `get_itinerary`          | `guides:read`  | Read days, entries, resolved activities, and `plan_version`.                                                                              |
| `add_place_to_itinerary` | `guides:write` | Resolve and add a place to a day, with optional time and note. Returns both `item_id` and `entry_id`.                                     |
| `add_day_note`           | `guides:write` | Add standalone text to a day. Returns its `entry_id`.                                                                                     |
| `update_entry`           | `guides:write` | Change an annotation or time, or rewrite a standalone note with `content`. Omitted fields stay unchanged; explicit null clears note/time. |
| `move_entry`             | `guides:write` | Move an existing entry to another day without resolving the place again. Preserves its IDs, time, and note.                               |
| `remove_from_day`        | `guides:write` | Remove one entry from a day.                                                                                                              |
| `set_trip_visibility`    | `guides:write` | Set `draft`, `private`, or `public`, with an optional slug. Publish only when requested.                                                  |

Day numbers start at 1 and must already exist. Use `get_itinerary` to inspect them. Use `entry_id` to edit, move, or remove a visit; `item_id` identifies its underlying activity. `plan_version` reports the current revision; it is not an optimistic-lock parameter.

### Correct a visit

After adding a place, keep the returned `entry_id`. For example, move it from day one to day two:

```json theme={null}
{
  "trip_id": "<trip_id>",
  "day_number": 1,
  "entry_id": "<entry_id>",
  "to_day_number": 2
}
```

Pass that object to `move_entry`. Then clear its annotation with `update_entry`:

```json theme={null}
{
  "trip_id": "<trip_id>",
  "day_number": 2,
  "entry_id": "<entry_id>",
  "note": null
}
```

The omitted time stays unchanged. Read `get_itinerary` afterward to verify the result.

## Bookings and recorded events

| Tool                     | Scope           | What it does                                                                                                      |
| ------------------------ | --------------- | ----------------------------------------------------------------------------------------------------------------- |
| `list_bookings`          | `bookings:read` | Read bookings, optionally filtered by type or trip. For precise flight segments, read `edit_data`.                |
| `get_forwarding_address` | `bookings:read` | Get your private booking-import email address. Keep it private: mail sent there can add bookings to your account. |
| `record_stay`            | `guides:write`  | Record a hotel or rental with dates. This does not purchase a reservation.                                        |
| `update_stay`            | `guides:write`  | Correct a recorded stay's dates, price, confirmation number, or other supported fields.                           |
| `remove_stay`            | `guides:write`  | Remove a stay from Stardrift; this does not cancel a supplier reservation.                                        |
| `record_event`           | `guides:write`  | Record a scheduled event, with optional local start/end times and location. Read any returned `warnings`.         |

There is no tool to add or edit a flight directly; forward its confirmation email to your import address. Event update/removal tools are not currently available. Recording an event does not buy a ticket.

## Saved lists

A saved list is a collection of places, separate from a day-by-day trip. New MCP lists are **private by default**.

| Tool                        | Scope         | What it does                                                                                                                                                          |
| --------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_saved_lists`          | `saved:read`  | List your collections with IDs, item counts, and visibility.                                                                                                          |
| `get_saved_list`            | `saved:read`  | Read list metadata, sections, places, captions, and editing IDs. Takes `offset` and `limit`; follow `next_offset` until null.                                         |
| `create_saved_list`         | `saved:write` | Create a private list. Explicit `visibility: "public"` publishes it.                                                                                                  |
| `update_saved_list`         | `saved:write` | Rename, change visibility, or edit the intro. Explicit null clears the intro.                                                                                         |
| `add_place_to_saved_list`   | `saved:write` | Save a place. Ambiguous queries return `candidates` without saving; choose a candidate and retry with its `place_id`. Query-based resolution also needs `saved:read`. |
| `update_saved_place`        | `saved:write` | Edit a caption or section membership. Omit to preserve; null clears the caption or removes section membership.                                                        |
| `remove_from_saved_list`    | `saved:write` | Remove a saved item using its `id`.                                                                                                                                   |
| `add_saved_list_section`    | `saved:write` | Create a heading, optionally assigning existing item IDs.                                                                                                             |
| `set_saved_list_section`    | `saved:write` | Update a heading's title/blurb or replace its ordered `item_ids`.                                                                                                     |
| `remove_saved_list_section` | `saved:write` | Delete a heading while keeping its places.                                                                                                                            |

### Edit an existing list in a fresh conversation

1. Find the list by title with `list_saved_lists`.
2. Call `get_saved_list(list_id=…)`. Its `list` contains metadata and sections; `items` contains saved-item IDs. The default page size is 100, with a maximum of 200.
3. Follow `next_offset` until null if you need every item.
4. Use a saved item's `id` for edits, removals, and section membership. Its `place_id` identifies the underlying place and is not the editing ID.
5. Read the list again after edits. Removal tools may return no body.

Publishing requires an explicit visibility change. A populated `public_url` alone does not mean the list is public. After making a list private, anonymous reads return a private-list placeholder without its places.

## Errors and recovery

| Status | Meaning                                                                     | What to do                                                                                                     |
| ------ | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `401`  | Missing, expired, invalid, or disconnected credentials                      | Reconnect through your client.                                                                                 |
| `403`  | The grant lacks the required permission                                     | Check the requested scopes and reconnect if needed.                                                            |
| `404`  | The record or day is missing, or belongs to another account                 | Read your own trips/list contents and use their returned IDs.                                                  |
| `409`  | A resolved place's name collides with a different place already in the trip | Read the itinerary and explain the conflict. The new place was not added.                                      |
| `422`  | Invalid input or an unresolved place                                        | Follow the error detail; for resolution failures, try a more specific venue, street, and city.                 |
| `429`  | The daily paid-lookup budget is exhausted                                   | Stop new paid lookups until the indicated reset. Reading or moving an existing entry does not resolve a place. |

Adding the same Google place again is not the name-collision error: the existing activity can be reused for another visit. Do not treat a 409 as proof that the requested place is already present.

The tools preserve API error explanations. The wrapper can also return input errors such as `Pass search_query or place_id`, or `No venue matched`, without an HTTP status.
