@cyanheads/wsdot-mcp-server 0.1.1
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/CLAUDE.md +343 -0
- package/Dockerfile +99 -0
- package/LICENSE +201 -0
- package/README.md +364 -0
- package/changelog/0.1.x/0.1.0.md +24 -0
- package/changelog/0.1.x/0.1.1.md +26 -0
- package/changelog/template.md +119 -0
- package/dist/config/server-config.d.ts +12 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +19 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-border-waits.tool.d.ts +28 -0
- package/dist/mcp-server/tools/definitions/get-border-waits.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-border-waits.tool.js +83 -0
- package/dist/mcp-server/tools/definitions/get-border-waits.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-alerts.tool.d.ts +22 -0
- package/dist/mcp-server/tools/definitions/get-ferry-alerts.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-alerts.tool.js +67 -0
- package/dist/mcp-server/tools/definitions/get-ferry-alerts.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.d.ts +33 -0
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.js +95 -0
- package/dist/mcp-server/tools/definitions/get-ferry-routes.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.d.ts +41 -0
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.js +117 -0
- package/dist/mcp-server/tools/definitions/get-ferry-schedule.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.d.ts +23 -0
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.js +56 -0
- package/dist/mcp-server/tools/definitions/get-ferry-terminals.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.d.ts +35 -0
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.js +116 -0
- package/dist/mcp-server/tools/definitions/get-mountain-passes.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-terminal-space.tool.d.ts +32 -0
- package/dist/mcp-server/tools/definitions/get-terminal-space.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-terminal-space.tool.js +118 -0
- package/dist/mcp-server/tools/definitions/get-terminal-space.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.d.ts +29 -0
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.js +85 -0
- package/dist/mcp-server/tools/definitions/get-toll-rates.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-travel-times.tool.d.ts +38 -0
- package/dist/mcp-server/tools/definitions/get-travel-times.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-travel-times.tool.js +141 -0
- package/dist/mcp-server/tools/definitions/get-travel-times.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-vessel-locations.tool.d.ts +35 -0
- package/dist/mcp-server/tools/definitions/get-vessel-locations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-vessel-locations.tool.js +120 -0
- package/dist/mcp-server/tools/definitions/get-vessel-locations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +17 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +17 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.d.ts +48 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.js +155 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-cameras.tool.d.ts +36 -0
- package/dist/mcp-server/tools/definitions/search-cameras.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-cameras.tool.js +116 -0
- package/dist/mcp-server/tools/definitions/search-cameras.tool.js.map +1 -0
- package/dist/services/ferry/ferry-service.d.ts +28 -0
- package/dist/services/ferry/ferry-service.d.ts.map +1 -0
- package/dist/services/ferry/ferry-service.js +222 -0
- package/dist/services/ferry/ferry-service.js.map +1 -0
- package/dist/services/ferry/types.d.ts +183 -0
- package/dist/services/ferry/types.d.ts.map +1 -0
- package/dist/services/ferry/types.js +6 -0
- package/dist/services/ferry/types.js.map +1 -0
- package/dist/services/traffic/traffic-service.d.ts +37 -0
- package/dist/services/traffic/traffic-service.d.ts.map +1 -0
- package/dist/services/traffic/traffic-service.js +290 -0
- package/dist/services/traffic/traffic-service.js.map +1 -0
- package/dist/services/traffic/types.d.ts +247 -0
- package/dist/services/traffic/types.d.ts.map +1 -0
- package/dist/services/traffic/types.js +6 -0
- package/dist/services/traffic/types.js.map +1 -0
- package/package.json +89 -0
- package/server.json +111 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool to fetch real-time vessel positions for all active WSF ferries.
|
|
3
|
+
* @module mcp-server/tools/definitions/get-vessel-locations.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const getVesselLocations: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
8
|
+
vessels: z.ZodArray<z.ZodObject<{
|
|
9
|
+
vesselId: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
vesselName: z.ZodOptional<z.ZodString>;
|
|
11
|
+
inService: z.ZodOptional<z.ZodBoolean>;
|
|
12
|
+
atDock: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
departingTerminalId: z.ZodOptional<z.ZodNumber>;
|
|
14
|
+
departingTerminalName: z.ZodOptional<z.ZodString>;
|
|
15
|
+
arrivingTerminalId: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
arrivingTerminalName: z.ZodOptional<z.ZodString>;
|
|
17
|
+
latitude: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
longitude: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
speed: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
heading: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
leftDock: z.ZodOptional<z.ZodString>;
|
|
22
|
+
eta: z.ZodOptional<z.ZodString>;
|
|
23
|
+
scheduledDeparture: z.ZodOptional<z.ZodString>;
|
|
24
|
+
opRouteAbbrev: z.ZodArray<z.ZodString>;
|
|
25
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
totalCount: z.ZodNumber;
|
|
28
|
+
}, z.core.$strip>, readonly [{
|
|
29
|
+
readonly reason: "api_unavailable";
|
|
30
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
31
|
+
readonly when: "WSF Ferry API is unreachable or returns a non-2xx response after retries.";
|
|
32
|
+
readonly retryable: true;
|
|
33
|
+
readonly recovery: "Retry in 30 seconds. If the issue persists, check wsdot.wa.gov/ferries for service status.";
|
|
34
|
+
}]>;
|
|
35
|
+
//# sourceMappingURL=get-vessel-locations.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-vessel-locations.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-vessel-locations.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,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiH7B,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool to fetch real-time vessel positions for all active WSF ferries.
|
|
3
|
+
* @module mcp-server/tools/definitions/get-vessel-locations.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getFerryApiService } from '../../../services/ferry/ferry-service.js';
|
|
8
|
+
export const getVesselLocations = tool('wsdot_get_vessel_locations', {
|
|
9
|
+
title: 'Get Vessel Locations',
|
|
10
|
+
description: 'Returns real-time AIS positions, speed, heading, ETA, and dock status for all active WSF vessels. ' +
|
|
11
|
+
'Use for "where is the ferry now?", vessel tracking, or checking if a vessel is in service. ' +
|
|
12
|
+
'Position data may lag by 30–60 seconds. Many fields are null for vessels not currently operating.',
|
|
13
|
+
annotations: { readOnlyHint: true },
|
|
14
|
+
input: z.object({}),
|
|
15
|
+
output: z.object({
|
|
16
|
+
vessels: z
|
|
17
|
+
.array(z
|
|
18
|
+
.object({
|
|
19
|
+
vesselId: z.number().optional().describe('Unique vessel identifier.'),
|
|
20
|
+
vesselName: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe('Vessel name (e.g. "Yakima", "Walla Walla").'),
|
|
24
|
+
inService: z
|
|
25
|
+
.boolean()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe('Whether the vessel is currently in service.'),
|
|
28
|
+
atDock: z
|
|
29
|
+
.boolean()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('True when the vessel is docked at a terminal.'),
|
|
32
|
+
departingTerminalId: z
|
|
33
|
+
.number()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe('Terminal the vessel is departing from.'),
|
|
36
|
+
departingTerminalName: z.string().optional().describe('Departing terminal name.'),
|
|
37
|
+
arrivingTerminalId: z
|
|
38
|
+
.number()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Terminal the vessel is heading toward.'),
|
|
41
|
+
arrivingTerminalName: z.string().optional().describe('Arriving terminal name.'),
|
|
42
|
+
latitude: z.number().optional().describe('Current latitude (AIS position).'),
|
|
43
|
+
longitude: z.number().optional().describe('Current longitude (AIS position).'),
|
|
44
|
+
speed: z.number().optional().describe('Speed in knots.'),
|
|
45
|
+
heading: z.number().optional().describe('Heading in degrees (0–359).'),
|
|
46
|
+
leftDock: z.string().optional().describe('Time the vessel last left the dock.'),
|
|
47
|
+
eta: z
|
|
48
|
+
.string()
|
|
49
|
+
.optional()
|
|
50
|
+
.describe('Estimated arrival time at the destination terminal.'),
|
|
51
|
+
scheduledDeparture: z.string().optional().describe('Scheduled departure time.'),
|
|
52
|
+
opRouteAbbrev: z
|
|
53
|
+
.array(z.string())
|
|
54
|
+
.describe('Abbreviations of routes this vessel operates on.'),
|
|
55
|
+
timestamp: z
|
|
56
|
+
.string()
|
|
57
|
+
.optional()
|
|
58
|
+
.describe('AIS data timestamp — indicates position data age.'),
|
|
59
|
+
})
|
|
60
|
+
.describe('Real-time position and status for one WSF vessel.'))
|
|
61
|
+
.describe('All WSF vessels with real-time position data.'),
|
|
62
|
+
totalCount: z.number().describe('Total number of vessels returned.'),
|
|
63
|
+
}),
|
|
64
|
+
errors: [
|
|
65
|
+
{
|
|
66
|
+
reason: 'api_unavailable',
|
|
67
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
68
|
+
when: 'WSF Ferry API is unreachable or returns a non-2xx response after retries.',
|
|
69
|
+
retryable: true,
|
|
70
|
+
recovery: 'Retry in 30 seconds. If the issue persists, check wsdot.wa.gov/ferries for service status.',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
async handler(_input, ctx) {
|
|
74
|
+
const vessels = await getFerryApiService().getVesselLocations(ctx);
|
|
75
|
+
ctx.log.info('Vessel locations fetched', { count: vessels.length });
|
|
76
|
+
return { vessels, totalCount: vessels.length };
|
|
77
|
+
},
|
|
78
|
+
format: (result) => {
|
|
79
|
+
if (result.vessels.length === 0) {
|
|
80
|
+
return [{ type: 'text', text: 'No vessel location data available. **Total:** 0' }];
|
|
81
|
+
}
|
|
82
|
+
const lines = [`## WSF Vessel Locations (${result.totalCount} vessels)\n`];
|
|
83
|
+
for (const v of result.vessels) {
|
|
84
|
+
const name = v.vesselName ?? `Vessel ${v.vesselId ?? '?'}`;
|
|
85
|
+
lines.push(`### ${name}`);
|
|
86
|
+
if (typeof v.inService === 'boolean')
|
|
87
|
+
lines.push(`**In Service:** ${v.inService ? 'Yes' : 'No'}`);
|
|
88
|
+
if (typeof v.atDock === 'boolean')
|
|
89
|
+
lines.push(`**At Dock:** ${v.atDock ? 'Yes' : 'No'}`);
|
|
90
|
+
if (v.departingTerminalId != null || v.departingTerminalName) {
|
|
91
|
+
lines.push(`**Departing:** ${v.departingTerminalName ?? ''}${v.departingTerminalId != null ? ` (ID: ${v.departingTerminalId})` : ''}`);
|
|
92
|
+
}
|
|
93
|
+
if (v.arrivingTerminalId != null || v.arrivingTerminalName) {
|
|
94
|
+
lines.push(`**Arriving:** ${v.arrivingTerminalName ?? ''}${v.arrivingTerminalId != null ? ` (ID: ${v.arrivingTerminalId})` : ''}`);
|
|
95
|
+
}
|
|
96
|
+
if (v.latitude != null && v.longitude != null) {
|
|
97
|
+
lines.push(`**Position:** ${v.latitude.toFixed(5)}, ${v.longitude.toFixed(5)}`);
|
|
98
|
+
}
|
|
99
|
+
if (v.speed != null)
|
|
100
|
+
lines.push(`**Speed:** ${v.speed} knots`);
|
|
101
|
+
if (v.heading != null)
|
|
102
|
+
lines.push(`**Heading:** ${v.heading}°`);
|
|
103
|
+
if (v.leftDock)
|
|
104
|
+
lines.push(`**Left Dock:** ${v.leftDock}`);
|
|
105
|
+
if (v.eta)
|
|
106
|
+
lines.push(`**ETA:** ${v.eta}`);
|
|
107
|
+
if (v.scheduledDeparture)
|
|
108
|
+
lines.push(`**Scheduled Departure:** ${v.scheduledDeparture}`);
|
|
109
|
+
if (v.opRouteAbbrev.length > 0)
|
|
110
|
+
lines.push(`**Routes:** ${v.opRouteAbbrev.join(', ')}`);
|
|
111
|
+
if (v.timestamp)
|
|
112
|
+
lines.push(`**Position Timestamp:** ${v.timestamp}`);
|
|
113
|
+
if (v.vesselId != null)
|
|
114
|
+
lines.push(`**Vessel ID:** ${v.vesselId}`);
|
|
115
|
+
lines.push('');
|
|
116
|
+
}
|
|
117
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=get-vessel-locations.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-vessel-locations.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-vessel-locations.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for all tool definitions.
|
|
3
|
+
* @module mcp-server/tools/definitions/index
|
|
4
|
+
*/
|
|
5
|
+
export { getBorderWaits } from './get-border-waits.tool.js';
|
|
6
|
+
export { getFerryAlerts } from './get-ferry-alerts.tool.js';
|
|
7
|
+
export { getFerryRoutes } from './get-ferry-routes.tool.js';
|
|
8
|
+
export { getFerrySchedule } from './get-ferry-schedule.tool.js';
|
|
9
|
+
export { getFerryTerminals } from './get-ferry-terminals.tool.js';
|
|
10
|
+
export { getMountainPasses } from './get-mountain-passes.tool.js';
|
|
11
|
+
export { getTerminalSpace } from './get-terminal-space.tool.js';
|
|
12
|
+
export { getTollRates } from './get-toll-rates.tool.js';
|
|
13
|
+
export { getTravelTimes } from './get-travel-times.tool.js';
|
|
14
|
+
export { getVesselLocations } from './get-vessel-locations.tool.js';
|
|
15
|
+
export { searchAlerts } from './search-alerts.tool.js';
|
|
16
|
+
export { searchCameras } from './search-cameras.tool.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for all tool definitions.
|
|
3
|
+
* @module mcp-server/tools/definitions/index
|
|
4
|
+
*/
|
|
5
|
+
export { getBorderWaits } from './get-border-waits.tool.js';
|
|
6
|
+
export { getFerryAlerts } from './get-ferry-alerts.tool.js';
|
|
7
|
+
export { getFerryRoutes } from './get-ferry-routes.tool.js';
|
|
8
|
+
export { getFerrySchedule } from './get-ferry-schedule.tool.js';
|
|
9
|
+
export { getFerryTerminals } from './get-ferry-terminals.tool.js';
|
|
10
|
+
export { getMountainPasses } from './get-mountain-passes.tool.js';
|
|
11
|
+
export { getTerminalSpace } from './get-terminal-space.tool.js';
|
|
12
|
+
export { getTollRates } from './get-toll-rates.tool.js';
|
|
13
|
+
export { getTravelTimes } from './get-travel-times.tool.js';
|
|
14
|
+
export { getVesselLocations } from './get-vessel-locations.tool.js';
|
|
15
|
+
export { searchAlerts } from './search-alerts.tool.js';
|
|
16
|
+
export { searchCameras } from './search-cameras.tool.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool to search WA highway alerts, incidents, and construction notices.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-alerts.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const searchAlerts: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
stateRoute: z.ZodOptional<z.ZodString>;
|
|
9
|
+
region: z.ZodOptional<z.ZodString>;
|
|
10
|
+
startMilepost: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
endMilepost: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
13
|
+
alerts: z.ZodArray<z.ZodObject<{
|
|
14
|
+
alertId: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
headlineDescription: z.ZodOptional<z.ZodString>;
|
|
16
|
+
extendedDescription: z.ZodOptional<z.ZodString>;
|
|
17
|
+
eventCategory: z.ZodOptional<z.ZodString>;
|
|
18
|
+
eventStatus: z.ZodOptional<z.ZodString>;
|
|
19
|
+
priority: z.ZodOptional<z.ZodString>;
|
|
20
|
+
region: z.ZodOptional<z.ZodString>;
|
|
21
|
+
county: z.ZodOptional<z.ZodString>;
|
|
22
|
+
startRoadwayLocation: z.ZodOptional<z.ZodObject<{
|
|
23
|
+
roadName: z.ZodOptional<z.ZodString>;
|
|
24
|
+
direction: z.ZodOptional<z.ZodString>;
|
|
25
|
+
milePost: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
latitude: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
longitude: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
}, z.core.$strip>>;
|
|
29
|
+
endRoadwayLocation: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
roadName: z.ZodOptional<z.ZodString>;
|
|
31
|
+
direction: z.ZodOptional<z.ZodString>;
|
|
32
|
+
milePost: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
latitude: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
longitude: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
startTime: z.ZodOptional<z.ZodString>;
|
|
37
|
+
endTime: z.ZodOptional<z.ZodString>;
|
|
38
|
+
lastUpdatedTime: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, z.core.$strip>>;
|
|
40
|
+
totalCount: z.ZodNumber;
|
|
41
|
+
}, z.core.$strip>, readonly [{
|
|
42
|
+
readonly reason: "api_unavailable";
|
|
43
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
44
|
+
readonly when: "WSDOT Traffic API is unreachable or returns a non-2xx response after retries.";
|
|
45
|
+
readonly retryable: true;
|
|
46
|
+
readonly recovery: "Retry in 30 seconds. If the issue persists, check wsdot.wa.gov for service status.";
|
|
47
|
+
}]>;
|
|
48
|
+
//# sourceMappingURL=search-alerts.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-alerts.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-alerts.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,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqJvB,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool to search WA highway alerts, incidents, and construction notices.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-alerts.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getTrafficApiService } from '../../../services/traffic/traffic-service.js';
|
|
8
|
+
export const searchAlerts = tool('wsdot_search_alerts', {
|
|
9
|
+
title: 'Search Highway Alerts',
|
|
10
|
+
description: 'Returns active WA highway alerts: incidents, construction, closures, and restrictions. ' +
|
|
11
|
+
'Filter by state route (zero-padded 3-digit number, e.g. "005" for I-5, "090" for I-90, "520" for SR 520), ' +
|
|
12
|
+
'WSDOT region (Northwest, Olympic, Southwest, South Central, North Central, Eastern), ' +
|
|
13
|
+
'or milepost range. Omit all filters to return all current statewide alerts.',
|
|
14
|
+
annotations: { readOnlyHint: true },
|
|
15
|
+
input: z.object({
|
|
16
|
+
stateRoute: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Zero-padded 3-digit state route number (e.g. "005" for I-5, "090" for I-90, "520" for SR 520).'),
|
|
20
|
+
region: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe('WSDOT region name: Northwest, Olympic, Southwest, South Central, North Central, or Eastern.'),
|
|
24
|
+
startMilepost: z.number().optional().describe('Start of milepost range to filter alerts.'),
|
|
25
|
+
endMilepost: z.number().optional().describe('End of milepost range to filter alerts.'),
|
|
26
|
+
}),
|
|
27
|
+
output: z.object({
|
|
28
|
+
alerts: z
|
|
29
|
+
.array(z
|
|
30
|
+
.object({
|
|
31
|
+
alertId: z.number().optional().describe('Unique alert identifier.'),
|
|
32
|
+
headlineDescription: z.string().optional().describe('Short summary of the alert.'),
|
|
33
|
+
extendedDescription: z.string().optional().describe('Full description of the alert.'),
|
|
34
|
+
eventCategory: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe('Category (e.g. "Incident", "Construction", "Closure").'),
|
|
38
|
+
eventStatus: z.string().optional().describe('Current status of the event.'),
|
|
39
|
+
priority: z.string().optional().describe('Priority level.'),
|
|
40
|
+
region: z.string().optional().describe('WSDOT region where the alert is located.'),
|
|
41
|
+
county: z.string().optional().describe('County where the alert is located.'),
|
|
42
|
+
startRoadwayLocation: z
|
|
43
|
+
.object({
|
|
44
|
+
roadName: z.string().optional().describe('Road name.'),
|
|
45
|
+
direction: z.string().optional().describe('Travel direction.'),
|
|
46
|
+
milePost: z.number().optional().describe('Starting milepost.'),
|
|
47
|
+
latitude: z.number().optional().describe('Latitude.'),
|
|
48
|
+
longitude: z.number().optional().describe('Longitude.'),
|
|
49
|
+
})
|
|
50
|
+
.optional()
|
|
51
|
+
.describe('Start location of the alert.'),
|
|
52
|
+
endRoadwayLocation: z
|
|
53
|
+
.object({
|
|
54
|
+
roadName: z.string().optional().describe('Road name.'),
|
|
55
|
+
direction: z.string().optional().describe('Travel direction.'),
|
|
56
|
+
milePost: z.number().optional().describe('Ending milepost.'),
|
|
57
|
+
latitude: z.number().optional().describe('Latitude.'),
|
|
58
|
+
longitude: z.number().optional().describe('Longitude.'),
|
|
59
|
+
})
|
|
60
|
+
.optional()
|
|
61
|
+
.describe('End location of the alert, if the event spans a range.'),
|
|
62
|
+
startTime: z
|
|
63
|
+
.string()
|
|
64
|
+
.optional()
|
|
65
|
+
.describe('When the event started or is scheduled to start.'),
|
|
66
|
+
endTime: z.string().optional().describe('When the event is expected to end.'),
|
|
67
|
+
lastUpdatedTime: z.string().optional().describe('When this alert was last updated.'),
|
|
68
|
+
})
|
|
69
|
+
.describe('A highway alert or incident.'))
|
|
70
|
+
.describe('Matching highway alerts.'),
|
|
71
|
+
totalCount: z.number().describe('Total number of alerts returned.'),
|
|
72
|
+
}),
|
|
73
|
+
errors: [
|
|
74
|
+
{
|
|
75
|
+
reason: 'api_unavailable',
|
|
76
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
77
|
+
when: 'WSDOT Traffic API is unreachable or returns a non-2xx response after retries.',
|
|
78
|
+
retryable: true,
|
|
79
|
+
recovery: 'Retry in 30 seconds. If the issue persists, check wsdot.wa.gov for service status.',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
async handler(input, ctx) {
|
|
83
|
+
const stateRoute = input.stateRoute?.trim() || undefined;
|
|
84
|
+
const region = input.region?.trim() || undefined;
|
|
85
|
+
const alerts = await getTrafficApiService().searchAlerts({
|
|
86
|
+
...(stateRoute && { stateRoute }),
|
|
87
|
+
...(region && { region }),
|
|
88
|
+
...(input.startMilepost != null && { startMilepost: input.startMilepost }),
|
|
89
|
+
...(input.endMilepost != null && { endMilepost: input.endMilepost }),
|
|
90
|
+
}, ctx);
|
|
91
|
+
ctx.log.info('Alerts fetched', { count: alerts.length });
|
|
92
|
+
return { alerts, totalCount: alerts.length };
|
|
93
|
+
},
|
|
94
|
+
format: (result) => {
|
|
95
|
+
if (result.alerts.length === 0) {
|
|
96
|
+
return [{ type: 'text', text: `No active alerts found. **Total:** 0` }];
|
|
97
|
+
}
|
|
98
|
+
const lines = [`## Highway Alerts (${result.totalCount})\n`];
|
|
99
|
+
for (const a of result.alerts) {
|
|
100
|
+
const id = a.alertId != null ? ` #${a.alertId}` : '';
|
|
101
|
+
lines.push(`### ${a.headlineDescription ?? 'Alert'}${id}`);
|
|
102
|
+
if (a.eventCategory)
|
|
103
|
+
lines.push(`**Category:** ${a.eventCategory}`);
|
|
104
|
+
if (a.eventStatus)
|
|
105
|
+
lines.push(`**Status:** ${a.eventStatus}`);
|
|
106
|
+
if (a.priority)
|
|
107
|
+
lines.push(`**Priority:** ${a.priority}`);
|
|
108
|
+
if (a.region)
|
|
109
|
+
lines.push(`**Region:** ${a.region}`);
|
|
110
|
+
if (a.county)
|
|
111
|
+
lines.push(`**County:** ${a.county}`);
|
|
112
|
+
if (a.startRoadwayLocation) {
|
|
113
|
+
const loc = a.startRoadwayLocation;
|
|
114
|
+
const parts = [
|
|
115
|
+
loc.roadName,
|
|
116
|
+
loc.direction,
|
|
117
|
+
loc.milePost != null ? `MP ${loc.milePost}` : undefined,
|
|
118
|
+
]
|
|
119
|
+
.filter(Boolean)
|
|
120
|
+
.join(' ');
|
|
121
|
+
if (parts)
|
|
122
|
+
lines.push(`**Location:** ${parts}`);
|
|
123
|
+
if (loc.latitude != null && loc.longitude != null) {
|
|
124
|
+
lines.push(`**Coords:** ${loc.latitude}, ${loc.longitude}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (a.endRoadwayLocation) {
|
|
128
|
+
const end = a.endRoadwayLocation;
|
|
129
|
+
const endParts = [
|
|
130
|
+
end.roadName,
|
|
131
|
+
end.direction,
|
|
132
|
+
end.milePost != null ? `MP ${end.milePost}` : undefined,
|
|
133
|
+
]
|
|
134
|
+
.filter(Boolean)
|
|
135
|
+
.join(' ');
|
|
136
|
+
if (endParts)
|
|
137
|
+
lines.push(`**End Location:** ${endParts}`);
|
|
138
|
+
if (end.latitude != null && end.longitude != null) {
|
|
139
|
+
lines.push(`**End Coords:** ${end.latitude}, ${end.longitude}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (a.extendedDescription)
|
|
143
|
+
lines.push(a.extendedDescription);
|
|
144
|
+
if (a.startTime)
|
|
145
|
+
lines.push(`**Start:** ${a.startTime}`);
|
|
146
|
+
if (a.endTime)
|
|
147
|
+
lines.push(`**End:** ${a.endTime}`);
|
|
148
|
+
if (a.lastUpdatedTime)
|
|
149
|
+
lines.push(`**Updated:** ${a.lastUpdatedTime}`);
|
|
150
|
+
lines.push('');
|
|
151
|
+
}
|
|
152
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=search-alerts.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-alerts.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-alerts.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool to search highway camera locations and metadata from the WSDOT Traffic API.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-cameras.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const searchCameras: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
stateRoute: z.ZodOptional<z.ZodString>;
|
|
9
|
+
region: z.ZodOptional<z.ZodString>;
|
|
10
|
+
startMilepost: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
endMilepost: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
13
|
+
cameras: z.ZodArray<z.ZodObject<{
|
|
14
|
+
cameraId: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
title: z.ZodOptional<z.ZodString>;
|
|
16
|
+
description: z.ZodOptional<z.ZodString>;
|
|
17
|
+
imageUrl: z.ZodOptional<z.ZodString>;
|
|
18
|
+
imageWidth: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
imageHeight: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
roadName: z.ZodOptional<z.ZodString>;
|
|
21
|
+
direction: z.ZodOptional<z.ZodString>;
|
|
22
|
+
milePost: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
region: z.ZodOptional<z.ZodString>;
|
|
24
|
+
latitude: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
longitude: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
totalCount: z.ZodNumber;
|
|
28
|
+
note: z.ZodOptional<z.ZodString>;
|
|
29
|
+
}, z.core.$strip>, readonly [{
|
|
30
|
+
readonly reason: "api_unavailable";
|
|
31
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
32
|
+
readonly when: "WSDOT Traffic API is unreachable or returns a non-2xx response after retries.";
|
|
33
|
+
readonly retryable: true;
|
|
34
|
+
readonly recovery: "Retry in 30 seconds. If the issue persists, check wsdot.wa.gov for service status.";
|
|
35
|
+
}]>;
|
|
36
|
+
//# sourceMappingURL=search-cameras.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-cameras.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-cameras.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsHxB,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool to search highway camera locations and metadata from the WSDOT Traffic API.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-cameras.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getTrafficApiService } from '../../../services/traffic/traffic-service.js';
|
|
8
|
+
const MAX_INLINE_CAMERAS = 20;
|
|
9
|
+
export const searchCameras = tool('wsdot_search_cameras', {
|
|
10
|
+
title: 'Search Highway Cameras',
|
|
11
|
+
description: 'Returns WSDOT highway camera locations, descriptions, and image URLs. ' +
|
|
12
|
+
'Camera images are copyright WSDOT — only metadata and image URLs are returned, not image bytes. ' +
|
|
13
|
+
'Filter by state route (e.g. "090" for I-90), WSDOT region, or milepost range. ' +
|
|
14
|
+
'Omit all filters to list all cameras statewide (potentially hundreds).',
|
|
15
|
+
annotations: { readOnlyHint: true },
|
|
16
|
+
input: z.object({
|
|
17
|
+
stateRoute: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe('Zero-padded 3-digit state route number (e.g. "005" for I-5, "090" for I-90).'),
|
|
21
|
+
region: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('WSDOT region name: Northwest, Olympic, Southwest, South Central, North Central, or Eastern.'),
|
|
25
|
+
startMilepost: z.number().optional().describe('Start of milepost range to filter cameras.'),
|
|
26
|
+
endMilepost: z.number().optional().describe('End of milepost range to filter cameras.'),
|
|
27
|
+
}),
|
|
28
|
+
output: z.object({
|
|
29
|
+
cameras: z
|
|
30
|
+
.array(z
|
|
31
|
+
.object({
|
|
32
|
+
cameraId: z.number().optional().describe('Unique camera identifier.'),
|
|
33
|
+
title: z.string().optional().describe('Camera title or location description.'),
|
|
34
|
+
description: z.string().optional().describe('Additional description.'),
|
|
35
|
+
imageUrl: z
|
|
36
|
+
.string()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('URL of the WSDOT-hosted camera image (JPEG). WSDOT copyright applies.'),
|
|
39
|
+
imageWidth: z.number().optional().describe('Image width in pixels.'),
|
|
40
|
+
imageHeight: z.number().optional().describe('Image height in pixels.'),
|
|
41
|
+
roadName: z.string().optional().describe('Road the camera monitors.'),
|
|
42
|
+
direction: z.string().optional().describe('Traffic direction monitored.'),
|
|
43
|
+
milePost: z.number().optional().describe('Milepost location of the camera.'),
|
|
44
|
+
region: z.string().optional().describe('WSDOT region.'),
|
|
45
|
+
latitude: z.number().optional().describe('Camera latitude.'),
|
|
46
|
+
longitude: z.number().optional().describe('Camera longitude.'),
|
|
47
|
+
})
|
|
48
|
+
.describe('Camera metadata and image URL for one WSDOT highway camera.'))
|
|
49
|
+
.describe('Camera metadata and image URLs. Images are copyright WSDOT.'),
|
|
50
|
+
totalCount: z.number().describe('Total number of cameras returned.'),
|
|
51
|
+
note: z
|
|
52
|
+
.string()
|
|
53
|
+
.optional()
|
|
54
|
+
.describe('Informational note about result truncation or copyright.'),
|
|
55
|
+
}),
|
|
56
|
+
errors: [
|
|
57
|
+
{
|
|
58
|
+
reason: 'api_unavailable',
|
|
59
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
60
|
+
when: 'WSDOT Traffic API is unreachable or returns a non-2xx response after retries.',
|
|
61
|
+
retryable: true,
|
|
62
|
+
recovery: 'Retry in 30 seconds. If the issue persists, check wsdot.wa.gov for service status.',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
async handler(input, ctx) {
|
|
66
|
+
const stateRoute = input.stateRoute?.trim() || undefined;
|
|
67
|
+
const region = input.region?.trim() || undefined;
|
|
68
|
+
const cameras = await getTrafficApiService().searchCameras({
|
|
69
|
+
...(stateRoute && { stateRoute }),
|
|
70
|
+
...(region && { region }),
|
|
71
|
+
...(input.startMilepost != null && { startMilepost: input.startMilepost }),
|
|
72
|
+
...(input.endMilepost != null && { endMilepost: input.endMilepost }),
|
|
73
|
+
}, ctx);
|
|
74
|
+
const note = cameras.length > MAX_INLINE_CAMERAS
|
|
75
|
+
? `Showing first ${MAX_INLINE_CAMERAS} of ${cameras.length} cameras. Add filters (stateRoute, region, or mileposts) to narrow results. Camera images are copyright WSDOT.`
|
|
76
|
+
: 'Camera images are copyright WSDOT. Follow image URLs to view live feeds.';
|
|
77
|
+
ctx.log.info('Cameras fetched', { count: cameras.length });
|
|
78
|
+
return { cameras, totalCount: cameras.length, note };
|
|
79
|
+
},
|
|
80
|
+
format: (result) => {
|
|
81
|
+
const lines = [];
|
|
82
|
+
if (result.note)
|
|
83
|
+
lines.push(`> ${result.note}\n`);
|
|
84
|
+
lines.push(`## Highway Cameras (${result.totalCount} total)\n`);
|
|
85
|
+
const display = result.cameras.slice(0, MAX_INLINE_CAMERAS);
|
|
86
|
+
for (const c of display) {
|
|
87
|
+
lines.push(`### ${c.title ?? `Camera ${c.cameraId ?? ''}`}`);
|
|
88
|
+
if (c.description)
|
|
89
|
+
lines.push(c.description);
|
|
90
|
+
if (c.roadName) {
|
|
91
|
+
const loc = [c.roadName, c.direction, c.milePost != null ? `MP ${c.milePost}` : undefined]
|
|
92
|
+
.filter(Boolean)
|
|
93
|
+
.join(' ');
|
|
94
|
+
lines.push(`**Location:** ${loc}`);
|
|
95
|
+
}
|
|
96
|
+
if (c.region)
|
|
97
|
+
lines.push(`**Region:** ${c.region}`);
|
|
98
|
+
if (c.imageUrl)
|
|
99
|
+
lines.push(`**Image:** ${c.imageUrl}`);
|
|
100
|
+
if (c.imageWidth != null && c.imageHeight != null) {
|
|
101
|
+
lines.push(`**Size:** ${c.imageWidth}×${c.imageHeight}px`);
|
|
102
|
+
}
|
|
103
|
+
if (c.latitude != null && c.longitude != null) {
|
|
104
|
+
lines.push(`**Coords:** ${c.latitude}, ${c.longitude}`);
|
|
105
|
+
}
|
|
106
|
+
if (c.cameraId != null)
|
|
107
|
+
lines.push(`**ID:** ${c.cameraId}`);
|
|
108
|
+
lines.push('');
|
|
109
|
+
}
|
|
110
|
+
if (result.cameras.length > MAX_INLINE_CAMERAS) {
|
|
111
|
+
lines.push(`_... ${result.cameras.length - MAX_INLINE_CAMERAS} more cameras in structuredContent_`);
|
|
112
|
+
}
|
|
113
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=search-cameras.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-cameras.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-cameras.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview WSF (Washington State Ferries) API service — terminals, routes,
|
|
3
|
+
* schedules, vessel locations, terminal space, and alerts.
|
|
4
|
+
* @module services/ferry/ferry-service
|
|
5
|
+
*/
|
|
6
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import type { AppConfig } from '@cyanheads/mcp-ts-core/config';
|
|
8
|
+
import type { StorageService } from '@cyanheads/mcp-ts-core/storage';
|
|
9
|
+
import type { FerryAlert, FerryRoute, FerrySchedule, FerryTerminal, TerminalSailingSpace, VesselLocation } from './types.js';
|
|
10
|
+
export declare class FerryApiService {
|
|
11
|
+
constructor(_config: AppConfig, _storage: StorageService);
|
|
12
|
+
private accessCode;
|
|
13
|
+
private buildUrl;
|
|
14
|
+
private fetchJson;
|
|
15
|
+
/** Validate and normalize an ISO 8601 date string for use in ferry API paths. */
|
|
16
|
+
static toFerryDate(isoDate: string): string;
|
|
17
|
+
/** Return today's date in YYYY-MM-DD format. */
|
|
18
|
+
static todayFerryDate(): string;
|
|
19
|
+
getTerminals(ctx: Context): Promise<FerryTerminal[]>;
|
|
20
|
+
getRoutes(tripDate: string, ctx: Context): Promise<FerryRoute[]>;
|
|
21
|
+
getSchedule(departingTerminalId: number, arrivingTerminalId: number, tripDate: string, remainingOnly: boolean, ctx: Context): Promise<FerrySchedule>;
|
|
22
|
+
getVesselLocations(ctx: Context): Promise<VesselLocation[]>;
|
|
23
|
+
getTerminalSailingSpace(ctx: Context): Promise<TerminalSailingSpace[]>;
|
|
24
|
+
getAlerts(ctx: Context): Promise<FerryAlert[]>;
|
|
25
|
+
}
|
|
26
|
+
export declare function initFerryApiService(config: AppConfig, storage: StorageService): void;
|
|
27
|
+
export declare function getFerryApiService(): FerryApiService;
|
|
28
|
+
//# sourceMappingURL=ferry-service.d.ts.map
|