@cyanheads/mcp-ts-core 0.13.3 → 0.13.5
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/AGENTS.md +9 -7
- package/CLAUDE.md +9 -7
- package/README.md +1 -1
- package/changelog/0.13.x/0.13.4.md +65 -0
- package/changelog/0.13.x/0.13.5.md +41 -0
- package/changelog/template.md +7 -7
- package/dist/config/appRoot.d.ts.map +1 -1
- package/dist/config/appRoot.js +48 -16
- package/dist/config/appRoot.js.map +1 -1
- package/dist/core/app.d.ts +20 -0
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +1 -0
- package/dist/core/app.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/linter/rules/error-contract-rules.d.ts +65 -3
- package/dist/linter/rules/error-contract-rules.d.ts.map +1 -1
- package/dist/linter/rules/error-contract-rules.js +138 -3
- package/dist/linter/rules/error-contract-rules.js.map +1 -1
- package/dist/linter/rules/index.d.ts +1 -1
- package/dist/linter/rules/index.d.ts.map +1 -1
- package/dist/linter/rules/index.js +1 -1
- package/dist/linter/rules/index.js.map +1 -1
- package/dist/linter/rules/resource-rules.d.ts.map +1 -1
- package/dist/linter/rules/resource-rules.js +4 -2
- package/dist/linter/rules/resource-rules.js.map +1 -1
- package/dist/linter/rules/schema-rules.d.ts +19 -0
- package/dist/linter/rules/schema-rules.d.ts.map +1 -1
- package/dist/linter/rules/schema-rules.js +36 -0
- package/dist/linter/rules/schema-rules.js.map +1 -1
- package/dist/linter/rules/tool-rules.d.ts +17 -0
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +101 -3
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/mcp-server/handlerContext.d.ts +11 -2
- package/dist/mcp-server/handlerContext.d.ts.map +1 -1
- package/dist/mcp-server/handlerContext.js +6 -4
- package/dist/mcp-server/handlerContext.js.map +1 -1
- package/dist/mcp-server/inputRequired.d.ts +35 -2
- package/dist/mcp-server/inputRequired.d.ts.map +1 -1
- package/dist/mcp-server/inputRequired.js +116 -2
- package/dist/mcp-server/inputRequired.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts +2 -1
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js +4 -4
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +2 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +5 -2
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +11 -2
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts +2 -1
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +4 -4
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts +114 -0
- package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/inputPrevalidation.js +428 -0
- package/dist/mcp-server/tools/utils/inputPrevalidation.js.map +1 -0
- package/dist/mcp-server/tools/utils/strictenRecord.d.ts +42 -0
- package/dist/mcp-server/tools/utils/strictenRecord.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/strictenRecord.js +48 -0
- package/dist/mcp-server/tools/utils/strictenRecord.js.map +1 -0
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts +27 -0
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js +35 -6
- package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +33 -5
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +136 -20
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.d.ts +4 -1
- package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.js +5 -0
- package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts +52 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js +79 -3
- package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
- package/dist/services/canvas/core/sqlGate.d.ts +14 -1
- package/dist/services/canvas/core/sqlGate.d.ts.map +1 -1
- package/dist/services/canvas/core/sqlGate.js +69 -7
- package/dist/services/canvas/core/sqlGate.js.map +1 -1
- package/dist/services/canvas/index.d.ts +2 -2
- package/dist/services/canvas/index.d.ts.map +1 -1
- package/dist/services/canvas/index.js +2 -2
- package/dist/services/canvas/index.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +20 -0
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +75 -25
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/canvas/types.d.ts +6 -1
- package/dist/services/canvas/types.d.ts.map +1 -1
- package/dist/types-global/errors.d.ts +30 -0
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/types-global/errors.js +4 -3
- package/dist/types-global/errors.js.map +1 -1
- package/dist/utils/index.d.ts +3 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.js +13 -3
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
- package/dist/utils/internal/error-handler/mappings.d.ts +14 -1
- package/dist/utils/internal/error-handler/mappings.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/mappings.js +19 -1
- package/dist/utils/internal/error-handler/mappings.js.map +1 -1
- package/dist/utils/internal/error-handler/types.d.ts +12 -1
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +4 -1
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/network/fetchWithTimeout.d.ts +24 -4
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +10 -6
- package/dist/utils/network/fetchWithTimeout.js.map +1 -1
- package/dist/utils/network/httpError.d.ts +56 -6
- package/dist/utils/network/httpError.d.ts.map +1 -1
- package/dist/utils/network/httpError.js +56 -7
- package/dist/utils/network/httpError.js.map +1 -1
- package/dist/utils/network/pacer.d.ts +117 -0
- package/dist/utils/network/pacer.d.ts.map +1 -0
- package/dist/utils/network/pacer.js +304 -0
- package/dist/utils/network/pacer.js.map +1 -0
- package/dist/utils/network/retry.d.ts +119 -3
- package/dist/utils/network/retry.d.ts.map +1 -1
- package/dist/utils/network/retry.js +176 -35
- package/dist/utils/network/retry.js.map +1 -1
- package/dist/utils/security/rateLimiter.d.ts +19 -1
- package/dist/utils/security/rateLimiter.d.ts.map +1 -1
- package/dist/utils/security/rateLimiter.js +49 -1
- package/dist/utils/security/rateLimiter.js.map +1 -1
- package/dist/utils/telemetry/attributes.d.ts +27 -0
- package/dist/utils/telemetry/attributes.d.ts.map +1 -1
- package/dist/utils/telemetry/attributes.js +38 -0
- package/dist/utils/telemetry/attributes.js.map +1 -1
- package/framework-skills/add-tool/SKILL.md +49 -5
- package/framework-skills/api-canvas/SKILL.md +37 -16
- package/framework-skills/api-config/SKILL.md +4 -4
- package/framework-skills/api-context/SKILL.md +4 -2
- package/framework-skills/api-errors/SKILL.md +39 -7
- package/framework-skills/api-linter/SKILL.md +92 -5
- package/framework-skills/api-telemetry/SKILL.md +43 -4
- package/framework-skills/api-utils/SKILL.md +9 -5
- package/framework-skills/api-utils/references/security.md +2 -2
- package/framework-skills/design-mcp-server/SKILL.md +20 -3
- package/framework-skills/field-test/SKILL.md +4 -2
- package/framework-skills/git-wrapup/SKILL.md +87 -69
- package/framework-skills/release-and-publish/SKILL.md +5 -5
- package/framework-skills/release-pr-review/SKILL.md +5 -5
- package/framework-skills/report-issue-framework/SKILL.md +6 -35
- package/framework-skills/report-issue-local/SKILL.md +6 -36
- package/package.json +2 -2
- package/templates/.github/ISSUE_TEMPLATE/bug_report.yml +2 -2
- package/templates/.github/ISSUE_TEMPLATE/feature_request.yml +2 -2
- package/templates/AGENTS.md +1 -1
- package/templates/CLAUDE.md +1 -1
- package/templates/changelog/template.md +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../../src/utils/security/rateLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAuB,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,IAAI,gBAA8D,CAAC;AAEnE,SAAS,mBAAmB;IAC1B,gBAAgB,KAAK,aAAa,CAChC,0BAA0B,EAC1B,uBAAuB,EACvB,cAAc,CACf,CAAC;IACF,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC9B,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,oBAAoB;IAClC,mBAAmB,EAAE,CAAC;AACxB,CAAC;AAkCD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,WAAW;
|
|
1
|
+
{"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../../src/utils/security/rateLimiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,6 +47,25 @@ export declare const ATTR_MCP_TOOL_ENRICHED = "mcp.tool.enriched";
|
|
|
47
47
|
export declare const ATTR_MCP_TOOL_BATCH_SUCCEEDED = "mcp.tool.batch.succeeded_count";
|
|
48
48
|
/** Number of items in the `failed` array of a batch tool result. */
|
|
49
49
|
export declare const ATTR_MCP_TOOL_BATCH_FAILED = "mcp.tool.batch.failed_count";
|
|
50
|
+
/**
|
|
51
|
+
* Why a root argument key was dropped: the ignore-list entry that matched
|
|
52
|
+
* (built-in, or a server's own `input.ignoreKeys`), or `underscore_prefix` for
|
|
53
|
+
* the heuristic. Bounded by the ignore list's length plus one.
|
|
54
|
+
*/
|
|
55
|
+
export declare const ATTR_MCP_INPUT_IGNORE_RULE = "mcp.input.ignore_rule";
|
|
56
|
+
/** The declared input key a rewrite resolved to — one of the tool's own properties. */
|
|
57
|
+
export declare const ATTR_MCP_INPUT_TARGET = "mcp.input.target";
|
|
58
|
+
/** Which half of the alias stage fired: `declared` or `case_style`. */
|
|
59
|
+
export declare const ATTR_MCP_INPUT_ALIAS_KIND = "mcp.input.alias_kind";
|
|
60
|
+
/** Which representation repair earned validity (`stringified_array`). */
|
|
61
|
+
export declare const ATTR_MCP_INPUT_COERCION = "mcp.input.coercion";
|
|
62
|
+
/**
|
|
63
|
+
* Author-set label of the outbound pacer a queue metric belongs to
|
|
64
|
+
* (`createPacer({ name })`). The only attribute the four `mcp.pacer.*`
|
|
65
|
+
* instruments carry — bounded by the server's own configuration, never by
|
|
66
|
+
* anything a caller supplies, for the cardinality reason stated above.
|
|
67
|
+
*/
|
|
68
|
+
export declare const ATTR_MCP_PACER_NAME = "mcp.pacer.name";
|
|
50
69
|
/**
|
|
51
70
|
* Full URI identifying the MCP resource being accessed (e.g., `myscheme://items/123`).
|
|
52
71
|
* Use on spans only — not on metrics, where unbounded cardinality is a concern.
|
|
@@ -158,4 +177,12 @@ export declare const ATTR_MCP_AUTH_SUBJECT = "mcp.auth.subject";
|
|
|
158
177
|
export declare const ATTR_MCP_CONNECTION_TRANSPORT = "mcp.connection.transport";
|
|
159
178
|
/** Classified JSON-RPC error code from ErrorHandler (e.g., `-32001`, `-32602`). */
|
|
160
179
|
export declare const ATTR_MCP_ERROR_CLASSIFIED_CODE = "mcp.error.classified_code";
|
|
180
|
+
/**
|
|
181
|
+
* Log level a definition declared for this failure mode: `debug`, `info`,
|
|
182
|
+
* `notice`, or `warning`. Set only on a record whose declared severity
|
|
183
|
+
* resolved, so a server that declares none emits exactly the series it did
|
|
184
|
+
* before. The `reason` itself is unbounded across a fleet and stays on the
|
|
185
|
+
* span and in the log.
|
|
186
|
+
*/
|
|
187
|
+
export declare const ATTR_MCP_ERROR_SEVERITY = "mcp.error.severity";
|
|
161
188
|
//# sourceMappingURL=attributes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAE5D,iGAAiG;AACjG,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAMpD;;GAEG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,0DAA0D;AAC1D,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAElE,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAEtE,kGAAkG;AAClG,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D,yGAAyG;AACzG,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAEtE,iGAAiG;AACjG,eAAO,MAAM,6BAA6B,6BAA6B,CAAC;AAExE,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAE1D,uEAAuE;AACvE,eAAO,MAAM,6BAA6B,mCAAmC,CAAC;AAE9E,oEAAoE;AACpE,eAAO,MAAM,0BAA0B,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,6 +54,36 @@ export const ATTR_MCP_TOOL_BATCH_SUCCEEDED = 'mcp.tool.batch.succeeded_count';
|
|
|
54
54
|
/** Number of items in the `failed` array of a batch tool result. */
|
|
55
55
|
export const ATTR_MCP_TOOL_BATCH_FAILED = 'mcp.tool.batch.failed_count';
|
|
56
56
|
// ============================================================================
|
|
57
|
+
// MCP Tool Input Pre-validation Attributes
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Every value below is author- or framework-defined, never the caller's own
|
|
60
|
+
// text. A caller-supplied key would mint a permanent time series per spelling a
|
|
61
|
+
// client invents — the unbounded-label leak #114 removed from the rate-limiter
|
|
62
|
+
// counter. The raw key and alias ride the debug log instead, which is where an
|
|
63
|
+
// operator looks for a new client artifact and where cardinality costs nothing.
|
|
64
|
+
/**
|
|
65
|
+
* Why a root argument key was dropped: the ignore-list entry that matched
|
|
66
|
+
* (built-in, or a server's own `input.ignoreKeys`), or `underscore_prefix` for
|
|
67
|
+
* the heuristic. Bounded by the ignore list's length plus one.
|
|
68
|
+
*/
|
|
69
|
+
export const ATTR_MCP_INPUT_IGNORE_RULE = 'mcp.input.ignore_rule';
|
|
70
|
+
/** The declared input key a rewrite resolved to — one of the tool's own properties. */
|
|
71
|
+
export const ATTR_MCP_INPUT_TARGET = 'mcp.input.target';
|
|
72
|
+
/** Which half of the alias stage fired: `declared` or `case_style`. */
|
|
73
|
+
export const ATTR_MCP_INPUT_ALIAS_KIND = 'mcp.input.alias_kind';
|
|
74
|
+
/** Which representation repair earned validity (`stringified_array`). */
|
|
75
|
+
export const ATTR_MCP_INPUT_COERCION = 'mcp.input.coercion';
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// MCP Outbound Pacer Attributes
|
|
78
|
+
// ============================================================================
|
|
79
|
+
/**
|
|
80
|
+
* Author-set label of the outbound pacer a queue metric belongs to
|
|
81
|
+
* (`createPacer({ name })`). The only attribute the four `mcp.pacer.*`
|
|
82
|
+
* instruments carry — bounded by the server's own configuration, never by
|
|
83
|
+
* anything a caller supplies, for the cardinality reason stated above.
|
|
84
|
+
*/
|
|
85
|
+
export const ATTR_MCP_PACER_NAME = 'mcp.pacer.name';
|
|
86
|
+
// ============================================================================
|
|
57
87
|
// MCP Resource Attributes
|
|
58
88
|
// ============================================================================
|
|
59
89
|
/**
|
|
@@ -198,4 +228,12 @@ export const ATTR_MCP_CONNECTION_TRANSPORT = 'mcp.connection.transport';
|
|
|
198
228
|
// ============================================================================
|
|
199
229
|
/** Classified JSON-RPC error code from ErrorHandler (e.g., `-32001`, `-32602`). */
|
|
200
230
|
export const ATTR_MCP_ERROR_CLASSIFIED_CODE = 'mcp.error.classified_code';
|
|
231
|
+
/**
|
|
232
|
+
* Log level a definition declared for this failure mode: `debug`, `info`,
|
|
233
|
+
* `notice`, or `warning`. Set only on a record whose declared severity
|
|
234
|
+
* resolved, so a server that declares none emits exactly the series it did
|
|
235
|
+
* before. The `reason` itself is unbounded across a fleet and stays on the
|
|
236
|
+
* span and in the log.
|
|
237
|
+
*/
|
|
238
|
+
export const ATTR_MCP_ERROR_SEVERITY = 'mcp.error.severity';
|
|
201
239
|
//# sourceMappingURL=attributes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new MCP tool definition. Use when the user asks to add a tool, create a new tool, or implement a new capability for the server.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.28"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -277,6 +277,45 @@ Two limits worth knowing when you write a schema:
|
|
|
277
277
|
- **An explicit opening wins.** A definition that declared `.passthrough()` or `.catchall(...)` asked for an open object, and `tool()` leaves it alone. Use that (deliberately) for tools that proxy arbitrary upstream query parameters.
|
|
278
278
|
- **A union root is strictened per variant.** See below — the branch is where the properties live, so that is where `additionalProperties: false` lands.
|
|
279
279
|
|
|
280
|
+
**Declare `.strict()` before `.describe()` / `.meta()` on the root.** Zod keys both to the schema *instance*, and `.strict()` clones without it — so `z.object({…}).describe('…')` loses the description when `tool()` strictens, and the advertised `inputSchema` carries none. `z.object({…}).strict().describe('…')` keeps it, because an already-strict schema is returned untouched. `lint:mcp` reports the loss as `schema-root-meta-discarded`. It bites the root only (and each variant of a union root); field- and nested-level describes are unaffected.
|
|
281
|
+
|
|
282
|
+
### Three things the framework fixes before the schema sees the arguments
|
|
283
|
+
|
|
284
|
+
Strict input is right for a misspelling the caller can fix, and wrong when the arguments the model wrote were correct and something between the model and the schema was not. An ordered step inside `parseToolArguments` covers those cases: **drop client-added keys → key aliases → parse → on failure, repair and one re-parse.** All three stages are on by default, none changes what `tools/list` advertises, and none appears in a response — each emits a debug log and a counter (`mcp.input.ignored_key`, `mcp.input.aliased`, `mcp.input.coerced`) instead, so a new client artifact surfaces in telemetry rather than as a failed call.
|
|
285
|
+
|
|
286
|
+
**1. Client-added root keys are dropped.** Some clients put their own keys inside `arguments`: a placeholder when the model sends none, a call description, a call id, or a `_meta` block that belongs on `params`. The model never wrote them and cannot remove them, so the retry fails identically. An undeclared root key is dropped when it is underscore-prefixed or on the built-in list (`_meta`, `tool_call_description`, `toolCallId`). Three boundaries: a declared key is never dropped (on a union root, that means every variant's keys); an author-opened root is left alone; and a tool declaring any underscore-prefixed key of its own switches the underscore rule off — otherwise a misspelled `_cursor` would vanish silently, which is the failure strict input exists to prevent.
|
|
287
|
+
|
|
288
|
+
**2. A key alias reaches the handler under the canonical name.** Declare the mappings you know:
|
|
289
|
+
|
|
290
|
+
```ts
|
|
291
|
+
export const drugProfile = tool('drug_profile', {
|
|
292
|
+
input: z.object({ drug: z.string().describe('Generic or brand name.') }),
|
|
293
|
+
inputAliases: { drug_name: 'drug', substance: 'drug' },
|
|
294
|
+
// …
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Alongside those, an undeclared key whose case-folded form (`-`/`_` stripped, lowercased) names exactly one declared key is rewritten too — `max_results`, `Max-Results`, and `MAXRESULTS` all reach a declared `maxResults`, with nothing declared. Neither half advertises anything: `inputSchema` is byte-identical with or without `inputAliases`, so the canonical key keeps its place in `required` and the model is still told to use it.
|
|
299
|
+
|
|
300
|
+
Declare an alias where the meaning is certain and the mapping is one-to-one — a sibling tool's spelling for the same concept, the upstream API's own name, a shorthand weaker models reach for. It is not fuzzy matching: a key matching no alias and no declared key is still rejected by name, with the accepted-key hint. Four boundaries: a rewrite applies only when the target key is absent (alias *and* target present fails exactly as it does today); an author-opened root is never rewritten; a union root resolves against the variant the discriminator selects, and rewrites nothing when the discriminator is absent or unrecognized; and a `headerParam`-designated target is never rewritten *to* — the SDK cross-checks the `Mcp-Param-<Name>` header against the raw body before dispatch, so a later rewrite would hand your handler a value no intermediary attested. `lint:mcp` rejects an alias that shadows a declared key, names a target that does not exist, or is ambiguous against another alias or key (`input-alias-conflict`).
|
|
301
|
+
|
|
302
|
+
**3. A stringified array is repaired after the parse fails.** `statusFilter: "[\"RECRUITING\"]"` against `z.array(z.string())` is a serialization slip the server can undo with certainty — `JSON.parse` is the exact inverse of the `JSON.stringify` that produced it, which is what separates it from the nearest-key guessing strict input refuses. The repair runs *only* on the failure branch, *only* at the paths the rejection's own issues name, and is kept only if the repaired arguments then pass your schema. So it cannot touch a value that was already valid — a free-text field legitimately holding `"[1,2,3]"` is not in the issue list, so it survives untouched even when the same call carries a genuine stringified array in another field. It walks values only: no key is added, dropped, or renamed. When nothing validates, the original rejection is thrown verbatim: same code, message, `data.issues`, and `data.recovery.hint`.
|
|
303
|
+
|
|
304
|
+
Turn any stage off per server — there is no per-tool switch:
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
await createApp({
|
|
308
|
+
input: {
|
|
309
|
+
ignoreKeys: ['some_client_field'], // adds to the built-in list; `false` disables the stage
|
|
310
|
+
caseStyleAliases: false, // declared `inputAliases` only
|
|
311
|
+
coerce: false, // never retry a failed parse
|
|
312
|
+
},
|
|
313
|
+
tools: allToolDefinitions,
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Those three stages are the whole of the framework's input edge: argument **key** names, and one **value** shape — a JSON-stringified array, which `JSON.parse` inverts with certainty. Every other value normalization is domain knowledge and belongs to the tool: the case or bare-leaf form of a code, a unit or vocabulary alias, a composite identifier assembled from two arguments, a delimiter-joined list, a spelled-out name. Which variants a given input accepts is decided per input at design time (`design-mcp-server` § *Parameter descriptions*) and applied at the head of the handler, on the unambiguous mappings only.
|
|
318
|
+
|
|
280
319
|
### Multi-mode tools take a discriminated-union input
|
|
281
320
|
|
|
282
321
|
When a tool has genuinely exclusive argument sets — look up by ID *or* search by name, never both — declare the union directly instead of making every field optional and checking the combination by hand:
|
|
@@ -594,6 +633,8 @@ format: (result) => [{
|
|
|
594
633
|
}],
|
|
595
634
|
```
|
|
596
635
|
|
|
636
|
+
**A parsed value is the same problem one step later.** `Number(raw)` over an absent or non-numeric upstream field yields `NaN`; a missing nested path yields `null` or `undefined`. Against a required `z.number()` / `z.string()` each of those fails the effective-output parse, and the agent gets an internal error in place of a record the tool otherwise had. Guard where the value is parsed, not at the schema: when a documented-sparse feed supplies nothing usable for a field, omit it (declare it `.optional()`, render it `Not available`) rather than passing a `NaN`, a `null`, or a coerced `0` into the return. Decide per field which upstream absences are expected — the honesty rule above, applied to values the server computes rather than copies.
|
|
637
|
+
|
|
597
638
|
### Error classification and messaging
|
|
598
639
|
|
|
599
640
|
**Recommended: declare an `errors[]` contract.** A typed contract surfaces in `tools/list` and gives the handler a typed `ctx.fail(reason, …)` keyed by the declared reason union — TypeScript catches `ctx.fail('typo')` at compile time, `data.reason` is auto-populated and tamper-proof, and the linter enforces conformance against the handler body.
|
|
@@ -699,9 +740,12 @@ import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
|
699
740
|
throw serviceUnavailable(`arXiv API returned HTTP ${status}. Retry in a few seconds.`);
|
|
700
741
|
|
|
701
742
|
// Recovery hint via the canonical `data.recovery.hint` shape — the framework
|
|
702
|
-
//
|
|
743
|
+
// mirrors it into the content[] text as `Recovery: <hint>`, so format()-only
|
|
703
744
|
// clients (Claude Desktop) see the same guidance that structuredContent clients
|
|
704
|
-
// (Claude Code) read from `error.data.recovery.hint`.
|
|
745
|
+
// (Claude Code) read from `error.data.recovery.hint`. A hint the message already
|
|
746
|
+
// contains verbatim is dropped from the text rather than stated twice; it stays
|
|
747
|
+
// on structuredContent regardless. `data.reason` and `data.retryable` render as
|
|
748
|
+
// a closing `(reason … · not retryable)` line; other `data` keys reach
|
|
705
749
|
// structuredContent only.
|
|
706
750
|
import { invalidParams } from '@cyanheads/mcp-ts-core/errors';
|
|
707
751
|
throw invalidParams(
|
|
@@ -774,7 +818,7 @@ Large payloads burn the agent's context window. Default to curated summaries; of
|
|
|
774
818
|
- **Lists**: Return top N with a total count and pagination cursor, not unbounded arrays
|
|
775
819
|
- **Large objects**: Return key fields by default; accept a `fields` or `verbose` parameter for full data
|
|
776
820
|
- **Binary/blob content**: Return metadata and a reference, not the raw content
|
|
777
|
-
- **Analytical working sets**: When upstream returns more *analytical* rows (data an agent would SQL — aggregate, group, join) than fit in context, `DataCanvas` (`core.canvas`, wired in `setup()` via `setCanvas`; Tier 3 — opt-in via `CANVAS_PROVIDER_TYPE=duckdb`) lets you register the rows and return the `canvas_id` plus a preview so the agent can run SQL to slice down without a re-fetch. The `spillover()` helper (`@cyanheads/mcp-ts-core/canvas`) automates the overflow case: drain rows up to a character budget for the inline preview, auto-register the full source on overflow, return both as a discriminated union. **Two gates:** it must be analytical, not a discovery/search surface of categorical metadata (those don't earn a canvas regardless of row count — use MCP-side list filtering or pagination); and a tool emitting a `canvas_id` MUST be paired with a registered `dataframe_query` tool, or the handle is unreachable. Compute distributions or refinement hints across the full result — not the preview — so the agent gets honest aggregate signal on the rows it didn't read. See `api-canvas` for the register / query / export pattern and the spillover flow.
|
|
821
|
+
- **Analytical working sets**: When upstream returns more *analytical* rows (data an agent would SQL — aggregate, group, join) than fit in context, `DataCanvas` (`core.canvas`, wired in `setup()` via `setCanvas`; Tier 3 — opt-in via `CANVAS_PROVIDER_TYPE=duckdb`) lets you register the rows and return the `canvas_id` plus a preview so the agent can run SQL to slice down without a re-fetch. The `spillover()` helper (`@cyanheads/mcp-ts-core/canvas`) automates the overflow case: drain rows up to a character budget for the inline preview, auto-register the full source on overflow, return both as a discriminated union. **Two gates:** it must be analytical, not a discovery/search surface of categorical metadata (those don't earn a canvas regardless of row count — use MCP-side list filtering or pagination); and a tool emitting a `canvas_id` MUST be paired with a registered `dataframe_query` tool, or the handle is unreachable. Compute distributions or refinement hints across the full result — not the preview — so the agent gets honest aggregate signal on the rows it didn't read. Declare the *input* `canvas_id` field with `CanvasIdSchema` (`@cyanheads/mcp-ts-core/canvas`) rather than a bare `z.string()`: it advertises the 10-character URL-safe pattern in `inputSchema`, so a model sees the shape before it calls and a value that could never be an id is rejected at argument validation instead of after a registry lookup. Add your own `.describe()` over it to say which tool produced the id. The *output* field stays a plain `z.string()` — that id came from the server. See `api-canvas` for the register / query / export pattern and the spillover flow.
|
|
778
822
|
- **One large document**: When a single call returns one document-shaped record (not a row set) that can overflow context, return a section *outline* — top-level keys + per-section byte size — and let the agent re-call with `sections: [...]` for only what it needs, instead of truncating one surface. `outlineOnOverflow()` with `OUTLINE_VARIANT` / `selectSections()` / `formatOutline()` (`@cyanheads/mcp-ts-core/utils`) measures the payload and returns a `full | outline` result. Declare the tool's `output` as a flat `z.object` with a `kind` discriminator and presence-based optional arms (fold in `OUTLINE_VARIANT.shape.sections` / `.notice`) — `tool()` rejects a `z.discriminatedUnion` output — and render each arm on field presence in `format()` so parity holds. Pure measure + key-slice — Workers-portable, unlike canvas `spillover()`. Use for one fat record; use `spillover()` for a row collection. See the `techniques` skill's `outline-on-overflow` reference.
|
|
779
823
|
|
|
780
824
|
## MCP-side list filtering
|
|
@@ -818,7 +862,7 @@ return { items: hits };
|
|
|
818
862
|
- [ ] `handler(input, ctx)` is pure — throws on failure, no try/catch (exception: batch tools with per-item isolation use try/catch inside the loop — that's intentional, don't remove it)
|
|
819
863
|
- [ ] `format()` renders every field in the output schema — enforced at lint time via sentinel injection, startup fails with `format-parity` errors otherwise. Different clients forward different surfaces (Claude Code → `structuredContent`, Claude Desktop → `content[]`); both must carry the same data. Primary fix: render the missing field in `format()` (use `z.discriminatedUnion` for list/detail variants). Escape hatch: if the output schema was over-typed for a genuinely dynamic upstream API, relax it (`z.object({}).passthrough()`) rather than maintaining aspirational typing
|
|
820
864
|
- [ ] Agent-facing context (empty-result notices, query/filter echo, pagination totals) declared in an `enrichment` block and populated via `ctx.enrich(...)` — reaches both `structuredContent` and `content[]` automatically, not authored solely in `format()` text. Enrichment keys disjoint from `output` keys
|
|
821
|
-
- [ ] If wrapping external API: output schema and `format()` preserve uncertainty from sparse upstream payloads instead of inventing concrete values
|
|
865
|
+
- [ ] If wrapping external API: output schema and `format()` preserve uncertainty from sparse upstream payloads instead of inventing concrete values, and a parsed `NaN`/`null` is dropped at the parse site rather than passed to a required output field
|
|
822
866
|
- [ ] `auth` scopes declared if the tool needs authorization
|
|
823
867
|
- [ ] `errors: [...]` contract declared for the tool's domain-specific failure modes — or block deleted if no domain failures apply (baseline codes bubble freely)
|
|
824
868
|
- [ ] Error contract declared inline on this tool — not imported from a shared module, even when other tools have near-identical entries
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
DataCanvas primitive reference — a Tier 3 SQL/analytical workspace for tabular MCP servers, backed by DuckDB. Use when registering tables from upstream APIs, running ad-hoc SQL across them, and exporting results. Covers the acquire → register → query → export flow, per-table TTL, the token-sharing pattern for multi-agent collaboration, env config, and Cloudflare Workers fail-closed behavior.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.3"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -79,9 +79,29 @@ A canvas is identified by an opaque 10-character URL-safe `canvasId` (~10¹⁸ k
|
|
|
79
79
|
| **Existing id (own tenant)** | Resolves to that canvas, slides TTL forward, returns `isNew: false`. |
|
|
80
80
|
| **Existing id (other tenant)** | Throws `NotFound` — uniform with unknown to avoid leaking existence across tenants. |
|
|
81
81
|
| **Unknown id** | Throws `NotFound` (`data.reason: 'canvas_not_found'`) with a recovery hint to re-run the producing tool or re-check the id. |
|
|
82
|
+
| **Malformed id** | Throws `ValidationError` (`data.reason: 'canvas_id_malformed'`) before any lookup, with a hint naming the format. A value that cannot be an id is an input error; only a well-formed id that is absent is a lookup miss. |
|
|
83
|
+
| **Omitted, tenant at its cap** | Throws `RateLimited` (`data.reason: 'canvas_capacity_exhausted'`, `retryable: true`) carrying `tenantId`, `activeCount`, and `cap`. The hint leads with reusing an id the caller already holds — the one reclaim path present in every configuration. |
|
|
82
84
|
|
|
83
85
|
When auth is enabled, the effective scope is the composite `(tenantId, canvasId)`. In `MCP_AUTH_MODE=none`, `tenantId` collapses to `'default'` and the canvasId is the only differentiator — entropy + TTL + the framework's rate limiter make brute-force discovery operationally infeasible. **Designed for public-data servers (BrAPI, OpenFEC, etc.). Don't put PII on a no-auth canvas.**
|
|
84
86
|
|
|
87
|
+
That collapse is also why the capacity hint reads the way it does: under `default` the occupied slots may belong to other callers, and a consumer's dataframe-drop tool is off by default, so "drop an unused canvas" is advice nobody can follow. The cap is reached only on the mint path, when `canvas_id` was omitted. The refusal keeps `-32003` and its HTTP 429 mapping; `data.reason` is what separates it from upstream throttling, including in the `mcp.tool.error_category` metric, where it files under `server` rather than `upstream`.
|
|
88
|
+
|
|
89
|
+
### Advertising the id shape
|
|
90
|
+
|
|
91
|
+
`CanvasIdSchema` is exported from `@cyanheads/mcp-ts-core/canvas` — `z.string().regex(/^[A-Za-z0-9_-]{10}$/)` with a `.describe()` naming where an id comes from. A tool that declares its `canvas_id` field with it advertises the constraint in `inputSchema`, so a model sees the shape before it calls and an impossible value is rejected at argument validation rather than inside the handler:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { CanvasIdSchema } from '@cyanheads/mcp-ts-core/canvas';
|
|
95
|
+
|
|
96
|
+
input: z.object({
|
|
97
|
+
canvas_id: CanvasIdSchema.optional().describe(
|
|
98
|
+
'Optional canvas ID from a prior call. Omit on first call to start a fresh canvas.',
|
|
99
|
+
),
|
|
100
|
+
}),
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The two halves are independent. On a tool that adopts the shape, `"x"` fails as `InvalidParams` (-32602) with the framework's own `reason: 'invalid_arguments'` and a schema-derived hint, and the handler never runs — so `canvas_id_malformed` never fires there. It covers tools that have not adopted it and ids the registry receives from somewhere other than a validated argument, `importFrom`'s source id in particular. Adopting the shape does not change any existing server's advertised schema until that server adopts it.
|
|
104
|
+
|
|
85
105
|
---
|
|
86
106
|
|
|
87
107
|
## Lifecycle
|
|
@@ -148,10 +168,14 @@ await instance.registerTable('recent_fetch', rows, { ttlMs: 30 * 60 * 1000 });
|
|
|
148
168
|
|
|
149
169
|
Run SQL across registered tables. Returns at most `rowLimit` rows (default 10 000). When the result exceeds `rowLimit`, the response carries `truncated: true` and `rowCount` reflects the number of materialized rows (not the full result set). For full result sets and exact counts, pass `registerAs` — the result is materialized as a new canvas table; the response carries a `preview` slice and the exact `rowCount`.
|
|
150
170
|
|
|
151
|
-
Querying a table that does not exist throws `NotFound` (`data.reason: 'missing_table'`) with a recovery hint to re-
|
|
171
|
+
Querying a table that does not exist throws `NotFound` (`data.reason: 'missing_table'`) with a recovery hint to re-run the tool that staged the table or list what is currently staged. This happens when a table has expired (per-table TTL), been dropped, or the name is mistyped. The error is `NotFound`, not `ValidationError` — agents should re-stage, not fix the SQL shape. A well-formed but unknown or expired `canvas_id` fails the same way (`data.reason: 'canvas_not_found'`, with its own recovery hint) — thrown by `acquire()` and every canvas operation. An id that fails the format check is a different failure: `ValidationError` with `data.reason: 'canvas_id_malformed'`, raised before the lookup on each of the three entry points that take a caller-supplied id — `acquire`, `drop` (which previously reported it as a silent `false`), and `importFrom`'s source id.
|
|
152
172
|
|
|
153
173
|
A `SELECT` that parses but fails to prepare for any other reason — a mistyped column, an unknown function, an invalid expression — throws `ValidationError` (`data.reason: 'invalid_sql'`) and preserves the DuckDB binder detail in `data.binderMessage` (e.g. `Referenced column "x" not found...`, often with a candidate suggestion). This is distinct from `non_select_statement`, reserved for statements that genuinely aren't `SELECT`s — here the shape is fine, so the agent should fix the named column or function.
|
|
154
174
|
|
|
175
|
+
A `SELECT` that prepares and then fails on the staged data throws `ValidationError` (`data.reason: 'sql_execution_error'`) with the engine message preserved and a hint pointing at `TRY_CAST` or filtering the offending rows. The split follows DuckDB's own execution-error classes — `Conversion Error`, `Invalid Input Error`, `Out of Range Error` — matched on the message prefix. Engine faults (`IO Error`, `INTERNAL Error`, `Out of Memory Error`, and anything unmatched) stay `DatabaseError`, so an export or import failing on I/O is never reported to the caller as bad SQL. `DUCKDB_ERROR_REASONS` exports these alongside `SQL_GATE_REASONS`.
|
|
176
|
+
|
|
177
|
+
**Every gate and engine rejection carries `data.recovery.hint`**, which the framework mirrors into `content[]` as a `Recovery:` line — so the guidance reaches `structuredContent`-only and `content[]`-only clients alike. The hints name a capability, never a framework method: an MCP client sees only the consuming server's tool names, so `registerTable()` or `describe()` in a hint is guidance it cannot follow. Write your own hints the same way (see `api-errors`).
|
|
178
|
+
|
|
155
179
|
```ts
|
|
156
180
|
const result = await instance.query(`
|
|
157
181
|
SELECT germplasmName, COUNT(*) AS n
|
|
@@ -230,7 +254,7 @@ await instance.export('g_with_obs', { format: 'csv', stream: writableStream });
|
|
|
230
254
|
|
|
231
255
|
```ts
|
|
232
256
|
const tables = await instance.describe();
|
|
233
|
-
// [{ name: 'germplasm', kind: 'table', rowCount: 200,
|
|
257
|
+
// [{ name: 'germplasm', kind: 'table', rowCount: 200, columns: [...] }, ...]
|
|
234
258
|
|
|
235
259
|
// Filter by kind ('table' | 'view').
|
|
236
260
|
const onlyViews = await instance.describe({ kind: 'view' });
|
|
@@ -241,7 +265,7 @@ await instance.clear(); // returns count dropped (drops views b
|
|
|
241
265
|
|
|
242
266
|
`TableInfo.kind` discriminates `'table'` vs `'view'`. For views, `rowCount` is materialized at describe time via `COUNT(*)` — not free; treat as an approximation if the view is expensive.
|
|
243
267
|
|
|
244
|
-
`TableInfo.approxSizeBytes` is
|
|
268
|
+
`TableInfo.approxSizeBytes` is `@deprecated` and never populated. DuckDB exposes no per-table byte footprint, so there is no size figure to report and no size-based eviction heuristic to build on; `rowCount` and the canvas memory limit are what `describe()` gives you. The member stays on the type so existing readers compile, and goes away in a future major.
|
|
245
269
|
|
|
246
270
|
### Cancellation
|
|
247
271
|
|
|
@@ -307,7 +331,7 @@ A fetcher that spills and a query tool that runs SQL across what was spilled —
|
|
|
307
331
|
|
|
308
332
|
```ts
|
|
309
333
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
310
|
-
import { spillover } from '@cyanheads/mcp-ts-core/canvas';
|
|
334
|
+
import { CanvasIdSchema, spillover } from '@cyanheads/mcp-ts-core/canvas';
|
|
311
335
|
import { getCanvas } from '@/services/canvas-accessor.js';
|
|
312
336
|
|
|
313
337
|
/** Fetch an upstream dataset, inline a preview, spill the full result to a canvas table. */
|
|
@@ -318,10 +342,9 @@ export const fetchDataset = tool('fetch_dataset', {
|
|
|
318
342
|
annotations: { readOnlyHint: true },
|
|
319
343
|
input: z.object({
|
|
320
344
|
query: z.string().describe('Upstream search/filter expression'),
|
|
321
|
-
canvas_id:
|
|
322
|
-
.
|
|
323
|
-
|
|
324
|
-
.describe('Canvas ID from a prior call. Omit to start fresh — the response returns a new one.'),
|
|
345
|
+
canvas_id: CanvasIdSchema.optional().describe(
|
|
346
|
+
'Canvas ID from a prior call. Omit to start fresh — the response returns a new one.',
|
|
347
|
+
),
|
|
325
348
|
}),
|
|
326
349
|
output: z.object({
|
|
327
350
|
canvas_id: z.string().describe('Canvas ID — pass to dataframe_query or another fetch call'),
|
|
@@ -357,7 +380,7 @@ export const dataframeQuery = tool('dataframe_query', {
|
|
|
357
380
|
description: 'Run a read-only SQL SELECT against tables staged on a canvas by fetch_dataset.',
|
|
358
381
|
annotations: { readOnlyHint: true },
|
|
359
382
|
input: z.object({
|
|
360
|
-
canvas_id:
|
|
383
|
+
canvas_id: CanvasIdSchema.describe('Canvas ID returned by fetch_dataset'),
|
|
361
384
|
sql: z.string().describe('Read-only SELECT. Reference tables by the names fetch_dataset returned.'),
|
|
362
385
|
}),
|
|
363
386
|
output: z.object({
|
|
@@ -393,18 +416,16 @@ A domain-specific instance of the [minimum viable spillover server](#minimum-via
|
|
|
393
416
|
|
|
394
417
|
```ts
|
|
395
418
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
419
|
+
import { CanvasIdSchema } from '@cyanheads/mcp-ts-core/canvas';
|
|
396
420
|
import { getCanvas } from '@/services/canvas-accessor.js';
|
|
397
421
|
|
|
398
422
|
export const fetchAndStage = tool('fetch_and_stage_germplasm', {
|
|
399
423
|
description: 'Fetch germplasm matching a query and stage it on a DataCanvas for follow-up SQL.',
|
|
400
424
|
input: z.object({
|
|
401
425
|
query: z.string().describe('Search query'),
|
|
402
|
-
canvas_id:
|
|
403
|
-
.
|
|
404
|
-
|
|
405
|
-
.describe(
|
|
406
|
-
'Optional 10-char canvas ID returned from a prior call. Omit on first call to start a fresh canvas; the response will include a new canvas_id you can pass to subsequent calls or share with another agent.',
|
|
407
|
-
),
|
|
426
|
+
canvas_id: CanvasIdSchema.optional().describe(
|
|
427
|
+
'Optional canvas ID returned from a prior call. Omit on first call to start a fresh canvas; the response will include a new canvas_id you can pass to subsequent calls or share with another agent.',
|
|
428
|
+
),
|
|
408
429
|
}),
|
|
409
430
|
output: z.object({
|
|
410
431
|
canvas_id: z.string().describe('Canvas ID — pass to subsequent tool calls'),
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Reference for core and server configuration in `@cyanheads/mcp-ts-core`. Covers env var tables with defaults, priority order, server-specific Zod schema pattern, and Workers lazy-parsing requirement.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.19"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -28,7 +28,7 @@ Managed by `@cyanheads/mcp-ts-core`. Validated via Zod from environment variable
|
|
|
28
28
|
3. `sessionMode.default` passed to `createApp()` — a default, so it sits *below* the env var it seeds, unlike the identity options above
|
|
29
29
|
4. `package.json` fields
|
|
30
30
|
|
|
31
|
-
**Where `package.json` is read from:** the application root — the nearest `package.json` at or above the process entry module (`process.argv[1]`), which is the served package on every launch path (`npx`, `.mcpb`, a client config naming `dist/index.js`), none of which run from the package root. The launching client's working directory is never the anchor: a stdio client starts the server from wherever it happens to be, so reading identity from there makes a server report a foreign project's name and version. When the entry module is a tool installed under
|
|
31
|
+
**Where `package.json` is read from:** the application root — the nearest `package.json` at or above the process entry module (`process.argv[1]`), which is the served package on every launch path (`npx`, `.mcpb`, a client config naming `dist/index.js`), none of which run from the package root. The launching client's working directory is never the anchor: a stdio client starts the server from wherever it happens to be, so reading identity from there makes a server report a foreign project's name and version. When the entry module is a tool installed under a `node_modules` tree and the process runs from the directory owning that tree — a test runner is the usual case — the nearest manifest at or above the working directory wins instead. That also covers a workspace monorepo, where the runner is hoisted to the repo root while the process runs from a package directory: an owner that is a strict *ancestor* of the working directory qualifies only when it declares a workspace (a `workspaces` field in its manifest, or a `pnpm-workspace.yaml` beside it), which is what keeps a cache prefix or a plain project root — equally ancestors of a working directory inside them — from overriding an installed package's own identity. The owner is the outermost `node_modules` boundary, so a transitively-installed runner and a pnpm isolated layout resolve the same way. With no manifest reachable, the framework's own identity is the fallback.
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -276,7 +276,7 @@ export function getServerConfig(): ServerConfig {
|
|
|
276
276
|
}
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
-
**Env booleans — use `z.stringbool()`, never `z.coerce.boolean()`.** `z.coerce.boolean()` runs `Boolean(value)`, so `"false"`, `"0"`, and `"no"` all coerce to `true` — the flag becomes impossible to disable through the environment except by omitting it entirely. `z.stringbool()` parses `true/false/1/0/yes/no/on/off` (case-insensitive) and rejects anything else, so `MY_VERBOSE_LOGGING=false` actually disables and a typo fails loudly at startup instead of silently coercing.
|
|
279
|
+
**Env booleans — use `z.stringbool()`, never `z.coerce.boolean()`.** `z.coerce.boolean()` runs `Boolean(value)`, so `"false"`, `"0"`, and `"no"` all coerce to `true` — the flag becomes impossible to disable through the environment except by omitting it entirely. `z.stringbool()` parses `true/false/1/0/yes/no/on/off` (case-insensitive) and rejects anything else, so `MY_VERBOSE_LOGGING=false` actually disables and a typo fails loudly at startup instead of silently coercing. An empty string is not in that accepted set — `z.stringbool()` rejects `''` with `Invalid option`. What makes a blank `.env` line take the default is the normalization layer described under **Unset means unset** below, not the schema type.
|
|
280
280
|
|
|
281
281
|
**Unset means unset.** `parseEnvConfig` and the framework's own config both treat an empty string and a whole-value `${…}` placeholder — what an MCPB or plugin host forwards when a user leaves an option blank and nothing substitutes it — as the variable being absent: an optional field stays `undefined`, a defaulted field takes its default, and a required field fails as missing rather than as a format error against the literal text. A value that merely contains `${…}` is kept. No per-field `z.preprocess` guard is needed for either case.
|
|
282
282
|
|
|
@@ -289,6 +289,6 @@ Server config validation failed:
|
|
|
289
289
|
|
|
290
290
|
Instead of a raw `ZodError` dump at startup. The framework catches the resulting `ConfigurationError` and prints a clean banner (full stack behind `DEBUG=true`).
|
|
291
291
|
|
|
292
|
-
Direct `ServerConfigSchema.parse(...)` still works — the framework intercepts raw `ZodError` thrown from `setup()` and converts it — but error messages won't know about env var names, so they show the Zod path (`apiKey`) instead of the variable name (`MY_API_KEY`).
|
|
292
|
+
Direct `ServerConfigSchema.parse(...)` still works — the framework intercepts raw `ZodError` thrown from `setup()` and converts it — but error messages won't know about env var names, so they show the Zod path (`apiKey`) instead of the variable name (`MY_API_KEY`). No normalization runs on that path either, so a blank `MY_FLAG=` arrives as `''` and fails validation. `normalizeEnv` is exported from `/config` for exactly that case: normalize the values first, then parse.
|
|
293
293
|
|
|
294
294
|
**Workers:** Do not parse `process.env` at module top-level. In Workers, env bindings are injected at request time via `injectEnvVars()`, after all static imports. Lazy parsing is required.
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Canonical reference for the unified `Context` object passed to every tool and resource handler in `@cyanheads/mcp-ts-core`. Covers the full interface, its `RequestContext` base, all sub-APIs (`ctx.log`, `ctx.state`, `ctx.requestInput`, `ctx.inputs`, `ctx.enrich`, `ctx.content`), and when to use each.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.5"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -326,7 +326,9 @@ Always present, on every transport and both protocol eras. A handler that needs
|
|
|
326
326
|
|
|
327
327
|
One code path serves both eras. A 2026-07-28 client fulfils the embedded requests and retries the call; for a 2025-era session the SDK's legacy shim fulfils the same returns by issuing real `elicitation/create` / `sampling/createMessage` / `roots/list` round trips and re-entering the handler itself.
|
|
328
328
|
|
|
329
|
-
|
|
329
|
+
**A 2025-era client that declared no matching capability is refused, with an envelope.** URL-mode elicitation needs `elicitation.url`, form-mode needs `elicitation.form` (a bare `elicitation: {}` satisfies it), sampling needs `sampling` — `sampling.tools` when the request carries `tools` / `toolChoice` — and `roots/list` needs `roots`. `ctx.requestInput` runs the check on the result it builds and throws the refusal instead of the signal, so it never reaches the wire and the handler fails where it stands — the execution measurement records it as a failed call, and each family's usual error path shapes it. A tool gets `isError` with `structuredContent.error.code = -32600` (`InvalidRequest`), `data.reason: 'client_capability_missing'`, and a `data.recovery.hint` naming the capability; a resource read gets the same code, reason, and hint through the JSON-RPC error envelope. A prompt's `generate` receives no `ctx`, so it has no `ctx.requestInput` to gate. The check runs on every round, so a handler that elicits first and samples second is gated again on the second. A return carrying only `requestState` asks the client for nothing and is never gated. On the 2026-07-28 leg the SDK owns this check and a violation surfaces as its `MissingRequiredClientCapabilityError` (`-32021`) instead.
|
|
330
|
+
|
|
331
|
+
**`MCP_SESSION_MODE` decides whether that second leg exists.** Under `stateful` / `auto` the shim has the session it needs. Under `stateless` each 2025-era request is served by a fresh instance that never saw `initialize`, so its client-capability view is empty and the round trip is refused rather than attempted — fail-closed, but the handler never gets its answer. The refusal carries the same envelope, with a message and hint that name the per-request case and point at a stateful session. Ship `stateless` on a server whose destructive tools gate on `ctx.requestInput` and those tools become unusable for v1 HTTP clients. 2026-07-28 clients are unaffected in either mode: that revision has no server→client request channel at all, which is precisely why `input_required` exists. stdio is unaffected in either mode.
|
|
330
332
|
|
|
331
333
|
**Declare the requirement rather than documenting it.** `createApp({ sessionMode: { default: 'stateful', require: 'stateful' } })` seeds the mode from code and refuses to start over HTTP when the resolved mode is `stateless`, so the incompatibility surfaces at boot instead of at the first refused confirmation. `MCP_SESSION_MODE` still wins over the default; the requirement is what an operator cannot silently override. Nothing derives this from handler code — `ctx.requestInput` is present on every transport and both eras, so whether a server needs a live session is a decision its author makes. Full precedence and error shape: `api-config` § Session mode.
|
|
332
334
|
|