mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
feat(mcp): add base server instructions for all MCP sessions
Injects a structured BASE_MCP_INSTRUCTIONS string into every session's initialize response so Claude has data model, workflow, and behavioral context without needing to infer it from tool names alone. Covers: data model hierarchy (trip→day→place→assignment), key discovery workflow (list_trips → get_trip_summary), correct place-to-itinerary flow (search_place → create_place → assign_place_to_day), accommodation creation order, access rules, date/time format, add-on feature list, and common pitfalls (e.g. don't skip search_place, confirm before bulk deletes). Static token deprecation notice is appended on top when applicable.
This commit is contained in:
+78
-6
@@ -13,6 +13,83 @@ import { McpSession, sessions, revokeUserSessions, revokeUserSessionsForClient }
|
||||
|
||||
export { revokeUserSessions, revokeUserSessionsForClient };
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Base instructions injected into every MCP session via the initialize response.
|
||||
// Claude and other clients use these as system-level context before any tool call.
|
||||
// Keep this actionable and concise — vague prose doesn't help the model.
|
||||
// ---------------------------------------------------------------------------
|
||||
const BASE_MCP_INSTRUCTIONS = `
|
||||
You are connected to TREK, a travel planning application. Below is a compact reference of the data model, key workflows, and behavioral rules you must follow.
|
||||
|
||||
## Data model
|
||||
|
||||
- **Trip** — top-level container. Has dates, currency, members (owner + collaborators), and optional add-ons.
|
||||
- **Day** — one calendar day within a trip (YYYY-MM-DD). Days are generated automatically when a trip is created with start/end dates.
|
||||
- **Place** — a point of interest (POI) stored in the trip's place pool. A place is NOT on the itinerary until it is assigned to a day.
|
||||
- **Assignment** — links a Place to a Day (ordered, with optional start/end time). This is what builds the daily itinerary.
|
||||
- **Accommodation** — a hotel or rental linked to a Place and a check-in/check-out day range.
|
||||
- **Reservation** — a booking record (flight, train, restaurant, etc.) with confirmation details, linked to a day.
|
||||
- **Day note** — a free-text annotation attached to a day (with optional time label and emoji icon).
|
||||
- **Budget item** — an expense entry for a trip (amount, category, payer, split between members).
|
||||
- **Packing item** — a checklist entry grouped into bags and categories.
|
||||
- **Todo** — a task (not packing-specific) attached to a trip, ordered and togglable.
|
||||
- **Tag** — a label that can be applied to places for filtering.
|
||||
- **Collab note / poll / message** — shared notes, decision polls, and chat messages for group trips.
|
||||
- **Atlas** — global travel journal: bucket list, visited countries and regions.
|
||||
- **Vacay** — vacation-day planner that tracks leave across team members and years.
|
||||
|
||||
## Key workflows
|
||||
|
||||
**Discovering trips:** Always call \`list_trips\` first when no trip ID has been provided. Never assume a trip ID.
|
||||
|
||||
**Loading trip context:** Before planning or modifying a trip, call \`get_trip_summary\` once. It returns all days (with assignments and notes), accommodations, budget, packing, reservations, collab notes, and todos in a single round-trip. Use this data to answer follow-up questions without extra tool calls.
|
||||
|
||||
**Adding a place to the itinerary (correct order):**
|
||||
1. \`search_place\` — find the real-world POI; note the \`osm_id\` and/or \`google_place_id\` in the result.
|
||||
2. \`create_place\` — add it to the trip's place pool, passing the IDs from step 1 (enables opening hours, ratings, and map linking in the app).
|
||||
3. \`assign_place_to_day\` — schedule it on the desired day using the dayId from \`get_trip_summary\`.
|
||||
|
||||
**Creating an accommodation:** A place must exist in the trip first. Create the place (or reuse an existing one), then call \`create_accommodation\` with that \`place_id\` and the \`start_day_id\`/\`end_day_id\`.
|
||||
|
||||
**Reordering:** Assignments, todos, packing items, and reservations all support positional reordering via dedicated reorder tools. Always read the current order from \`get_trip_summary\` before reordering.
|
||||
|
||||
## Access rules
|
||||
|
||||
- The authenticated user can only access trips they own or are a member of. Never guess at trip IDs.
|
||||
- Only the trip owner can delete the trip, add members, or remove members.
|
||||
- Deleting a place removes all of its day assignments as well — warn the user before doing this.
|
||||
- Trips created via MCP are capped at 90 days.
|
||||
|
||||
## Dates and times
|
||||
|
||||
- All dates use ISO format: **YYYY-MM-DD**.
|
||||
- Times are strings like **"09:00"** or **"14:30"** (24-hour). Pass \`null\` to clear a time.
|
||||
- When displaying dates to users, use a friendly human-readable format (e.g. "Mon, Apr 14").
|
||||
|
||||
## Add-on features
|
||||
|
||||
The following features are optional and may not be available on every TREK instance. Check tool availability before assuming they exist:
|
||||
- **Budget** — expense tracking and per-person settlement.
|
||||
- **Packing** — checklist with bags, categories, and templates.
|
||||
- **Collab** — shared notes, polls, and chat messages for group trips.
|
||||
- **Atlas** — bucket list and visited-country/region tracking.
|
||||
- **Vacay** — team vacation-day planner with public holiday integration.
|
||||
|
||||
## Behavioral rules
|
||||
|
||||
- Prefer \`get_trip_summary\` over individual list tools when you need a full picture — it is one call instead of many.
|
||||
- Use \`search_place\` before \`create_place\` so the app gets structured POI data (coordinates, address, opening hours). Do not skip this step.
|
||||
- When the user asks to "add X to day Y", resolve both the place (search + create if needed) and the day ID before calling \`assign_place_to_day\`.
|
||||
- Do not batch destructive operations (delete trip, delete day, delete place) without explicit user confirmation for each.
|
||||
- Present budget amounts with the trip's currency. Use \`get_trip_summary\` to read the currency field.
|
||||
- For group trips, always check member IDs via \`list_trip_members\` before calling tools that require a \`userId\` (e.g. budget splits, assignment participants).
|
||||
`.trim();
|
||||
|
||||
const STATIC_TOKEN_DEPRECATION_NOTICE =
|
||||
'\n\n⚠️ IMPORTANT: This MCP session is authenticated with a static API token (trek_…). ' +
|
||||
'Static token authentication is deprecated and will be removed in a future version of TREK. ' +
|
||||
'Please inform the user that they must migrate to OAuth 2.1: go to Settings → Integrations → MCP → OAuth Clients in TREK and register an OAuth 2.1 application for their MCP client.';
|
||||
|
||||
const SESSION_TTL_MS = 60 * 60 * 1000; // 1 hour
|
||||
const sessionParsed = Number.parseInt(process.env.MCP_MAX_SESSION_PER_USER ?? "");
|
||||
const MAX_SESSIONS_PER_USER = Number.isFinite(sessionParsed) && sessionParsed > 0 ? sessionParsed : 5;
|
||||
@@ -173,12 +250,7 @@ export async function mcpHandler(req: Request, res: Response): Promise<void> {
|
||||
tools: { listChanged: true },
|
||||
prompts: { listChanged: true },
|
||||
},
|
||||
...(isStaticToken && {
|
||||
instructions:
|
||||
'⚠️ IMPORTANT: This MCP session is authenticated with a static API token (trek_…). ' +
|
||||
'Static token authentication is deprecated and will be removed in a future version of TREK. ' +
|
||||
'Please inform the user that they must migrate to OAuth 2.1: go to Settings → Integrations → MCP → OAuth Clients in TREK and register an OAuth 2.1 application for their MCP client.',
|
||||
}),
|
||||
instructions: BASE_MCP_INSTRUCTIONS + (isStaticToken ? STATIC_TOKEN_DEPRECATION_NOTICE : ''),
|
||||
}
|
||||
);
|
||||
registerResources(server, user.id, scopes);
|
||||
|
||||
Reference in New Issue
Block a user