@cyanheads/mcp-ts-core 0.10.0 → 0.10.2
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 +2 -2
- package/CLAUDE.md +2 -2
- package/README.md +1 -1
- package/changelog/0.10.x/0.10.1.md +28 -0
- package/changelog/0.10.x/0.10.2.md +35 -0
- package/dist/core/context.d.ts +22 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +12 -0
- package/dist/core/context.js.map +1 -1
- package/dist/linter/rules/enrichment-rules.d.ts +20 -0
- package/dist/linter/rules/enrichment-rules.d.ts.map +1 -1
- package/dist/linter/rules/enrichment-rules.js +74 -9
- package/dist/linter/rules/enrichment-rules.js.map +1 -1
- package/dist/linter/rules/index.d.ts +2 -2
- package/dist/linter/rules/index.d.ts.map +1 -1
- package/dist/linter/rules/index.js +2 -2
- package/dist/linter/rules/index.js.map +1 -1
- package/dist/linter/rules/schema-rules.d.ts +4 -0
- package/dist/linter/rules/schema-rules.d.ts.map +1 -1
- package/dist/linter/rules/schema-rules.js +13 -0
- package/dist/linter/rules/schema-rules.js.map +1 -1
- package/dist/linter/rules/tool-rules.d.ts +12 -0
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +48 -1
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/linter/types.d.ts +17 -0
- package/dist/linter/types.d.ts.map +1 -1
- package/dist/linter/validate.d.ts.map +1 -1
- package/dist/linter/validate.js +55 -1
- package/dist/linter/validate.js.map +1 -1
- package/dist/logs/combined.log +4 -3
- package/dist/logs/error.log +2 -2
- package/dist/services/canvas/core/CanvasInstance.d.ts +1 -1
- package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.js +36 -11
- package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts +50 -3
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js +163 -6
- package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
- package/dist/services/canvas/core/sqlGate.d.ts +3 -2
- package/dist/services/canvas/core/sqlGate.d.ts.map +1 -1
- package/dist/services/canvas/core/sqlGate.js +32 -4
- package/dist/services/canvas/core/sqlGate.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +37 -14
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/canvas/spillover.d.ts +6 -0
- package/dist/services/canvas/spillover.d.ts.map +1 -1
- package/dist/services/canvas/spillover.js +1 -0
- package/dist/services/canvas/spillover.js.map +1 -1
- package/dist/services/canvas/types.d.ts +21 -0
- package/dist/services/canvas/types.d.ts.map +1 -1
- package/dist/utils/scheduling/scheduler.d.ts.map +1 -1
- package/dist/utils/scheduling/scheduler.js +4 -1
- package/dist/utils/scheduling/scheduler.js.map +1 -1
- package/package.json +8 -8
- package/scripts/lint-packaging.ts +125 -3
- package/skills/add-tool/SKILL.md +38 -1
- package/skills/api-canvas/SKILL.md +23 -3
- package/skills/api-context/SKILL.md +41 -1
- package/skills/api-linter/SKILL.md +77 -3
- package/skills/api-mirror/SKILL.md +30 -1
- package/skills/design-mcp-server/SKILL.md +2 -1
- package/templates/AGENTS.md +1 -1
- package/templates/CLAUDE.md +1 -1
- package/templates/Dockerfile +17 -0
- package/templates/_.mcpbignore +10 -10
- package/templates/manifest.json +1 -0
- package/templates/package.json +12 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spillover.d.ts","sourceRoot":"","sources":["../../../src/services/canvas/spillover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE,sDAAsD;AACtD,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC,qCAAqC;AACrC,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,GAAG;IAC7C,uDAAuD;IACvD,MAAM,EAAE,cAAc,CAAC;IACvB,6CAA6C;IAC7C,IAAI,CAAC,EAAE;QACL;;;;WAIG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6DAA6D;IAC7D,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"spillover.d.ts","sourceRoot":"","sources":["../../../src/services/canvas/spillover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE,sDAAsD;AACtD,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC,qCAAqC;AACrC,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,GAAG;IAC7C,uDAAuD;IACvD,MAAM,EAAE,cAAc,CAAC;IACvB,6CAA6C;IAC7C,IAAI,CAAC,EAAE;QACL;;;;WAIG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6DAA6D;IAC7D,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2FAA2F;AAC3F,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,WAAW,EAAE,CAAC,EAAE,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;CAChB;AAED,kGAAkG;AAClG,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,+EAA+E;IAC/E,MAAM,EAAE,mBAAmB,CAAC;IAC5B,WAAW,EAAE,CAAC,EAAE,CAAC;IACjB,OAAO,EAAE,IAAI,CAAC;IACd;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wDAAwD;AACxD,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAMjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAsB,SAAS,CAAC,CAAC,SAAS,GAAG,EAC3C,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CA0E7B"}
|
|
@@ -105,6 +105,7 @@ export async function spillover(opts) {
|
|
|
105
105
|
handle = await opts.canvas.registerTable(tableName, merged, {
|
|
106
106
|
schema,
|
|
107
107
|
...(opts.signal !== undefined && { signal: opts.signal }),
|
|
108
|
+
...(opts.ttlMs !== undefined && { ttlMs: opts.ttlMs }),
|
|
108
109
|
});
|
|
109
110
|
}
|
|
110
111
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spillover.js","sourceRoot":"","sources":["../../../src/services/canvas/spillover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"spillover.js","sourceRoot":"","sources":["../../../src/services/canvas/spillover.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,12 @@ export interface TableInfo {
|
|
|
27
27
|
approxSizeBytes?: number;
|
|
28
28
|
/** Resolved schema for the table or view. */
|
|
29
29
|
columns: ColumnSchema[];
|
|
30
|
+
/**
|
|
31
|
+
* ISO 8601 wall-clock expiry for this table's per-table TTL. Present only
|
|
32
|
+
* when the table was registered with a `ttlMs` option. When absent, the
|
|
33
|
+
* table inherits the canvas lifecycle (no independent expiry).
|
|
34
|
+
*/
|
|
35
|
+
expiresAt?: string;
|
|
30
36
|
/** Whether this entry is a base table or a registered view. */
|
|
31
37
|
kind: CanvasObjectKind;
|
|
32
38
|
/** Canvas-local name. */
|
|
@@ -48,6 +54,15 @@ export interface RegisterTableOptions {
|
|
|
48
54
|
schema?: ColumnSchema[];
|
|
49
55
|
/** Cancellation signal forwarded to the provider. */
|
|
50
56
|
signal?: AbortSignal;
|
|
57
|
+
/**
|
|
58
|
+
* Per-table sliding TTL in milliseconds. When set, this table expires
|
|
59
|
+
* independently of the canvas — the sliding window is extended on any read
|
|
60
|
+
* or write against this specific table. The sweep loop drops the table and
|
|
61
|
+
* clears its bookkeeping when it expires; the canvas itself is unaffected
|
|
62
|
+
* unless its own expiry fires independently. When omitted, the table
|
|
63
|
+
* inherits the canvas lifecycle (no independent expiry).
|
|
64
|
+
*/
|
|
65
|
+
ttlMs?: number;
|
|
51
66
|
}
|
|
52
67
|
/** Result of a successful {@link CanvasInstance.registerTable} call. */
|
|
53
68
|
export interface RegisterTableResult {
|
|
@@ -80,6 +95,12 @@ export interface QueryOptions {
|
|
|
80
95
|
rowLimit?: number;
|
|
81
96
|
/** Cancellation signal — interrupts the underlying connection. */
|
|
82
97
|
signal?: AbortSignal;
|
|
98
|
+
/**
|
|
99
|
+
* Per-table sliding TTL for the table materialized via `registerAs`.
|
|
100
|
+
* Ignored when `registerAs` is not set. Semantics match
|
|
101
|
+
* {@link RegisterTableOptions.ttlMs}.
|
|
102
|
+
*/
|
|
103
|
+
ttlMs?: number;
|
|
83
104
|
}
|
|
84
105
|
/** Result of a successful {@link CanvasInstance.query} call. */
|
|
85
106
|
export interface QueryResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/canvas/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,MAAM,GACN,MAAM,GACN,MAAM,CAAC;AAEX,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,yFAAyF;AACzF,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhD,4DAA4D;AAC5D,MAAM,WAAW,SAAS;IACxB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,+DAA+D;IAC/D,IAAI,EAAE,gBAAgB,CAAC;IACvB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,qDAAqD;IACrD,MAAM,CAAC,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/canvas/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/utils/scheduling/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/utils/scheduling/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAgCzE;;;;;;;;GAQG;AACH,MAAM,WAAW,GAAG;IAClB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,6GAA6G;IAC7G,IAAI,EAAE,aAAa,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmB;IAC1C,OAAO,CAAC,IAAI,CAA+B;IAE3C,eAAe;IACf,OAAO;IAMP;;;;;;;OAOG;WACW,WAAW,IAAI,gBAAgB;IAO7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACU,QAAQ,CACnB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC/D,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,GAAG,CAAC;IA2Df;;;;;;;;OAQG;IACI,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAU9B;;;;;;;;;OASG;IACI,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAU7B;;;;;;;;;OASG;IACI,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAW/B;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAQlB;;;;;;;;;;;;;;;OAeG;IACI,UAAU,IAAI,IAAI;IAYzB;;;;;;;;;OASG;IACI,QAAQ,IAAI,GAAG,EAAE;CAGzB;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,kBAAiC,CAAC"}
|
|
@@ -15,7 +15,10 @@ async function loadCron() {
|
|
|
15
15
|
throw configurationError('SchedulerService requires a Node.js runtime. Cron scheduling is not available in Workers or browser environments.');
|
|
16
16
|
}
|
|
17
17
|
if (!cronModulePromise) {
|
|
18
|
-
cronModulePromise = import('node-cron')
|
|
18
|
+
cronModulePromise = import('node-cron').catch((err) => {
|
|
19
|
+
cronModulePromise = null;
|
|
20
|
+
throw configurationError('SchedulerService requires the "node-cron" peer dependency — add it to your server\'s dependencies (^4.2.1).', undefined, { cause: err instanceof Error ? err : undefined });
|
|
21
|
+
});
|
|
19
22
|
}
|
|
20
23
|
return await cronModulePromise;
|
|
21
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/utils/scheduling/scheduler.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACjG,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;;;;GAMG;AACH,IAAI,iBAAiB,GAA+C,IAAI,CAAC;AAEzE,KAAK,UAAU,QAAQ;IACrB,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;QACpD,MAAM,kBAAkB,CACtB,mHAAmH,CACpH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,iBAAiB,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/utils/scheduling/scheduler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/mcp-ts-core",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"mcpName": "io.github.cyanheads/mcp-ts-core",
|
|
5
5
|
"description": "Agent-native TypeScript framework for building MCP servers. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Bun/Node/Cloudflare Workers.",
|
|
6
6
|
"main": "dist/core/index.js",
|
|
@@ -177,8 +177,8 @@
|
|
|
177
177
|
},
|
|
178
178
|
"devDependencies": {
|
|
179
179
|
"@biomejs/biome": "2.4.16",
|
|
180
|
-
"@cloudflare/vitest-pool-workers": "^0.16.
|
|
181
|
-
"@cloudflare/workers-types": "4.
|
|
180
|
+
"@cloudflare/vitest-pool-workers": "^0.16.14",
|
|
181
|
+
"@cloudflare/workers-types": "4.20260610.1",
|
|
182
182
|
"@duckdb/node-api": "^1.5.3-r.3",
|
|
183
183
|
"@hono/otel": "^1.1.2",
|
|
184
184
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.218.0",
|
|
@@ -190,10 +190,10 @@
|
|
|
190
190
|
"@opentelemetry/sdk-node": "^0.218.0",
|
|
191
191
|
"@opentelemetry/sdk-trace-node": "^2.7.1",
|
|
192
192
|
"@opentelemetry/semantic-conventions": "^1.41.1",
|
|
193
|
-
"@supabase/supabase-js": "^2.
|
|
193
|
+
"@supabase/supabase-js": "^2.108.1",
|
|
194
194
|
"@types/bun": "^1.3.14",
|
|
195
195
|
"@types/js-yaml": "^4.0.9",
|
|
196
|
-
"@types/node": "^25.9.
|
|
196
|
+
"@types/node": "^25.9.2",
|
|
197
197
|
"@types/papaparse": "^5.5.2",
|
|
198
198
|
"@types/sanitize-html": "^2.16.1",
|
|
199
199
|
"@types/validator": "^13.15.10",
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
"pdf-lib": "^1.17.1",
|
|
219
219
|
"pino-pretty": "^13.1.3",
|
|
220
220
|
"repomix": "^1.14.1",
|
|
221
|
-
"sanitize-html": "^2.17.
|
|
221
|
+
"sanitize-html": "^2.17.5",
|
|
222
222
|
"tsc-alias": "^1.8.17",
|
|
223
223
|
"typedoc": "^0.28.19",
|
|
224
224
|
"typescript": "^6.0.3",
|
|
@@ -278,11 +278,11 @@
|
|
|
278
278
|
"dependencies": {
|
|
279
279
|
"@hono/mcp": "^0.3.0",
|
|
280
280
|
"@hono/node-server": "^2.0.4",
|
|
281
|
-
"@modelcontextprotocol/ext-apps": "^1.7.
|
|
281
|
+
"@modelcontextprotocol/ext-apps": "^1.7.4",
|
|
282
282
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
283
283
|
"@opentelemetry/api": "^1.9.1",
|
|
284
284
|
"dotenv": "^17.4.2",
|
|
285
|
-
"hono": "^4.12.
|
|
285
|
+
"hono": "^4.12.25",
|
|
286
286
|
"jose": "^6.2.3",
|
|
287
287
|
"pino": "^10.3.1",
|
|
288
288
|
"zod": "^4.4.3"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @fileoverview MCPB packaging linter — validates env var alignment between
|
|
4
4
|
* `manifest.json` (MCPB bundle install UX) and `server.json` (MCP Registry
|
|
5
|
-
* discovery) for stdio packages.
|
|
5
|
+
* discovery) for stdio packages, and guards against bundle-content mistakes.
|
|
6
6
|
*
|
|
7
7
|
* Used by devcheck and as a standalone script: `bun run lint:packaging` /
|
|
8
8
|
* `npm run lint:packaging`.
|
|
@@ -15,8 +15,16 @@
|
|
|
15
15
|
* advertises the configurable knob the bundle surfaces).
|
|
16
16
|
* 4. Every required stdio env var in server.json (no default) must appear
|
|
17
17
|
* as a key in manifest `mcp_config.env` (the bundle can receive it).
|
|
18
|
+
* 5. Bundle-content guard: known root dev directories must not appear at
|
|
19
|
+
* bundle root after `.mcpbignore` evaluation (dev dir not excluded).
|
|
20
|
+
* 6. Bundle-content guard: `.mcpbignore` must not use unanchored patterns
|
|
21
|
+
* for root dev dirs — an unanchored `skills/` also strips
|
|
22
|
+
* `node_modules/x/skills/` (runtime path bypass, issues #172/#207).
|
|
23
|
+
* 7. Bundle-content guard: `.mcpbignore` patterns must not strip critical
|
|
24
|
+
* runtime package paths (e.g. `node_modules/@opentelemetry/api/build/src/`).
|
|
18
25
|
*
|
|
19
26
|
* Checks 1–2 run with `manifest.json` alone; 3–4 require `server.json`.
|
|
27
|
+
* Checks 5–7 run when `.mcpbignore` is present (silently skip otherwise).
|
|
20
28
|
*
|
|
21
29
|
* Skips cleanly when `manifest.json` is absent — consumers who deleted it for
|
|
22
30
|
* an HTTP-only deploy should not fail this check.
|
|
@@ -55,6 +63,26 @@ interface Manifest {
|
|
|
55
63
|
|
|
56
64
|
const USER_CONFIG_REF = /^\$\{user_config\.([\w-]+)\}$/;
|
|
57
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Root dev directories the scaffold template excludes from the bundle, and
|
|
68
|
+
* whose `.mcpbignore` patterns must be anchored with `/` to avoid also
|
|
69
|
+
* stripping nested runtime paths like `node_modules/x/skills/`. Keep in step
|
|
70
|
+
* with the directory entries in `templates/_.mcpbignore`.
|
|
71
|
+
*/
|
|
72
|
+
const KNOWN_DEV_DIRS = ['skills/', '.agents/', '.claude/'];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Critical runtime paths that must NOT be stripped by any `.mcpbignore` pattern.
|
|
76
|
+
* These are sampled representative paths — enough to catch a bare `skills/`
|
|
77
|
+
* pattern accidentally stripping `node_modules/…/skills/`.
|
|
78
|
+
*/
|
|
79
|
+
const CRITICAL_RUNTIME_PATHS = [
|
|
80
|
+
'node_modules/@opentelemetry/api/build/src/',
|
|
81
|
+
'node_modules/@modelcontextprotocol/sdk/dist/',
|
|
82
|
+
'node_modules/@cyanheads/mcp-ts-core/dist/',
|
|
83
|
+
'dist/index.js',
|
|
84
|
+
];
|
|
85
|
+
|
|
58
86
|
function tryReadJson<T>(path: string): T | undefined {
|
|
59
87
|
try {
|
|
60
88
|
if (!existsSync(path)) return;
|
|
@@ -65,7 +93,94 @@ function tryReadJson<T>(path: string): T | undefined {
|
|
|
65
93
|
}
|
|
66
94
|
}
|
|
67
95
|
|
|
68
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Run bundle-content checks (5–7) against the .mcpbignore patterns.
|
|
98
|
+
*
|
|
99
|
+
* Uses the `ignore` package (already a devDependency in scaffolded servers)
|
|
100
|
+
* to evaluate which paths survive the ignore rules. Returns an array of error
|
|
101
|
+
* strings; empty means all checks passed.
|
|
102
|
+
*
|
|
103
|
+
* **Context note:** this guard runs inside the scaffolded server project, not
|
|
104
|
+
* inside mcp-ts-core itself. `ignore` is listed in `templates/package.json`
|
|
105
|
+
* devDependencies (`^7.0.5`) and is therefore available in the server's
|
|
106
|
+
* `node_modules` when `bun run lint:packaging` is invoked there.
|
|
107
|
+
*/
|
|
108
|
+
async function checkBundleContent(mcpbignorePath: string): Promise<string[]> {
|
|
109
|
+
const errors: string[] = [];
|
|
110
|
+
|
|
111
|
+
let createIgnore: typeof import('ignore')['default'];
|
|
112
|
+
try {
|
|
113
|
+
// Dynamic import so the rest of the linter still runs when `ignore` is absent.
|
|
114
|
+
createIgnore = ((await import('ignore')) as typeof import('ignore')).default;
|
|
115
|
+
} catch {
|
|
116
|
+
// `ignore` not installed — skip the guard without failing (e.g. in a minimal
|
|
117
|
+
// CI environment that omits devDependencies).
|
|
118
|
+
return errors;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const raw = readFileSync(mcpbignorePath, 'utf-8');
|
|
122
|
+
const lines = raw
|
|
123
|
+
.split('\n')
|
|
124
|
+
.map((l) => l.trim())
|
|
125
|
+
.filter((l) => l && !l.startsWith('#'));
|
|
126
|
+
|
|
127
|
+
const ig = createIgnore().add(lines);
|
|
128
|
+
|
|
129
|
+
// Check 5: dev dirs must be excluded at bundle root.
|
|
130
|
+
for (const dir of KNOWN_DEV_DIRS) {
|
|
131
|
+
const probe = `${dir}README.md`;
|
|
132
|
+
if (!ig.ignores(probe)) {
|
|
133
|
+
errors.push(
|
|
134
|
+
`.mcpbignore does not exclude root dev directory "${dir}" — ` +
|
|
135
|
+
`bundle will include dev files. Add a pattern like "/${dir}" to exclude it.`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check 6: unanchored dev-dir patterns also strip runtime paths inside
|
|
141
|
+
// node_modules. Any pattern that excludes a known dev dir must be anchored
|
|
142
|
+
// (leading "/") so it only matches at root.
|
|
143
|
+
for (const dir of KNOWN_DEV_DIRS) {
|
|
144
|
+
// Strip trailing slash for the node_modules probe path.
|
|
145
|
+
const name = dir.replace(/\/$/, '');
|
|
146
|
+
const runtimeProbe = `node_modules/some-pkg/${name}/index.js`;
|
|
147
|
+
if (ig.ignores(runtimeProbe)) {
|
|
148
|
+
// Find the offending pattern.
|
|
149
|
+
const offending = lines.filter((p) => {
|
|
150
|
+
try {
|
|
151
|
+
return createIgnore().add([p]).ignores(runtimeProbe);
|
|
152
|
+
} catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
errors.push(
|
|
157
|
+
`.mcpbignore uses an unanchored pattern that also strips runtime paths under node_modules: ` +
|
|
158
|
+
`[${offending.join(', ')}]. Use a leading "/" to anchor to root (e.g. "/${dir}").`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Check 7: no pattern should strip critical runtime paths.
|
|
164
|
+
for (const critPath of CRITICAL_RUNTIME_PATHS) {
|
|
165
|
+
if (ig.ignores(critPath)) {
|
|
166
|
+
const offending = lines.filter((p) => {
|
|
167
|
+
try {
|
|
168
|
+
return createIgnore().add([p]).ignores(critPath);
|
|
169
|
+
} catch {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
errors.push(
|
|
174
|
+
`.mcpbignore pattern(s) [${offending.join(', ')}] would strip critical runtime path ` +
|
|
175
|
+
`"${critPath}" — add a leading "/" to anchor to root (e.g. "/${offending[0] ?? '?'}").`,
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return errors;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function main(): Promise<void> {
|
|
69
184
|
const manifestPath = resolve('manifest.json');
|
|
70
185
|
if (!existsSync(manifestPath)) {
|
|
71
186
|
console.log('No manifest.json — skipping lint:packaging.');
|
|
@@ -133,6 +248,13 @@ function main(): void {
|
|
|
133
248
|
}
|
|
134
249
|
}
|
|
135
250
|
|
|
251
|
+
// Bundle-content guard (checks 5–7).
|
|
252
|
+
const mcpbignorePath = resolve('.mcpbignore');
|
|
253
|
+
if (existsSync(mcpbignorePath)) {
|
|
254
|
+
const bundleErrors = await checkBundleContent(mcpbignorePath);
|
|
255
|
+
errors.push(...bundleErrors);
|
|
256
|
+
}
|
|
257
|
+
|
|
136
258
|
if (errors.length === 0) {
|
|
137
259
|
console.log('Packaging alignment OK.');
|
|
138
260
|
process.exit(0);
|
|
@@ -141,4 +263,4 @@ function main(): void {
|
|
|
141
263
|
process.exit(1);
|
|
142
264
|
}
|
|
143
265
|
|
|
144
|
-
main();
|
|
266
|
+
await main();
|
package/skills/add-tool/SKILL.md
CHANGED
|
@@ -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.14"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -252,6 +252,43 @@ enrichmentTrailer: {
|
|
|
252
252
|
|
|
253
253
|
`structuredContent` always keeps the full structured value; `enrichmentTrailer` only controls the human-facing `content[]` line.
|
|
254
254
|
|
|
255
|
+
### Capped lists must disclose truncation
|
|
256
|
+
|
|
257
|
+
When a tool accepts a cap-like input (`limit`, `per_page`, `page_size`, `max_results`, `max_items`) and returns an array, disclose when the cap was hit — the agent otherwise treats a partial set as complete.
|
|
258
|
+
|
|
259
|
+
The one-liner: `ctx.enrich.truncated({ shown, cap })`. Declare the fields in the `enrichment` block:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
enrichment: {
|
|
263
|
+
truncated: z.boolean().describe('True when the list was capped at the limit.'),
|
|
264
|
+
shown: z.number().describe('Number of items returned.'),
|
|
265
|
+
cap: z.number().describe('The limit that was applied.'),
|
|
266
|
+
},
|
|
267
|
+
async handler(input, ctx) {
|
|
268
|
+
const items = await fetchItems(input.limit);
|
|
269
|
+
if (items.length >= input.limit) {
|
|
270
|
+
ctx.enrich.truncated({ shown: items.length, cap: input.limit });
|
|
271
|
+
}
|
|
272
|
+
return { items };
|
|
273
|
+
},
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Alternatively, if the upstream total is known, `ctx.enrich.total(n)` (writes `totalCount`) also satisfies the lint rule.
|
|
277
|
+
|
|
278
|
+
**Threshold bound** — when the upstream total is unknowable but the list is sorted by the cap key, the smallest shown value is a rigorous upper bound on all omitted items (Fagin Threshold Algorithm). Pass it as `ceiling`:
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
// items is sorted descending by count; anything hidden has count ≤ items.at(-1).count
|
|
282
|
+
ctx.enrich.truncated({
|
|
283
|
+
shown: items.length,
|
|
284
|
+
cap: input.limit,
|
|
285
|
+
ceiling: items.at(-1)?.count,
|
|
286
|
+
guidance: 'Narrow with filters or raise per_page (max 200).',
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Declare `truncationCeiling: z.number().optional()` in the `enrichment` block to surface it. The `capped-list-no-truncation` lint rule warns when this disclosure is absent — see `api-linter`.
|
|
291
|
+
|
|
255
292
|
### Communicate filtering and exclusions
|
|
256
293
|
|
|
257
294
|
If the tool omitted, truncated, or filtered anything, say what and how to get it back. Silent omission is invisible to the agent — it can't act on what it doesn't know about.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: api-canvas
|
|
3
3
|
description: >
|
|
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, the token-sharing pattern for multi-agent collaboration, env config, and Cloudflare Workers fail-closed behavior.
|
|
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: "1.
|
|
7
|
+
version: "1.5"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -129,10 +129,21 @@ await instance.registerTable('big_dataset', asyncRows, {
|
|
|
129
129
|
{ name: 'label', type: 'VARCHAR', nullable: true },
|
|
130
130
|
],
|
|
131
131
|
});
|
|
132
|
+
|
|
133
|
+
// Per-table TTL — this table ages on its own clock (30 min sliding window).
|
|
134
|
+
// The canvas itself is unaffected; other tables on the same canvas are not touched.
|
|
135
|
+
await instance.registerTable('recent_fetch', rows, { ttlMs: 30 * 60 * 1000 });
|
|
132
136
|
```
|
|
133
137
|
|
|
134
138
|
**Schema inference** when `schema` is omitted: sniffer materializes the first 100 rows, unions JS-side types per column, and maps to DuckDB types. Fall-backs to `VARCHAR` for ambiguous unions (string mixed with numerics). Numeric widening: `INTEGER + DOUBLE → DOUBLE`, `INTEGER + BIGINT → BIGINT`. Column ordering follows first-appearance.
|
|
135
139
|
|
|
140
|
+
**Per-table TTL (`ttlMs`)** — optional sliding TTL for this table specifically. When set:
|
|
141
|
+
- The sweep loop drops the table (and clears its bookkeeping) when its window expires.
|
|
142
|
+
- The TTL slides on any read or write against this table: on `registerTable` (initial set), on `query()` (both when the table appears in the SQL text and when it is the `registerAs` target).
|
|
143
|
+
- The canvas itself is unaffected — canvas-level expiry is independent.
|
|
144
|
+
- Tables registered without `ttlMs` inherit the canvas lifecycle exactly as before (no change to default behavior).
|
|
145
|
+
- `instance.describe()` surfaces `TableInfo.expiresAt` (ISO 8601) for tables that have a per-table TTL; absent otherwise.
|
|
146
|
+
|
|
136
147
|
### `instance.query(sql, options?)`
|
|
137
148
|
|
|
138
149
|
Run SQL across registered tables. Returns at most `rowLimit` rows (default 10 000). For full result sets, pass `registerAs` — the result is materialized as a new canvas table; the response carries a `preview` slice plus the table reference.
|
|
@@ -149,10 +160,18 @@ const joined = await instance.query(`
|
|
|
149
160
|
FROM germplasm g JOIN observations o ON g.germplasmDbId = o.germplasmDbId
|
|
150
161
|
`, { registerAs: 'g_with_obs', preview: 10 });
|
|
151
162
|
// joined.tableName === 'g_with_obs'; joined.rows.length === 10; joined.rowCount === <full count>
|
|
163
|
+
|
|
164
|
+
// Materialize with a per-table TTL so the chained result ages independently.
|
|
165
|
+
const chained = await instance.query(
|
|
166
|
+
'SELECT * FROM recent_fetch WHERE score > 0.8',
|
|
167
|
+
{ registerAs: 'high_score', ttlMs: 15 * 60 * 1000 },
|
|
168
|
+
);
|
|
152
169
|
```
|
|
153
170
|
|
|
154
171
|
`registerAs` rejects with `ValidationError` (`data.reason: 'register_as_clash'`) if the target name already exists — drop it first.
|
|
155
172
|
|
|
173
|
+
`ttlMs` on `query({ registerAs })` assigns a per-table TTL to the materialized table — the same sliding semantics as `registerTable({ ttlMs })`. The SQL text is also scanned for referenced table names; any tracked per-table TTL entry found is slid on each `query()` call.
|
|
174
|
+
|
|
156
175
|
**Read-only enforcement** (four layers):
|
|
157
176
|
1. Text-level deny-list — pre-parse scan for file/HTTP-reading table functions (`read_csv*`, `read_json*`, `read_parquet*`, `read_text`, `read_blob`, `glob`, `iceberg_scan`, `delta_scan`, `postgres_scan`, `mysql_scan`, `sqlite_scan`, plus pre-staged spatial ones).
|
|
158
177
|
2. Statement count (must be 1) via `extractStatements`.
|
|
@@ -354,7 +373,7 @@ export const dataframeQuery = tool('dataframe_query', {
|
|
|
354
373
|
| Underlying data is publicly accessible | ✅ |
|
|
355
374
|
| Single-user deployment (stdio, or HTTP with one user) | ✅ — no cross-user surface regardless of data sensitivity |
|
|
356
375
|
| Use case is research / analytics, not multi-tenant SaaS | ✅ |
|
|
357
|
-
| Dataframes must age individually |
|
|
376
|
+
| Dataframes must age individually | ✅ Use `registerTable({ ttlMs })` or `query({ registerAs, ttlMs })` — per-table TTL is independent of canvas-level expiry. The sweep loop drops expired tables while keeping the canvas (and other tables) alive. |
|
|
358
377
|
| Per-user row visibility matters in a multi-user deployment | ❌ — add session/tenant scoping at the server level |
|
|
359
378
|
|
|
360
379
|
The germplasm-flavored [consumer tool template](#consumer-tool-template) below is the same pattern with domain-specific naming.
|
|
@@ -421,6 +440,7 @@ const result = await spillover({
|
|
|
421
440
|
previewChars: 100_000, // ≈ 25k tokens of inline rows
|
|
422
441
|
caps: { maxRows: 50_000 }, // hard upper bound on registered rows
|
|
423
442
|
signal: ctx.signal,
|
|
443
|
+
ttlMs: 30 * 60 * 1000, // optional: per-table TTL forwarded to registerTable
|
|
424
444
|
});
|
|
425
445
|
|
|
426
446
|
if (result.spilled) {
|
|
@@ -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, all sub-APIs (`ctx.log`, `ctx.state`, `ctx.elicit`, `ctx.sample`, `ctx.progress`, `ctx.enrich`), and when to use each.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.7"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -591,6 +591,11 @@ ctx.enrich.notice(text: string): void // writes `notice` → blockq
|
|
|
591
591
|
ctx.enrich.total(count: number): void // writes `totalCount` → "N total"
|
|
592
592
|
ctx.enrich.echo(query: string): void // writes `effectiveQuery` → "Query: …"
|
|
593
593
|
ctx.enrich.delta({ field, before, after }): void // writes `{before, after}` → "field: before → after"
|
|
594
|
+
|
|
595
|
+
// Truncation disclosure — for capped lists:
|
|
596
|
+
ctx.enrich.truncated({ shown, cap, ceiling?, guidance? }): void
|
|
597
|
+
// writes: truncated=true, shown, cap, truncationCeiling? (if ceiling provided)
|
|
598
|
+
// also writes notice via guidance or a generated default (last-wins with other notice calls)
|
|
594
599
|
```
|
|
595
600
|
|
|
596
601
|
### Behavior
|
|
@@ -606,6 +611,41 @@ ctx.enrich.delta({ field, before, after }): void // writes `{before, after}`
|
|
|
606
611
|
| `format-parity` | Enrichment lives outside `output`, so the `format-parity` lint never requires it in `format()`. |
|
|
607
612
|
| Trailer rendering | Per field: kind-tag if set (notice/total/echo/delta), else the definition's `enrichmentTrailer.render`/`label`, else `**key:** value` (objects/arrays `JSON.stringify`'d). A structured field with no `render` errors under `enrichment-trailer-render` — supply one so it renders as markdown; `structuredContent` keeps the full value regardless. |
|
|
608
613
|
|
|
614
|
+
### `ctx.enrich.truncated()` — capped-list disclosure
|
|
615
|
+
|
|
616
|
+
For tools that cap a list (i.e. have a `limit`/`per_page`/`page_size`/`max_results`/`max_items` input), call `truncated()` when the cap was actually hit:
|
|
617
|
+
|
|
618
|
+
```ts
|
|
619
|
+
enrichment: {
|
|
620
|
+
truncated: z.boolean().describe('True when the list was capped.'),
|
|
621
|
+
shown: z.number().describe('Number of items returned.'),
|
|
622
|
+
cap: z.number().describe('The limit that was applied.'),
|
|
623
|
+
truncationCeiling: z.number().optional().describe('Upper bound for omitted items (threshold bound).'),
|
|
624
|
+
},
|
|
625
|
+
async handler(input, ctx) {
|
|
626
|
+
const items = await fetch(input.limit);
|
|
627
|
+
if (items.length >= input.limit) {
|
|
628
|
+
ctx.enrich.truncated({
|
|
629
|
+
shown: items.length,
|
|
630
|
+
cap: input.limit,
|
|
631
|
+
ceiling: items.at(-1)?.count, // optional — only when list sorted by cap key
|
|
632
|
+
guidance: 'Narrow with filters or raise per_page (max 200).',
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
return { items };
|
|
636
|
+
},
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
| Field written | Key | Notes |
|
|
640
|
+
|:---|:---|:---|
|
|
641
|
+
| `truncated` | `true` | Always |
|
|
642
|
+
| `shown` | `number` | Always |
|
|
643
|
+
| `cap` | `number` | Always |
|
|
644
|
+
| `truncationCeiling` | `number` | Only when `ceiling` is passed |
|
|
645
|
+
| `notice` | `string` | Via `guidance` or a generated default; **last-wins** — a handler with multiple notice sources (e.g. both truncation and empty-result) should compose them into one string passed as `guidance`, or call `truncated()` after the other notice calls. |
|
|
646
|
+
|
|
647
|
+
The `capped-list-no-truncation` lint rule fires when a cap-like input + array output shape is present without any of: `truncated` or `totalCount` in the declared `enrichment`, or `truncated` or `totalCount` in `output`. Using `ctx.enrich.total(n)` (writes `totalCount`) is also recognized as honest disclosure.
|
|
648
|
+
|
|
609
649
|
See `add-tool`'s **Tool Response Design** and `skills/api-linter` (`enrichment-*` rules) for the full pattern. Test enrichment with `getEnrichment(ctx)` from `@cyanheads/mcp-ts-core/testing`.
|
|
610
650
|
|
|
611
651
|
---
|