@honua/mcp-server 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -67,7 +67,10 @@ and their approval authority are separate.
67
67
  This preview forwards canonical paginated tools, resources, resource templates,
68
68
  prompts, request metadata, tool progress, cancellation, and catalog-change
69
69
  notifications. It negotiates its own MCP identity and preserves the configured
70
- workflow view. It does not advertise subscriptions, sampling, roots,
70
+ workflow view. When a client omits its view, the persistent connector selects
71
+ the server's `full` view so Studio and the other GIS workflows remain
72
+ discoverable on the same registration. This changes discovery only; Server
73
+ RBAC and approval policy still govern every operation. It does not advertise subscriptions, sampling, roots,
71
74
  completions, or tasks. Durable workflow context, command reconciliation, browser
72
75
  pairing, and coordinated Console/Studio artifacts remain tracked in
73
76
  [the unified workspace workstream](https://github.com/honua-io/honua-server/issues/6297).
@@ -1 +1 @@
1
- {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../src/agent/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AA4B/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AA0DrF,MAAM,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9F,oFAAoF;AACpF,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,OAAO,KAAK,GACvB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAMD,gGAAgG;AAChG,qBAAa,iBAAiB;;IAgB1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAlB1B,QAAQ,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAKb;gBAUiB,OAAO,EAAE,YAAY,EACrB,QAAQ,GAAE,eAAsC,EAChD,MAAM,CAAC,EAAE,eAAe,YAAA,EACxB,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO;IAwGvD,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAqD5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,0FAA0F;IACpF,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAuH5C"}
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../src/agent/gateway.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AA8B/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AA2FrF,MAAM,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9F,oFAAoF;AACpF,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,OAAO,KAAK,GACvB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAMD,gGAAgG;AAChG,qBAAa,iBAAiB;;IAgB1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAlB1B,QAAQ,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAKb;gBAUiB,OAAO,EAAE,YAAY,EACrB,QAAQ,GAAE,eAAsC,EAChD,MAAM,CAAC,EAAE,eAAe,YAAA,EACxB,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO;IAoGvD,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAyD5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,0FAA0F;IACpF,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAuH5C"}
@@ -1,11 +1,21 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
3
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
4
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
5
  import { CallToolRequestSchema, CallToolResultSchema, ErrorCode, GetPromptRequestSchema, GetPromptResultSchema, InitializeRequestSchema, ListPromptsRequestSchema, ListPromptsResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListToolsRequestSchema, ListToolsResultSchema, McpError, PromptListChangedNotificationSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, ToolListChangedNotificationSchema, } from "@modelcontextprotocol/sdk/types.js";
5
6
  import { z } from "zod";
7
+ import { z as protocolZod } from "zod/v4";
6
8
  import { SERVER_VERSION } from "../index.js";
7
9
  import { WORKFLOW_VIEW_META_KEY, buildUpstreamHeaders, readWorkflowView } from "../proxy.js";
8
10
  import { WORKFLOW_KNOWLEDGE, WORKFLOW_KNOWLEDGE_URI } from "./workflow-knowledge.js";
11
+ // Honua chunks large resource documents. The standard MCP schema strips
12
+ // these extension fields before the handler runs, so declare them explicitly.
13
+ const honuaReadResourceRequestSchema = ReadResourceRequestSchema.extend({
14
+ params: ReadResourceRequestSchema.shape.params.extend({
15
+ cursor: protocolZod.string().optional(),
16
+ maxChars: protocolZod.number().int().min(1).max(1_000_000).optional(),
17
+ }),
18
+ });
9
19
  const PREFIX = "honua_agent_";
10
20
  const DEVOPS_PREFIX = "honua_agent_devops_";
11
21
  const knowledgeResource = {
@@ -14,6 +24,32 @@ const knowledgeResource = {
14
24
  description: "Versioned workflow semantics and evidence requirements; canonical tools remain authoritative.",
15
25
  mimeType: "application/json",
16
26
  };
27
+ const knowledgeText = JSON.stringify(WORKFLOW_KNOWLEDGE);
28
+ const knowledgeDigest = createHash("sha256").update(knowledgeText).digest("hex");
29
+ function readKnowledgeWindow(params) {
30
+ let offset = 0;
31
+ if (params.cursor !== undefined) {
32
+ const invalid = () => new McpError(ErrorCode.InvalidParams, "Invalid workflow knowledge continuation cursor");
33
+ if (!/^[A-Za-z0-9_-]{1,256}$/.test(params.cursor))
34
+ throw invalid();
35
+ const decoded = Buffer.from(params.cursor, "base64url");
36
+ if (decoded.toString("base64url") !== params.cursor)
37
+ throw invalid();
38
+ const [digest, position, ...extra] = decoded.toString("utf8").split(":");
39
+ if (digest !== knowledgeDigest || extra.length !== 0 || !/^[1-9][0-9]*$/.test(position ?? ""))
40
+ throw invalid();
41
+ offset = Number(position);
42
+ if (!Number.isSafeInteger(offset) || offset >= knowledgeText.length)
43
+ throw invalid();
44
+ }
45
+ const end = Math.min(offset + (params.maxChars ?? 64_000), knowledgeText.length);
46
+ return {
47
+ contents: [{ uri: WORKFLOW_KNOWLEDGE_URI, mimeType: "application/json", text: knowledgeText.slice(offset, end) }],
48
+ ...(end < knowledgeText.length
49
+ ? { nextCursor: Buffer.from(`${knowledgeDigest}:${end}`).toString("base64url") }
50
+ : {}),
51
+ };
52
+ }
17
53
  const installInput = z
18
54
  .object({
19
55
  confirm: z.literal(true),
@@ -180,12 +216,8 @@ export class HonuaAgentGateway {
180
216
  this.server.setRequestHandler(ListResourceTemplatesRequestSchema, (request, extra) => !this.#client
181
217
  ? { resourceTemplates: [] }
182
218
  : this.#withClient((client) => client.request(request, ListResourceTemplatesResultSchema, { signal: extra.signal })));
183
- this.server.setRequestHandler(ReadResourceRequestSchema, (request, extra) => request.params.uri === WORKFLOW_KNOWLEDGE_URI
184
- ? {
185
- contents: [
186
- { uri: WORKFLOW_KNOWLEDGE_URI, mimeType: "application/json", text: JSON.stringify(WORKFLOW_KNOWLEDGE) },
187
- ],
188
- }
219
+ this.server.setRequestHandler(honuaReadResourceRequestSchema, (request, extra) => request.params.uri === WORKFLOW_KNOWLEDGE_URI
220
+ ? readKnowledgeWindow(request.params)
189
221
  : this.#withClient((client) => client.request(request, ReadResourceResultSchema, { signal: extra.signal })));
190
222
  this.server.setRequestHandler(ListPromptsRequestSchema, (request, extra) => !this.#client
191
223
  ? { prompts: [] }
@@ -226,7 +258,11 @@ export class HonuaAgentGateway {
226
258
  transport.onmessage = (message, extra) => {
227
259
  if ("method" in message && message.method === "initialize") {
228
260
  try {
229
- this.#view = readWorkflowView(InitializeRequestSchema.parse(message));
261
+ // Ordinary MCP hosts do not send Honua-specific view metadata. The
262
+ // persistent connector spans GIS workflows, including Studio; the
263
+ // Server's bounded default omits those tools. Membership and authority
264
+ // remain Server-owned, and an explicit client view still takes priority.
265
+ this.#view = readWorkflowView(InitializeRequestSchema.parse(message)) ?? "full";
230
266
  }
231
267
  catch {
232
268
  if ("id" in message)
@@ -2,9 +2,9 @@
2
2
  export declare const WORKFLOW_KNOWLEDGE_URI = "honua://agent/knowledge/workflows/v1";
3
3
  export declare const WORKFLOW_KNOWLEDGE: {
4
4
  readonly schemaVersion: "honua.agent-workflow-knowledge/v1";
5
- readonly knowledgeVersion: "2026-10-17.2";
5
+ readonly knowledgeVersion: "2026-10-19.2";
6
6
  readonly qualification: "contract-guidance-only";
7
- readonly authority: readonly ["Use discovered canonical tool schemas; these workflow descriptions never grant authorization.", "Bind every step to the current principal, tenant and target. Recheck credentials and RBAC on each action.", "Persist resource, operation and command references from canonical responses. Model prose cannot create a verified observation.", "After a lost mutation response reconcile the durable command/operation before retry; never infer failure from a timeout.", "The human approval inbox and approving principal are distinct from the agent. AwaitingApproval is a successful handoff, not a published result.", "Keep bootstrap secrets, cloud credentials, signing keys and private environment values outside model context."];
7
+ readonly authority: readonly ["Use discovered canonical tool schemas; these workflow descriptions never grant authorization.", "Bind every step to the current principal, tenant and target. Recheck credentials and RBAC on each action.", "Persist resource, operation and command references from canonical responses. Model prose cannot create a verified observation.", "After a lost mutation response reconcile the durable command/operation before retry; never infer failure from a timeout.", "The human approval inbox and approving principal are distinct from the agent. AwaitingApproval is a successful handoff, not a published result.", "Keep bootstrap secrets, cloud credentials, signing keys and private environment values outside model context.", "Large JSON resources can arrive as incomplete text windows. Echo nextCursor as cursor for the same URI and concatenate text per URI before parsing. Bound pages and reject repeated cursors; a first chunk is not the complete process catalog or job result."];
8
8
  readonly workflows: readonly [{
9
9
  readonly id: "local-bootstrap";
10
10
  readonly intent: "Evaluate Honua locally from one persistent MCP registration.";
@@ -27,10 +27,10 @@ export declare const WORKFLOW_KNOWLEDGE: {
27
27
  readonly id: "data-and-services";
28
28
  readonly intent: "Connect or import data, publish a service and verify a query.";
29
29
  readonly preconditions: readonly ["Verified current target", "Caller import/connect and publish permissions", "Explicit source and destination"];
30
- readonly actions: readonly ["Discover connection/import tools", "Validate source schema and geometry/CRS", "Execute canonical import or connection", "Publish via discovered service/layer tool", "Query the published layer"];
30
+ readonly actions: readonly ["Discover connection/import tools", "For an installed local Docker target register its catalog through the discovered secret-reference-only connection tool using the host-allowed env:HONUA_LOCAL_DB_PASSWORD reference; never request or reveal the password", "Verify the returned connection actually targets the ingest catalog before publication; an imported table with no registered connection is not ready to publish", "Validate source schema and geometry/CRS", "Execute canonical import or connection", "Publish via discovered service/layer tool", "Query the published layer"];
31
31
  readonly inputReferences: readonly ["connection/source reference", "upload/artifact reference", "destination schema"];
32
32
  readonly outputReferences: readonly ["import job id", "service id", "layer id or protocol-neutral source reference"];
33
- readonly observedOutcomes: readonly ["terminal import outcome", "service catalog entry", "query result with expected schema and representative data"];
33
+ readonly observedOutcomes: readonly ["terminal import outcome", "stored target CRS verified against canonical table metadata, distinct from the detected source CRS", "service catalog entry", "query result with expected schema and representative data"];
34
34
  readonly failureRule: "An accepted job or publish request is not successful ingestion or query verification.";
35
35
  }, {
36
36
  readonly id: "studio-map-and-publication";
@@ -45,7 +45,7 @@ export declare const WORKFLOW_KNOWLEDGE: {
45
45
  readonly id: "processes";
46
46
  readonly intent: "Run a built-in process graph or develop separately sandboxed Python/.NET code and map its output.";
47
47
  readonly preconditions: readonly ["Discovered Processes capabilities", "Input resource references", "Explicit built-in versus custom-code execution mode"];
48
- readonly actions: readonly ["Snapshot inputs and graph/code immutably", "Validate/build in the selected adapter", "Run with bounded resources", "Read sanitized diagnostics", "Correct and rerun as a new snapshot when needed", "Import output with normal artifact/import tools", "Query/map the imported output"];
48
+ readonly actions: readonly ["For built-in asynchronous jobs read the complete honua://catalog/processes resource; select executionKind=Job with Async support and its typed inputs", "Snapshot inputs and graph/code immutably", "Validate/build in the selected adapter", "Run with bounded resources", "Read sanitized diagnostics", "Correct and rerun as a new snapshot when needed", "Import output with normal artifact/import tools", "Query/map the imported output"];
49
49
  readonly inputReferences: readonly ["graph definition or isolated code snapshot", "input artifact/layer ids", "adapter/runtime version"];
50
50
  readonly outputReferences: readonly ["snapshot/build/run ids", "diagnostic references", "output artifact id", "imported layer reference"];
51
51
  readonly observedOutcomes: readonly ["failed and corrected run statuses", "cancellation status when requested", "output schema/CRS", "query/map evidence"];
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-knowledge.d.ts","sourceRoot":"","sources":["../../../src/agent/workflow-knowledge.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAC7E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyOrB,CAAC"}
1
+ {"version":3,"file":"workflow-knowledge.d.ts","sourceRoot":"","sources":["../../../src/agent/workflow-knowledge.ts"],"names":[],"mappings":"AAEA,qFAAqF;AACrF,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAC7E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8OrB,CAAC"}
@@ -1,8 +1,10 @@
1
+ // Generated from src/studio-agent/workflow-knowledge.ts.
2
+ // Update the canonical source, then run node scripts/sync-workflow-knowledge.mjs --write.
1
3
  /** Versioned semantic guidance, not an executor or a claim of live qualification. */
2
4
  export const WORKFLOW_KNOWLEDGE_URI = "honua://agent/knowledge/workflows/v1";
3
5
  export const WORKFLOW_KNOWLEDGE = {
4
6
  schemaVersion: "honua.agent-workflow-knowledge/v1",
5
- knowledgeVersion: "2026-10-17.2",
7
+ knowledgeVersion: "2026-10-19.2",
6
8
  qualification: "contract-guidance-only",
7
9
  authority: [
8
10
  "Use discovered canonical tool schemas; these workflow descriptions never grant authorization.",
@@ -11,6 +13,7 @@ export const WORKFLOW_KNOWLEDGE = {
11
13
  "After a lost mutation response reconcile the durable command/operation before retry; never infer failure from a timeout.",
12
14
  "The human approval inbox and approving principal are distinct from the agent. AwaitingApproval is a successful handoff, not a published result.",
13
15
  "Keep bootstrap secrets, cloud credentials, signing keys and private environment values outside model context.",
16
+ "Large JSON resources can arrive as incomplete text windows. Echo nextCursor as cursor for the same URI and concatenate text per URI before parsing. Bound pages and reject repeated cursors; a first chunk is not the complete process catalog or job result.",
14
17
  ],
15
18
  workflows: [
16
19
  {
@@ -81,6 +84,8 @@ export const WORKFLOW_KNOWLEDGE = {
81
84
  ],
82
85
  actions: [
83
86
  "Discover connection/import tools",
87
+ "For an installed local Docker target register its catalog through the discovered secret-reference-only connection tool using the host-allowed env:HONUA_LOCAL_DB_PASSWORD reference; never request or reveal the password",
88
+ "Verify the returned connection actually targets the ingest catalog before publication; an imported table with no registered connection is not ready to publish",
84
89
  "Validate source schema and geometry/CRS",
85
90
  "Execute canonical import or connection",
86
91
  "Publish via discovered service/layer tool",
@@ -90,6 +95,7 @@ export const WORKFLOW_KNOWLEDGE = {
90
95
  outputReferences: ["import job id", "service id", "layer id or protocol-neutral source reference"],
91
96
  observedOutcomes: [
92
97
  "terminal import outcome",
98
+ "stored target CRS verified against canonical table metadata, distinct from the detected source CRS",
93
99
  "service catalog entry",
94
100
  "query result with expected schema and representative data",
95
101
  ],
@@ -132,6 +138,7 @@ export const WORKFLOW_KNOWLEDGE = {
132
138
  "Explicit built-in versus custom-code execution mode",
133
139
  ],
134
140
  actions: [
141
+ "For built-in asynchronous jobs read the complete honua://catalog/processes resource; select executionKind=Job with Async support and its typed inputs",
135
142
  "Snapshot inputs and graph/code immutably",
136
143
  "Validate/build in the selected adapter",
137
144
  "Run with bounded resources",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honua/mcp-server",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
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",
@@ -97,9 +97,9 @@
97
97
  "@biomejs/biome": "1.9.4",
98
98
  "@honua/sdk-js": "file:..",
99
99
  "@types/node": "^24.3.1",
100
- "@vitest/coverage-v8": "^4.0.16",
100
+ "@vitest/coverage-v8": "^4.1.11",
101
101
  "typescript": "^5.9.2",
102
- "vitest": "^4.0.16"
102
+ "vitest": "^4.1.11"
103
103
  },
104
104
  "files": [
105
105
  "dist/src",