@honua/mcp-server 0.0.20-alpha.0 → 0.1.1-beta.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.
Files changed (107) hide show
  1. package/README.md +141 -15
  2. package/certification/geospatial-mcp-schemas/PROVENANCE.md +15 -7
  3. package/certification/geospatial-mcp-schemas/conformance/manifest.schema.json +6 -0
  4. package/certification/geospatial-mcp-schemas/index.json +88 -9
  5. package/certification/geospatial-mcp-schemas/tools/apply_style_preset.schema.json +13 -9
  6. package/certification/geospatial-mcp-schemas/tools/buffer_features.schema.json +60 -0
  7. package/certification/geospatial-mcp-schemas/tools/edit_features.schema.json +74 -0
  8. package/certification/geospatial-mcp-schemas/tools/export_dataset.schema.json +60 -0
  9. package/certification/geospatial-mcp-schemas/tools/geocode_addresses.schema.json +34 -0
  10. package/certification/geospatial-mcp-schemas/tools/get_style.schema.json +13 -3
  11. package/certification/geospatial-mcp-schemas/tools/ingest_dataset.schema.json +45 -0
  12. package/certification/geospatial-mcp-schemas/tools/join_features.schema.json +73 -0
  13. package/certification/geospatial-mcp-schemas/tools/overlay_features.schema.json +53 -0
  14. package/certification/geospatial-mcp-schemas/tools/query_features.schema.json +20 -0
  15. package/certification/geospatial-mcp-schemas/tools/render_map.schema.json +5 -0
  16. package/certification/geospatial-mcp-schemas/tools/reproject_features.schema.json +49 -0
  17. package/certification/geospatial-mcp-schemas/tools/summarize_statistics.schema.json +71 -0
  18. package/dist/src/agent-execution.d.ts +16 -0
  19. package/dist/src/agent-execution.d.ts.map +1 -0
  20. package/dist/src/agent-execution.js +46 -0
  21. package/dist/src/capability.d.ts +48 -0
  22. package/dist/src/capability.d.ts.map +1 -0
  23. package/dist/src/capability.js +44 -0
  24. package/dist/src/certification/census-data.d.ts +33 -0
  25. package/dist/src/certification/census-data.d.ts.map +1 -0
  26. package/dist/src/certification/census-data.js +506 -0
  27. package/dist/src/certification/census-fixture-client.d.ts +7 -0
  28. package/dist/src/certification/census-fixture-client.d.ts.map +1 -0
  29. package/dist/src/certification/census-fixture-client.js +226 -0
  30. package/dist/src/certification/certifier.d.ts +7 -1
  31. package/dist/src/certification/certifier.d.ts.map +1 -1
  32. package/dist/src/certification/certifier.js +52 -7
  33. package/dist/src/certification/cli.js +19 -4
  34. package/dist/src/certification/contracts.d.ts +41 -0
  35. package/dist/src/certification/contracts.d.ts.map +1 -1
  36. package/dist/src/certification/contracts.js +71 -0
  37. package/dist/src/certification/fixture-client.d.ts.map +1 -1
  38. package/dist/src/certification/fixtures.d.ts +13 -0
  39. package/dist/src/certification/fixtures.d.ts.map +1 -1
  40. package/dist/src/certification/fixtures.js +28 -0
  41. package/dist/src/certification/json-schema.d.ts +23 -1
  42. package/dist/src/certification/json-schema.d.ts.map +1 -1
  43. package/dist/src/certification/json-schema.js +10 -2
  44. package/dist/src/certification/lifecycle.d.ts +14 -0
  45. package/dist/src/certification/lifecycle.d.ts.map +1 -0
  46. package/dist/src/certification/lifecycle.js +326 -0
  47. package/dist/src/certification/operator-catalog.d.ts +8 -0
  48. package/dist/src/certification/operator-catalog.d.ts.map +1 -1
  49. package/dist/src/certification/operator-catalog.js +189 -5
  50. package/dist/src/certification/report.d.ts.map +1 -1
  51. package/dist/src/certification/report.js +13 -0
  52. package/dist/src/certification/run.d.ts.map +1 -1
  53. package/dist/src/certification/run.js +1 -0
  54. package/dist/src/certification/schema-index.d.ts +25 -0
  55. package/dist/src/certification/schema-index.d.ts.map +1 -1
  56. package/dist/src/certification/schema-index.js +27 -0
  57. package/dist/src/certification/target.d.ts +9 -1
  58. package/dist/src/certification/target.d.ts.map +1 -1
  59. package/dist/src/certification/target.js +54 -2
  60. package/dist/src/eval/cli.js +4 -2
  61. package/dist/src/eval/corpus.d.ts +7 -0
  62. package/dist/src/eval/corpus.d.ts.map +1 -1
  63. package/dist/src/eval/corpus.js +16 -0
  64. package/dist/src/eval/drivers/deterministic.d.ts.map +1 -1
  65. package/dist/src/eval/drivers/deterministic.js +13 -0
  66. package/dist/src/eval/grade.d.ts.map +1 -1
  67. package/dist/src/eval/grade.js +20 -1
  68. package/dist/src/eval/report.d.ts +5 -0
  69. package/dist/src/eval/report.d.ts.map +1 -1
  70. package/dist/src/eval/report.js +3 -0
  71. package/dist/src/eval/runner.d.ts +6 -0
  72. package/dist/src/eval/runner.d.ts.map +1 -1
  73. package/dist/src/eval/runner.js +21 -7
  74. package/dist/src/eval/standalone-corpus.d.ts +3 -0
  75. package/dist/src/eval/standalone-corpus.d.ts.map +1 -0
  76. package/dist/src/eval/standalone-corpus.js +699 -0
  77. package/dist/src/eval/types.d.ts +25 -0
  78. package/dist/src/eval/types.d.ts.map +1 -1
  79. package/dist/src/helpers.d.ts +1 -1
  80. package/dist/src/helpers.d.ts.map +1 -1
  81. package/dist/src/index.d.ts +37 -6
  82. package/dist/src/index.d.ts.map +1 -1
  83. package/dist/src/index.js +47 -22
  84. package/dist/src/nl-map-control.d.ts +70 -0
  85. package/dist/src/nl-map-control.d.ts.map +1 -0
  86. package/dist/src/nl-map-control.js +470 -0
  87. package/dist/src/provenance.d.ts +44 -0
  88. package/dist/src/provenance.d.ts.map +1 -0
  89. package/dist/src/provenance.js +37 -0
  90. package/dist/src/resources/styles.d.ts.map +1 -1
  91. package/dist/src/resources/styles.js +36 -3
  92. package/dist/src/stable-json.d.ts +14 -0
  93. package/dist/src/stable-json.d.ts.map +1 -0
  94. package/dist/src/stable-json.js +126 -0
  95. package/dist/src/styles.d.ts +2 -0
  96. package/dist/src/styles.d.ts.map +1 -1
  97. package/dist/src/styles.js +29 -3
  98. package/dist/src/tools/apply-style-preset.d.ts.map +1 -1
  99. package/dist/src/tools/apply-style-preset.js +14 -2
  100. package/dist/src/tools/explain-capability-gap.d.ts +3 -3
  101. package/dist/src/tools/explain-capability-gap.d.ts.map +1 -1
  102. package/dist/src/tools/explain-capability-gap.js +1 -1
  103. package/dist/src/tools/get-style.d.ts.map +1 -1
  104. package/dist/src/tools/get-style.js +24 -13
  105. package/dist/src/tools/list-services.d.ts.map +1 -1
  106. package/dist/src/tools/list-services.js +16 -1
  107. package/package.json +27 -2
@@ -0,0 +1,60 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/export_dataset.schema.json",
4
+ "title": "export_dataset inputSchema",
5
+ "description": "Direct geoprocessing verb (advertised name honua_export_dataset): materialize a dataset — a published layer or a prior verb/job result — into a downloadable artifact in the requested format and return an ArtifactRef with a content locator. Use this for a single self-contained export step (\"export the intersect result as GeoPackage\"); for multi-step analysis with dependencies and a packaged result, use plan_analysis + execute_plan instead. Member of the standard's opt-in **analysis** conformance profile (see /CONFORMANCE.md and docs/adr/0029-direct-geoprocessing-verbs.md). Long-running calls return an ExecutionJob handle (honua://jobs/{job_id}), pollable and cancelable via cancel_job; small/fast calls may return an inline result referencing the produced artifact. Advertised readOnlyHint: false — it writes a new downloadable artifact — but non-destructive (it creates a new artifact and mutates no source records) and idempotent. It is NOT feature mutation and is not part of the mutation profile. x-honua-reference-shape: the concrete source (serviceId/layerId, artifactId) spellings track the reference pipeline.",
6
+ "x-honua-reference-shape": true,
7
+ "type": "object",
8
+ "required": ["source", "format"],
9
+ "properties": {
10
+ "source": {
11
+ "description": "Dataset to export: EITHER a published layer (serviceId + layerId) OR a prior-result artifact (artifactId) from an earlier analysis job or verb.",
12
+ "oneOf": [
13
+ { "$ref": "#/$defs/layerRef" },
14
+ { "$ref": "#/$defs/artifactRef" }
15
+ ]
16
+ },
17
+ "format": {
18
+ "type": "string",
19
+ "enum": ["geojson", "geopackage", "csv", "parquet"],
20
+ "description": "Output format. geojson: RFC 7946 features. geopackage: OGC GeoPackage (.gpkg). csv: attribute rows (geometry as WKT when returnGeometry). parquet: (Geo)Parquet columnar."
21
+ },
22
+ "where": {
23
+ "type": "string",
24
+ "description": "Optional attribute filter (ArcGIS/SQL WHERE clause) selecting which features to export."
25
+ },
26
+ "outFields": {
27
+ "type": "array",
28
+ "items": { "type": "string" },
29
+ "description": "Optional attribute fields to include; omit for all fields."
30
+ },
31
+ "returnGeometry": {
32
+ "type": "boolean",
33
+ "default": true,
34
+ "description": "When false, export attributes only (no geometry). csv/parquet exports of attribute tables commonly set this false."
35
+ },
36
+ "outSrid": {
37
+ "type": "integer",
38
+ "description": "Output spatial reference (SRID/WKID) for exported geometries; defaults to the source CRS."
39
+ }
40
+ },
41
+ "$defs": {
42
+ "layerRef": {
43
+ "type": "object",
44
+ "required": ["serviceId", "layerId"],
45
+ "additionalProperties": false,
46
+ "properties": {
47
+ "serviceId": { "type": "string", "minLength": 1, "description": "Published service identifier or name (from list_layers.serviceId or resolve_entity)." },
48
+ "layerId": { "type": "integer", "minimum": 0, "description": "Service-local layer index (from list_layers.layerId)." }
49
+ }
50
+ },
51
+ "artifactRef": {
52
+ "type": "object",
53
+ "required": ["artifactId"],
54
+ "additionalProperties": false,
55
+ "properties": {
56
+ "artifactId": { "type": "string", "minLength": 1, "description": "Identifier (artifact_…) of a prior-result ArtifactRef produced by an earlier analysis job or verb. See resources/artifact.schema.json." }
57
+ }
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/geocode_addresses.schema.json",
4
+ "title": "geocode_addresses inputSchema",
5
+ "description": "Argument shape for the analysis/geoprocessing batch geocode tool (advertised name honua_geocode_addresses). Resolves up to 100 freeform addresses in one call, returning one result per input in input order ({input, ok, location?, score?, error?}); a failed address surfaces per item without failing the batch. First step of the CSV-of-addresses workflow: geocode here, then load the coordinates with ingest_dataset and publish the table with publish_service. x-honua-reference-shape: this shape tracks the reference implementation.",
6
+ "x-honua-reference-shape": true,
7
+ "type": "object",
8
+ "required": ["addresses"],
9
+ "properties": {
10
+ "addresses": {
11
+ "type": "array",
12
+ "minItems": 1,
13
+ "maxItems": 100,
14
+ "items": {
15
+ "type": "string",
16
+ "minLength": 1
17
+ },
18
+ "description": "Freeform single-line addresses to geocode, in the order results should be returned."
19
+ },
20
+ "countryCodes": {
21
+ "type": "string",
22
+ "description": "Optional comma-separated ISO 3166 country codes to restrict the search."
23
+ },
24
+ "outSrid": {
25
+ "type": "integer",
26
+ "default": 4326,
27
+ "description": "Spatial reference (SRID/WKID) for returned coordinates (x=longitude, y=latitude order). Defaults to 4326 (WGS84 lon/lat)."
28
+ },
29
+ "provider": {
30
+ "type": "string",
31
+ "description": "Optional preferred geocoding provider name."
32
+ }
33
+ }
34
+ }
@@ -2,13 +2,23 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/get_style.schema.json",
4
4
  "title": "get_style inputSchema",
5
- "description": "Argument shape for get_style (Analyze, Publish Data, Build App). Read-only style inspection: with styleId, resolves a single canonical StyleRef (style_id/title/encodings) from the server OGC API – Styles surface; without styleId, lists the available styles (honua://styles). Like every MCP tool it is read-only and never mutates server-side styles. See taxonomy.md §Style inspection and resources.md §honua://styles/{style_id}.",
5
+ "description": "Argument shape for get_style (Analyze, Publish Data, Build App). Read-only style inspection: with styleId, resolves a single canonical StyleRef (style_id/title/encodings) from the server OGC API – Styles surface; with serviceId+layerId (a reference-implementation convenience) resolves the primary/default StyleRef bound to that published layer; with none of these, lists the available styles (honua://styles). Like every MCP tool it is read-only and never mutates server-side styles. See taxonomy.md §Style inspection and resources.md §honua://styles.",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "styleId": {
9
9
  "type": "string",
10
10
  "minLength": 1,
11
- "description": "StyleRef identifier (style_…) to resolve. When omitted, the tool lists the available styles (honua://styles)."
11
+ "description": "StyleRef identifier (style_…) to resolve. When omitted, the tool resolves the styleId bound to serviceId+layerId, or lists the available styles (honua://styles) when neither is given."
12
+ },
13
+ "serviceId": {
14
+ "type": "string",
15
+ "minLength": 1,
16
+ "description": "Reference-implementation shape (honua_get_style): published service identifier or name. Paired with layerId, resolves that layer's primary/default StyleRef when styleId is omitted."
17
+ },
18
+ "layerId": {
19
+ "type": "integer",
20
+ "minimum": 0,
21
+ "description": "Reference-implementation shape (honua_get_style): service-local layer index. Paired with serviceId, resolves that layer's primary/default StyleRef when styleId is omitted."
12
22
  },
13
23
  "encoding": {
14
24
  "type": "string",
@@ -24,7 +34,7 @@
24
34
  },
25
35
  "includeStylesheet": {
26
36
  "type": "boolean",
27
- "description": "When true and styleId is set, include the resolved stylesheet body (inlineBody) for the selected encoding; otherwise the StyleRef projection advertises derived encodings by reference (storageRef)."
37
+ "description": "When true and a single style resolves, include the resolved stylesheet body (inlineBody) for the selected encoding; otherwise the StyleRef projection advertises derived encodings by reference (storageRef)."
28
38
  }
29
39
  }
30
40
  }
@@ -0,0 +1,45 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/ingest_dataset.schema.json",
4
+ "title": "ingest_dataset inputSchema",
5
+ "description": "Argument shape for the Publish Data ingest tool (advertised name honua_ingest_dataset). Loads a small inline dataset (CSV with a header row, or a GeoJSON FeatureCollection; 4 MB cap) into the reference implementation's catalog database as a table, returning the {connectionId, schema, table} triple plus row count and per-row errors so the result chains directly into publish_service. CSV point geometry comes from longitude/latitude columns (auto-detected or explicit), a WKT column, or a server-geocoded address column; coordinate order is lon/lat and the CRS defaults to EPSG:4326. x-honua-reference-shape: this shape tracks the reference implementation.",
6
+ "x-honua-reference-shape": true,
7
+ "type": "object",
8
+ "required": ["format", "data", "datasetName"],
9
+ "properties": {
10
+ "format": {
11
+ "type": "string",
12
+ "enum": ["csv", "geojson"],
13
+ "description": "Inline data format: \"csv\" (text with a header row) or \"geojson\" (a GeoJSON FeatureCollection document)."
14
+ },
15
+ "data": {
16
+ "type": "string",
17
+ "minLength": 1,
18
+ "description": "The dataset content, inline. Capped at 4 MB; larger datasets use the implementation's out-of-band upload surface."
19
+ },
20
+ "datasetName": {
21
+ "type": "string",
22
+ "minLength": 1,
23
+ "maxLength": 63,
24
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
25
+ "description": "Target dataset/table name (letters, digits, underscores; must not start with a digit)."
26
+ },
27
+ "sourceSrid": {
28
+ "type": "integer",
29
+ "default": 4326,
30
+ "description": "Spatial reference (SRID/WKID) of the input coordinates; data is stored in EPSG:4326. Defaults to 4326 (WGS84 lon/lat)."
31
+ },
32
+ "longitudeColumn": {
33
+ "type": "string",
34
+ "description": "CSV only: explicit longitude (X) column name. Pair with latitudeColumn. When omitted, lon/lng/long/longitude/x is auto-detected."
35
+ },
36
+ "latitudeColumn": {
37
+ "type": "string",
38
+ "description": "CSV only: explicit latitude (Y) column name. Pair with longitudeColumn. When omitted, lat/latitude/y is auto-detected."
39
+ },
40
+ "addressColumn": {
41
+ "type": "string",
42
+ "description": "CSV only: column holding freeform addresses to geocode into point geometry server-side (up to 100 rows). Mutually exclusive with longitudeColumn/latitudeColumn."
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/join_features.schema.json",
4
+ "title": "join_features inputSchema",
5
+ "description": "Direct geoprocessing verb (advertised name honua_join_features): join a second dataset onto a target dataset — either an attribute join on matching key fields or a spatial join by geometric relationship — and return the joined features. Use this for a single self-contained join step (\"attach the demographics table to the tracts\", \"tag each incident with the county it falls in\"); for multi-step analysis with dependencies and a packaged result, use plan_analysis + execute_plan instead. Member of the standard's opt-in **analysis** conformance profile (see /CONFORMANCE.md and docs/adr/0029-direct-geoprocessing-verbs.md). Long-running calls return an ExecutionJob handle (honua://jobs/{job_id}), pollable and cancelable via cancel_job; small/fast calls may return an inline result. Advertised readOnlyHint: true (computes a derived result; mutates no server state). x-honua-reference-shape: the concrete source (serviceId/layerId, artifactId) spellings track the reference pipeline.",
6
+ "x-honua-reference-shape": true,
7
+ "type": "object",
8
+ "required": ["target", "join", "joinType"],
9
+ "properties": {
10
+ "target": {
11
+ "description": "Target (left) dataset whose features are kept and enriched: EITHER a published layer (serviceId + layerId) OR a prior-result artifact (artifactId).",
12
+ "oneOf": [
13
+ { "$ref": "#/$defs/layerRef" },
14
+ { "$ref": "#/$defs/artifactRef" }
15
+ ]
16
+ },
17
+ "join": {
18
+ "description": "Join (right) dataset supplying attributes to append: EITHER a published layer (serviceId + layerId) OR a prior-result artifact (artifactId).",
19
+ "oneOf": [
20
+ { "$ref": "#/$defs/layerRef" },
21
+ { "$ref": "#/$defs/artifactRef" }
22
+ ]
23
+ },
24
+ "joinType": {
25
+ "type": "string",
26
+ "enum": ["attribute", "spatial"],
27
+ "description": "attribute: match on equal key fields (targetField = joinField). spatial: match by geometric relationship (spatialRelationship)."
28
+ },
29
+ "targetField": {
30
+ "type": "string",
31
+ "description": "Attribute join only: key field on the target dataset. Required when joinType is attribute."
32
+ },
33
+ "joinField": {
34
+ "type": "string",
35
+ "description": "Attribute join only: key field on the join dataset matched against targetField. Required when joinType is attribute."
36
+ },
37
+ "spatialRelationship": {
38
+ "type": "string",
39
+ "enum": ["intersects", "contains", "within", "nearest"],
40
+ "description": "Spatial join only: geometric predicate relating a target feature to join features. Required when joinType is spatial."
41
+ },
42
+ "joinOperation": {
43
+ "type": "string",
44
+ "default": "one_to_one",
45
+ "enum": ["one_to_one", "one_to_many"],
46
+ "description": "one_to_one: one output row per target feature (matches aggregated per joinAggregation on conflict). one_to_many: one output row per matching pair."
47
+ },
48
+ "joinAggregation": {
49
+ "type": "string",
50
+ "enum": ["first", "count", "sum", "min", "max", "mean"],
51
+ "description": "one_to_one only: how to reduce multiple matches for a target feature. Defaults to an implementation-defined first-match when omitted."
52
+ }
53
+ },
54
+ "$defs": {
55
+ "layerRef": {
56
+ "type": "object",
57
+ "required": ["serviceId", "layerId"],
58
+ "additionalProperties": false,
59
+ "properties": {
60
+ "serviceId": { "type": "string", "minLength": 1, "description": "Published service identifier or name (from list_layers.serviceId or resolve_entity)." },
61
+ "layerId": { "type": "integer", "minimum": 0, "description": "Service-local layer index (from list_layers.layerId)." }
62
+ }
63
+ },
64
+ "artifactRef": {
65
+ "type": "object",
66
+ "required": ["artifactId"],
67
+ "additionalProperties": false,
68
+ "properties": {
69
+ "artifactId": { "type": "string", "minLength": 1, "description": "Identifier (artifact_…) of a prior-result ArtifactRef produced by an earlier analysis job or verb. See resources/artifact.schema.json." }
70
+ }
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/overlay_features.schema.json",
4
+ "title": "overlay_features inputSchema",
5
+ "description": "Direct geoprocessing verb (advertised name honua_overlay_features): compute a two-input topological overlay (intersect, union, difference, erase, or clip) and return the result features. Use this for a single self-contained overlay step (\"intersect the flood zones with the parcels\"); for multi-step analysis with dependencies and a packaged result, use plan_analysis + execute_plan instead. Member of the standard's opt-in **analysis** conformance profile (see /CONFORMANCE.md and docs/adr/0029-direct-geoprocessing-verbs.md). Long-running calls return an ExecutionJob handle (honua://jobs/{job_id}), pollable and cancelable via cancel_job; small/fast calls may return an inline result. Advertised readOnlyHint: true (computes a derived result; mutates no server state). x-honua-reference-shape: the concrete source (serviceId/layerId, artifactId) spellings track the reference pipeline.",
6
+ "x-honua-reference-shape": true,
7
+ "type": "object",
8
+ "required": ["source", "overlay", "operation"],
9
+ "properties": {
10
+ "source": {
11
+ "description": "Primary input dataset: EITHER a published layer (serviceId + layerId) OR a prior-result artifact (artifactId).",
12
+ "oneOf": [
13
+ { "$ref": "#/$defs/layerRef" },
14
+ { "$ref": "#/$defs/artifactRef" }
15
+ ]
16
+ },
17
+ "overlay": {
18
+ "description": "Overlay dataset combined with source: EITHER a published layer (serviceId + layerId) OR a prior-result artifact (artifactId).",
19
+ "oneOf": [
20
+ { "$ref": "#/$defs/layerRef" },
21
+ { "$ref": "#/$defs/artifactRef" }
22
+ ]
23
+ },
24
+ "operation": {
25
+ "type": "string",
26
+ "enum": ["intersect", "union", "difference", "erase", "clip"],
27
+ "description": "Overlay operation. intersect: geometry AND attributes of both where they overlap. union: full combination of both inputs. difference: source minus overlay (source attributes kept). erase: remove the overlay area from source. clip: cut source to the overlay boundary (source attributes only)."
28
+ },
29
+ "outSrid": {
30
+ "type": "integer",
31
+ "description": "Output spatial reference (SRID/WKID) for the returned overlay features; defaults to the source CRS."
32
+ }
33
+ },
34
+ "$defs": {
35
+ "layerRef": {
36
+ "type": "object",
37
+ "required": ["serviceId", "layerId"],
38
+ "additionalProperties": false,
39
+ "properties": {
40
+ "serviceId": { "type": "string", "minLength": 1, "description": "Published service identifier or name (from list_layers.serviceId or resolve_entity)." },
41
+ "layerId": { "type": "integer", "minimum": 0, "description": "Service-local layer index (from list_layers.layerId)." }
42
+ }
43
+ },
44
+ "artifactRef": {
45
+ "type": "object",
46
+ "required": ["artifactId"],
47
+ "additionalProperties": false,
48
+ "properties": {
49
+ "artifactId": { "type": "string", "minLength": 1, "description": "Identifier (artifact_…) of a prior-result ArtifactRef produced by an earlier analysis job or verb. See resources/artifact.schema.json." }
50
+ }
51
+ }
52
+ }
53
+ }
@@ -45,10 +45,30 @@
45
45
  "default": 100,
46
46
  "description": "Maximum number of features to return (capped at 1000)."
47
47
  },
48
+ "resultOffset": {
49
+ "type": "integer",
50
+ "minimum": 0,
51
+ "default": 0,
52
+ "description": "Number of matching features to skip before returning results (pagination). Pair with limit to page mechanically through large result sets: when a response reports exceededTransferLimit=true, re-issue the same query with resultOffset set to the returned nextOffset until exceededTransferLimit is false."
53
+ },
54
+ "returnGeometry": {
55
+ "type": "boolean",
56
+ "default": true,
57
+ "description": "When false, features are returned without geometry (attribute-only rows). Use for attribute scans where returning geometry would waste the response/context budget."
58
+ },
59
+ "returnCountOnly": {
60
+ "type": "boolean",
61
+ "default": false,
62
+ "description": "When true, return only the matching feature count and no features. Use for cheap cardinality checks before deciding whether/how to page."
63
+ },
48
64
  "outSrid": {
49
65
  "type": "integer",
50
66
  "default": 4326,
51
67
  "description": "Output spatial reference (SRID/WKID) for returned geometries."
68
+ },
69
+ "geometryPrecision": {
70
+ "type": "integer",
71
+ "description": "Optional number of decimal places to round returned GeoJSON coordinates to, trading positional precision for a smaller response/context budget. A negative value returns full precision. When omitted, precision is implementation-defined; the reference implementation defaults to 6 (~0.1 m), which cuts coordinate payload roughly 12% at the default and far more for dense geometries. Standardized from the honua-server x-honua extension (geospatial-mcp#52)."
52
72
  }
53
73
  }
54
74
  }
@@ -50,6 +50,11 @@
50
50
  "type": "boolean",
51
51
  "default": false,
52
52
  "description": "Render a transparent background instead of an opaque one."
53
+ },
54
+ "maxInlineBytes": {
55
+ "type": "integer",
56
+ "minimum": 0,
57
+ "description": "Optional ceiling, in bytes, on inline base64 image content. When the rendered image is at or below this size it may be returned inline; above it, the tool returns a resource_link href to the image instead of inlining megabytes of PNG into model context. When omitted, inlining behavior is implementation-defined; the reference implementation defaults to returning a resource_link href rather than inlining. Standardized from the honua-server x-honua extension (geospatial-mcp#52)."
53
58
  }
54
59
  }
55
60
  }
@@ -0,0 +1,49 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/reproject_features.schema.json",
4
+ "title": "reproject_features inputSchema",
5
+ "description": "Direct geoprocessing verb (advertised name honua_reproject_features): reproject a whole dataset into a target spatial reference and return the reprojected features. Use this when reprojection is the goal (\"give me this layer in EPSG:3857\"); when you only need another verb's output in a particular CRS, prefer that verb's optional outSrid param instead of a second call. For multi-step analysis with dependencies and a packaged result, use plan_analysis + execute_plan instead. Member of the standard's opt-in **analysis** conformance profile (see /CONFORMANCE.md and docs/adr/0029-direct-geoprocessing-verbs.md). Long-running calls return an ExecutionJob handle (honua://jobs/{job_id}), pollable and cancelable via cancel_job; small/fast calls may return an inline result. Advertised readOnlyHint: true (computes a derived result; mutates no server state). x-honua-reference-shape: the concrete source (serviceId/layerId, artifactId) spellings track the reference pipeline.",
6
+ "x-honua-reference-shape": true,
7
+ "type": "object",
8
+ "required": ["source", "targetSrid"],
9
+ "properties": {
10
+ "source": {
11
+ "description": "Dataset to reproject: EITHER a published layer (serviceId + layerId) OR a prior-result artifact (artifactId).",
12
+ "oneOf": [
13
+ { "$ref": "#/$defs/layerRef" },
14
+ { "$ref": "#/$defs/artifactRef" }
15
+ ]
16
+ },
17
+ "targetSrid": {
18
+ "type": "integer",
19
+ "description": "Target spatial reference (SRID/WKID) to reproject into. Required — it is the operation's defining parameter."
20
+ },
21
+ "sourceSrid": {
22
+ "type": "integer",
23
+ "description": "Spatial reference (SRID/WKID) of the input geometries; defaults to the dataset's declared CRS. Provide only to override a missing or incorrect source CRS."
24
+ },
25
+ "where": {
26
+ "type": "string",
27
+ "description": "Optional attribute filter (ArcGIS/SQL WHERE clause) selecting which input features to reproject."
28
+ }
29
+ },
30
+ "$defs": {
31
+ "layerRef": {
32
+ "type": "object",
33
+ "required": ["serviceId", "layerId"],
34
+ "additionalProperties": false,
35
+ "properties": {
36
+ "serviceId": { "type": "string", "minLength": 1, "description": "Published service identifier or name (from list_layers.serviceId or resolve_entity)." },
37
+ "layerId": { "type": "integer", "minimum": 0, "description": "Service-local layer index (from list_layers.layerId)." }
38
+ }
39
+ },
40
+ "artifactRef": {
41
+ "type": "object",
42
+ "required": ["artifactId"],
43
+ "additionalProperties": false,
44
+ "properties": {
45
+ "artifactId": { "type": "string", "minLength": 1, "description": "Identifier (artifact_…) of a prior-result ArtifactRef produced by an earlier analysis job or verb. See resources/artifact.schema.json." }
46
+ }
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://geospatial-mcp.honua.io/spec/schemas/tools/summarize_statistics.schema.json",
4
+ "title": "summarize_statistics inputSchema",
5
+ "description": "Direct geoprocessing verb (advertised name honua_summarize_statistics): compute summary statistics over a dataset, optionally grouped by attribute fields, and return the summary rows. Use this for a single self-contained summary step (\"total population by county\", \"mean parcel value by zoning\") over a layer or a prior overlay/verb result; for multi-step analysis with dependencies and a packaged result, use plan_analysis + execute_plan instead. Member of the standard's opt-in **analysis** conformance profile (see /CONFORMANCE.md and docs/adr/0029-direct-geoprocessing-verbs.md). Long-running calls return an ExecutionJob handle (honua://jobs/{job_id}), pollable and cancelable via cancel_job; small/fast calls may return an inline result. Advertised readOnlyHint: true (computes a derived result; mutates no server state). x-honua-reference-shape: the concrete source (serviceId/layerId, artifactId) spellings track the reference pipeline.",
6
+ "x-honua-reference-shape": true,
7
+ "type": "object",
8
+ "required": ["source", "statistics"],
9
+ "properties": {
10
+ "source": {
11
+ "description": "Dataset to summarize: EITHER a published layer (serviceId + layerId) OR a prior-result artifact (artifactId) such as an overlay_features or join_features result.",
12
+ "oneOf": [
13
+ { "$ref": "#/$defs/layerRef" },
14
+ { "$ref": "#/$defs/artifactRef" }
15
+ ]
16
+ },
17
+ "groupByFields": {
18
+ "type": "array",
19
+ "items": { "type": "string" },
20
+ "description": "Attribute fields to group by. Omit for a single summary row over all matching features."
21
+ },
22
+ "statistics": {
23
+ "type": "array",
24
+ "minItems": 1,
25
+ "description": "Statistics to compute. Each entry names a statistic type and the field it is computed on.",
26
+ "items": {
27
+ "type": "object",
28
+ "required": ["statisticType", "onField"],
29
+ "additionalProperties": false,
30
+ "properties": {
31
+ "statisticType": {
32
+ "type": "string",
33
+ "enum": ["count", "sum", "min", "max", "mean", "stddev", "var"],
34
+ "description": "Aggregate to compute. count ignores onField values (counts rows)."
35
+ },
36
+ "onField": {
37
+ "type": "string",
38
+ "description": "Attribute field the statistic is computed on."
39
+ },
40
+ "outField": {
41
+ "type": "string",
42
+ "description": "Optional name for the output column; defaults to an implementation-defined name derived from statisticType and onField."
43
+ }
44
+ }
45
+ }
46
+ },
47
+ "where": {
48
+ "type": "string",
49
+ "description": "Optional attribute filter (ArcGIS/SQL WHERE clause) selecting which input features are summarized."
50
+ }
51
+ },
52
+ "$defs": {
53
+ "layerRef": {
54
+ "type": "object",
55
+ "required": ["serviceId", "layerId"],
56
+ "additionalProperties": false,
57
+ "properties": {
58
+ "serviceId": { "type": "string", "minLength": 1, "description": "Published service identifier or name (from list_layers.serviceId or resolve_entity)." },
59
+ "layerId": { "type": "integer", "minimum": 0, "description": "Service-local layer index (from list_layers.layerId)." }
60
+ }
61
+ },
62
+ "artifactRef": {
63
+ "type": "object",
64
+ "required": ["artifactId"],
65
+ "additionalProperties": false,
66
+ "properties": {
67
+ "artifactId": { "type": "string", "minLength": 1, "description": "Identifier (artifact_…) of a prior-result ArtifactRef produced by an earlier analysis job or verb. See resources/artifact.schema.json." }
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,16 @@
1
+ import type { AgentOperationExecutorV1 } from "@honua/sdk-js/agent-safety";
2
+ import type { JsonValue } from "@honua/sdk-js/query-planner";
3
+ /** A named, read-only MCP tool handler adapted to the SDK approval boundary. */
4
+ export interface ReadOnlyMcpAgentTool<TArguments> {
5
+ readonly name: string;
6
+ parse(parameters: JsonValue): TArguments;
7
+ execute(arguments_: TArguments, signal?: AbortSignal): Promise<unknown>;
8
+ /** Deterministically count logical rows/records in the returned MCP result. */
9
+ countRows(result: unknown): number;
10
+ }
11
+ /**
12
+ * Adapt a standalone MCP read tool without introducing a second approval or
13
+ * audit model. The SDK validates the exact tool/effect before this handler runs.
14
+ */
15
+ export declare function createReadOnlyMcpAgentExecutor<TArguments>(tool: ReadOnlyMcpAgentTool<TArguments>): AgentOperationExecutorV1;
16
+ //# sourceMappingURL=agent-execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-execution.d.ts","sourceRoot":"","sources":["../../src/agent-execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EAEzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,gFAAgF;AAChF,MAAM,WAAW,oBAAoB,CAAC,UAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,UAAU,EAAE,SAAS,GAAG,UAAU,CAAC;IACzC,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,+EAA+E;IAC/E,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EACvD,IAAI,EAAE,oBAAoB,CAAC,UAAU,CAAC,GACrC,wBAAwB,CA0B1B"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Adapt a standalone MCP read tool without introducing a second approval or
3
+ * audit model. The SDK validates the exact tool/effect before this handler runs.
4
+ */
5
+ export function createReadOnlyMcpAgentExecutor(tool) {
6
+ if (!tool || typeof tool !== "object")
7
+ throw new TypeError("MCP tool descriptor is required");
8
+ const name = dataProperty(tool, "name");
9
+ if (typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_.:-]{0,127}$/.test(name))
10
+ throw new TypeError("MCP tool name must be a bounded exact identifier");
11
+ const parse = callback(tool, "parse");
12
+ const execute = callback(tool, "execute");
13
+ const countRows = callback(tool, "countRows");
14
+ return Object.freeze({
15
+ tool: name,
16
+ effect: "read",
17
+ async execute(operation, _limits, signal) {
18
+ if (operation.tool !== name || operation.effect !== "read")
19
+ throw new TypeError("approved operation does not match the read-only MCP tool");
20
+ const arguments_ = parse(operation.parameters);
21
+ const result = await execute(arguments_, signal);
22
+ const rows = countRows(result);
23
+ if (!Number.isSafeInteger(rows) || rows < 0)
24
+ throw new TypeError("MCP tool row count must be a non-negative safe integer");
25
+ return { rows, value: result };
26
+ },
27
+ });
28
+ }
29
+ function dataProperty(input, key) {
30
+ let descriptor;
31
+ try {
32
+ descriptor = Reflect.getOwnPropertyDescriptor(input, key);
33
+ }
34
+ catch {
35
+ throw new TypeError(`MCP tool ${key} could not be safely captured`);
36
+ }
37
+ if (!descriptor || descriptor.get || descriptor.set)
38
+ throw new TypeError(`MCP tool ${key} must be a data property`);
39
+ return descriptor.value;
40
+ }
41
+ function callback(input, key) {
42
+ const value = dataProperty(input, key);
43
+ if (typeof value !== "function")
44
+ throw new TypeError(`MCP tool ${key} callback is required`);
45
+ return value.bind(input);
46
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Platform-free capability degradation (issue #369).
3
+ *
4
+ * `@honua/mcp-server` runs in two modes: against a Honua-enhanced deployment
5
+ * (which exposes extra surfaces such as OGC API – Styles) and — the platform-free
6
+ * front door — against ANY plain public Esri FeatureServer / OGC endpoint that
7
+ * has none of those surfaces. A tool that depends on a Honua-only surface must
8
+ * NEVER crash, hang, or return misleading empty data on a plain target. Instead
9
+ * it detects the missing surface and reports a clear, structured "not available
10
+ * on this target" result — the same skip-with-reason honesty the certification
11
+ * suite uses.
12
+ *
13
+ * Probing helpers throw {@link CapabilityUnavailableError} when a surface is
14
+ * absent; the tool/resource layer catches it and returns
15
+ * {@link capabilityUnavailable}, a non-error tool result carrying
16
+ * `available: false` plus a human-readable reason.
17
+ */
18
+ export declare class CapabilityUnavailableError extends Error {
19
+ readonly code = "CAPABILITY_UNAVAILABLE";
20
+ /** Human label of the missing surface, e.g. "OGC API - Styles". */
21
+ readonly surface: string;
22
+ /** Why the surface was judged unavailable (status / parse / shape). */
23
+ readonly reason: string;
24
+ constructor(surface: string, reason: string);
25
+ }
26
+ /** Machine-readable body of a graceful capability-degradation result. */
27
+ export interface CapabilityUnavailablePayload {
28
+ available: false;
29
+ surface: string;
30
+ reason: string;
31
+ /** What a client can do instead on a plain public endpoint. */
32
+ guidance: string;
33
+ }
34
+ /**
35
+ * Build a structured "not available on this target" tool/resource result. The
36
+ * result is deliberately NOT an MCP error: a plain FeatureServer legitimately
37
+ * lacks the surface, so degradation is an honest, expected outcome — not a
38
+ * failure. Clients branch on `available === false`.
39
+ */
40
+ export declare function capabilityUnavailablePayload(surface: string, reason: string, guidance: string): CapabilityUnavailablePayload;
41
+ /** Convenience: the {@link capabilityUnavailablePayload} body wrapped as tool text content. */
42
+ export declare function capabilityUnavailable(surface: string, reason: string, guidance: string): {
43
+ content: Array<{
44
+ type: "text";
45
+ text: string;
46
+ }>;
47
+ };
48
+ //# sourceMappingURL=capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/capability.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,IAAI,4BAA4B;IACzC,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAM5C;AAED,yEAAyE;AACzE,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,KAAK,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,4BAA4B,CAE9B;AAED,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;EAEtF"}