@cyanheads/wsdot-mcp-server 0.2.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +32 -23
- package/changelog/0.3.x/0.3.0.md +30 -0
- package/changelog/0.4.x/0.4.0.md +26 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.d.ts +9 -2
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.js +40 -5
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.d.ts +10 -3
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.js +96 -20
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.d.ts +2 -2
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.js +12 -5
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.d.ts +2 -2
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.js +9 -4
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-terminal-space.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-terminal-space.tool.js +2 -0
- package/dist/mcp-server/tools/definitions/get-terminal-space.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.d.ts +4 -0
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.js +123 -79
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-travel-times.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-travel-times.tool.js +103 -101
- package/dist/mcp-server/tools/definitions/get-travel-times.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-alerts.tool.d.ts +10 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-alerts.tool.js +152 -130
- package/dist/mcp-server/tools/definitions/search-alerts.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-cameras.tool.d.ts +12 -0
- package/dist/mcp-server/tools/definitions/search-cameras.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-cameras.tool.js +118 -67
- package/dist/mcp-server/tools/definitions/search-cameras.tool.js.map +1 -1
- package/dist/mcp-server/tools/page-budget.d.ts +56 -0
- package/dist/mcp-server/tools/page-budget.d.ts.map +1 -0
- package/dist/mcp-server/tools/page-budget.js +76 -0
- package/dist/mcp-server/tools/page-budget.js.map +1 -0
- package/dist/services/ferry/ferry-service.d.ts +20 -0
- package/dist/services/ferry/ferry-service.d.ts.map +1 -1
- package/dist/services/ferry/ferry-service.js +186 -49
- package/dist/services/ferry/ferry-service.js.map +1 -1
- package/dist/services/ferry/types.d.ts +52 -4
- package/dist/services/ferry/types.d.ts.map +1 -1
- package/dist/services/text-field.d.ts +31 -0
- package/dist/services/text-field.d.ts.map +1 -0
- package/dist/services/text-field.js +41 -0
- package/dist/services/text-field.js.map +1 -0
- package/dist/services/traffic/traffic-service.d.ts.map +1 -1
- package/dist/services/traffic/traffic-service.js +66 -86
- package/dist/services/traffic/traffic-service.js.map +1 -1
- package/dist/services/traffic/types.d.ts +3 -3
- package/dist/services/traffic/types.d.ts.map +1 -1
- package/dist/services/wcf-date.d.ts +6 -4
- package/dist/services/wcf-date.d.ts.map +1 -1
- package/dist/services/wcf-date.js +8 -4
- package/dist/services/wcf-date.js.map +1 -1
- package/package.json +2 -2
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** @cyanheads/wsdot-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
4
|
+
**Version:** 0.4.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.6`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0 (protocol revisions 2026-07-28 and 2025-*)
|
package/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** @cyanheads/wsdot-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
4
|
+
**Version:** 0.4.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.6`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0 (protocol revisions 2026-07-28 and 2025-*)
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/wsdot-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/wsdot-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -34,12 +34,12 @@ Washington State transportation data from the WSDOT Traveler API and the WSF Fer
|
|
|
34
34
|
| `wsdot_get_mountain_passes` | Current conditions for all WA mountain passes: status, road condition, traction laws, temperature, elevation. |
|
|
35
35
|
| `wsdot_search_alerts` | Active highway alerts — incidents, construction, closures — filterable by state route, WSDOT region, and milepost range. |
|
|
36
36
|
| `wsdot_get_travel_times` | Current vs. average travel times for named WA highway corridors (I-5, I-90, SR 520, etc.) with congestion delay. |
|
|
37
|
-
| `wsdot_get_toll_rates` | Dynamic toll rates for WA express lanes and tolled facilities
|
|
37
|
+
| `wsdot_get_toll_rates` | Dynamic toll rates for WA express lanes and tolled facilities — SR 99, SR 167 HOT, I-405 Express, SR 509, SR 520 — filterable by route. |
|
|
38
38
|
| `wsdot_get_border_waits` | Current vehicle wait times at all WA/Canada land border crossings. |
|
|
39
|
-
| `wsdot_search_cameras` | Highway camera metadata and image URLs, filterable by state route, region, and
|
|
40
|
-
| `wsdot_get_ferry_terminals` | All WSF ferry terminals with numeric IDs needed for schedule and space lookups. |
|
|
41
|
-
| `wsdot_get_ferry_routes` | WSF routes operating on a given date — route ID, abbreviation, and
|
|
42
|
-
| `wsdot_get_ferry_schedule` | Departure times for a specific WSF route — today-remaining or full-day future mode. |
|
|
39
|
+
| `wsdot_search_cameras` | Highway camera metadata and image URLs, filterable by state route, region, milepost range, and title words. |
|
|
40
|
+
| `wsdot_get_ferry_terminals` | All WSF ferry terminals with numeric IDs needed for schedule and space lookups, plus coordinates. |
|
|
41
|
+
| `wsdot_get_ferry_routes` | WSF routes operating on a given date — route ID, abbreviation, description, and the terminal pairs each serves, for route discovery, schedule lookups, and ferry-alert cross-reference. |
|
|
42
|
+
| `wsdot_get_ferry_schedule` | Departure times for a specific WSF route — today-remaining or full-day future mode — with each sailing's vessel, loading rule, and notes. |
|
|
43
43
|
| `wsdot_get_vessel_locations` | Real-time AIS positions, speed, heading, ETA, and dock status for all active WSF vessels. |
|
|
44
44
|
| `wsdot_get_terminal_space` | Drive-up and reservable vehicle space available at WSF terminals for upcoming sailings. |
|
|
45
45
|
| `wsdot_get_ferry_alerts` | Active WSF service disruptions and bulletins with impacted route IDs. |
|
|
@@ -57,21 +57,21 @@ Washington State transportation data from the WSDOT Traveler API and the WSF Fer
|
|
|
57
57
|
### `wsdot_search_alerts` <sub>tool</sub>
|
|
58
58
|
|
|
59
59
|
- Filter by state route — natural forms all work: `"I-90"`, `"90"`, `"090"`, or `"SR 520"` / `"520"`
|
|
60
|
-
- Filter by WSDOT region: Northwest, Olympic, Southwest, South Central, North Central, Eastern
|
|
61
|
-
- Filter by milepost range to scope to a corridor — an alert matches when its extent overlaps the range, so a closure that spans the boundary is returned
|
|
62
|
-
- Omit all filters to return all current statewide alerts
|
|
60
|
+
- Filter by WSDOT region name: Northwest, Olympic, Southwest, South Central, North Central, Eastern (case-insensitive; any other value is rejected with `invalid_region`)
|
|
61
|
+
- Filter by milepost range to scope to a corridor — an alert matches when its extent overlaps the range, so a closure that spans the boundary is returned. Either bound may be given alone; a start above the end is rejected with `invalid_milepost_range`
|
|
62
|
+
- Omit all filters to return all current statewide alerts; `stateRoute` and `region` accept at most 200 characters
|
|
63
63
|
- Descriptions are normalized to plain text; a link renders inline as `link text (url)`
|
|
64
|
-
- Results ordered by `alertId` and paged (default
|
|
64
|
+
- Results ordered by `alertId` and paged (default 20, max 500) — pass `offset`/`limit`; a page also ends early at a 24,000-byte response budget, and the notice reports the next offset
|
|
65
65
|
|
|
66
66
|
---
|
|
67
67
|
|
|
68
68
|
### `wsdot_get_travel_times` <sub>tool</sub>
|
|
69
69
|
|
|
70
70
|
- Covers I-5, I-90, SR 520, SR 99, I-405, SR 167, and others
|
|
71
|
-
- Filter by route (`"I-5"`, `"5"`, `"SR 520"`) to get every corridor measured on it, or by any text to match corridor names (`"Everett"`)
|
|
71
|
+
- Filter by route (`"I-5"`, `"5"`, `"SR 520"`) to get every corridor measured on it, or by any text to match corridor names (`"Everett"`); `route` accepts at most 200 characters
|
|
72
72
|
- When current time exceeds average, the corridor is congested; the delta is the delay
|
|
73
73
|
- Reversible express-lane corridors report no travel time while closed in the queried direction — those figures are omitted rather than reported as zero minutes
|
|
74
|
-
- Results are paged (default 50, max 500) — pass `offset`/`limit`; the notice reports the next offset
|
|
74
|
+
- Results are paged (default 50, max 500) — pass `offset`/`limit`; a page also ends early at a 24,000-byte response budget, and the notice reports the next offset
|
|
75
75
|
|
|
76
76
|
---
|
|
77
77
|
|
|
@@ -79,9 +79,11 @@ Washington State transportation data from the WSDOT Traveler API and the WSF Fer
|
|
|
79
79
|
|
|
80
80
|
- Covers SR 99 (WSDOT Tunnel), SR 167 HOT Lanes, I-405 Express Lanes, the SR 509 tolled segment, and the SR 520 Bridge
|
|
81
81
|
- Rates are time-banded and change dynamically based on traffic conditions
|
|
82
|
-
- `stateRoute`
|
|
82
|
+
- Filter to one facility with `stateRoute` — `"SR 520"`, `"520"`, `"0520"`, `"I-405"`, and `"405"` all work, matched against the posted designation, so `"SR 405"` matches nothing. A route with no tolled facility returns an empty page whose notice names the tolled routes; the filter (at most 200 characters) is applied before paging and echoed in `appliedFilters`
|
|
83
|
+
- Each row's `stateRoute` is the bare, zero-padded route number the feed carries (`"099"`, `"405"`) with no route type; the rendered text resolves the posted designation, so I-405 reads as `I-405` rather than `SR 405`
|
|
84
|
+
- `travelDirection` is the feed's code, not the direction of travel: SR 99, SR 509, and SR 520 carry one fixed code per facility although trips run both ways — read direction from the segment's start and end
|
|
83
85
|
- Each entry leads with its readable `startLocationName → endLocationName` segment; the opaque upstream trip key stays available as `tripName`
|
|
84
|
-
- Results are paged (default 50, max 500) — pass `offset`/`limit`; the notice reports the next offset
|
|
86
|
+
- Results are paged (default 50, max 500) — pass `offset`/`limit`; a page also ends early at a 24,000-byte response budget, and the notice reports the next offset
|
|
85
87
|
|
|
86
88
|
---
|
|
87
89
|
|
|
@@ -96,10 +98,13 @@ Washington State transportation data from the WSDOT Traveler API and the WSF Fer
|
|
|
96
98
|
|
|
97
99
|
### `wsdot_search_cameras` <sub>tool</sub>
|
|
98
100
|
|
|
99
|
-
- Filter by state route (`"I-90"`, `"90"`, `"SR 520"`, or `"520"` all work), WSDOT region, or
|
|
101
|
+
- Filter by state route (`"I-90"`, `"90"`, `"SR 520"`, or `"520"` all work), WSDOT region code, milepost range, or words in the camera title; `stateRoute`, `region`, and `titleContains` accept at most 200 characters
|
|
100
102
|
- Camera road names carry a route-type prefix, so `"SR 26"` excludes US 26 and `"US 97"` excludes US 97A; a bare `"26"` returns both
|
|
103
|
+
- Region codes: `NW`, `SW`, `OL`, `ER`, `SC`, `NC`, `OS` (Oregon — the TripCheck cameras around Portland), and `WA` (airport cameras plus a few ferry-terminal cameras — most ferry-terminal cameras sit in `NW` and `OL`). Case-insensitive; any other value is rejected with `invalid_region`
|
|
104
|
+
- `titleContains` matches the title as WSDOT wrote it — case-insensitive, every word must appear in any order — so `"Snoqualmie"` returns Snoqualmie Summit and East Snoqualmie Summit but not Hyak. Titles lead with route and milepost, so filter a route with `stateRoute`
|
|
105
|
+
- Either milepost bound may be given alone; a start above the end is rejected with `invalid_milepost_range`
|
|
101
106
|
- Returns metadata and image URLs — camera images are copyright WSDOT, not fetched as bytes
|
|
102
|
-
- Results are ordered by `cameraId` and paged (default 50, max 500) — pass `offset`/`limit`; the notice reports the next offset
|
|
107
|
+
- Results are ordered by `cameraId` and paged (default 50, max 500) — pass `offset`/`limit`; a page also ends early at a 24,000-byte response budget, and the notice reports the next offset
|
|
103
108
|
|
|
104
109
|
---
|
|
105
110
|
|
|
@@ -107,27 +112,31 @@ Washington State transportation data from the WSDOT Traveler API and the WSF Fer
|
|
|
107
112
|
|
|
108
113
|
- No input parameters — returns all 20 WSF ferry terminals; the list rarely changes
|
|
109
114
|
- Call this first to resolve human-readable names (e.g. "Bainbridge Island", "Seattle", "Kingston") to the numeric IDs required by `wsdot_get_ferry_schedule` and `wsdot_get_terminal_space`
|
|
110
|
-
- Each terminal also carries
|
|
115
|
+
- Each terminal also carries its abbreviation and latitude/longitude
|
|
111
116
|
|
|
112
117
|
---
|
|
113
118
|
|
|
114
119
|
### `wsdot_get_ferry_routes` <sub>tool</sub>
|
|
115
120
|
|
|
116
121
|
- Optional `tripDate` (ISO 8601 `YYYY-MM-DD`); defaults to today
|
|
117
|
-
- Returns each route's ID, abbreviation, and description
|
|
122
|
+
- Returns each route's ID, abbreviation, and description, plus `terminalPairs`: the directed departing → arriving terminal pairs (IDs and names) the route serves that day. These are exactly the pairs `wsdot_get_ferry_schedule` accepts for that date; a route serving none carries an empty list
|
|
118
123
|
- Route IDs correspond to `impactedRouteIds` in `wsdot_get_ferry_alerts` — use this tool to resolve alert route IDs to route names
|
|
119
|
-
-
|
|
124
|
+
- A date outside the range WSF has published (before today, or past the posted schedule) returns a typed `invalid_date` error stating WSF's range. A date inside that range with no sailings loaded yet returns an empty list and a notice
|
|
125
|
+
- The pairs cost one lookup per route, cached per date until WSF signals a schedule change; if any lookup fails, the whole call fails
|
|
120
126
|
|
|
121
127
|
---
|
|
122
128
|
|
|
123
129
|
### `wsdot_get_ferry_schedule` <sub>tool</sub>
|
|
124
130
|
|
|
125
|
-
- Requires
|
|
126
|
-
- Optional `tripDate` (defaults to today) and `remainingOnly: true` (only future departures for today; ignored for
|
|
131
|
+
- Requires `departingTerminalId` and `arrivingTerminalId`, both positive integers — use `wsdot_get_ferry_terminals` first, or pick a pair from `terminalPairs` on `wsdot_get_ferry_routes`
|
|
132
|
+
- Optional `tripDate` (defaults to today) and `remainingOnly: true` (only future departures for today; ignored for any other date, and the response then reports `remainingOnly: false`)
|
|
133
|
+
- Each sailing carries `vesselId` (the ID `wsdot_get_vessel_locations` reports), `loadingRule`, `vesselHandicapAccessible`, and `annotationIndexes` into the pair's `annotations`, notes such as "No interisland vehicles. Foot passenger and bikes okay." The rendered text lists each sailing's notes under it. WSF does not document `loadingRule`: 3 appears on nearly every sailing and 1 only on vehicle-restricted ones, so read the notes for the restriction itself
|
|
134
|
+
- `annotations` and the pair-wide `sailingNotes` arrive from WSF as HTML and are returned as plain text, with links kept as `link text (url)`
|
|
127
135
|
- `departureTime` and `arrivalTime` are ISO 8601 **UTC**, while `tripDate` is the Pacific service day — an evening sailing therefore carries the following UTC calendar date and will not match `tripDate`. Convert to `America/Los_Angeles` before quoting a clock time
|
|
128
136
|
- `arrivalTime` is populated on some routes and absent on others
|
|
129
137
|
- No cancellation status — WSF drops a cancelled sailing from the schedule rather than flagging it, so a listed sailing is not confirmation it will run; check `wsdot_get_ferry_alerts`, which reports disruptions at route level
|
|
130
|
-
- An invalid or non-through terminal pair returns a typed `invalid_terminal_pair` error rather than an empty schedule
|
|
138
|
+
- An invalid or non-through terminal pair returns a typed `invalid_terminal_pair` error rather than an empty schedule; its recovery hint points at `terminalPairs` on `wsdot_get_ferry_routes` for the same date
|
|
139
|
+
- A date WSF has no schedule for returns `invalid_date` instead — whether it falls outside WSF's published range or inside it with no routes loaded
|
|
131
140
|
|
|
132
141
|
---
|
|
133
142
|
|
|
@@ -174,7 +183,7 @@ Agent-friendly output:
|
|
|
174
183
|
- Typed failure — `invalid_access_code` and `api_unavailable` errors carry an explicit recovery hint distinguishing configuration faults from transient upstream ones
|
|
175
184
|
- `driveUpSpaceCount: 0` and congestion delta fields (`delayInMinutes`) give agents actionable signal without string parsing
|
|
176
185
|
- Partial data preserved — sparse upstream payloads surface `null`/`undefined` rather than synthetic defaults (e.g. an omitted `waitTimeInMinutes`, an absent `arrivalTime`)
|
|
177
|
-
- `content[]` and `structuredContent` carry the same values, not just the same fields — a `false` flag, an empty list, and one populated half of a coordinate pair all render rather than dropping out of the markdown surface that some clients read
|
|
186
|
+
- `content[]` and `structuredContent` carry the same values, not just the same fields — a `false` flag, an empty list, and one populated half of a coordinate pair all render rather than dropping out of the markdown surface that some clients read; a blank or whitespace-only upstream string is absent from both, and a populated one arrives trimmed
|
|
178
187
|
|
|
179
188
|
## Getting started
|
|
180
189
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Traffic tools reject invalid regions and reversed milepost ranges, toll rates gain a stateRoute filter and cameras a titleContains filter, and each traffic page now ends at a 24,000-byte budget per surface."
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.3.0 — 2026-09-24
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`wsdot_get_toll_rates` `stateRoute` filter** ([#44](https://github.com/cyanheads/wsdot-mcp-server/issues/44)) — `"SR 520"`, `"520"`, `"0520"`, `"I-405"`, and `"405"` all work, matched against the posted designation before paging and echoed in a new `appliedFilters` enrichment. A route with no tolled facility returns an empty page whose notice names the tolled routes.
|
|
12
|
+
- **`wsdot_search_cameras` `titleContains` filter** ([#45](https://github.com/cyanheads/wsdot-mcp-server/issues/45)) — case-insensitive, every whitespace-separated word must appear in the camera title; composes with the other filters and is echoed in `appliedFilters`.
|
|
13
|
+
- **Page byte budget** ([#43](https://github.com/cyanheads/wsdot-mcp-server/issues/43)) — `wsdot_search_alerts`, `wsdot_search_cameras`, `wsdot_get_travel_times`, and `wsdot_get_toll_rates` end a page at `limit` or at 24,000 bytes per surface (`structuredContent` and `content[]`), whichever comes first; a budget-ended page says so in its notice.
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- **Invalid traffic filters fail instead of returning an empty page** ([#39](https://github.com/cyanheads/wsdot-mcp-server/issues/39)) — on `wsdot_search_alerts` and `wsdot_search_cameras`, a `region` outside the tool's vocabulary (names on alerts, codes on cameras; case-insensitive) raises `invalid_region`, and `startMilepost > endMilepost` raises `invalid_milepost_range`. Blank filters are still treated as omitted.
|
|
18
|
+
- **Ferry terminal IDs must be positive integers** — `departingTerminalId` on `wsdot_get_terminal_space` and both IDs on `wsdot_get_ferry_schedule`; anything else is an `InvalidParams` rejection that never reaches the upstream.
|
|
19
|
+
- **Free-text traffic filters accept at most 200 characters** — `stateRoute`, `region`, `route`, and `titleContains`.
|
|
20
|
+
- **`wsdot_search_alerts` default `limit`** drops from 50 to 20; the other three paged traffic tools stay at 50.
|
|
21
|
+
- **Migration:** a region outside the tool's vocabulary, a reversed milepost range, a non-positive or fractional terminal ID, or a filter over 200 characters now errors instead of returning an empty page; an alerts page defaults to 20 rows; and any traffic page may end before `limit` at the byte budget, reported through `hasMore` / `nextOffset` and the notice.
|
|
22
|
+
|
|
23
|
+
## Fixed
|
|
24
|
+
|
|
25
|
+
- **`wsdot_get_toll_rates` output descriptions** — `stateRoute` is stated as the bare, zero-padded feed value, and `travelDirection` as one fixed code per facility on SR 99, SR 509, and SR 520 rather than the direction of travel.
|
|
26
|
+
- **`wsdot_search_cameras` `region` description** — `OS` is the Oregon TripCheck cameras around Portland and `WA` the airport cameras plus a few ferry-terminal cameras, not "Olympic South" and "statewide".
|
|
27
|
+
|
|
28
|
+
## Dependencies
|
|
29
|
+
|
|
30
|
+
- `@types/node` `^26.6.1` → `^26.6.2` (dev)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Ferry routes list the terminal pairs each one serves and schedules carry per-sailing vessel and annotation detail; dates WSF has no schedule for fail as invalid_date, and blank upstream strings are absent instead of empty."
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.0 — 2026-09-24
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`wsdot_get_ferry_routes` `terminalPairs`** ([#41](https://github.com/cyanheads/wsdot-mcp-server/issues/41)) — each route lists the directed departing → arriving terminal IDs and names it serves on the date, the exact pairs `wsdot_get_ferry_schedule` accepts; `[]` when it serves none. Pairs are cached per date until WSF's `cacheflushdate` changes, and a failed pair lookup fails the call.
|
|
12
|
+
- **`wsdot_get_ferry_schedule` sailing detail** ([#50](https://github.com/cyanheads/wsdot-mcp-server/issues/50)) — each sailing gains `vesselId`, `loadingRule`, `vesselHandicapAccessible`, and `annotationIndexes` into a new pair-level `annotations` list, plus a pair-wide `sailingNotes`. Both note fields are HTML upstream and returned as plain text with link URLs kept.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **Ferry dates without a published schedule fail as `invalid_date`** ([#40](https://github.com/cyanheads/wsdot-mcp-server/issues/40)) — on `wsdot_get_ferry_routes` and `wsdot_get_ferry_schedule`, a date outside WSF's window is non-retryable `invalid_date` with WSF's accepted range in the message, not `api_unavailable` or `invalid_terminal_pair`. The schedule tool also returns `invalid_date` for an in-window date with no routes loaded; the routes tool returns `[]` with a notice that no longer advises retrying.
|
|
17
|
+
- **`invalid_terminal_pair` recovery hint** points at `terminalPairs` on `wsdot_get_ferry_routes` for the same date.
|
|
18
|
+
- **Identity fields are optional** ([#46](https://github.com/cyanheads/wsdot-mcp-server/issues/46)) — `mountainPassId` and `mountainPassName` on `wsdot_get_mountain_passes`, and `terminalId` and `terminalName` on `wsdot_get_ferry_terminals`, are absent when upstream omits them instead of `0` / `'Unknown'`.
|
|
19
|
+
- **Migration:** read the four identity fields above as optional, and expect `invalid_date` where an out-of-window ferry date previously returned `api_unavailable` or `invalid_terminal_pair`.
|
|
20
|
+
- **Internal:** `docs/design.md` gives the ferry `TripDate` path format as `YYYY-MM-DD` and records decisions 13 (pair cache) and 14 (date rejection over a `validdaterange` pre-check); service tests reject any unmocked `fetch`.
|
|
21
|
+
|
|
22
|
+
## Fixed
|
|
23
|
+
|
|
24
|
+
- **Blank upstream strings** ([#46](https://github.com/cyanheads/wsdot-mcp-server/issues/46)) — an empty, whitespace-only, or markup-only upstream string is absent from both `structuredContent` and `content[]` on every tool, and a populated one is trimmed; a blank WCF date yields no date field. A pass's blank `weatherCondition` was the visible case.
|
|
25
|
+
- **`wsdot_get_ferry_terminals` coordinates** ([#42](https://github.com/cyanheads/wsdot-mcp-server/issues/42)) — the service reads `Terminals/rest/terminallocations`, so `latitude` and `longitude` populate on all 20 terminals.
|
|
26
|
+
- **`wsdot_get_ferry_schedule` `remainingOnly`** — reports the effective value, `false` for any date other than today.
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ await createApp({
|
|
|
36
36
|
],
|
|
37
37
|
resources: [],
|
|
38
38
|
prompts: [],
|
|
39
|
-
instructions: 'WSDOT Traveler Information server for Washington State. Traffic tools (mountain passes, alerts, travel times, toll rates, border waits, cameras) use the WSDOT Traffic API. Ferry tools use the WSF Ferry API. For ferry schedule and space lookups, first call wsdot_get_ferry_terminals to resolve terminal names to numeric IDs. Ferry route IDs from wsdot_get_ferry_routes correspond to impactedRouteIds in wsdot_get_ferry_alerts.',
|
|
39
|
+
instructions: 'WSDOT Traveler Information server for Washington State. Traffic tools (mountain passes, alerts, travel times, toll rates, border waits, cameras) use the WSDOT Traffic API. Ferry tools use the WSF Ferry API. For ferry schedule and space lookups, first call wsdot_get_ferry_terminals to resolve terminal names to numeric IDs; wsdot_get_ferry_routes lists the terminal pairs each route serves on a date, which are the pairs wsdot_get_ferry_schedule accepts. Ferry route IDs from wsdot_get_ferry_routes correspond to impactedRouteIds in wsdot_get_ferry_alerts.',
|
|
40
40
|
landing: { requireAuth: false },
|
|
41
41
|
setup(core) {
|
|
42
42
|
initTrafficApiService(core.config, core.storage);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,kBAAkB;IACzB,4FAA4F;IAC5F,yFAAyF;IACzF,sCAAsC;IACtC,WAAW,EAAE,WAAW;IACxB,qFAAqF;IACrF,kFAAkF;IAClF,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE;QACzD,iBAAiB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE;KAC/D;IACD,KAAK,EAAE;QACL,iBAAiB;QACjB,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,cAAc;QACd,aAAa;QACb,iBAAiB;QACjB,cAAc;QACd,gBAAgB;QAChB,kBAAkB;QAClB,gBAAgB;QAChB,cAAc;KACf;IACD,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,YAAY,EACV,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,kBAAkB;IACzB,4FAA4F;IAC5F,yFAAyF;IACzF,sCAAsC;IACtC,WAAW,EAAE,WAAW;IACxB,qFAAqF;IACrF,kFAAkF;IAClF,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE;QACzD,iBAAiB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE;KAC/D;IACD,KAAK,EAAE;QACL,iBAAiB;QACjB,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,cAAc;QACd,aAAa;QACb,iBAAiB;QACjB,cAAc;QACd,gBAAgB;QAChB,kBAAkB;QAClB,gBAAgB;QAChB,cAAc;KACf;IACD,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,YAAY,EACV,8iBAA8iB;IAChjB,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAC/B,KAAK,CAAC,IAAI;QACR,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjD,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -11,6 +11,12 @@ export declare const getFerryRoutes: import("@cyanheads/mcp-ts-core").ToolDefini
|
|
|
11
11
|
routeId: z.ZodOptional<z.ZodNumber>;
|
|
12
12
|
routeAbbrev: z.ZodOptional<z.ZodString>;
|
|
13
13
|
description: z.ZodOptional<z.ZodString>;
|
|
14
|
+
terminalPairs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
15
|
+
departingTerminalId: z.ZodNumber;
|
|
16
|
+
departingTerminalName: z.ZodOptional<z.ZodString>;
|
|
17
|
+
arrivingTerminalId: z.ZodNumber;
|
|
18
|
+
arrivingTerminalName: z.ZodOptional<z.ZodString>;
|
|
19
|
+
}, z.core.$strip>>>;
|
|
14
20
|
}, z.core.$strip>>;
|
|
15
21
|
}, z.core.$strip>, readonly [{
|
|
16
22
|
readonly reason: "api_unavailable";
|
|
@@ -29,8 +35,9 @@ export declare const getFerryRoutes: import("@cyanheads/mcp-ts-core").ToolDefini
|
|
|
29
35
|
}, {
|
|
30
36
|
readonly reason: "invalid_date";
|
|
31
37
|
readonly code: JsonRpcErrorCode.ValidationError;
|
|
32
|
-
readonly when: "The
|
|
33
|
-
readonly
|
|
38
|
+
readonly when: "The tripDate is not a valid YYYY-MM-DD date, or WSF rejects it as outside the dates it has published a schedule for.";
|
|
39
|
+
readonly retryable: false;
|
|
40
|
+
readonly recovery: "Use a YYYY-MM-DD date from today (Pacific time) through the end of the posted schedule; when WSF rejects the date, the message states the range it accepts.";
|
|
34
41
|
}], {
|
|
35
42
|
readonly tripDate: z.ZodString;
|
|
36
43
|
readonly totalCount: z.ZodNumber;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-ferry-routes.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-ferry-routes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"get-ferry-routes.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-ferry-routes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyKzB,CAAC"}
|
|
@@ -7,10 +7,12 @@ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
|
7
7
|
import { FerryApiService, getFerryApiService } from '../../../services/ferry/ferry-service.js';
|
|
8
8
|
export const getFerryRoutes = tool('wsdot_get_ferry_routes', {
|
|
9
9
|
title: 'Get Ferry Routes',
|
|
10
|
-
description: 'Returns the main WSF ferry routes operating on a given date
|
|
10
|
+
description: 'Returns the main WSF ferry routes operating on a given date, each with the directed terminal ' +
|
|
11
|
+
'pairs it serves that day (terminalPairs) — departing and arriving terminal IDs and names, which ' +
|
|
12
|
+
'are exactly the pairs wsdot_get_ferry_schedule accepts for that date. ' +
|
|
11
13
|
'Route IDs correspond to impactedRouteIds in ferry alerts from wsdot_get_ferry_alerts, though some ' +
|
|
12
14
|
'alert route IDs (seasonal, San Juan interisland, or Sidney B.C.) may not appear in this list. ' +
|
|
13
|
-
'
|
|
15
|
+
'For the full terminal list with coordinates, use wsdot_get_ferry_terminals.',
|
|
14
16
|
annotations: { readOnlyHint: true },
|
|
15
17
|
input: z.object({
|
|
16
18
|
tripDate: z
|
|
@@ -35,6 +37,28 @@ export const getFerryRoutes = tool('wsdot_get_ferry_routes', {
|
|
|
35
37
|
.string()
|
|
36
38
|
.optional()
|
|
37
39
|
.describe('Full route description (e.g. "Seattle/Bainbridge Island").'),
|
|
40
|
+
terminalPairs: z
|
|
41
|
+
.array(z
|
|
42
|
+
.object({
|
|
43
|
+
departingTerminalId: z
|
|
44
|
+
.number()
|
|
45
|
+
.describe('Departing terminal ID — the departingTerminalId to pass to wsdot_get_ferry_schedule.'),
|
|
46
|
+
departingTerminalName: z
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Departing terminal name. Absent when upstream omits it.'),
|
|
50
|
+
arrivingTerminalId: z
|
|
51
|
+
.number()
|
|
52
|
+
.describe('Arriving terminal ID — the arrivingTerminalId to pass to wsdot_get_ferry_schedule.'),
|
|
53
|
+
arrivingTerminalName: z
|
|
54
|
+
.string()
|
|
55
|
+
.optional()
|
|
56
|
+
.describe('Arriving terminal name. Absent when upstream omits it.'),
|
|
57
|
+
})
|
|
58
|
+
.describe('One direction of service between two terminals on the requested date.'))
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Directed terminal pairs this route serves on the requested date; empty when it serves none. ' +
|
|
61
|
+
'Absent only when upstream omits the route ID the lookup needs.'),
|
|
38
62
|
})
|
|
39
63
|
.describe('A WSF ferry route operating on the requested date.'))
|
|
40
64
|
.describe('Ferry routes operating on the requested date.'),
|
|
@@ -67,8 +91,9 @@ export const getFerryRoutes = tool('wsdot_get_ferry_routes', {
|
|
|
67
91
|
{
|
|
68
92
|
reason: 'invalid_date',
|
|
69
93
|
code: JsonRpcErrorCode.ValidationError,
|
|
70
|
-
when: 'The
|
|
71
|
-
|
|
94
|
+
when: 'The tripDate is not a valid YYYY-MM-DD date, or WSF rejects it as outside the dates it has published a schedule for.',
|
|
95
|
+
retryable: false,
|
|
96
|
+
recovery: 'Use a YYYY-MM-DD date from today (Pacific time) through the end of the posted schedule; when WSF rejects the date, the message states the range it accepts.',
|
|
72
97
|
},
|
|
73
98
|
],
|
|
74
99
|
async handler(input, ctx) {
|
|
@@ -85,7 +110,7 @@ export const getFerryRoutes = tool('wsdot_get_ferry_routes', {
|
|
|
85
110
|
ctx.log.info('Ferry routes fetched', { tripDate, count: routes.length });
|
|
86
111
|
ctx.enrich({ tripDate, totalCount: routes.length });
|
|
87
112
|
if (routes.length === 0) {
|
|
88
|
-
ctx.enrich.notice(`
|
|
113
|
+
ctx.enrich.notice(`WSF lists no routes for ${tripDate}. The date is inside the window WSF accepts, but no sailings are loaded for it yet — typically a season whose schedule has not been posted. Try an earlier date.`);
|
|
89
114
|
}
|
|
90
115
|
return { routes };
|
|
91
116
|
},
|
|
@@ -93,6 +118,7 @@ export const getFerryRoutes = tool('wsdot_get_ferry_routes', {
|
|
|
93
118
|
if (result.routes.length === 0) {
|
|
94
119
|
return [{ type: 'text', text: 'No ferry routes found for this date.' }];
|
|
95
120
|
}
|
|
121
|
+
const terminal = (id, name) => name ? `${name} (${id})` : `terminal ${id}`;
|
|
96
122
|
const lines = [];
|
|
97
123
|
for (const r of result.routes) {
|
|
98
124
|
const name = r.description ?? r.routeAbbrev ?? 'Unknown route';
|
|
@@ -101,6 +127,15 @@ export const getFerryRoutes = tool('wsdot_get_ferry_routes', {
|
|
|
101
127
|
lines.push(`**Abbrev:** ${r.routeAbbrev}`);
|
|
102
128
|
if (r.routeId != null)
|
|
103
129
|
lines.push(`**Route ID:** ${r.routeId}`);
|
|
130
|
+
if (r.terminalPairs?.length === 0) {
|
|
131
|
+
lines.push('**Terminal pairs:** none served on this date');
|
|
132
|
+
}
|
|
133
|
+
else if (r.terminalPairs) {
|
|
134
|
+
lines.push('**Terminal pairs** (departing → arriving):');
|
|
135
|
+
for (const p of r.terminalPairs) {
|
|
136
|
+
lines.push(`- ${terminal(p.departingTerminalId, p.departingTerminalName)} → ${terminal(p.arrivingTerminalId, p.arrivingTerminalName)}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
104
139
|
lines.push('');
|
|
105
140
|
}
|
|
106
141
|
return [{ type: 'text', text: lines.join('\n') }];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-ferry-routes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-ferry-routes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAExF,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,wBAAwB,EAAE;IAC3D,KAAK,EAAE,kBAAkB;IACzB,WAAW,EACT,+
|
|
1
|
+
{"version":3,"file":"get-ferry-routes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-ferry-routes.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,10 +12,16 @@ export declare const getFerrySchedule: import("@cyanheads/mcp-ts-core").ToolDefi
|
|
|
12
12
|
}, z.core.$strip>, z.ZodObject<{
|
|
13
13
|
departingTerminalName: z.ZodOptional<z.ZodString>;
|
|
14
14
|
arrivingTerminalName: z.ZodOptional<z.ZodString>;
|
|
15
|
+
annotations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
16
|
+
sailingNotes: z.ZodOptional<z.ZodString>;
|
|
15
17
|
sailings: z.ZodArray<z.ZodObject<{
|
|
16
18
|
departureTime: z.ZodOptional<z.ZodString>;
|
|
17
19
|
arrivalTime: z.ZodOptional<z.ZodString>;
|
|
18
20
|
vesselName: z.ZodOptional<z.ZodString>;
|
|
21
|
+
vesselId: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
loadingRule: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
vesselHandicapAccessible: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
+
annotationIndexes: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
19
25
|
}, z.core.$strip>>;
|
|
20
26
|
}, z.core.$strip>, readonly [{
|
|
21
27
|
readonly reason: "api_unavailable";
|
|
@@ -35,12 +41,13 @@ export declare const getFerrySchedule: import("@cyanheads/mcp-ts-core").ToolDefi
|
|
|
35
41
|
readonly reason: "invalid_terminal_pair";
|
|
36
42
|
readonly code: JsonRpcErrorCode.ValidationError;
|
|
37
43
|
readonly when: "The terminal ID pair is invalid or does not form a valid ferry route.";
|
|
38
|
-
readonly recovery: "
|
|
44
|
+
readonly recovery: "Call wsdot_get_ferry_routes for the same tripDate and pick a departing → arriving pair from a route’s terminalPairs; wsdot_get_ferry_terminals maps terminal names to IDs.";
|
|
39
45
|
}, {
|
|
40
46
|
readonly reason: "invalid_date";
|
|
41
47
|
readonly code: JsonRpcErrorCode.ValidationError;
|
|
42
|
-
readonly when: "The
|
|
43
|
-
readonly
|
|
48
|
+
readonly when: "The tripDate is not a valid YYYY-MM-DD date, WSF rejects it as outside the dates it has published a schedule for, or WSF lists no routes on it.";
|
|
49
|
+
readonly retryable: false;
|
|
50
|
+
readonly recovery: "Use a YYYY-MM-DD date from today (Pacific time) through the end of the posted schedule, on which wsdot_get_ferry_routes lists routes; when WSF rejects the date, the message states the range it accepts.";
|
|
44
51
|
}], {
|
|
45
52
|
readonly tripDate: z.ZodString;
|
|
46
53
|
readonly remainingOnly: z.ZodBoolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-ferry-schedule.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-ferry-schedule.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAY,MAAM,+BAA+B,CAAC;AAI3E,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"get-ferry-schedule.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-ferry-schedule.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAY,MAAM,+BAA+B,CAAC;AAI3E,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8R3B,CAAC"}
|