@squawk/mcp 0.12.1 → 0.13.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.
@@ -4,7 +4,7 @@
4
4
  * by the US NASR snapshot in `@squawk/navaid-data`.
5
5
  */
6
6
  import { z } from 'zod';
7
- import { navaidResolver } from '../resolvers.js';
7
+ import { getNavaidResolver } from '../resolvers.js';
8
8
  /** All {@link NavaidType} values, used for input validation. */
9
9
  const NAVAID_TYPE_VALUES = [
10
10
  'VOR',
@@ -19,8 +19,9 @@ const NAVAID_TYPE_VALUES = [
19
19
  'VOT',
20
20
  ];
21
21
  /**
22
- * Registers navaid lookup tools on the given MCP server. Uses the shared
23
- * {@link navaidResolver} built at module load time.
22
+ * Registers navaid lookup tools on the given MCP server. Each handler pulls
23
+ * the shared resolver from {@link getNavaidResolver}, which imports and
24
+ * indexes the bundled US NASR snapshot on the first invocation.
24
25
  *
25
26
  * @param server - The MCP server instance to register tools on.
26
27
  */
@@ -31,8 +32,9 @@ export function registerNavaidTools(server) {
31
32
  inputSchema: {
32
33
  ident: z.string().min(1).describe('Navaid identifier (case-insensitive).'),
33
34
  },
34
- }, ({ ident }) => {
35
- const navaids = navaidResolver.byIdent(ident);
35
+ }, async ({ ident }) => {
36
+ const resolver = await getNavaidResolver();
37
+ const navaids = resolver.byIdent(ident);
36
38
  return {
37
39
  content: [{ type: 'text', text: JSON.stringify(navaids, null, 2) }],
38
40
  structuredContent: { navaids },
@@ -59,8 +61,9 @@ export function registerNavaidTools(server) {
59
61
  .optional()
60
62
  .describe('Maximum great-circle distance in nautical miles. Omit to let the nearest match win regardless of distance.'),
61
63
  },
62
- }, ({ ident, lat, lon, toleranceNm }) => {
63
- const navaid = navaidResolver.byIdentAtPosition(ident, lat, lon, toleranceNm) ?? null;
64
+ }, async ({ ident, lat, lon, toleranceNm }) => {
65
+ const resolver = await getNavaidResolver();
66
+ const navaid = resolver.byIdentAtPosition(ident, lat, lon, toleranceNm) ?? null;
64
67
  return {
65
68
  content: [{ type: 'text', text: JSON.stringify(navaid, null, 2) }],
66
69
  structuredContent: { navaid },
@@ -85,7 +88,8 @@ export function registerNavaidTools(server) {
85
88
  .optional()
86
89
  .describe('Maximum number of results to return. Defaults to 20.'),
87
90
  },
88
- }, ({ frequency, navaidTypes, limit }) => {
91
+ }, async ({ frequency, navaidTypes, limit }) => {
92
+ const resolver = await getNavaidResolver();
89
93
  const query = { frequency };
90
94
  if (navaidTypes !== undefined) {
91
95
  query.types = new Set(navaidTypes);
@@ -93,7 +97,7 @@ export function registerNavaidTools(server) {
93
97
  if (limit !== undefined) {
94
98
  query.limit = limit;
95
99
  }
96
- const navaids = navaidResolver.byFrequency(query);
100
+ const navaids = resolver.byFrequency(query);
97
101
  return {
98
102
  content: [{ type: 'text', text: JSON.stringify(navaids, null, 2) }],
99
103
  structuredContent: { navaids },
@@ -121,7 +125,8 @@ export function registerNavaidTools(server) {
121
125
  .optional()
122
126
  .describe('Restrict results to these navaid types. Omit to include all types.'),
123
127
  },
124
- }, ({ lat, lon, maxDistanceNm, limit, navaidTypes }) => {
128
+ }, async ({ lat, lon, maxDistanceNm, limit, navaidTypes }) => {
129
+ const resolver = await getNavaidResolver();
125
130
  const query = { lat, lon };
126
131
  if (maxDistanceNm !== undefined) {
127
132
  query.maxDistanceNm = maxDistanceNm;
@@ -132,7 +137,7 @@ export function registerNavaidTools(server) {
132
137
  if (navaidTypes !== undefined) {
133
138
  query.types = new Set(navaidTypes);
134
139
  }
135
- const results = navaidResolver.nearest(query);
140
+ const results = resolver.nearest(query);
136
141
  return {
137
142
  content: [{ type: 'text', text: JSON.stringify(results, null, 2) }],
138
143
  structuredContent: { results },
@@ -163,7 +168,8 @@ export function registerNavaidTools(server) {
163
168
  .optional()
164
169
  .describe('Minimum match score (exclusive) in [0, 1] a result must reach. Defaults to 0. Raise it to drop weak fuzzy matches.'),
165
170
  },
166
- }, ({ text, navaidTypes, limit, minScore }) => {
171
+ }, async ({ text, navaidTypes, limit, minScore }) => {
172
+ const resolver = await getNavaidResolver();
167
173
  const query = { text };
168
174
  if (navaidTypes !== undefined) {
169
175
  query.types = new Set(navaidTypes);
@@ -174,7 +180,7 @@ export function registerNavaidTools(server) {
174
180
  if (minScore !== undefined) {
175
181
  query.minScore = minScore;
176
182
  }
177
- const navaids = navaidResolver.search(query);
183
+ const navaids = resolver.search(query);
178
184
  return {
179
185
  content: [{ type: 'text', text: JSON.stringify(navaids, null, 2) }],
180
186
  structuredContent: { navaids },
@@ -7,8 +7,9 @@
7
7
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
8
  /**
9
9
  * Registers procedure lookup tools (SIDs, STARs, and IAPs) on the given
10
- * MCP server. Uses the shared {@link procedureResolver} built at module
11
- * load time from the bundled FAA CIFP snapshot.
10
+ * MCP server. Each handler pulls the shared resolver from
11
+ * {@link getProcedureResolver}, which imports and indexes the bundled FAA
12
+ * CIFP snapshot on the first invocation.
12
13
  *
13
14
  * @param server - The MCP server instance to register tools on.
14
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../../src/tools/procedures.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiCzE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgQ9D"}
1
+ {"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../../src/tools/procedures.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiCzE;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwQ9D"}
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { z } from 'zod';
8
8
  import { expansionToLineString, extractLegPoints } from '@squawk/procedures';
9
- import { procedureResolver } from '../resolvers.js';
9
+ import { getProcedureResolver } from '../resolvers.js';
10
10
  /** All {@link ProcedureType} values, used for input validation. */
11
11
  const PROCEDURE_TYPE_VALUES = ['SID', 'STAR', 'IAP'];
12
12
  /** All {@link ApproachType} values, used for input validation. */
@@ -31,8 +31,9 @@ const APPROACH_TYPE_VALUES = [
31
31
  ];
32
32
  /**
33
33
  * Registers procedure lookup tools (SIDs, STARs, and IAPs) on the given
34
- * MCP server. Uses the shared {@link procedureResolver} built at module
35
- * load time from the bundled FAA CIFP snapshot.
34
+ * MCP server. Each handler pulls the shared resolver from
35
+ * {@link getProcedureResolver}, which imports and indexes the bundled FAA
36
+ * CIFP snapshot on the first invocation.
36
37
  *
37
38
  * @param server - The MCP server instance to register tools on.
38
39
  */
@@ -46,8 +47,9 @@ export function registerProcedureTools(server) {
46
47
  .min(1)
47
48
  .describe('CIFP procedure identifier (case-insensitive). Examples: "AALLE4", "NUBLE4", "I04L", "R13".'),
48
49
  },
49
- }, ({ identifier }) => {
50
- const procedures = procedureResolver.byIdentifier(identifier);
50
+ }, async ({ identifier }) => {
51
+ const resolver = await getProcedureResolver();
52
+ const procedures = resolver.byIdentifier(identifier);
51
53
  return {
52
54
  content: [{ type: 'text', text: JSON.stringify(procedures, null, 2) }],
53
55
  structuredContent: { procedures },
@@ -63,8 +65,9 @@ export function registerProcedureTools(server) {
63
65
  .describe('Airport identifier (ICAO or FAA, case-insensitive).'),
64
66
  identifier: z.string().min(1).describe('CIFP procedure identifier (case-insensitive).'),
65
67
  },
66
- }, ({ airportId, identifier }) => {
67
- const procedure = procedureResolver.byAirportAndIdentifier(airportId, identifier);
68
+ }, async ({ airportId, identifier }) => {
69
+ const resolver = await getProcedureResolver();
70
+ const procedure = resolver.byAirportAndIdentifier(airportId, identifier);
68
71
  if (procedure === undefined) {
69
72
  return {
70
73
  content: [
@@ -87,8 +90,9 @@ export function registerProcedureTools(server) {
87
90
  inputSchema: {
88
91
  airportId: z.string().min(1).describe('Airport identifier (case-insensitive).'),
89
92
  },
90
- }, ({ airportId }) => {
91
- const procedures = procedureResolver.byAirport(airportId);
93
+ }, async ({ airportId }) => {
94
+ const resolver = await getProcedureResolver();
95
+ const procedures = resolver.byAirport(airportId);
92
96
  return {
93
97
  content: [{ type: 'text', text: JSON.stringify(procedures, null, 2) }],
94
98
  structuredContent: { procedures },
@@ -104,8 +108,9 @@ export function registerProcedureTools(server) {
104
108
  .min(1)
105
109
  .describe('Runway identifier, without the "RW" prefix (e.g. "04L", "13", "27R").'),
106
110
  },
107
- }, ({ airportId, runway }) => {
108
- const procedures = procedureResolver.byAirportAndRunway(airportId, runway);
111
+ }, async ({ airportId, runway }) => {
112
+ const resolver = await getProcedureResolver();
113
+ const procedures = resolver.byAirportAndRunway(airportId, runway);
109
114
  return {
110
115
  content: [{ type: 'text', text: JSON.stringify(procedures, null, 2) }],
111
116
  structuredContent: { procedures },
@@ -119,8 +124,9 @@ export function registerProcedureTools(server) {
119
124
  .enum(APPROACH_TYPE_VALUES)
120
125
  .describe('Approach classification. Use LOC_BC for localizer back-course approaches.'),
121
126
  },
122
- }, ({ approachType }) => {
123
- const procedures = procedureResolver.byApproachType(approachType);
127
+ }, async ({ approachType }) => {
128
+ const resolver = await getProcedureResolver();
129
+ const procedures = resolver.byApproachType(approachType);
124
130
  return {
125
131
  content: [{ type: 'text', text: JSON.stringify(procedures, null, 2) }],
126
132
  structuredContent: { procedures },
@@ -138,8 +144,9 @@ export function registerProcedureTools(server) {
138
144
  .optional()
139
145
  .describe('Optional transition name. Omit to return just the common route.'),
140
146
  },
141
- }, ({ airportId, identifier, transitionName }) => {
142
- const expansion = procedureResolver.expand(airportId, identifier, transitionName);
147
+ }, async ({ airportId, identifier, transitionName }) => {
148
+ const resolver = await getProcedureResolver();
149
+ const expansion = resolver.expand(airportId, identifier, transitionName);
143
150
  if (expansion === undefined) {
144
151
  return {
145
152
  content: [
@@ -171,8 +178,9 @@ export function registerProcedureTools(server) {
171
178
  .optional()
172
179
  .describe('Optional transition name. Omit to use just the common route.'),
173
180
  },
174
- }, ({ airportId, identifier, transitionName }) => {
175
- const expansion = procedureResolver.expand(airportId, identifier, transitionName);
181
+ }, async ({ airportId, identifier, transitionName }) => {
182
+ const resolver = await getProcedureResolver();
183
+ const expansion = resolver.expand(airportId, identifier, transitionName);
176
184
  if (expansion === undefined) {
177
185
  return {
178
186
  content: [
@@ -221,7 +229,8 @@ export function registerProcedureTools(server) {
221
229
  .optional()
222
230
  .describe('Minimum match score (exclusive) in [0, 1] a result must reach. Defaults to 0. Raise it to drop weak fuzzy matches.'),
223
231
  },
224
- }, ({ text, procedureType, approachType, limit, minScore }) => {
232
+ }, async ({ text, procedureType, approachType, limit, minScore }) => {
233
+ const resolver = await getProcedureResolver();
225
234
  const query = { text };
226
235
  if (procedureType !== undefined) {
227
236
  query.type = procedureType;
@@ -235,7 +244,7 @@ export function registerProcedureTools(server) {
235
244
  if (minScore !== undefined) {
236
245
  query.minScore = minScore;
237
246
  }
238
- const procedures = procedureResolver.search(query);
247
+ const procedures = resolver.search(query);
239
248
  return {
240
249
  content: [{ type: 'text', text: JSON.stringify(procedures, null, 2) }],
241
250
  structuredContent: { procedures },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squawk/mcp",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "description": "Model Context Protocol server exposing squawk's aviation libraries as tools for LLM clients",
6
6
  "author": "Neil Cochran",
@@ -41,22 +41,22 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@modelcontextprotocol/sdk": "^1.30.0",
44
- "@squawk/airport-data": "^0.7.12",
44
+ "@squawk/airport-data": "^0.8.0",
45
45
  "@squawk/airports": "^0.7.1",
46
46
  "@squawk/airspace": "^0.9.1",
47
- "@squawk/airspace-data": "^0.5.2",
48
- "@squawk/airway-data": "^0.5.12",
47
+ "@squawk/airspace-data": "^0.6.0",
48
+ "@squawk/airway-data": "^0.6.0",
49
49
  "@squawk/airways": "^0.5.1",
50
- "@squawk/fix-data": "^0.6.12",
50
+ "@squawk/fix-data": "^0.7.0",
51
51
  "@squawk/fixes": "^0.5.1",
52
52
  "@squawk/flight-math": "^0.5.3",
53
53
  "@squawk/flightplan": "^0.6.1",
54
54
  "@squawk/geo": "^0.4.10",
55
55
  "@squawk/icao-registry": "^0.5.8",
56
- "@squawk/navaid-data": "^0.6.12",
56
+ "@squawk/navaid-data": "^0.7.0",
57
57
  "@squawk/navaids": "^0.6.1",
58
58
  "@squawk/notams": "^0.3.12",
59
- "@squawk/procedure-data": "^0.7.10",
59
+ "@squawk/procedure-data": "^0.8.0",
60
60
  "@squawk/procedures": "^0.7.1",
61
61
  "@squawk/types": "^0.9.0",
62
62
  "@squawk/weather": "^0.6.1",