@squawk/mcp 0.11.0 → 0.12.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/README.md CHANGED
@@ -98,7 +98,7 @@ version explicitly in the client config:
98
98
  "mcpServers": {
99
99
  "squawk": {
100
100
  "command": "npx",
101
- "args": ["-y", "@squawk/mcp@0.11.0"]
101
+ "args": ["-y", "@squawk/mcp@0.12.0"]
102
102
  }
103
103
  }
104
104
  }
@@ -164,7 +164,7 @@ Pinning works the same way:
164
164
  "mcpServers": {
165
165
  "squawk": {
166
166
  "command": "npx",
167
- "args": ["-y", "-p", "@squawk/icao-registry-data@0.8.10", "@squawk/mcp@0.11.0"]
167
+ "args": ["-y", "-p", "@squawk/icao-registry-data@0.8.12", "@squawk/mcp@0.12.0"]
168
168
  }
169
169
  }
170
170
  }
@@ -193,8 +193,8 @@ the absolute path to a modern node + the absolute path to the installed `bin.js`
193
193
  }
194
194
  ```
195
195
 
196
- The server logs `[squawk-mcp] node <version> on <platform>/<arch>` and the tool-module count
197
- to stderr on every startup so you can verify the right runtime is being used.
196
+ The server logs `[squawk-mcp] node <version> on <platform>/<arch>` and how many tool groups
197
+ registered to stderr on every startup so you can verify the right runtime is being used.
198
198
 
199
199
  ### Example prompts
200
200
 
@@ -226,6 +226,17 @@ const server = createSquawkMcpServer();
226
226
  await server.connect(new StdioServerTransport());
227
227
  ```
228
228
 
229
+ Pass `toolGroups` to register part of the catalog. An explicit list takes precedence over
230
+ the environment variables described under [Configuration](#configuration); omit the option
231
+ entirely to honor them. `TOOL_GROUP_NAMES` holds every valid group name, and an unknown one
232
+ throws a `ToolGroupConfigError`.
233
+
234
+ ```typescript
235
+ import { createSquawkMcpServer, TOOL_GROUP_NAMES } from '@squawk/mcp';
236
+
237
+ const server = createSquawkMcpServer({ toolGroups: ['airports', 'navaids', 'geo'] });
238
+ ```
239
+
229
240
  ## Tool catalog
230
241
 
231
242
  Tools are grouped by domain. Every tool returns both a human-readable text block and a structured
@@ -390,9 +401,74 @@ left to the model itself.
390
401
 
391
402
  ## Configuration
392
403
 
393
- | Environment variable | Effect |
394
- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
395
- | `SQUAWK_AWC_BASE_URL` | Override the Aviation Weather Center base URL used by every `fetch_*` tool. Defaults to `https://aviationweather.gov/api/data`. Useful for proxies and regional mirrors. |
404
+ | Environment variable | Effect |
405
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
406
+ | `SQUAWK_MCP_TOOLS` | Register only the named tool groups. See [Choosing which tools to register](#choosing-which-tools-to-register). |
407
+ | `SQUAWK_MCP_DISABLE_TOOLS` | Register every tool group except the named ones. Mutually exclusive with `SQUAWK_MCP_TOOLS`. |
408
+ | `SQUAWK_AWC_BASE_URL` | Override the Aviation Weather Center base URL used by every `fetch_*` tool. Defaults to `https://aviationweather.gov/api/data`. Useful for proxies and regional mirrors. |
409
+
410
+ ### Choosing which tools to register
411
+
412
+ The full catalog is 79 tools, which costs roughly 18k tokens of context in every session
413
+ before you ask anything. If you only reach for part of it, register only that part and the
414
+ rest never reaches your client.
415
+
416
+ Each tool group is one row below. Set `SQUAWK_MCP_TOOLS` to the groups you want, or
417
+ `SQUAWK_MCP_DISABLE_TOOLS` to the groups you do not. With neither set, every group is
418
+ registered.
419
+
420
+ | Group | Tools | ~Tokens |
421
+ | --------------- | ----: | ------: |
422
+ | `geo` | 5 | 1,100 |
423
+ | `flight-math` | 24 | 5,300 |
424
+ | `airports` | 4 | 900 |
425
+ | `airspace` | 5 | 1,700 |
426
+ | `navaids` | 5 | 1,300 |
427
+ | `fixes` | 4 | 1,000 |
428
+ | `airways` | 4 | 800 |
429
+ | `procedures` | 8 | 1,900 |
430
+ | `icao-registry` | 1 | 250 |
431
+ | `weather` | 12 | 2,100 |
432
+ | `notams` | 2 | 300 |
433
+ | `flightplan` | 4 | 1,400 |
434
+ | `datasets` | 1 | 180 |
435
+
436
+ A VFR pilot who wants airport, navaid, and fix lookups plus a distance calculator:
437
+
438
+ ```json
439
+ {
440
+ "mcpServers": {
441
+ "squawk": {
442
+ "command": "npx",
443
+ "args": ["-y", "@squawk/mcp"],
444
+ "env": { "SQUAWK_MCP_TOOLS": "airports,navaids,fixes,geo" }
445
+ }
446
+ }
447
+ }
448
+ ```
449
+
450
+ That registers 18 tools for roughly 4.3k tokens, down from 79 and 18k. Dropping just
451
+ `flight-math` and `weather` - the two largest groups - takes the catalog to 43 tools and
452
+ roughly 11k tokens while leaving every lookup tool in place.
453
+
454
+ Names are case-insensitive and whitespace around them is ignored. The server refuses to
455
+ start, with an explanation on stderr, when a group name is unrecognized, when both
456
+ variables are set, or when the result would leave it with no tools at all. Check your
457
+ host's MCP log if the server fails to come up after a config change; the startup
458
+ diagnostic also reports how many groups registered and names the ones that did not.
459
+
460
+ Two things worth knowing before you trim:
461
+
462
+ - **`datasets` is a group like any other.** It holds `get_dataset_status`, the tool that
463
+ reports which NASR and CIFP cycles the running server is serving. An allowlist that
464
+ leaves it out means you can no longer ask how current the data is, so include it unless
465
+ you are sure you do not want it. It is the cheapest group in the catalog.
466
+ - **Groups gate the catalog, not the data.** The bundled snapshots are loaded and indexed
467
+ at startup no matter which groups you register, so trimming the catalog does not reduce
468
+ the server's startup time or memory use. It also means a group you kept keeps working
469
+ even when it reads data belonging to a group you dropped - `flightplan` still resolves
470
+ airports and navaids in a route string with `airports` and `navaids` disabled, because
471
+ you disabled those tools, not that data.
396
472
 
397
473
  ## Notes
398
474
 
@@ -403,7 +479,7 @@ left to the model itself.
403
479
  - Live weather tools issue HTTPS requests to `https://aviationweather.gov/api/data/...` (or the
404
480
  override above). They are the only tools that touch the network at invocation time; everything
405
481
  else operates against bundled snapshots in memory.
406
- - The bundled snapshots are decompressed and indexed once when the server starts. Expect a few
407
- hundred milliseconds of startup time. The aircraft registration snapshot (the largest, and an
408
- optional peer dependency) is decompressed lazily on the first `lookup_aircraft_by_icao_hex` call,
409
- if the package is installed.
482
+ - The bundled snapshots are decompressed and indexed once when the server starts, which takes on
483
+ the order of a second and is unaffected by which tool groups you register. The aircraft
484
+ registration snapshot (the largest, and an optional peer dependency) is decompressed lazily on
485
+ the first `lookup_aircraft_by_icao_hex` call, if the package is installed.
package/dist/bin.js CHANGED
@@ -8,21 +8,31 @@
8
8
  * All logs go to stderr; stdout is reserved for MCP protocol messages.
9
9
  */
10
10
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
11
- import { createSquawkMcpServer, PACKAGE_NAME, PACKAGE_VERSION, TOOL_MODULE_COUNT, } from './server.js';
11
+ import { createSquawkMcpServer, PACKAGE_NAME, PACKAGE_VERSION } from './server.js';
12
+ import { TOOL_GROUP_NAMES, resolveToolGroupsFromEnv } from './tool-groups.js';
12
13
  /**
13
14
  * Logs the Node.js version this process is running on, the running build's
14
- * package version, the tool-module count, and warns when the environment is
15
- * missing capabilities the live weather fetch tools require.
15
+ * package version, which tool groups ended up registered, and warns when the
16
+ * environment is missing capabilities the live weather fetch tools require.
16
17
  *
17
18
  * GUI MCP hosts (Claude Desktop, etc.) often launch child processes with a
18
19
  * different PATH than the user's interactive shell, so `node` may resolve to
19
20
  * an older binary than `which node` suggests. Surfacing the actual runtime
20
21
  * version and the running package version up front makes mismatches easy to
21
- * diagnose from the host's MCP log without bisecting tool failures.
22
+ * diagnose from the host's MCP log without bisecting tool failures. Naming the
23
+ * disabled groups does the same for a mistyped tool-group variable, which
24
+ * otherwise shows up only as tools the model never calls.
25
+ *
26
+ * @param enabledGroups - Tool groups the server is about to register.
22
27
  */
23
- function logRuntimeDiagnostics() {
28
+ function logRuntimeDiagnostics(enabledGroups) {
24
29
  console.error(`[squawk-mcp] node ${process.version} on ${process.platform}/${process.arch}`);
25
- console.error(`[squawk-mcp] ${PACKAGE_NAME} v${PACKAGE_VERSION}, ${TOOL_MODULE_COUNT} tool modules registered`);
30
+ console.error(`[squawk-mcp] ${PACKAGE_NAME} v${PACKAGE_VERSION}, ` +
31
+ `${enabledGroups.length}/${TOOL_GROUP_NAMES.length} tool groups registered`);
32
+ const disabled = TOOL_GROUP_NAMES.filter((name) => !enabledGroups.includes(name));
33
+ if (disabled.length > 0) {
34
+ console.error(`[squawk-mcp] disabled tool groups: ${disabled.join(', ')}`);
35
+ }
26
36
  if (typeof fetch !== 'function') {
27
37
  console.error('[squawk-mcp] WARNING: global fetch() is unavailable in this Node runtime. ' +
28
38
  'Live weather fetch_* tools will fail. Upgrade to Node >=22, or pin an ' +
@@ -30,12 +40,19 @@ function logRuntimeDiagnostics() {
30
40
  }
31
41
  }
32
42
  async function main() {
33
- logRuntimeDiagnostics();
34
- const server = createSquawkMcpServer();
43
+ const resolution = resolveToolGroupsFromEnv(process.env);
44
+ if (!resolution.ok) {
45
+ console.error(`[squawk-mcp] configuration error: ${resolution.error}`);
46
+ // eslint-disable-next-line n/no-process-exit -- serving a catalog the user did not ask for is worse than refusing to start; the host surfaces this line in its MCP log.
47
+ process.exit(1);
48
+ }
49
+ logRuntimeDiagnostics(resolution.toolGroups);
50
+ const server = createSquawkMcpServer({ toolGroups: resolution.toolGroups });
35
51
  const transport = new StdioServerTransport();
36
52
  await server.connect(transport);
37
53
  }
38
54
  main().catch((err) => {
39
55
  console.error('[squawk-mcp] fatal error:', err);
56
+ // eslint-disable-next-line n/no-process-exit -- a failed stdio connect can leave the transport holding stdin; exiting beats hanging the host that spawned us.
40
57
  process.exit(1);
41
58
  });
package/dist/index.d.ts CHANGED
@@ -19,6 +19,15 @@
19
19
  * const server = createSquawkMcpServer();
20
20
  * await server.connect(new StdioServerTransport());
21
21
  * ```
22
+ *
23
+ * Pass `toolGroups` to register only part of the catalog:
24
+ *
25
+ * ```typescript
26
+ * const server = createSquawkMcpServer({ toolGroups: ['airports', 'navaids', 'geo'] });
27
+ * ```
22
28
  */
23
29
  export { createSquawkMcpServer } from './server.js';
30
+ export { TOOL_GROUP_NAMES, ToolGroupConfigError } from './tool-groups.js';
31
+ export type { CreateSquawkMcpServerOptions } from './server.js';
32
+ export type { ToolGroupName } from './tool-groups.js';
24
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,YAAY,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -19,5 +19,12 @@
19
19
  * const server = createSquawkMcpServer();
20
20
  * await server.connect(new StdioServerTransport());
21
21
  * ```
22
+ *
23
+ * Pass `toolGroups` to register only part of the catalog:
24
+ *
25
+ * ```typescript
26
+ * const server = createSquawkMcpServer({ toolGroups: ['airports', 'navaids', 'geo'] });
27
+ * ```
22
28
  */
23
29
  export { createSquawkMcpServer } from './server.js';
30
+ export { TOOL_GROUP_NAMES, ToolGroupConfigError } from './tool-groups.js';
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../src/resolvers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGjF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAErF,qEAAqE;AACrE,eAAO,MAAM,eAAe,EAAE,eAE5B,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,gBAAgB,EAAE,gBAE7B,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,cAAc,EAAE,cAE3B,CAAC;AAEH,iEAAiE;AACjE,eAAO,MAAM,WAAW,EAAE,WAAiE,CAAC;AAE5F,oEAAoE;AACpE,eAAO,MAAM,cAAc,EAAE,cAE3B,CAAC;AAEH,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,EAAE,iBAE9B,CAAC;AAEH;;;;;GAKG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC;;;;;OAKG;gBACS,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAQrD;AAoBD,2EAA2E;AAC3E,KAAK,sBAAsB,GAAG,MAAM,OAAO,CAAC,cAAc,4BAA4B,CAAC,CAAC,CAAC;AA2BzF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAuB7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,sBAAsB,GAAG,SAAS,GACzC,IAAI,CAKN;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IACnC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC5C,SAAS,CAEZ"}
1
+ {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../src/resolvers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGjF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAErF,qEAAqE;AACrE,eAAO,MAAM,eAAe,EAAE,eAE5B,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,gBAAgB,EAAE,gBAE7B,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,cAAc,EAAE,cAE3B,CAAC;AAEH,iEAAiE;AACjE,eAAO,MAAM,WAAW,EAAE,WAAiE,CAAC;AAE5F,oEAAoE;AACpE,eAAO,MAAM,cAAc,EAAE,cAE3B,CAAC;AAEH,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,EAAE,iBAE9B,CAAC;AAEH;;;;;GAKG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC;;;;;OAKG;gBACS,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAQrD;AAoBD,2EAA2E;AAC3E,KAAK,sBAAsB,GAAG,MAAM,OAAO,CAAC,cAAc,4BAA4B,CAAC,CAAC,CAAC;AA2BzF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAuB7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,sBAAsB,GAAG,SAAS,GACzC,IAAI,CAKN;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IACrC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAEzD"}
package/dist/server.d.ts CHANGED
@@ -1,15 +1,22 @@
1
1
  /**
2
2
  * @packageDocumentation
3
- * Server factory for @squawk/mcp. Assembles an {@link McpServer} preloaded
4
- * with every squawk aviation tool module.
3
+ * Server factory for @squawk/mcp. Assembles an {@link McpServer} carrying the
4
+ * squawk aviation tool modules the caller asked for, defaulting to all of them.
5
5
  */
6
6
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
+ import { type ToolGroupName } from './tool-groups.js';
7
8
  /**
8
- * Number of tool modules registered by {@link createSquawkMcpServer}. Exposed
9
- * so the stdio entrypoint can include the count in its startup diagnostic
10
- * without re-counting at runtime.
9
+ * Options accepted by {@link createSquawkMcpServer}.
11
10
  */
12
- export declare const TOOL_MODULE_COUNT: number;
11
+ export interface CreateSquawkMcpServerOptions {
12
+ /**
13
+ * Tool groups to register. Omit to resolve the set from the
14
+ * `SQUAWK_MCP_TOOLS` / `SQUAWK_MCP_DISABLE_TOOLS` environment variables,
15
+ * which default to every group. Order is ignored; groups always register in
16
+ * `TOOL_GROUP_NAMES` order.
17
+ */
18
+ readonly toolGroups?: readonly ToolGroupName[];
19
+ }
13
20
  /**
14
21
  * Package name as published to npm. Convenient for diagnostic logs that want
15
22
  * to identify the running server without re-reading `package.json`.
@@ -21,7 +28,14 @@ export declare const PACKAGE_NAME: string;
21
28
  */
22
29
  export declare const PACKAGE_VERSION: string;
23
30
  /**
24
- * Creates an MCP server preloaded with every squawk aviation tool module.
31
+ * Creates an MCP server carrying the requested squawk aviation tool groups,
32
+ * defaulting to all of them.
33
+ *
34
+ * Disabling a group keeps its tools out of the catalog the LLM client sees,
35
+ * which is the point: the full catalog is roughly 18k tokens of context on
36
+ * every session. It does not reduce the server's startup time or memory
37
+ * footprint - the bundled snapshots are imported and indexed at module load
38
+ * regardless of which groups register.
25
39
  *
26
40
  * Tool registration triggers eager construction of the shared resolver
27
41
  * singletons in `./resolvers.js` for every domain except the ICAO aircraft
@@ -33,13 +47,17 @@ export declare const PACKAGE_VERSION: string;
33
47
  * import { createSquawkMcpServer } from '@squawk/mcp';
34
48
  * import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
35
49
  *
36
- * const server = createSquawkMcpServer();
50
+ * const server = createSquawkMcpServer({ toolGroups: ['airports', 'geo'] });
37
51
  * await server.connect(new StdioServerTransport());
38
52
  * ```
39
53
  *
54
+ * @param options - Server options. Omit to honor the environment variables.
40
55
  * @returns A fully configured MCP server instance. Connect it to a transport
41
56
  * (typically `StdioServerTransport` for CLI use) via
42
57
  * `server.connect(transport)` to begin handling protocol messages.
58
+ * @throws {ToolGroupConfigError} when `options.toolGroups` names an unknown
59
+ * group or is empty, or when the environment variables cannot be
60
+ * honored (both set at once, unknown names, or nothing left enabled).
43
61
  */
44
- export declare function createSquawkMcpServer(): McpServer;
62
+ export declare function createSquawkMcpServer(options?: CreateSquawkMcpServerOptions): McpServer;
45
63
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2CpE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAsC,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAyB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAA4B,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,IAAI,SAAS,CAWjD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AA0C1B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAChD;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAyB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAA4B,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAsBvF"}
package/dist/server.js CHANGED
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * @packageDocumentation
3
- * Server factory for @squawk/mcp. Assembles an {@link McpServer} preloaded
4
- * with every squawk aviation tool module.
3
+ * Server factory for @squawk/mcp. Assembles an {@link McpServer} carrying the
4
+ * squawk aviation tool modules the caller asked for, defaulting to all of them.
5
5
  */
6
6
  import { readFileSync } from 'node:fs';
7
7
  import { dirname, resolve } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10
+ import { ToolGroupConfigError, normalizeToolGroups, resolveToolGroupsFromEnv, } from './tool-groups.js';
10
11
  import { registerAirportTools } from './tools/airports.js';
11
12
  import { registerAirspaceTools } from './tools/airspace.js';
12
13
  import { registerAirwayTools } from './tools/airways.js';
@@ -23,32 +24,26 @@ import { registerWeatherTools } from './tools/weather.js';
23
24
  const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), '../package.json');
24
25
  const packageMeta = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
25
26
  /**
26
- * Ordered list of tool-module registrars invoked during server construction.
27
- * Holding them in a single array keeps {@link createSquawkMcpServer} symmetric
28
- * across modules and lets {@link TOOL_MODULE_COUNT} stay accurate without
29
- * manual bookkeeping.
27
+ * Registrar for each toggleable tool group. Keying by {@link ToolGroupName}
28
+ * makes the mapping exhaustive: adding a name to `TOOL_GROUP_NAMES` without
29
+ * wiring its registrar here is a compile error, so the group list and the
30
+ * modules it toggles cannot drift apart.
30
31
  */
31
- const TOOL_MODULE_REGISTRARS = [
32
- registerGeoTools,
33
- registerFlightMathTools,
34
- registerAirportTools,
35
- registerAirspaceTools,
36
- registerNavaidTools,
37
- registerFixTools,
38
- registerAirwayTools,
39
- registerProcedureTools,
40
- registerIcaoRegistryTools,
41
- registerWeatherTools,
42
- registerNotamTools,
43
- registerFlightplanTools,
44
- registerDatasetTools,
45
- ];
46
- /**
47
- * Number of tool modules registered by {@link createSquawkMcpServer}. Exposed
48
- * so the stdio entrypoint can include the count in its startup diagnostic
49
- * without re-counting at runtime.
50
- */
51
- export const TOOL_MODULE_COUNT = TOOL_MODULE_REGISTRARS.length;
32
+ const TOOL_GROUP_REGISTRARS = {
33
+ geo: registerGeoTools,
34
+ 'flight-math': registerFlightMathTools,
35
+ airports: registerAirportTools,
36
+ airspace: registerAirspaceTools,
37
+ navaids: registerNavaidTools,
38
+ fixes: registerFixTools,
39
+ airways: registerAirwayTools,
40
+ procedures: registerProcedureTools,
41
+ 'icao-registry': registerIcaoRegistryTools,
42
+ weather: registerWeatherTools,
43
+ notams: registerNotamTools,
44
+ flightplan: registerFlightplanTools,
45
+ datasets: registerDatasetTools,
46
+ };
52
47
  /**
53
48
  * Package name as published to npm. Convenient for diagnostic logs that want
54
49
  * to identify the running server without re-reading `package.json`.
@@ -60,7 +55,14 @@ export const PACKAGE_NAME = packageMeta.name;
60
55
  */
61
56
  export const PACKAGE_VERSION = packageMeta.version;
62
57
  /**
63
- * Creates an MCP server preloaded with every squawk aviation tool module.
58
+ * Creates an MCP server carrying the requested squawk aviation tool groups,
59
+ * defaulting to all of them.
60
+ *
61
+ * Disabling a group keeps its tools out of the catalog the LLM client sees,
62
+ * which is the point: the full catalog is roughly 18k tokens of context on
63
+ * every session. It does not reduce the server's startup time or memory
64
+ * footprint - the bundled snapshots are imported and indexed at module load
65
+ * regardless of which groups register.
64
66
  *
65
67
  * Tool registration triggers eager construction of the shared resolver
66
68
  * singletons in `./resolvers.js` for every domain except the ICAO aircraft
@@ -72,21 +74,36 @@ export const PACKAGE_VERSION = packageMeta.version;
72
74
  * import { createSquawkMcpServer } from '@squawk/mcp';
73
75
  * import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
74
76
  *
75
- * const server = createSquawkMcpServer();
77
+ * const server = createSquawkMcpServer({ toolGroups: ['airports', 'geo'] });
76
78
  * await server.connect(new StdioServerTransport());
77
79
  * ```
78
80
  *
81
+ * @param options - Server options. Omit to honor the environment variables.
79
82
  * @returns A fully configured MCP server instance. Connect it to a transport
80
83
  * (typically `StdioServerTransport` for CLI use) via
81
84
  * `server.connect(transport)` to begin handling protocol messages.
85
+ * @throws {ToolGroupConfigError} when `options.toolGroups` names an unknown
86
+ * group or is empty, or when the environment variables cannot be
87
+ * honored (both set at once, unknown names, or nothing left enabled).
82
88
  */
83
- export function createSquawkMcpServer() {
89
+ export function createSquawkMcpServer(options) {
84
90
  const server = new McpServer({
85
91
  name: PACKAGE_NAME,
86
92
  version: PACKAGE_VERSION,
87
93
  });
88
- for (const register of TOOL_MODULE_REGISTRARS) {
89
- register(server);
94
+ let enabledGroups;
95
+ if (options?.toolGroups === undefined) {
96
+ const resolution = resolveToolGroupsFromEnv(process.env);
97
+ if (!resolution.ok) {
98
+ throw new ToolGroupConfigError(resolution.error);
99
+ }
100
+ enabledGroups = resolution.toolGroups;
101
+ }
102
+ else {
103
+ enabledGroups = normalizeToolGroups(options.toolGroups);
104
+ }
105
+ for (const group of enabledGroups) {
106
+ TOOL_GROUP_REGISTRARS[group](server);
90
107
  }
91
108
  return server;
92
109
  }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Tool-group identity and configuration parsing for @squawk/mcp. Every domain
4
+ * module under `src/tools/` is one toggleable group, so a client that only
5
+ * needs part of the catalog can keep the rest out of its context window.
6
+ *
7
+ * This module owns the canonical group-name list and turns the server's
8
+ * environment variables into the concrete set of groups to register.
9
+ */
10
+ /**
11
+ * Every toggleable tool group, in the order they are registered on the
12
+ * server. Each name matches exactly one domain module filename under
13
+ * `src/tools/`, so `airports` maps to `src/tools/airports.ts`.
14
+ */
15
+ export declare const TOOL_GROUP_NAMES: readonly ["geo", "flight-math", "airports", "airspace", "navaids", "fixes", "airways", "procedures", "icao-registry", "weather", "notams", "flightplan", "datasets"];
16
+ /** Name of a single toggleable tool group. */
17
+ export type ToolGroupName = (typeof TOOL_GROUP_NAMES)[number];
18
+ /**
19
+ * Environment variable naming the only tool groups to register. Acts as an
20
+ * allowlist: groups absent from the list are not registered, including groups
21
+ * added by future releases.
22
+ */
23
+ export declare const TOOL_ALLOWLIST_ENV_VAR = "SQUAWK_MCP_TOOLS";
24
+ /**
25
+ * Environment variable naming tool groups to skip. Acts as a denylist: every
26
+ * group not listed is registered, including groups added by future releases.
27
+ */
28
+ export declare const TOOL_DENYLIST_ENV_VAR = "SQUAWK_MCP_DISABLE_TOOLS";
29
+ /**
30
+ * Successful resolution of the tool-group configuration.
31
+ */
32
+ export interface ToolGroupResolutionSuccess {
33
+ /** Discriminant marking a successful resolution. */
34
+ readonly ok: true;
35
+ /** Groups to register, in {@link TOOL_GROUP_NAMES} order. Never empty. */
36
+ readonly toolGroups: readonly ToolGroupName[];
37
+ }
38
+ /**
39
+ * Failed resolution of the tool-group configuration, carrying a message ready
40
+ * to print for the user.
41
+ */
42
+ export interface ToolGroupResolutionFailure {
43
+ /** Discriminant marking a failed resolution. */
44
+ readonly ok: false;
45
+ /** Human-readable explanation naming the offending value and the fix. */
46
+ readonly error: string;
47
+ }
48
+ /** Outcome of resolving the tool-group environment variables. */
49
+ export type ToolGroupResolution = ToolGroupResolutionSuccess | ToolGroupResolutionFailure;
50
+ /**
51
+ * Error thrown by `createSquawkMcpServer` when the tool-group configuration
52
+ * cannot be honored. A server has no partial-success shape to return - an
53
+ * unusable catalog is worse than a failed start, particularly for aviation
54
+ * data - so the factory throws rather than silently registering the wrong
55
+ * tools.
56
+ */
57
+ export declare class ToolGroupConfigError extends Error {
58
+ /**
59
+ * Constructs a new configuration error.
60
+ *
61
+ * @param message - Human-readable explanation naming the offending value.
62
+ */
63
+ constructor(message: string);
64
+ }
65
+ /**
66
+ * Resolves which tool groups to register from the process environment.
67
+ *
68
+ * With neither variable set, every group is enabled, matching the behavior of
69
+ * a server that predates this configuration. {@link TOOL_ALLOWLIST_ENV_VAR}
70
+ * and {@link TOOL_DENYLIST_ENV_VAR} are mutually exclusive: setting both is an
71
+ * error rather than a precedence rule, so the resolved catalog is always
72
+ * readable straight off the configuration.
73
+ *
74
+ * ```typescript
75
+ * const resolution = resolveToolGroupsFromEnv({ SQUAWK_MCP_TOOLS: 'airports,geo' });
76
+ * if (resolution.ok) {
77
+ * console.log(resolution.toolGroups); // ['geo', 'airports']
78
+ * }
79
+ * ```
80
+ *
81
+ * @param env - Environment to read, normally `process.env`.
82
+ * @returns The resolved groups, or a failure carrying a printable message.
83
+ */
84
+ export declare function resolveToolGroupsFromEnv(env: Record<string, string | undefined>): ToolGroupResolution;
85
+ /**
86
+ * Validates an explicitly supplied group list and returns it in registration
87
+ * order. Unlike {@link resolveToolGroupsFromEnv}, a bad value here is a
88
+ * programmer error rather than user misconfiguration, so it throws.
89
+ *
90
+ * @param toolGroups - Group names supplied by the caller.
91
+ * @returns The distinct groups in {@link TOOL_GROUP_NAMES} order.
92
+ * @throws {ToolGroupConfigError} when a name is unknown or the list is empty.
93
+ */
94
+ export declare function normalizeToolGroups(toolGroups: readonly ToolGroupName[]): readonly ToolGroupName[];
95
+ //# sourceMappingURL=tool-groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-groups.d.ts","sourceRoot":"","sources":["../src/tool-groups.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,sKAcnB,CAAC;AAEX,8CAA8C;AAC9C,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,oDAAoD;IACpD,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;CAC/C;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,iEAAiE;AACjE,MAAM,MAAM,mBAAmB,GAAG,0BAA0B,GAAG,0BAA0B,CAAC;AAE1F;;;;;;GAMG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAI5B;AAsED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,mBAAmB,CAuCrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,SAAS,aAAa,EAAE,GACnC,SAAS,aAAa,EAAE,CAU1B"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Tool-group identity and configuration parsing for @squawk/mcp. Every domain
4
+ * module under `src/tools/` is one toggleable group, so a client that only
5
+ * needs part of the catalog can keep the rest out of its context window.
6
+ *
7
+ * This module owns the canonical group-name list and turns the server's
8
+ * environment variables into the concrete set of groups to register.
9
+ */
10
+ /**
11
+ * Every toggleable tool group, in the order they are registered on the
12
+ * server. Each name matches exactly one domain module filename under
13
+ * `src/tools/`, so `airports` maps to `src/tools/airports.ts`.
14
+ */
15
+ export const TOOL_GROUP_NAMES = [
16
+ 'geo',
17
+ 'flight-math',
18
+ 'airports',
19
+ 'airspace',
20
+ 'navaids',
21
+ 'fixes',
22
+ 'airways',
23
+ 'procedures',
24
+ 'icao-registry',
25
+ 'weather',
26
+ 'notams',
27
+ 'flightplan',
28
+ 'datasets',
29
+ ];
30
+ /**
31
+ * Environment variable naming the only tool groups to register. Acts as an
32
+ * allowlist: groups absent from the list are not registered, including groups
33
+ * added by future releases.
34
+ */
35
+ export const TOOL_ALLOWLIST_ENV_VAR = 'SQUAWK_MCP_TOOLS';
36
+ /**
37
+ * Environment variable naming tool groups to skip. Acts as a denylist: every
38
+ * group not listed is registered, including groups added by future releases.
39
+ */
40
+ export const TOOL_DENYLIST_ENV_VAR = 'SQUAWK_MCP_DISABLE_TOOLS';
41
+ /**
42
+ * Error thrown by `createSquawkMcpServer` when the tool-group configuration
43
+ * cannot be honored. A server has no partial-success shape to return - an
44
+ * unusable catalog is worse than a failed start, particularly for aviation
45
+ * data - so the factory throws rather than silently registering the wrong
46
+ * tools.
47
+ */
48
+ export class ToolGroupConfigError extends Error {
49
+ /**
50
+ * Constructs a new configuration error.
51
+ *
52
+ * @param message - Human-readable explanation naming the offending value.
53
+ */
54
+ constructor(message) {
55
+ super(message);
56
+ this.name = 'ToolGroupConfigError';
57
+ }
58
+ }
59
+ /** Comma-separated list of every valid group name, for error messages. */
60
+ const VALID_GROUPS_SUFFIX = `Valid groups: ${TOOL_GROUP_NAMES.join(', ')}.`;
61
+ /**
62
+ * Returns `true` when an environment variable carries no usable value. Hosts
63
+ * routinely pass empty strings for unset entries, so a blank value means
64
+ * "not configured" rather than "configured to nothing".
65
+ *
66
+ * @param value - Raw environment variable value.
67
+ * @returns `true` when the value is absent or whitespace-only.
68
+ */
69
+ function isBlank(value) {
70
+ return value === undefined || value.trim() === '';
71
+ }
72
+ /**
73
+ * Narrows an arbitrary string to a {@link ToolGroupName}.
74
+ *
75
+ * @param value - Candidate group name, already trimmed and lowercased.
76
+ * @returns `true` when the value names a known group.
77
+ */
78
+ function isToolGroupName(value) {
79
+ return TOOL_GROUP_NAMES.some((name) => name === value);
80
+ }
81
+ /**
82
+ * Splits a comma-separated group list into normalized, deduplicated tokens.
83
+ * Tokens are trimmed and lowercased so `Airports, WEATHER` resolves the same
84
+ * way as `airports,weather`.
85
+ *
86
+ * @param value - Raw environment variable value.
87
+ * @returns The distinct tokens, in the order they first appeared.
88
+ */
89
+ function parseGroupList(value) {
90
+ const tokens = value
91
+ .split(',')
92
+ .map((token) => token.trim().toLowerCase())
93
+ .filter((token) => token !== '');
94
+ return [...new Set(tokens)];
95
+ }
96
+ /**
97
+ * Validates parsed tokens against {@link TOOL_GROUP_NAMES}.
98
+ *
99
+ * @param tokens - Normalized tokens from {@link parseGroupList}.
100
+ * @param envVar - Variable the tokens came from, named in the error message.
101
+ * @returns The validated group names, or a failure describing the bad tokens.
102
+ */
103
+ function validateGroupList(tokens, envVar) {
104
+ if (tokens.length === 0) {
105
+ return {
106
+ ok: false,
107
+ error: `${envVar} names no tool groups. Remove it to use the default, or list at least one group. ${VALID_GROUPS_SUFFIX}`,
108
+ };
109
+ }
110
+ const unknown = tokens.filter((token) => !isToolGroupName(token));
111
+ if (unknown.length > 0) {
112
+ return {
113
+ ok: false,
114
+ error: `${envVar} names unknown tool ${unknown.length === 1 ? 'group' : 'groups'}: ${unknown.join(', ')}. ${VALID_GROUPS_SUFFIX}`,
115
+ };
116
+ }
117
+ return { ok: true, groups: tokens.filter(isToolGroupName) };
118
+ }
119
+ /**
120
+ * Resolves which tool groups to register from the process environment.
121
+ *
122
+ * With neither variable set, every group is enabled, matching the behavior of
123
+ * a server that predates this configuration. {@link TOOL_ALLOWLIST_ENV_VAR}
124
+ * and {@link TOOL_DENYLIST_ENV_VAR} are mutually exclusive: setting both is an
125
+ * error rather than a precedence rule, so the resolved catalog is always
126
+ * readable straight off the configuration.
127
+ *
128
+ * ```typescript
129
+ * const resolution = resolveToolGroupsFromEnv({ SQUAWK_MCP_TOOLS: 'airports,geo' });
130
+ * if (resolution.ok) {
131
+ * console.log(resolution.toolGroups); // ['geo', 'airports']
132
+ * }
133
+ * ```
134
+ *
135
+ * @param env - Environment to read, normally `process.env`.
136
+ * @returns The resolved groups, or a failure carrying a printable message.
137
+ */
138
+ export function resolveToolGroupsFromEnv(env) {
139
+ const rawAllowlist = env[TOOL_ALLOWLIST_ENV_VAR];
140
+ const rawDenylist = env[TOOL_DENYLIST_ENV_VAR];
141
+ const hasAllowlist = !isBlank(rawAllowlist);
142
+ const hasDenylist = !isBlank(rawDenylist);
143
+ if (hasAllowlist && hasDenylist) {
144
+ return {
145
+ ok: false,
146
+ error: `${TOOL_ALLOWLIST_ENV_VAR} and ${TOOL_DENYLIST_ENV_VAR} are mutually exclusive. Set one or the other, not both.`,
147
+ };
148
+ }
149
+ if (hasAllowlist && rawAllowlist !== undefined) {
150
+ const validated = validateGroupList(parseGroupList(rawAllowlist), TOOL_ALLOWLIST_ENV_VAR);
151
+ if (!validated.ok) {
152
+ return validated;
153
+ }
154
+ const allowed = new Set(validated.groups);
155
+ return { ok: true, toolGroups: TOOL_GROUP_NAMES.filter((name) => allowed.has(name)) };
156
+ }
157
+ if (hasDenylist && rawDenylist !== undefined) {
158
+ const validated = validateGroupList(parseGroupList(rawDenylist), TOOL_DENYLIST_ENV_VAR);
159
+ if (!validated.ok) {
160
+ return validated;
161
+ }
162
+ const denied = new Set(validated.groups);
163
+ const remaining = TOOL_GROUP_NAMES.filter((name) => !denied.has(name));
164
+ if (remaining.length === 0) {
165
+ return {
166
+ ok: false,
167
+ error: `${TOOL_DENYLIST_ENV_VAR} disables every tool group, leaving the server with no tools to offer.`,
168
+ };
169
+ }
170
+ return { ok: true, toolGroups: remaining };
171
+ }
172
+ return { ok: true, toolGroups: TOOL_GROUP_NAMES };
173
+ }
174
+ /**
175
+ * Validates an explicitly supplied group list and returns it in registration
176
+ * order. Unlike {@link resolveToolGroupsFromEnv}, a bad value here is a
177
+ * programmer error rather than user misconfiguration, so it throws.
178
+ *
179
+ * @param toolGroups - Group names supplied by the caller.
180
+ * @returns The distinct groups in {@link TOOL_GROUP_NAMES} order.
181
+ * @throws {ToolGroupConfigError} when a name is unknown or the list is empty.
182
+ */
183
+ export function normalizeToolGroups(toolGroups) {
184
+ const validated = validateGroupList([...new Set(toolGroups.map((group) => group.trim().toLowerCase()))], 'toolGroups');
185
+ if (!validated.ok) {
186
+ throw new ToolGroupConfigError(validated.error);
187
+ }
188
+ const requested = new Set(validated.groups);
189
+ return TOOL_GROUP_NAMES.filter((name) => requested.has(name));
190
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squawk/mcp",
3
- "version": "0.11.0",
3
+ "version": "0.12.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",
@@ -31,7 +31,7 @@
31
31
  "!dist/**/*.spec.*"
32
32
  ],
33
33
  "scripts": {
34
- "build": "tsc && chmod +x dist/bin.js",
34
+ "build": "tsc && node -e \"require('fs').chmodSync('dist/bin.js', 0o755)\"",
35
35
  "test": "vitest run",
36
36
  "test:coverage": "vitest run --coverage",
37
37
  "lint": "tsc --noEmit && eslint src",
@@ -40,30 +40,30 @@
40
40
  "api:report": "api-extractor run --local --verbose"
41
41
  },
42
42
  "dependencies": {
43
- "@modelcontextprotocol/sdk": "^1.29.0",
44
- "@squawk/airport-data": "^0.7.3",
45
- "@squawk/airports": "^0.7.0",
46
- "@squawk/airspace": "^0.9.0",
43
+ "@modelcontextprotocol/sdk": "^1.30.0",
44
+ "@squawk/airport-data": "^0.7.12",
45
+ "@squawk/airports": "^0.7.1",
46
+ "@squawk/airspace": "^0.9.1",
47
47
  "@squawk/airspace-data": "^0.5.2",
48
- "@squawk/airway-data": "^0.5.3",
49
- "@squawk/airways": "^0.5.0",
50
- "@squawk/fix-data": "^0.6.3",
51
- "@squawk/fixes": "^0.5.0",
48
+ "@squawk/airway-data": "^0.5.12",
49
+ "@squawk/airways": "^0.5.1",
50
+ "@squawk/fix-data": "^0.6.12",
51
+ "@squawk/fixes": "^0.5.1",
52
52
  "@squawk/flight-math": "^0.5.3",
53
- "@squawk/flightplan": "^0.6.0",
54
- "@squawk/geo": "^0.4.3",
55
- "@squawk/icao-registry": "^0.5.1",
56
- "@squawk/navaid-data": "^0.6.3",
57
- "@squawk/navaids": "^0.6.0",
58
- "@squawk/notams": "^0.3.5",
59
- "@squawk/procedure-data": "^0.7.2",
60
- "@squawk/procedures": "^0.7.0",
61
- "@squawk/types": "^0.8.0",
62
- "@squawk/weather": "^0.6.0",
63
- "zod": "^4.4.3"
53
+ "@squawk/flightplan": "^0.6.1",
54
+ "@squawk/geo": "^0.4.10",
55
+ "@squawk/icao-registry": "^0.5.8",
56
+ "@squawk/navaid-data": "^0.6.12",
57
+ "@squawk/navaids": "^0.6.1",
58
+ "@squawk/notams": "^0.3.12",
59
+ "@squawk/procedure-data": "^0.7.10",
60
+ "@squawk/procedures": "^0.7.1",
61
+ "@squawk/types": "^0.9.0",
62
+ "@squawk/weather": "^0.6.1",
63
+ "zod": "^4.6.2"
64
64
  },
65
65
  "peerDependencies": {
66
- "@squawk/icao-registry-data": "^0.8.3"
66
+ "@squawk/icao-registry-data": "^0.8.12"
67
67
  },
68
68
  "peerDependenciesMeta": {
69
69
  "@squawk/icao-registry-data": {
@@ -71,8 +71,8 @@
71
71
  }
72
72
  },
73
73
  "devDependencies": {
74
- "@squawk/icao-registry-data": "^0.8.3",
75
- "@types/node": "^25.9.3"
74
+ "@squawk/icao-registry-data": "^0.8.12",
75
+ "@types/node": "^26.5.1"
76
76
  },
77
77
  "keywords": [
78
78
  "aviation",