@honua/mcp-server 0.0.10-alpha.0 → 0.0.20-alpha.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 +167 -0
- package/certification/geospatial-mcp-schemas/PROVENANCE.md +33 -0
- package/certification/geospatial-mcp-schemas/README.md +90 -0
- package/certification/geospatial-mcp-schemas/common/geoprocessing-error.schema.json +45 -0
- package/certification/geospatial-mcp-schemas/conformance/manifest.schema.json +73 -0
- package/certification/geospatial-mcp-schemas/index.json +311 -0
- package/certification/geospatial-mcp-schemas/resources/app-package.schema.json +20 -0
- package/certification/geospatial-mcp-schemas/resources/app-template.schema.json +15 -0
- package/certification/geospatial-mcp-schemas/resources/artifact.schema.json +69 -0
- package/certification/geospatial-mcp-schemas/resources/deployment.schema.json +27 -0
- package/certification/geospatial-mcp-schemas/resources/map-package.schema.json +21 -0
- package/certification/geospatial-mcp-schemas/resources/map-template.schema.json +15 -0
- package/certification/geospatial-mcp-schemas/resources/provenance.schema.json +50 -0
- package/certification/geospatial-mcp-schemas/resources/published-service.schema.json +21 -0
- package/certification/geospatial-mcp-schemas/resources/result-package.schema.json +64 -0
- package/certification/geospatial-mcp-schemas/resources/style.schema.json +12 -0
- package/certification/geospatial-mcp-schemas/resources/theme.schema.json +12 -0
- package/certification/geospatial-mcp-schemas/resources/workspace.schema.json +63 -0
- package/certification/geospatial-mcp-schemas/tools/apply_style_preset.schema.json +23 -0
- package/certification/geospatial-mcp-schemas/tools/cancel_job.schema.json +15 -0
- package/certification/geospatial-mcp-schemas/tools/clarify_intent.schema.json +69 -0
- package/certification/geospatial-mcp-schemas/tools/compose_mixed_protocol_map.schema.json +21 -0
- package/certification/geospatial-mcp-schemas/tools/create_app_package.schema.json +33 -0
- package/certification/geospatial-mcp-schemas/tools/create_map_package.schema.json +41 -0
- package/certification/geospatial-mcp-schemas/tools/execute_plan.schema.json +64 -0
- package/certification/geospatial-mcp-schemas/tools/geocode_address.schema.json +36 -0
- package/certification/geospatial-mcp-schemas/tools/get_style.schema.json +30 -0
- package/certification/geospatial-mcp-schemas/tools/ground_candidates.schema.json +66 -0
- package/certification/geospatial-mcp-schemas/tools/list_capabilities.schema.json +21 -0
- package/certification/geospatial-mcp-schemas/tools/list_layers.schema.json +14 -0
- package/certification/geospatial-mcp-schemas/tools/plan_analysis.schema.json +19 -0
- package/certification/geospatial-mcp-schemas/tools/preview_app_package.schema.json +15 -0
- package/certification/geospatial-mcp-schemas/tools/preview_map_package.schema.json +17 -0
- package/certification/geospatial-mcp-schemas/tools/preview_package.schema.json +40 -0
- package/certification/geospatial-mcp-schemas/tools/propose_operation.schema.json +28 -0
- package/certification/geospatial-mcp-schemas/tools/publish_result.schema.json +29 -0
- package/certification/geospatial-mcp-schemas/tools/publish_service.schema.json +59 -0
- package/certification/geospatial-mcp-schemas/tools/query_features.schema.json +54 -0
- package/certification/geospatial-mcp-schemas/tools/refine_map_package.schema.json +22 -0
- package/certification/geospatial-mcp-schemas/tools/render_map.schema.json +55 -0
- package/certification/geospatial-mcp-schemas/tools/resolve_entity.schema.json +30 -0
- package/certification/geospatial-mcp-schemas/tools/solve_route.schema.json +39 -0
- package/certification/geospatial-mcp-schemas/tools/validate_package.schema.json +35 -0
- package/certification/geospatial-mcp-schemas/tools/validate_plan.schema.json +61 -0
- package/dist/src/certification/certifier.d.ts +119 -0
- package/dist/src/certification/certifier.d.ts.map +1 -0
- package/dist/src/certification/certifier.js +410 -0
- package/dist/src/certification/cli.d.ts +3 -0
- package/dist/src/certification/cli.d.ts.map +1 -0
- package/dist/src/certification/cli.js +48 -0
- package/dist/src/certification/contracts.d.ts +62 -0
- package/dist/src/certification/contracts.d.ts.map +1 -0
- package/dist/src/certification/contracts.js +174 -0
- package/dist/src/certification/fixture-client.d.ts +4 -0
- package/dist/src/certification/fixture-client.d.ts.map +1 -0
- package/dist/src/certification/fixture-client.js +113 -0
- package/dist/src/certification/fixtures.d.ts +32 -0
- package/dist/src/certification/fixtures.d.ts.map +1 -0
- package/dist/src/certification/fixtures.js +64 -0
- package/dist/src/certification/json-schema.d.ts +49 -0
- package/dist/src/certification/json-schema.d.ts.map +1 -0
- package/dist/src/certification/json-schema.js +164 -0
- package/dist/src/certification/mock-upstream.d.ts +29 -0
- package/dist/src/certification/mock-upstream.d.ts.map +1 -0
- package/dist/src/certification/mock-upstream.js +96 -0
- package/dist/src/certification/operator-catalog.d.ts +82 -0
- package/dist/src/certification/operator-catalog.d.ts.map +1 -0
- package/dist/src/certification/operator-catalog.js +466 -0
- package/dist/src/certification/report.d.ts +4 -0
- package/dist/src/certification/report.d.ts.map +1 -0
- package/dist/src/certification/report.js +90 -0
- package/dist/src/certification/run.d.ts +28 -0
- package/dist/src/certification/run.d.ts.map +1 -0
- package/dist/src/certification/run.js +31 -0
- package/dist/src/certification/schema-index.d.ts +69 -0
- package/dist/src/certification/schema-index.d.ts.map +1 -0
- package/dist/src/certification/schema-index.js +82 -0
- package/dist/src/certification/target.d.ts +40 -0
- package/dist/src/certification/target.d.ts.map +1 -0
- package/dist/src/certification/target.js +167 -0
- package/dist/src/eval/cli.d.ts +3 -0
- package/dist/src/eval/cli.d.ts.map +1 -0
- package/dist/src/eval/cli.js +116 -0
- package/dist/src/eval/corpus.d.ts +27 -0
- package/dist/src/eval/corpus.d.ts.map +1 -0
- package/dist/src/eval/corpus.js +134 -0
- package/dist/src/eval/drivers/anthropic.d.ts +14 -0
- package/dist/src/eval/drivers/anthropic.d.ts.map +1 -0
- package/dist/src/eval/drivers/anthropic.js +120 -0
- package/dist/src/eval/drivers/bedrock.d.ts +54 -0
- package/dist/src/eval/drivers/bedrock.d.ts.map +1 -0
- package/dist/src/eval/drivers/bedrock.js +178 -0
- package/dist/src/eval/drivers/deterministic.d.ts +17 -0
- package/dist/src/eval/drivers/deterministic.d.ts.map +1 -0
- package/dist/src/eval/drivers/deterministic.js +51 -0
- package/dist/src/eval/drivers/index.d.ts +34 -0
- package/dist/src/eval/drivers/index.d.ts.map +1 -0
- package/dist/src/eval/drivers/index.js +74 -0
- package/dist/src/eval/drivers/openai.d.ts +14 -0
- package/dist/src/eval/drivers/openai.d.ts.map +1 -0
- package/dist/src/eval/drivers/openai.js +136 -0
- package/dist/src/eval/grade.d.ts +14 -0
- package/dist/src/eval/grade.d.ts.map +1 -0
- package/dist/src/eval/grade.js +56 -0
- package/dist/src/eval/northstar-corpus.d.ts +3 -0
- package/dist/src/eval/northstar-corpus.d.ts.map +1 -0
- package/dist/src/eval/northstar-corpus.js +194 -0
- package/dist/src/eval/operator-corpus.d.ts +3 -0
- package/dist/src/eval/operator-corpus.d.ts.map +1 -0
- package/dist/src/eval/operator-corpus.js +193 -0
- package/dist/src/eval/report.d.ts +104 -0
- package/dist/src/eval/report.d.ts.map +1 -0
- package/dist/src/eval/report.js +130 -0
- package/dist/src/eval/runner.d.ts +22 -0
- package/dist/src/eval/runner.d.ts.map +1 -0
- package/dist/src/eval/runner.js +116 -0
- package/dist/src/eval/types.d.ts +93 -0
- package/dist/src/eval/types.d.ts.map +1 -0
- package/dist/src/eval/types.js +10 -0
- package/dist/src/helpers.d.ts +11 -0
- package/dist/src/helpers.d.ts.map +1 -1
- package/dist/src/helpers.js +22 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +30 -4
- package/dist/src/proxy.d.ts +46 -0
- package/dist/src/proxy.d.ts.map +1 -0
- package/dist/src/proxy.js +124 -0
- package/dist/src/resources/styles.d.ts +29 -0
- package/dist/src/resources/styles.d.ts.map +1 -0
- package/dist/src/resources/styles.js +43 -0
- package/dist/src/styles.d.ts +110 -0
- package/dist/src/styles.d.ts.map +1 -0
- package/dist/src/styles.js +118 -0
- package/dist/src/tools/apply-style-preset.d.ts +27 -0
- package/dist/src/tools/apply-style-preset.d.ts.map +1 -0
- package/dist/src/tools/apply-style-preset.js +29 -0
- package/dist/src/tools/count-features.d.ts.map +1 -1
- package/dist/src/tools/count-features.js +5 -4
- package/dist/src/tools/get-extent.d.ts.map +1 -1
- package/dist/src/tools/get-extent.js +6 -4
- package/dist/src/tools/get-style.d.ts +24 -0
- package/dist/src/tools/get-style.d.ts.map +1 -0
- package/dist/src/tools/get-style.js +28 -0
- package/dist/src/tools/query-features.d.ts.map +1 -1
- package/dist/src/tools/query-features.js +4 -1
- package/package.json +19 -4
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin read-only client over the server's OGC API – Styles surface
|
|
3
|
+
* (honua-server, ADR-0048):
|
|
4
|
+
*
|
|
5
|
+
* GET /ogc/styles -> styles list ({ styles: [{ id, title, links }], default? })
|
|
6
|
+
* GET /ogc/styles/{styleId}/metadata -> style metadata ({ id, title, description, keywords, license, version, links })
|
|
7
|
+
* GET /ogc/styles/{styleId} -> stylesheet body (MapLibre/Mapbox JSON by default; SLD via Accept)
|
|
8
|
+
*
|
|
9
|
+
* These helpers project the server responses into the geospatial-grpc
|
|
10
|
+
* `StyleRef` / `StyleEncoding` shape (style_id / title / encodings) so the MCP
|
|
11
|
+
* resource + `get_style` tool surface a single canonical style object.
|
|
12
|
+
*
|
|
13
|
+
* The MCP package only consumes the public {@link HonuaClient.pipelineFetch}
|
|
14
|
+
* request pipeline (auth / retry / timeout / interceptors) rather than a
|
|
15
|
+
* private route, matching the other `/ogc/*` consumers in the SDK.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
/** Default path prefix for the server's OGC API – Styles surface. */
|
|
20
|
+
export const OGC_STYLES_PATH = "/ogc/styles";
|
|
21
|
+
/** MapLibre / Mapbox style media type (server default stylesheet encoding). */
|
|
22
|
+
export const MAPLIBRE_STYLE_MEDIA_TYPE = "application/vnd.mapbox.style+json";
|
|
23
|
+
/** SLD 1.0 stylesheet media type. */
|
|
24
|
+
export const SLD_10_MEDIA_TYPE = "application/vnd.ogc.sld+xml;version=1.0";
|
|
25
|
+
/** SLD 1.1 stylesheet media type. */
|
|
26
|
+
export const SLD_11_MEDIA_TYPE = "application/vnd.ogc.sld+xml;version=1.1";
|
|
27
|
+
/**
|
|
28
|
+
* Stylesheet encodings the MCP surface understands, keyed by the canonical
|
|
29
|
+
* geospatial-grpc `StyleEncoding.encoding` identifier. The server
|
|
30
|
+
* content-negotiates these via the `Accept` header.
|
|
31
|
+
*/
|
|
32
|
+
export const STYLE_ENCODINGS = {
|
|
33
|
+
"mapbox-style": MAPLIBRE_STYLE_MEDIA_TYPE,
|
|
34
|
+
"sld-1.0.0": SLD_10_MEDIA_TYPE,
|
|
35
|
+
"sld-1.1.0": SLD_11_MEDIA_TYPE,
|
|
36
|
+
};
|
|
37
|
+
function isRecord(value) {
|
|
38
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
39
|
+
}
|
|
40
|
+
async function getJson(client, path, accept) {
|
|
41
|
+
const response = await client.pipelineFetch("GET", path, { headers: { Accept: accept } });
|
|
42
|
+
return (await response.json());
|
|
43
|
+
}
|
|
44
|
+
function stylePath(styleId) {
|
|
45
|
+
return `${OGC_STYLES_PATH}/${encodeURIComponent(styleId)}`;
|
|
46
|
+
}
|
|
47
|
+
/** List available styles via `GET /ogc/styles`. */
|
|
48
|
+
export async function listStyles(client) {
|
|
49
|
+
const body = await getJson(client, OGC_STYLES_PATH, "application/json");
|
|
50
|
+
if (!isRecord(body) || !Array.isArray(body.styles)) {
|
|
51
|
+
return { styles: [] };
|
|
52
|
+
}
|
|
53
|
+
const styles = [];
|
|
54
|
+
for (const entry of body.styles) {
|
|
55
|
+
if (isRecord(entry) && typeof entry.id === "string") {
|
|
56
|
+
styles.push({
|
|
57
|
+
id: entry.id,
|
|
58
|
+
...(typeof entry.title === "string" ? { title: entry.title } : {}),
|
|
59
|
+
...(Array.isArray(entry.links) ? { links: entry.links } : {}),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
styles,
|
|
65
|
+
...(typeof body.default === "string" ? { default: body.default } : {}),
|
|
66
|
+
...(Array.isArray(body.links) ? { links: body.links } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Fetch style metadata via `GET /ogc/styles/{styleId}/metadata`. */
|
|
70
|
+
export async function getStyleMetadata(client, styleId) {
|
|
71
|
+
const body = await getJson(client, `${stylePath(styleId)}/metadata`, "application/json");
|
|
72
|
+
return body;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fetch the MapLibre/Mapbox stylesheet body via `GET /ogc/styles/{styleId}`
|
|
76
|
+
* (content-negotiated to {@link MAPLIBRE_STYLE_MEDIA_TYPE}).
|
|
77
|
+
*/
|
|
78
|
+
export async function getMapLibreStylesheet(client, styleId) {
|
|
79
|
+
return getJson(client, stylePath(styleId), `${MAPLIBRE_STYLE_MEDIA_TYPE}, application/json;q=0.9`);
|
|
80
|
+
}
|
|
81
|
+
/** Coerce a free-form metadata `version` (string) into the numeric style_version, when possible. */
|
|
82
|
+
function parseStyleVersion(version) {
|
|
83
|
+
if (version === undefined)
|
|
84
|
+
return null;
|
|
85
|
+
const parsed = Number.parseInt(version, 10);
|
|
86
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resolve a single style into a `StyleRef` projection: fetch metadata and the
|
|
90
|
+
* canonical MapLibre stylesheet, and advertise the alternate SLD encodings by
|
|
91
|
+
* reference. The stylesheet base URL (`{baseUrl}/ogc/styles/{styleId}`) backs
|
|
92
|
+
* the `storageRef` for the by-reference encodings.
|
|
93
|
+
*/
|
|
94
|
+
export async function resolveStyleRef(client, styleId) {
|
|
95
|
+
const [metadata, maplibre] = await Promise.all([
|
|
96
|
+
getStyleMetadata(client, styleId).catch(() => null),
|
|
97
|
+
getMapLibreStylesheet(client, styleId),
|
|
98
|
+
]);
|
|
99
|
+
const stylesheetUrl = `${client.serverBaseUrl}${stylePath(styleId)}`;
|
|
100
|
+
const encodings = [
|
|
101
|
+
{
|
|
102
|
+
encoding: "mapbox-style",
|
|
103
|
+
contentType: MAPLIBRE_STYLE_MEDIA_TYPE,
|
|
104
|
+
inlineBody: maplibre,
|
|
105
|
+
},
|
|
106
|
+
{ encoding: "sld-1.0.0", contentType: SLD_10_MEDIA_TYPE, storageRef: stylesheetUrl },
|
|
107
|
+
{ encoding: "sld-1.1.0", contentType: SLD_11_MEDIA_TYPE, storageRef: stylesheetUrl },
|
|
108
|
+
];
|
|
109
|
+
const legendUrl = metadata?.links?.find((l) => l.rel === "preview")?.href ?? null;
|
|
110
|
+
return {
|
|
111
|
+
styleId,
|
|
112
|
+
title: metadata?.title ?? styleId,
|
|
113
|
+
description: metadata?.description ?? null,
|
|
114
|
+
styleVersion: parseStyleVersion(metadata?.version),
|
|
115
|
+
legendUrl,
|
|
116
|
+
encodings,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HonuaClient } from "@honua/sdk-js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const schema: z.ZodObject<{
|
|
4
|
+
styleId: z.ZodString;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
styleId: string;
|
|
7
|
+
}, {
|
|
8
|
+
styleId: string;
|
|
9
|
+
}>;
|
|
10
|
+
export type Input = z.infer<typeof schema>;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a style preset for client-side application. Returns the canonical
|
|
13
|
+
* `StyleRef` plus the MapLibre/Mapbox stylesheet body so an agent or downstream
|
|
14
|
+
* runtime can apply the preset to a map.
|
|
15
|
+
*
|
|
16
|
+
* This is a read-only inspection projection: it resolves and returns the
|
|
17
|
+
* preset's stylesheet but never mutates server state. Persisting a preset onto
|
|
18
|
+
* a map or published service stays with the typed gRPC execution layer per the
|
|
19
|
+
* MCP boundary (geospatial-mcp taxonomy / ADR-0028).
|
|
20
|
+
*/
|
|
21
|
+
export declare function execute(client: HonuaClient, input: Input): Promise<{
|
|
22
|
+
content: Array<{
|
|
23
|
+
type: "text";
|
|
24
|
+
text: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
//# sourceMappingURL=apply-style-preset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-style-preset.d.ts","sourceRoot":"","sources":["../../../src/tools/apply-style-preset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,MAAM;;;;;;EAEjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;;;;;GAa9D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonText } from "../helpers.js";
|
|
3
|
+
import { resolveStyleRef } from "../styles.js";
|
|
4
|
+
export const schema = z.object({
|
|
5
|
+
styleId: z.string().describe("Stable style identifier of the preset to resolve."),
|
|
6
|
+
});
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a style preset for client-side application. Returns the canonical
|
|
9
|
+
* `StyleRef` plus the MapLibre/Mapbox stylesheet body so an agent or downstream
|
|
10
|
+
* runtime can apply the preset to a map.
|
|
11
|
+
*
|
|
12
|
+
* This is a read-only inspection projection: it resolves and returns the
|
|
13
|
+
* preset's stylesheet but never mutates server state. Persisting a preset onto
|
|
14
|
+
* a map or published service stays with the typed gRPC execution layer per the
|
|
15
|
+
* MCP boundary (geospatial-mcp taxonomy / ADR-0028).
|
|
16
|
+
*/
|
|
17
|
+
export async function execute(client, input) {
|
|
18
|
+
// `resolveStyleRef` already fetches the MapLibre stylesheet and inlines it on
|
|
19
|
+
// the `mapbox-style` encoding, so reuse that body instead of issuing a second
|
|
20
|
+
// identical GET /ogc/styles/{id}.
|
|
21
|
+
const styleRef = await resolveStyleRef(client, input.styleId);
|
|
22
|
+
const stylesheet = styleRef.encodings.find((e) => e.encoding === "mapbox-style")?.inlineBody ?? null;
|
|
23
|
+
return jsonText({
|
|
24
|
+
style: styleRef,
|
|
25
|
+
stylesheet,
|
|
26
|
+
application: "client-side",
|
|
27
|
+
note: "Apply this MapLibre stylesheet client-side. MCP does not mutate server state; persisting a preset to a map or service uses the gRPC execution layer.",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -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;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;EAajB,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":"count-features.d.ts","sourceRoot":"","sources":["../../../src/tools/count-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;EAajB,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;;;;;GAqB9D"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { GEOMETRY_TYPES, jsonText, mapSpatialRel, resolveGeometryType } from "../helpers.js";
|
|
2
|
+
import { GEOMETRY_TYPES, coerceCount, jsonText, mapSpatialRel, resolveGeometryType } from "../helpers.js";
|
|
3
3
|
export const schema = z.object({
|
|
4
4
|
serviceId: z.string().describe("The feature service ID"),
|
|
5
5
|
layerId: z.number().int().nonnegative().describe("The layer ID within the service"),
|
|
@@ -26,9 +26,10 @@ export async function execute(client, input) {
|
|
|
26
26
|
outFields: "OBJECTID",
|
|
27
27
|
extraParams: { returnCountOnly: true },
|
|
28
28
|
}));
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
// The default grpc-web transport returns very large counts as a string to
|
|
30
|
+
// preserve precision beyond Number.MAX_SAFE_INTEGER; accept both forms.
|
|
31
|
+
const count = coerceCount(response.count);
|
|
32
|
+
if (count === undefined) {
|
|
32
33
|
throw new Error("Count query did not return a numeric count.");
|
|
33
34
|
}
|
|
34
35
|
return jsonText({ count });
|
|
@@ -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;AAGxB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;EAajB,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;AAGxB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;EAajB,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;;;;;GAoC9D"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { GEOMETRY_TYPES, jsonText, mapSpatialRel, resolveGeometryType } from "../helpers.js";
|
|
2
|
+
import { GEOMETRY_TYPES, coerceCount, jsonText, mapSpatialRel, resolveGeometryType } from "../helpers.js";
|
|
3
3
|
export const schema = z.object({
|
|
4
4
|
serviceId: z.string().describe("The feature service ID"),
|
|
5
5
|
layerId: z.number().int().nonnegative().describe("The layer ID within the service"),
|
|
@@ -25,8 +25,9 @@ export async function execute(client, input) {
|
|
|
25
25
|
returnGeometry: false,
|
|
26
26
|
extraParams: { returnExtentOnly: true },
|
|
27
27
|
}));
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// Accept large counts returned as strings by the grpc-web transport (chosen
|
|
29
|
+
// to preserve precision beyond Number.MAX_SAFE_INTEGER) as well as numbers.
|
|
30
|
+
const count = coerceCount(response.count);
|
|
30
31
|
const hasExtent = Object.prototype.hasOwnProperty.call(response, "extent");
|
|
31
32
|
if (!hasExtent) {
|
|
32
33
|
// Some backends can return count-only payloads for empty extent queries.
|
|
@@ -39,7 +40,8 @@ export async function execute(client, input) {
|
|
|
39
40
|
if (response.extent === null) {
|
|
40
41
|
extent = null;
|
|
41
42
|
}
|
|
42
|
-
else if (typeof response.extent === "object") {
|
|
43
|
+
else if (typeof response.extent === "object" && !Array.isArray(response.extent)) {
|
|
44
|
+
// A JSON array is `typeof "object"` but is not a valid extent envelope.
|
|
43
45
|
extent = response.extent;
|
|
44
46
|
}
|
|
45
47
|
else {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HonuaClient } from "@honua/sdk-js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const schema: z.ZodObject<{
|
|
4
|
+
styleId: z.ZodOptional<z.ZodString>;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
styleId?: string | undefined;
|
|
7
|
+
}, {
|
|
8
|
+
styleId?: string | undefined;
|
|
9
|
+
}>;
|
|
10
|
+
export type Input = z.infer<typeof schema>;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a style from the server's OGC API – Styles surface. With a `styleId`,
|
|
13
|
+
* returns the canonical `StyleRef` projection (style_id / title / description /
|
|
14
|
+
* style_version / encodings / legend_url), with the MapLibre stylesheet inlined.
|
|
15
|
+
* Without a `styleId`, returns the styles catalog so an agent can discover what
|
|
16
|
+
* is available.
|
|
17
|
+
*/
|
|
18
|
+
export declare function execute(client: HonuaClient, input: Input): Promise<{
|
|
19
|
+
content: Array<{
|
|
20
|
+
type: "text";
|
|
21
|
+
text: string;
|
|
22
|
+
}>;
|
|
23
|
+
}>;
|
|
24
|
+
//# sourceMappingURL=get-style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-style.d.ts","sourceRoot":"","sources":["../../../src/tools/get-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,MAAM;;;;;;EAEjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;;;;;GAe9D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonText } from "../helpers.js";
|
|
3
|
+
import { listStyles, resolveStyleRef } from "../styles.js";
|
|
4
|
+
export const schema = z.object({
|
|
5
|
+
styleId: z.string().optional().describe("Stable style identifier. Omit to list the styles available on the server."),
|
|
6
|
+
});
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a style from the server's OGC API – Styles surface. With a `styleId`,
|
|
9
|
+
* returns the canonical `StyleRef` projection (style_id / title / description /
|
|
10
|
+
* style_version / encodings / legend_url), with the MapLibre stylesheet inlined.
|
|
11
|
+
* Without a `styleId`, returns the styles catalog so an agent can discover what
|
|
12
|
+
* is available.
|
|
13
|
+
*/
|
|
14
|
+
export async function execute(client, input) {
|
|
15
|
+
if (!input.styleId) {
|
|
16
|
+
const list = await listStyles(client);
|
|
17
|
+
return jsonText({
|
|
18
|
+
styles: list.styles.map((entry) => ({
|
|
19
|
+
styleId: entry.id,
|
|
20
|
+
title: entry.title ?? entry.id,
|
|
21
|
+
uri: `honua://styles/${encodeURIComponent(entry.id)}`,
|
|
22
|
+
})),
|
|
23
|
+
default: list.default ?? null,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const styleRef = await resolveStyleRef(client, input.styleId);
|
|
27
|
+
return jsonText(styleRef);
|
|
28
|
+
}
|
|
@@ -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;AAGxB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBjB,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;AAGxB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBjB,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;;;;;GA+B9D"}
|
|
@@ -24,7 +24,10 @@ export async function execute(client, input) {
|
|
|
24
24
|
serviceId: input.serviceId,
|
|
25
25
|
layerId: input.layerId,
|
|
26
26
|
where: input.where,
|
|
27
|
-
|
|
27
|
+
// An empty array is a natural "no specific fields" from an agent, but Esri
|
|
28
|
+
// FeatureServer treats an empty outFields as "OBJECTID only". Coerce both
|
|
29
|
+
// missing and empty to "*" so all fields are returned.
|
|
30
|
+
outFields: input.outFields && input.outFields.length > 0 ? input.outFields : "*",
|
|
28
31
|
geometry: input.geometry,
|
|
29
32
|
geometryType: resolveGeometryType(input.geometry, input.geometryType),
|
|
30
33
|
spatialRel: mapSpatialRel(input.spatialRel),
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@honua/mcp-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20-alpha.0",
|
|
4
4
|
"description": "MCP server for Honua geospatial feature services",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"honua-mcp": "dist/src/index.js"
|
|
7
|
+
"honua-mcp": "dist/src/index.js",
|
|
8
|
+
"honua-mcp-proxy": "dist/src/proxy.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
11
|
"clean": "rm -rf dist coverage",
|
|
@@ -14,6 +15,14 @@
|
|
|
14
15
|
"test": "npm run build --silent && vitest run --coverage",
|
|
15
16
|
"test:unit": "vitest run",
|
|
16
17
|
"test:coverage": "vitest run --coverage",
|
|
18
|
+
"certify": "npm run build --silent && node dist/src/certification/cli.js",
|
|
19
|
+
"test:certification": "npm run build --silent && vitest run test/certification && node dist/src/certification/cli.js",
|
|
20
|
+
"test:certification:artifact": "npm run build --silent && node dist/src/certification/cli.js --artifact-only",
|
|
21
|
+
"eval": "npm run build --silent && node dist/src/eval/cli.js",
|
|
22
|
+
"eval:offline": "npm run build --silent && node dist/src/eval/cli.js --offline",
|
|
23
|
+
"eval:live": "npm run build --silent && node dist/src/eval/cli.js --corpus operator --artifact-only",
|
|
24
|
+
"test:eval": "npm run build --silent && vitest run test/eval && node dist/src/eval/cli.js --offline",
|
|
25
|
+
"test:eval:artifact": "npm run build --silent && node dist/src/eval/cli.js --artifact-only",
|
|
17
26
|
"lint": "biome lint src/ test/",
|
|
18
27
|
"lint:fix": "biome lint --write src/ test/",
|
|
19
28
|
"format": "biome format src/ test/",
|
|
@@ -22,15 +31,20 @@
|
|
|
22
31
|
"check:fix": "biome check --write src/ test/"
|
|
23
32
|
},
|
|
24
33
|
"dependencies": {
|
|
34
|
+
"@aws-sdk/client-bedrock-runtime": "^3.901.0",
|
|
25
35
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
36
|
+
"ajv": "^8.20.0",
|
|
26
37
|
"zod": "^3.24.0"
|
|
27
38
|
},
|
|
39
|
+
"overrides": {
|
|
40
|
+
"hono": "^4.12.21"
|
|
41
|
+
},
|
|
28
42
|
"peerDependencies": {
|
|
29
|
-
"@honua/sdk-js": "^0.0.
|
|
43
|
+
"@honua/sdk-js": "^0.0.20-alpha.0"
|
|
30
44
|
},
|
|
31
45
|
"devDependencies": {
|
|
32
|
-
"@honua/sdk-js": "file:..",
|
|
33
46
|
"@biomejs/biome": "1.9.4",
|
|
47
|
+
"@honua/sdk-js": "file:..",
|
|
34
48
|
"@types/node": "^24.3.1",
|
|
35
49
|
"@vitest/coverage-v8": "^4.0.16",
|
|
36
50
|
"typescript": "^5.9.2",
|
|
@@ -38,6 +52,7 @@
|
|
|
38
52
|
},
|
|
39
53
|
"files": [
|
|
40
54
|
"dist/src",
|
|
55
|
+
"certification/geospatial-mcp-schemas",
|
|
41
56
|
"README.md"
|
|
42
57
|
],
|
|
43
58
|
"engines": {
|