cancel_trip
Status: Verified | Module: trip
Cancel an active trip. Implements the single-tool two-step pattern: omit reason to fetch the available cancellation reasons; pass reason to fuzzy-match and cancel. This folds in the responsibilities of the removed get_cancellation_reasons tool — agents no longer need a separate read tool before cancelling.
Two-Step Flow
Section titled “Two-Step Flow”Step 1: Fetch reasons
Section titled “Step 1: Fetch reasons”Call cancel_trip WITHOUT a reason argument. The use case fetches the available cancellation reasons for the trip and returns them in available_reasons. No cancellation is performed.
Step 2: Cancel with chosen reason
Section titled “Step 2: Cancel with chosen reason”Call cancel_trip again WITH reason set to either:
- the chosen reason name (case-insensitive, substring match supported), OR
- the chosen
reason_id(UUID).
The matcher tries, in order: case-insensitive id match → exact case-insensitive name match → bidirectional substring match (single hit wins, multiple = ambiguous_match error) → UUID/numeric pass-through. Some reasons require an additional reason_description (the matched reason’s description_required flag tells you).
Annotations
Section titled “Annotations”| Hint | Value |
|---|---|
| readOnlyHint | false |
| destructiveHint | true |
| idempotentHint | false |
| Field | Type | Required | Description |
|---|---|---|---|
session_id |
string | yes | Active session ID from verify_member |
trip_id |
string | yes | Trip identifier from get_active_trips. Accepts trip UUID or human-readable ID (e.g. 04-21-2026-91-B). Auto-detected. |
reason |
string | no | Reason name OR reason_id. Omit to fetch the list of available reasons. |
reason_description |
string | no | Free-text explanation. Required when the matched reason carries description_required: true. |
Output
Section titled “Output”The output is a discriminated wrapper — exactly one of the two shapes below is populated.
When reason is omitted (Step 1)
Section titled “When reason is omitted (Step 1)”| Field | Type | Description |
|---|---|---|
status |
string | success |
available_reasons |
CancellationReason[] | Available reasons for the trip |
message |
string | “Found N available cancellation reasons. Pick one and call cancel_trip again with the reason name or reason_id.” |
CancellationReason
Section titled “CancellationReason”| Field | Type | Description |
|---|---|---|
reason_id |
string | Reason UUID (pass back as reason) |
name |
string | Human-readable name |
description_required |
bool | Whether the next call needs reason_description |
When reason is supplied (Step 2)
Section titled “When reason is supplied (Step 2)”| Field | Type | Description |
|---|---|---|
status |
string | success |
trip_id |
string | Cancelled trip UUID |
message |
string | Confirmation message |
Side Effects
Section titled “Side Effects”- Loads session and validates the trip belongs to the session’s member (defense in depth).
- Step 1 emits
mcp.cancel_trip.list_reasonsaudit entry (no PHI in metadata, justreason_count). - Step 2 emits
mcp.cancel_tripaudit entry withcancellation_reason_id+reason_name.
Error Codes
Section titled “Error Codes”MISSING_PREREQUISITE— suppliedreasondid not match any available reason (the error message lists the valid reasons),ambiguous match, or missingreason_descriptionfor a reason that requires one.TRIP_NOT_FOUND— trip not in the session member’s active set.
Example: Step 1 (fetch reasons)
Section titled “Example: Step 1 (fetch reasons)”{ "params": { "name": "cancel_trip", "arguments": { "session_id": "a1b2c3d4-...", "trip_id": "trip-uuid-001" } }}Example: Step 2 (cancel)
Section titled “Example: Step 2 (cancel)”{ "params": { "name": "cancel_trip", "arguments": { "session_id": "a1b2c3d4-...", "trip_id": "trip-uuid-001", "reason": "Member Request" } }}Related
Section titled “Related”- Cancellation Flow
- Source:
internal/app/trip/usecases/cancel_trip.go - Companion: cancel_standing_order (same two-step pattern)