fix: stabilize post-MVP travel-agent and itinerary workflows
This commit is contained in:
@@ -255,6 +255,10 @@ export default defineConfig({
|
||||
text: "Guides",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Travel Agent (MCP)",
|
||||
link: "/docs/guides/travel_agent",
|
||||
},
|
||||
{
|
||||
text: "Admin Panel",
|
||||
link: "/docs/guides/admin_panel",
|
||||
|
||||
@@ -9,4 +9,15 @@ In addition to the primary configuration variables listed above, there are sever
|
||||
| `SOCIALACCOUNT_ALLOW_SIGNUP` | No | When set to `True`, signup will be allowed via social providers even if registration is disabled. | `False` | Backend |
|
||||
| `OSRM_BASE_URL` | No | Base URL of the OSRM routing server used for itinerary connector distance/travel-time metrics. The public OSRM demo server is used by default. Set this to point at your own OSRM instance (e.g. `http://osrm:5000`) for higher rate limits or offline use. When the OSRM server is unreachable, the backend automatically falls back to haversine-based approximations so the itinerary UI always shows metrics. | `https://router.project-osrm.org` | Backend |
|
||||
| `FIELD_ENCRYPTION_KEY` | No* | Fernet key used to encrypt user API keys at rest (integrations API key storage). Generate a 32-byte urlsafe base64 key (e.g. `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"`). If missing/invalid, only API-key storage endpoints fail gracefully and the rest of the app remains available. | _(none)_ | Backend |
|
||||
| `DJANGO_MCP_ENDPOINT` | No | HTTP path used for Django MCP server streamable endpoint. | `api/mcp` | Backend |
|
||||
| `DJANGO_MCP_ENDPOINT` | No | HTTP path used for the Voyage Travel Agent MCP endpoint. Clients call this endpoint with `Authorization: Token <token>` using a DRF auth token for the target user account. | `api/mcp` | Backend |
|
||||
|
||||
## MCP endpoint authentication details
|
||||
|
||||
Voyage's MCP endpoint requires token authentication.
|
||||
|
||||
- Header format: `Authorization: Token <token>`
|
||||
- Default endpoint path: `api/mcp`
|
||||
- Override path with: `DJANGO_MCP_ENDPOINT`
|
||||
- Token bootstrap endpoint for authenticated sessions: `GET /auth/mcp-token/`
|
||||
|
||||
For MCP usage patterns and tool-level examples, see the [Travel Agent (MCP) guide](../guides/travel_agent.md).
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
# Updating
|
||||
|
||||
Updating Voyage when using docker can be quite easy. Run the following commands to pull the latest version and restart the containers. Make sure you backup your instance before updating just in case!
|
||||
Updating Voyage when using docker can be quite easy. Run a collections backup before upgrading, then pull the latest version and restart the containers.
|
||||
|
||||
## Pre-upgrade backup (recommended)
|
||||
|
||||
Before running migrations or updating containers, export a collections snapshot:
|
||||
|
||||
```bash
|
||||
docker compose exec server python manage.py export_collections_backup
|
||||
```
|
||||
|
||||
You can also provide a custom output path:
|
||||
|
||||
```bash
|
||||
docker compose exec server python manage.py export_collections_backup --output /code/backups/collections_backup_pre_upgrade.json
|
||||
```
|
||||
|
||||
The backup file includes a timestamp, record counts, and snapshot data for:
|
||||
|
||||
- `Collection`
|
||||
- `CollectionItineraryItem`
|
||||
|
||||
Note: Make sure you are in the same directory as your `docker-compose.yml` file.
|
||||
|
||||
|
||||
155
documentation/docs/guides/travel_agent.md
Normal file
155
documentation/docs/guides/travel_agent.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# Travel Agent (MCP)
|
||||
|
||||
Voyage includes a **Travel Agent** interface exposed through an **MCP-compatible HTTP endpoint**. This lets external MCP clients read and manage trip itineraries programmatically for authenticated users.
|
||||
|
||||
## Endpoint
|
||||
|
||||
- Default path: `api/mcp`
|
||||
- Configurable with: `DJANGO_MCP_ENDPOINT`
|
||||
|
||||
If you run Voyage at `https://voyage.example.com`, the default MCP URL is:
|
||||
|
||||
```text
|
||||
https://voyage.example.com/api/mcp
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
MCP requests must include a DRF token in the `Authorization` header:
|
||||
|
||||
```text
|
||||
Authorization: Token <token>
|
||||
```
|
||||
|
||||
Use a token associated with the Voyage user account that should execute the MCP actions.
|
||||
|
||||
### Get a token from an authenticated session
|
||||
|
||||
Voyage exposes a token bootstrap endpoint for logged-in users:
|
||||
|
||||
- `GET /auth/mcp-token/`
|
||||
|
||||
Call it with your authenticated browser session (or any authenticated session cookie flow). It returns:
|
||||
|
||||
```json
|
||||
{ "token": "<token>" }
|
||||
```
|
||||
|
||||
Then use that token in all MCP requests with the same header format:
|
||||
|
||||
```text
|
||||
Authorization: Token <token>
|
||||
```
|
||||
|
||||
## Available MCP tools
|
||||
|
||||
The Voyage MCP server currently exposes these tools:
|
||||
|
||||
- `list_collections`
|
||||
- `get_collection_details`
|
||||
- `list_itinerary_items`
|
||||
- `create_itinerary_item`
|
||||
- `reorder_itinerary`
|
||||
|
||||
### Tool parameters
|
||||
|
||||
#### `list_collections`
|
||||
|
||||
- No parameters.
|
||||
|
||||
#### `get_collection_details`
|
||||
|
||||
- `collection_id` (required, string UUID): collection to inspect.
|
||||
|
||||
#### `list_itinerary_items`
|
||||
|
||||
- `collection_id` (optional, string UUID): if provided, limits results to one collection.
|
||||
|
||||
#### `create_itinerary_item`
|
||||
|
||||
Required:
|
||||
|
||||
- `collection_id` (string UUID)
|
||||
- `content_type` (`location` \| `transportation` \| `note` \| `lodging` \| `visit` \| `checklist`)
|
||||
- `object_id` (string UUID, id of the referenced content object)
|
||||
|
||||
Optional:
|
||||
|
||||
- `date` (ISO date string, required when `is_global` is `false`)
|
||||
- `is_global` (boolean, default `false`; when `true`, `date` must be omitted)
|
||||
- `order` (integer; if omitted, Voyage appends to the end of the relevant scope)
|
||||
|
||||
#### `reorder_itinerary`
|
||||
|
||||
Required:
|
||||
|
||||
- `items` (list of item update objects)
|
||||
|
||||
Each entry in `items` should include:
|
||||
|
||||
- `id` (required, string UUID of `CollectionItineraryItem`)
|
||||
- `date` (ISO date string for dated items)
|
||||
- `order` (integer target order)
|
||||
- `is_global` (optional boolean; include when moving between global and dated scopes)
|
||||
|
||||
## End-to-end example flow
|
||||
|
||||
This example shows a typical interaction from an MCP client.
|
||||
|
||||
1. **Connect** to the MCP endpoint using your Voyage server URL and token header.
|
||||
2. Call **`list_collections`** to find the trip/collection you want to work with.
|
||||
3. Call **`get_collection_details`** for the selected collection ID to inspect current trip context.
|
||||
4. Call **`list_itinerary_items`** for a specific date or collection scope.
|
||||
5. Call **`create_itinerary_item`** to add a new stop (for example, a location or note) to the itinerary.
|
||||
6. Call **`reorder_itinerary`** to persist the final ordering after insertion.
|
||||
|
||||
### Example request headers (HTTP transport)
|
||||
|
||||
```http
|
||||
POST /api/mcp HTTP/1.1
|
||||
Host: voyage.example.com
|
||||
Authorization: Token <token>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
### Example interaction sequence (conceptual)
|
||||
|
||||
```text
|
||||
Client -> list_collections
|
||||
Server -> [{"id": "6c5d9f61-2f09-4882-b277-8884b633d36b", "name": "Japan 2026"}, ...]
|
||||
|
||||
Client -> get_collection_details({"collection_id": "6c5d9f61-2f09-4882-b277-8884b633d36b"})
|
||||
Server -> {...collection metadata...}
|
||||
|
||||
Client -> list_itinerary_items({"collection_id": "6c5d9f61-2f09-4882-b277-8884b633d36b"})
|
||||
Server -> [...current ordered itinerary items...]
|
||||
|
||||
Client -> create_itinerary_item({
|
||||
"collection_id": "6c5d9f61-2f09-4882-b277-8884b633d36b",
|
||||
"content_type": "location",
|
||||
"object_id": "fe7ee379-8a2b-456d-9c59-1eafcf83979b",
|
||||
"date": "2026-06-12",
|
||||
"order": 3
|
||||
})
|
||||
Server -> {"id": "5eb8c40c-7e36-4709-b4ec-7dc4cfa26ca5", ...}
|
||||
|
||||
Client -> reorder_itinerary({"items": [
|
||||
{
|
||||
"id": "5eb8c40c-7e36-4709-b4ec-7dc4cfa26ca5",
|
||||
"date": "2026-06-12",
|
||||
"order": 0
|
||||
},
|
||||
{
|
||||
"id": "a044f903-d788-4f67-bba7-3ee73da6d504",
|
||||
"date": "2026-06-12",
|
||||
"order": 1,
|
||||
"is_global": false
|
||||
}
|
||||
]})
|
||||
Server -> [...updated itinerary items...]
|
||||
```
|
||||
|
||||
## Related docs
|
||||
|
||||
- [Advanced Configuration](../configuration/advanced_configuration.md)
|
||||
- [How to use Voyage](../usage/usage.md)
|
||||
@@ -23,6 +23,7 @@ Voyage is a full-fledged travel companion. With Voyage, you can log your adventu
|
||||
- Locations and itineraries can be shared via a public link or directly with other Voyage users.
|
||||
- Collaborators can view and edit shared itineraries (collections), making planning a breeze.
|
||||
- **Customizable Themes** 🎨: Choose from 10 built-in themes including Light, Dark, Dim, Night, Forest, Aqua, Catppuccin Mocha, Aesthetic Light, Aesthetic Dark, and Northern Lights. Theme selection persists across sessions.
|
||||
- **Travel Agent (MCP) access** 🤖: Voyage exposes an authenticated MCP endpoint so external clients can list collections, inspect itineraries, create itinerary items, and reorder trip timelines. See the [Travel Agent (MCP) guide](../guides/travel_agent.md).
|
||||
|
||||
## Why Voyage?
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Welcome to Voyage! This guide will help you get started with Voyage and provide you with an overview of the features available to you.
|
||||
|
||||
Voyage also includes a Travel Agent MCP interface for authenticated programmatic trip access and itinerary actions. See the [Travel Agent (MCP) guide](../guides/travel_agent.md).
|
||||
|
||||
## Key Terms
|
||||
|
||||
#### Locations
|
||||
|
||||
Reference in New Issue
Block a user