@honua/mcp-server 0.1.13 → 0.1.14
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 +8 -1
- package/dist/src/index.js +4 -4
- package/dist/src/neutral/result.d.ts +2 -2
- package/dist/src/neutral/result.d.ts.map +1 -1
- package/dist/src/neutral/result.js +11 -4
- package/dist/src/tools/count-features.d.ts +1 -1
- package/dist/src/tools/count-features.d.ts.map +1 -1
- package/dist/src/tools/count-features.js +2 -1
- package/dist/src/tools/get-extent.d.ts +1 -1
- package/dist/src/tools/get-extent.d.ts.map +1 -1
- package/dist/src/tools/get-extent.js +2 -1
- package/dist/src/tools/query-features.d.ts +1 -1
- package/dist/src/tools/query-features.d.ts.map +1 -1
- package/dist/src/tools/query-features.js +2 -1
- package/dist/src/tools/statistics.d.ts +1 -1
- package/dist/src/tools/statistics.d.ts.map +1 -1
- package/dist/src/tools/statistics.js +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -260,7 +260,7 @@ Embedding the server in your own Node.js host needs the packages as local
|
|
|
260
260
|
dependencies of that host project:
|
|
261
261
|
|
|
262
262
|
```bash
|
|
263
|
-
npm install @honua/mcp-server @honua/sdk-js
|
|
263
|
+
npm install @honua/mcp-server@0.1.13 @honua/sdk-js@0.1.13
|
|
264
264
|
```
|
|
265
265
|
|
|
266
266
|
The map runtime, model callback, approval verifier, receipt signer, and
|
|
@@ -346,6 +346,7 @@ cd honua-sdk-js
|
|
|
346
346
|
npm ci
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
+
<!-- doc-run: checkout -->
|
|
349
350
|
```bash
|
|
350
351
|
npm run build # the SDK that mcp/ links to; takes a few minutes
|
|
351
352
|
cd mcp
|
|
@@ -354,6 +355,7 @@ npm ci
|
|
|
354
355
|
|
|
355
356
|
From `mcp/`:
|
|
356
357
|
|
|
358
|
+
<!-- doc-run: checkout=mcp -->
|
|
357
359
|
```bash
|
|
358
360
|
# Run the certifier against the offline fixture backend and write artifacts:
|
|
359
361
|
npm run certify
|
|
@@ -384,6 +386,7 @@ skip-with-reason. Fixture-backed and deterministic — no network — as long as
|
|
|
384
386
|
instead (the scheduled live variant). Unset it if you exported it for `honua-mcp`
|
|
385
387
|
above:
|
|
386
388
|
|
|
389
|
+
<!-- doc-run: checkout=mcp -->
|
|
387
390
|
```bash
|
|
388
391
|
unset HONUA_BASE_URL
|
|
389
392
|
npm run certify:standalone # platform-free cert (plain FeatureServer fixture)
|
|
@@ -406,6 +409,7 @@ in `config/live-conformance-endpoints.v1.json`). Nothing Esri exists there: the
|
|
|
406
409
|
GeoServices entry points all reject, so a tool that still secretly required
|
|
407
410
|
`serviceId`/`layerId` fails loudly instead of passing by accident.
|
|
408
411
|
|
|
412
|
+
<!-- doc-run: checkout=mcp -->
|
|
409
413
|
```bash
|
|
410
414
|
npm run certify:standalone-ogc # non-GeoServices cert (OGC API Features fixture)
|
|
411
415
|
npm run test:certification:standalone-ogc # CI gate variant
|
|
@@ -521,6 +525,7 @@ honua-io/honua-server#1956.)
|
|
|
521
525
|
dependencies); keys come from the environment and are never hardcoded. Set
|
|
522
526
|
`HONUA_MCP_REMOTE_URL` to drive a live remote `/mcp` instead of the fixture.
|
|
523
527
|
|
|
528
|
+
<!-- doc-run: checkout=mcp -->
|
|
524
529
|
```bash
|
|
525
530
|
npm run eval # run the eval (live models join if their keys are set)
|
|
526
531
|
npm run eval:offline # force the deterministic control + fixture surface
|
|
@@ -546,6 +551,7 @@ guards. Because the fixture replays real recorded data, a wrong number or a
|
|
|
546
551
|
hallucinated place name fails. The grading taxonomy is documented in
|
|
547
552
|
[`evals/README.md`](evals/README.md).
|
|
548
553
|
|
|
554
|
+
<!-- doc-run: checkout=mcp -->
|
|
549
555
|
```bash
|
|
550
556
|
npm run eval:standalone # deterministic control over the census fixture (offline)
|
|
551
557
|
```
|
|
@@ -564,6 +570,7 @@ an extent that came from the declared collection extent must say so, and a CQL2
|
|
|
564
570
|
spatial predicate the endpoint does not publish must come back as a structured
|
|
565
571
|
capability refusal — never as an empty result set.
|
|
566
572
|
|
|
573
|
+
<!-- doc-run: checkout=mcp -->
|
|
567
574
|
```bash
|
|
568
575
|
npm run eval:ogc # deterministic control over the OGC API Features fixture (offline)
|
|
569
576
|
```
|
package/dist/src/index.js
CHANGED
|
@@ -172,10 +172,10 @@ export function createServer(client, options = {}) {
|
|
|
172
172
|
registerNlMapControlMcpTools(server, options.nlMapControl);
|
|
173
173
|
}
|
|
174
174
|
server.tool("honua_describe_layer", "Describe a source: its protocol, the capabilities it actually supports, field schema, geometry type, and extent. Address it with `source` (from honua_list_sources); the serviceId/layerId pair is deprecated but still accepted.", describeLayer.schema.shape, async (args) => describeLayer.execute(client, describeLayer.schema.parse(args)));
|
|
175
|
-
server.tool("honua_query_features", "Query features from any supported protocol. Address the source with `source`; filter with the typed protocol-neutral `filter`, a GeoJSON `geometry` or `bbox` plus `spatialRel`, and `temporal`. returnGeometry defaults to false to save tokens. A construct the backing protocol cannot express returns a structured capability error, never a silently empty result.", queryFeatures.schema.shape, async (args) => queryFeatures.execute(client, queryFeatures.schema.parse(args)));
|
|
176
|
-
server.tool("honua_count_features", "Count features matching a filter without returning data. Use before querying to check cardinality.", countFeatures.schema.shape, async (args) => countFeatures.execute(client, countFeatures.schema.parse(args)));
|
|
177
|
-
server.tool("honua_get_extent", "Get the spatial bounding box of features matching a filter.", getExtent.schema.shape, async (args) => getExtent.execute(client, getExtent.schema.parse(args)));
|
|
178
|
-
server.tool("honua_statistics", "Compute aggregate statistics (count, sum, avg, min, max, stddev, var) on a field, optionally grouped. Protocols without server-side aggregation answer client-side and report the degradation.", statistics.schema.shape, async (args) => statistics.execute(client, statistics.schema.parse(args)));
|
|
175
|
+
server.tool("honua_query_features", "Query features from any supported protocol. Address the source with `source`; filter with the typed protocol-neutral `filter`, a GeoJSON `geometry` or `bbox` plus `spatialRel`, and `temporal`. returnGeometry defaults to false to save tokens. A construct the backing protocol cannot express returns a structured capability error, never a silently empty result.", queryFeatures.schema.shape, async (args, extra) => queryFeatures.execute(client, queryFeatures.schema.parse(args), extra?.signal));
|
|
176
|
+
server.tool("honua_count_features", "Count features matching a filter without returning data. Use before querying to check cardinality.", countFeatures.schema.shape, async (args, extra) => countFeatures.execute(client, countFeatures.schema.parse(args), extra?.signal));
|
|
177
|
+
server.tool("honua_get_extent", "Get the spatial bounding box of features matching a filter.", getExtent.schema.shape, async (args, extra) => getExtent.execute(client, getExtent.schema.parse(args), extra?.signal));
|
|
178
|
+
server.tool("honua_statistics", "Compute aggregate statistics (count, sum, avg, min, max, stddev, var) on a field, optionally grouped. Protocols without server-side aggregation answer client-side and report the degradation.", statistics.schema.shape, async (args, extra) => statistics.execute(client, statistics.schema.parse(args), extra?.signal));
|
|
179
179
|
server.tool("honua_explain_capability_gap", "Explain whether a source/protocol supports a capability and suggest a safe fallback when it does not.", explainCapabilityGap.schema.shape, async (args) => explainCapabilityGap.execute(client, explainCapabilityGap.schema.parse(args)));
|
|
180
180
|
server.tool("honua_get_style", "Resolve a style from a server's OGC API – Styles surface. Pass styleId for the canonical StyleRef (style_id, title, encodings incl. inlined MapLibre); omit it to list available styles. On a plain FeatureServer with no styling surface, reports a structured 'not available on this target' result.", getStyle.schema.shape, async (args) => getStyle.execute(client, getStyle.schema.parse(args)));
|
|
181
181
|
server.tool("honua_apply_style_preset", "Resolve a style preset and its MapLibre stylesheet for client-side application. Read-only: returns the stylesheet to apply locally; it does not mutate server state. Degrades gracefully on a target with no styling surface.", applyStylePreset.schema.shape, async (args) => applyStylePreset.execute(client, applyStylePreset.schema.parse(args)));
|
|
@@ -16,9 +16,9 @@ export type GeometryFormat = "geojson" | "esri-json";
|
|
|
16
16
|
export declare function projectGeometry(geometry: Record<string, unknown> | null | undefined, format: GeometryFormat): Record<string, unknown> | null;
|
|
17
17
|
/** Normalize `Result.degraded` for tool output; `undefined` when nothing degraded. */
|
|
18
18
|
export declare function projectDegraded(degraded: readonly DegradedReason[] | undefined): {
|
|
19
|
-
capability: import("@honua/sdk-js
|
|
19
|
+
capability: import("@honua/sdk-js").Capability;
|
|
20
20
|
reason: string;
|
|
21
|
-
protocol: import("@honua/sdk-js
|
|
21
|
+
protocol: import("@honua/sdk-js").Protocol | null;
|
|
22
22
|
sourceId: string | null;
|
|
23
23
|
}[] | undefined;
|
|
24
24
|
export interface ProjectFeaturesOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../../src/neutral/result.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../../src/neutral/result.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGrE;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AAMrD,gEAAgE;AAChE,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACpD,MAAM,EAAE,cAAc,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWhC;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS;;;;;gBAQ9E;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CACzC;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB;;;IAU9E"}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HonuaCapabilityNotSupportedError } from "@honua/sdk-js";
|
|
2
|
+
import { esriToGeoJson, geoJsonToEsri } from "@honua/sdk-js/geometry";
|
|
2
3
|
function looksGeoJson(geometry) {
|
|
3
|
-
return typeof geometry.type === "string" && "coordinates" in geometry;
|
|
4
|
+
return typeof geometry.type === "string" && ("coordinates" in geometry || geometry.type === "GeometryCollection");
|
|
4
5
|
}
|
|
5
6
|
/** Re-encode one feature geometry into the requested format. */
|
|
6
7
|
export function projectGeometry(geometry, format) {
|
|
7
8
|
if (!geometry)
|
|
8
9
|
return null;
|
|
9
|
-
if (format === "esri-json")
|
|
10
|
-
|
|
10
|
+
if (format === "esri-json") {
|
|
11
|
+
if (!looksGeoJson(geometry))
|
|
12
|
+
return geometry;
|
|
13
|
+
const converted = geoJsonToEsri(geometry);
|
|
14
|
+
if (!converted)
|
|
15
|
+
throw new HonuaCapabilityNotSupportedError("geometryFormat.esri-json", "geometry-projection");
|
|
16
|
+
return converted;
|
|
17
|
+
}
|
|
11
18
|
if (looksGeoJson(geometry))
|
|
12
19
|
return geometry;
|
|
13
20
|
const converted = esriToGeoJson(geometry);
|
|
@@ -89,7 +89,7 @@ interface CountOutcome {
|
|
|
89
89
|
}
|
|
90
90
|
/** Resolve a feature count through the canonical `Source` surface. */
|
|
91
91
|
export declare function countThroughSource(source: CapabilityAwareSource, query: Query, protocol: string, sourceId: string): Promise<CountOutcome>;
|
|
92
|
-
export declare function execute(client: HonuaClient, input: Input): Promise<{
|
|
92
|
+
export declare function execute(client: HonuaClient, input: Input, signal?: AbortSignal): Promise<{
|
|
93
93
|
content: Array<{
|
|
94
94
|
type: "text";
|
|
95
95
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"count-features.d.ts","sourceRoot":"","sources":["../../../src/tools/count-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,GAAG,YAAY,CAAC;IACvC,QAAQ,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CAC9C;AAED,sEAAsE;AACtE,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,qBAAqB,EAC7B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAevB;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"count-features.d.ts","sourceRoot":"","sources":["../../../src/tools/count-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,GAAG,YAAY,CAAC;IACvC,QAAQ,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CAC9C;AAED,sEAAsE;AACtE,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,qBAAqB,EAC7B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAevB;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW;;;;;;;;;;;;GAoBpF"}
|
|
@@ -38,10 +38,11 @@ export async function countThroughSource(source, query, protocol, sourceId) {
|
|
|
38
38
|
}
|
|
39
39
|
throw new HonuaCapabilityNotSupportedError("count", protocol, sourceId);
|
|
40
40
|
}
|
|
41
|
-
export async function execute(client, input) {
|
|
41
|
+
export async function execute(client, input, signal) {
|
|
42
42
|
return withCapabilityHonesty(async () => {
|
|
43
43
|
const resolved = resolveSource(client, input);
|
|
44
44
|
const query = toQuery(input, { protocol: resolved.descriptor.protocol, paginate: false });
|
|
45
|
+
query.signal = signal;
|
|
45
46
|
const outcome = await countThroughSource(resolved.source, query, resolved.descriptor.protocol, resolved.descriptor.id);
|
|
46
47
|
return jsonText({
|
|
47
48
|
source: resolved.ref.ref,
|
|
@@ -74,7 +74,7 @@ export declare const schema: z.ZodObject<{
|
|
|
74
74
|
spatialRel?: "intersects" | "contains" | "within" | "crosses" | "touches" | "overlaps" | "bbox-intersects" | undefined;
|
|
75
75
|
}>;
|
|
76
76
|
export type Input = z.infer<typeof schema>;
|
|
77
|
-
export declare function execute(client: HonuaClient, input: Input): Promise<{
|
|
77
|
+
export declare function execute(client: HonuaClient, input: Input, signal?: AbortSignal): Promise<{
|
|
78
78
|
content: Array<{
|
|
79
79
|
type: "text";
|
|
80
80
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-extent.d.ts","sourceRoot":"","sources":["../../../src/tools/get-extent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"get-extent.d.ts","sourceRoot":"","sources":["../../../src/tools/get-extent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW;;;;;;;;;;;;GAiBpF"}
|
|
@@ -15,10 +15,11 @@ export const schema = z.object({
|
|
|
15
15
|
...sourceRefFields,
|
|
16
16
|
...queryFilterFields,
|
|
17
17
|
});
|
|
18
|
-
export async function execute(client, input) {
|
|
18
|
+
export async function execute(client, input, signal) {
|
|
19
19
|
return withCapabilityHonesty(async () => {
|
|
20
20
|
const resolved = resolveSource(client, input);
|
|
21
21
|
const query = toQuery(input, { protocol: resolved.descriptor.protocol, paginate: false });
|
|
22
|
+
query.signal = signal;
|
|
22
23
|
const { extent, count } = await resolved.source.queryExtent(query);
|
|
23
24
|
return jsonText({
|
|
24
25
|
source: resolved.ref.ref,
|
|
@@ -111,7 +111,7 @@ export declare const schema: z.ZodObject<{
|
|
|
111
111
|
outSr?: string | number | undefined;
|
|
112
112
|
}>;
|
|
113
113
|
export type Input = z.infer<typeof schema>;
|
|
114
|
-
export declare function execute(client: HonuaClient, input: Input): Promise<{
|
|
114
|
+
export declare function execute(client: HonuaClient, input: Input, signal?: AbortSignal): Promise<{
|
|
115
115
|
content: Array<{
|
|
116
116
|
type: "text";
|
|
117
117
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-features.d.ts","sourceRoot":"","sources":["../../../src/tools/query-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"query-features.d.ts","sourceRoot":"","sources":["../../../src/tools/query-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW;;;;;;;;;;;;GA0BpF"}
|
|
@@ -18,10 +18,11 @@ export const schema = z.object({
|
|
|
18
18
|
...queryFilterFields,
|
|
19
19
|
...queryShapeFields,
|
|
20
20
|
});
|
|
21
|
-
export async function execute(client, input) {
|
|
21
|
+
export async function execute(client, input, signal) {
|
|
22
22
|
return withCapabilityHonesty(async () => {
|
|
23
23
|
const resolved = resolveSource(client, input);
|
|
24
24
|
const query = toQuery(input, { protocol: resolved.descriptor.protocol });
|
|
25
|
+
query.signal = signal;
|
|
25
26
|
const result = await resolved.source.query(query);
|
|
26
27
|
// Legacy addressing keeps legacy output: a client that still sends
|
|
27
28
|
// serviceId/layerId also still expects Esri-JSON geometry. Neutral
|
|
@@ -84,7 +84,7 @@ export declare const schema: z.ZodObject<{
|
|
|
84
84
|
groupBy?: string | string[] | undefined;
|
|
85
85
|
}>;
|
|
86
86
|
export type Input = z.infer<typeof schema>;
|
|
87
|
-
export declare function execute(client: HonuaClient, input: Input): Promise<{
|
|
87
|
+
export declare function execute(client: HonuaClient, input: Input, signal?: AbortSignal): Promise<{
|
|
88
88
|
content: Array<{
|
|
89
89
|
type: "text";
|
|
90
90
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statistics.d.ts","sourceRoot":"","sources":["../../../src/tools/statistics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAQ3C,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"statistics.d.ts","sourceRoot":"","sources":["../../../src/tools/statistics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAQ3C,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW;;;;;;;;;;;;GAiCpF"}
|
|
@@ -31,10 +31,11 @@ function normalizeGroupBy(groupBy) {
|
|
|
31
31
|
const fields = (Array.isArray(groupBy) ? groupBy : groupBy.split(",")).map((f) => f.trim()).filter(Boolean);
|
|
32
32
|
return fields.length > 0 ? fields : undefined;
|
|
33
33
|
}
|
|
34
|
-
export async function execute(client, input) {
|
|
34
|
+
export async function execute(client, input, signal) {
|
|
35
35
|
return withCapabilityHonesty(async () => {
|
|
36
36
|
const resolved = resolveSource(client, input);
|
|
37
37
|
const base = toQuery(input, { protocol: resolved.descriptor.protocol, paginate: false });
|
|
38
|
+
base.signal = signal;
|
|
38
39
|
// GeoServices rejects an `outStatistics` query that carries no `where`;
|
|
39
40
|
// every other protocol treats "no filter" as "all records". Supplying the
|
|
40
41
|
// tautology keeps the neutral "omit the filter ⇒ aggregate everything"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@honua/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Platform-free MCP server for geospatial services: expose discovery, query, and analysis over any public ArcGIS/Esri FeatureServer or OGC API endpoint to any MCP client, with no platform lock-in",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Honua",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"qs": "^6.16.0"
|
|
90
90
|
},
|
|
91
91
|
"peerDependencies": {
|
|
92
|
-
"@honua/sdk-js": "^0.1.
|
|
92
|
+
"@honua/sdk-js": "^0.1.14"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@biomejs/biome": "1.9.4",
|