@cyanheads/mcp-ts-core 0.8.7 → 0.8.9
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/CLAUDE.md +2 -0
- package/README.md +1 -1
- package/biome.json +1 -1
- package/changelog/0.8.x/0.8.8.md +11 -0
- package/changelog/0.8.x/0.8.9.md +34 -0
- package/dist/canvas/core/CanvasInstance.d.ts +43 -0
- package/dist/canvas/core/CanvasInstance.d.ts.map +1 -0
- package/dist/canvas/core/CanvasInstance.js +63 -0
- package/dist/canvas/core/CanvasInstance.js.map +1 -0
- package/dist/canvas/core/CanvasRegistry.d.ts +96 -0
- package/dist/canvas/core/CanvasRegistry.d.ts.map +1 -0
- package/dist/canvas/core/CanvasRegistry.js +250 -0
- package/dist/canvas/core/CanvasRegistry.js.map +1 -0
- package/dist/canvas/core/DataCanvas.d.ts +49 -0
- package/dist/canvas/core/DataCanvas.d.ts.map +1 -0
- package/dist/canvas/core/DataCanvas.js +85 -0
- package/dist/canvas/core/DataCanvas.js.map +1 -0
- package/dist/canvas/core/IDataCanvasProvider.d.ts +47 -0
- package/dist/canvas/core/IDataCanvasProvider.d.ts.map +1 -0
- package/dist/canvas/core/IDataCanvasProvider.js +10 -0
- package/dist/canvas/core/IDataCanvasProvider.js.map +1 -0
- package/dist/canvas/core/canvasFactory.d.ts +26 -0
- package/dist/canvas/core/canvasFactory.d.ts.map +1 -0
- package/dist/canvas/core/canvasFactory.js +63 -0
- package/dist/canvas/core/canvasFactory.js.map +1 -0
- package/dist/canvas/core/sqlGate.d.ts +107 -0
- package/dist/canvas/core/sqlGate.d.ts.map +1 -0
- package/dist/canvas/core/sqlGate.js +267 -0
- package/dist/canvas/core/sqlGate.js.map +1 -0
- package/dist/canvas/index.d.ts +21 -0
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +19 -0
- package/dist/canvas/index.js.map +1 -0
- package/dist/canvas/providers/duckdb/DuckdbProvider.d.ts +56 -0
- package/dist/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -0
- package/dist/canvas/providers/duckdb/DuckdbProvider.js +600 -0
- package/dist/canvas/providers/duckdb/DuckdbProvider.js.map +1 -0
- package/dist/canvas/providers/duckdb/exportWriter.d.ts +48 -0
- package/dist/canvas/providers/duckdb/exportWriter.d.ts.map +1 -0
- package/dist/canvas/providers/duckdb/exportWriter.js +119 -0
- package/dist/canvas/providers/duckdb/exportWriter.js.map +1 -0
- package/dist/canvas/providers/duckdb/schemaSniffer.d.ts +44 -0
- package/dist/canvas/providers/duckdb/schemaSniffer.d.ts.map +1 -0
- package/dist/canvas/providers/duckdb/schemaSniffer.js +134 -0
- package/dist/canvas/providers/duckdb/schemaSniffer.js.map +1 -0
- package/dist/canvas/types.d.ts +134 -0
- package/dist/canvas/types.d.ts.map +1 -0
- package/dist/canvas/types.js +9 -0
- package/dist/canvas/types.js.map +1 -0
- package/dist/config/index.d.ts +51 -15
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +44 -0
- package/dist/config/index.js.map +1 -1
- package/dist/core/app.d.ts +8 -0
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +11 -0
- package/dist/core/app.js.map +1 -1
- package/dist/core/worker.d.ts +7 -0
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js +1 -0
- package/dist/core/worker.js.map +1 -1
- package/dist/logs/combined.log +4 -4
- package/dist/logs/error.log +4 -4
- package/dist/storage/core/storageValidation.d.ts.map +1 -1
- package/dist/storage/core/storageValidation.js +7 -1
- package/dist/storage/core/storageValidation.js.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.js +2 -1
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
- package/package.json +18 -8
- package/skills/api-canvas/SKILL.md +260 -0
- package/skills/api-config/SKILL.md +18 -0
- package/skills/api-workers/SKILL.md +6 -0
- package/skills/report-issue-framework/SKILL.md +1 -0
- package/skills/report-issue-local/SKILL.md +2 -0
- package/templates/.github/ISSUE_TEMPLATE/bug_report.yml +1 -0
- package/templates/.github/ISSUE_TEMPLATE/feature_request.yml +1 -0
package/dist/logs/error.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{"level":50,"time":
|
|
2
|
-
{"level":50,"time":
|
|
3
|
-
{"level":50,"time":
|
|
4
|
-
{"level":50,"time":
|
|
1
|
+
{"level":50,"time":1777761262998,"env":"testing","version":"0.0.0-test","pid":35802,"requestId":"AORVI-VMVJR","timestamp":"2026-05-02T22:34:22.998Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"5321b082b248c8c90bbac890111dbf363e3d137972760d25f52d149d902e724b","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"5321b082b248c8c90bbac890111dbf363e3d137972760d25f52d149d902e724b","toolName":"scoped_echo","requestId":"AORVI-VMVJR","timestamp":"2026-05-02T22:34:22.998Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:133:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:168:26)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
|
|
2
|
+
{"level":50,"time":1777761263315,"env":"testing","version":"0.8.9","pid":35804,"requestId":"7YMS4-V1N73","timestamp":"2026-05-02T22:34:23.314Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"7YMS4-V1N73","timestamp":"2026-05-02T22:34:23.314Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
3
|
+
{"level":50,"time":1777761263331,"env":"testing","version":"0.8.9","pid":35804,"requestId":"7WNIU-7KMCT","timestamp":"2026-05-02T22:34:23.331Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"7WNIU-7KMCT","timestamp":"2026-05-02T22:34:23.331Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
4
|
+
{"level":50,"time":1777761263334,"env":"testing","version":"0.8.9","pid":35804,"requestId":"RXHHM-HMZQ6","timestamp":"2026-05-02T22:34:23.334Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"RXHHM-HMZQ6","timestamp":"2026-05-02T22:34:23.334Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storageValidation.d.ts","sourceRoot":"","sources":["../../../src/storage/core/storageValidation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storageValidation.d.ts","sourceRoot":"","sources":["../../../src/storage/core/storageValidation.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA0CzE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAqChF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CA4BtE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAyC5E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,OAAO,EAAE,cAAc,GACtB,IAAI,CA2BN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,OAAO,EAAE,cAAc,GACtB,IAAI,CA+DN;AAyCD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKtE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAwD9F"}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
22
22
|
import { invalidParams, McpError, validationError } from '../../types-global/errors.js';
|
|
23
23
|
import { base64ToString, stringToBase64 } from '../../utils/internal/encoding.js';
|
|
24
|
+
import { logger } from '../../utils/internal/logger.js';
|
|
24
25
|
/**
|
|
25
26
|
* Per-process HMAC key for cursor integrity. Generated once at module load.
|
|
26
27
|
* Does not need to survive restarts — cursors are ephemeral pagination tokens.
|
|
@@ -363,10 +364,15 @@ export function decodeCursor(cursor, tenantId, context) {
|
|
|
363
364
|
if (error instanceof McpError) {
|
|
364
365
|
throw error;
|
|
365
366
|
}
|
|
367
|
+
// Stack stays in the server log; McpError.data is wire-visible.
|
|
368
|
+
logger.warning('Failed to decode cursor', {
|
|
369
|
+
...context,
|
|
370
|
+
operation: 'decodeCursor',
|
|
371
|
+
error: error instanceof Error ? error.stack : String(error),
|
|
372
|
+
});
|
|
366
373
|
throw invalidParams('Failed to decode cursor. Cursor may be corrupted or invalid.', {
|
|
367
374
|
...context,
|
|
368
375
|
operation: 'decodeCursor',
|
|
369
|
-
rawError: error instanceof Error ? error.stack : String(error),
|
|
370
376
|
});
|
|
371
377
|
}
|
|
372
378
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storageValidation.js","sourceRoot":"","sources":["../../../src/storage/core/storageValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"storageValidation.js","sourceRoot":"","sources":["../../../src/storage/core/storageValidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/errorHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,gBAAgB,EAAY,MAAM,0BAA0B,CAAC;AActE,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAapE,0FAA0F;AAC1F,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;GAEG;AAEH,qBAAa,YAAY;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;WACW,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB;IAuClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;WACW,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,KAAK;
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/errorHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,gBAAgB,EAAY,MAAM,0BAA0B,CAAC;AActE,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAapE,0FAA0F;AAC1F,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;GAEG;AAEH,qBAAa,YAAY;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;WACW,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB;IAuClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;WACW,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,KAAK;IAyI9E;;;;;;;;;;OAUG;WACW,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG;QAC1C,IAAI,EAAE,gBAAgB,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAChC;IAiBD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;WACW,QAAQ,CAAC,CAAC,SAAS,KAAK,EACpC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EACxC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,GACxE,CAAC,GAAG,KAAK;IAkBZ;;;;;;;;;;;;;;;;;;OAkBG;WACW,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAwBlE;;;;;;;;;;;;;;;;;;;;;OAqBG;WACiB,QAAQ,CAAC,CAAC,EAC5B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACxB,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,GAC5C,OAAO,CAAC,CAAC,CAAC;CAWd"}
|
|
@@ -117,8 +117,9 @@ export class ErrorHandler {
|
|
|
117
117
|
*/
|
|
118
118
|
static handleError(error, options) {
|
|
119
119
|
// --- OpenTelemetry Integration ---
|
|
120
|
+
// Skip ended/no-op spans — measure*Execution paths already record + end the span before re-throwing.
|
|
120
121
|
const activeSpan = trace.getActiveSpan();
|
|
121
|
-
if (activeSpan) {
|
|
122
|
+
if (activeSpan?.isRecording()) {
|
|
122
123
|
if (error instanceof Error) {
|
|
123
124
|
activeSpan.recordException(error);
|
|
124
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/errorHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,IAAI,sBAAoE,CAAC;AAEzE,SAAS,eAAe;IACtB,sBAAsB,KAAK,aAAa,CACtC,uBAAuB,EACvB,gDAAgD,EAChD,UAAU,CACX,CAAC;IACF,OAAO,EAAE,sBAAsB,EAAE,CAAC;AACpC,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,gBAAgB;IAC9B,eAAe,EAAE,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,gHAAgH;AAChH,MAAM,OAAO,YAAY;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACI,MAAM,CAAC,kBAAkB,CAAC,KAAc;QAC7C,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,CAAC;QAED,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAE5C,gDAAgD;QAChD,MAAM,cAAc,GAAI,mBAAwD,CAAC,SAAS,CAAC,CAAC;QAC5F,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,yDAAyD;QACzD,KAAK,MAAM,OAAO,IAAI,0BAA0B,EAAE,CAAC;YACjD,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1F,OAAO,OAAO,CAAC,SAAS,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,iFAAiF;QACjF,KAAK,MAAM,OAAO,IAAI,uBAAuB,EAAE,CAAC;YAC9C,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1F,OAAO,OAAO,CAAC,SAAS,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,sCAAsC;QACtC,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,MAAM,IAAI,KAAK;YACd,KAA2B,CAAC,IAAI,KAAK,YAAY,EAClD,CAAC;YACD,OAAO,gBAAgB,CAAC,OAAO,CAAC;QAClC,CAAC;QACD,OAAO,gBAAgB,CAAC,aAAa,CAAC;IACxC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACI,MAAM,CAAC,WAAW,CAAC,KAAc,EAAE,OAA4B;QACpE,oCAAoC;QACpC,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;QACzC,IAAI,UAAU,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/errorHandler.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.8.
|
|
3
|
+
"version": "0.8.9",
|
|
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",
|
|
@@ -73,6 +73,10 @@
|
|
|
73
73
|
"types": "./dist/storage/core/IStorageProvider.d.ts",
|
|
74
74
|
"import": "./dist/storage/core/IStorageProvider.js"
|
|
75
75
|
},
|
|
76
|
+
"./canvas": {
|
|
77
|
+
"types": "./dist/canvas/index.d.ts",
|
|
78
|
+
"import": "./dist/canvas/index.js"
|
|
79
|
+
},
|
|
76
80
|
"./utils": {
|
|
77
81
|
"types": "./dist/utils/index.d.ts",
|
|
78
82
|
"import": "./dist/utils/index.js"
|
|
@@ -156,11 +160,13 @@
|
|
|
156
160
|
"path-to-regexp": "8.4.2",
|
|
157
161
|
"picomatch": "2.3.2",
|
|
158
162
|
"protobufjs": "7.5.5",
|
|
159
|
-
"yaml": "1.10.3"
|
|
163
|
+
"yaml": "1.10.3",
|
|
164
|
+
"zod": "4.4.2"
|
|
160
165
|
},
|
|
161
166
|
"devDependencies": {
|
|
162
|
-
"@biomejs/biome": "2.4.
|
|
163
|
-
"@cloudflare/workers-types": "^4.
|
|
167
|
+
"@biomejs/biome": "2.4.14",
|
|
168
|
+
"@cloudflare/workers-types": "^4.20260502.1",
|
|
169
|
+
"@duckdb/node-api": "^1.5.2-r.1",
|
|
164
170
|
"@hono/otel": "^1.1.1",
|
|
165
171
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.216.0",
|
|
166
172
|
"@opentelemetry/exporter-trace-otlp-http": "^0.216.0",
|
|
@@ -199,7 +205,7 @@
|
|
|
199
205
|
"pino-pretty": "^13.1.3",
|
|
200
206
|
"repomix": "^1.14.0",
|
|
201
207
|
"sanitize-html": "^2.17.3",
|
|
202
|
-
"tsc-alias": "^1.8.
|
|
208
|
+
"tsc-alias": "^1.8.17",
|
|
203
209
|
"typedoc": "^0.28.19",
|
|
204
210
|
"typescript": "^6.0.3",
|
|
205
211
|
"unpdf": "^1.6.2",
|
|
@@ -257,17 +263,18 @@
|
|
|
257
263
|
},
|
|
258
264
|
"dependencies": {
|
|
259
265
|
"@hono/mcp": "^0.2.5",
|
|
260
|
-
"@hono/node-server": "^2.0.
|
|
266
|
+
"@hono/node-server": "^2.0.1",
|
|
261
267
|
"@modelcontextprotocol/ext-apps": "^1.7.1",
|
|
262
268
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
263
269
|
"@opentelemetry/api": "^1.9.1",
|
|
264
270
|
"dotenv": "^17.4.2",
|
|
265
|
-
"hono": "^4.12.
|
|
271
|
+
"hono": "^4.12.16",
|
|
266
272
|
"jose": "^6.2.3",
|
|
267
273
|
"pino": "^10.3.1",
|
|
268
|
-
"zod": "^4.
|
|
274
|
+
"zod": "^4.4.2"
|
|
269
275
|
},
|
|
270
276
|
"peerDependencies": {
|
|
277
|
+
"@duckdb/node-api": "^1.5.0",
|
|
271
278
|
"@hono/otel": "^1.1.1",
|
|
272
279
|
"@opentelemetry/instrumentation-http": "^0.215.0",
|
|
273
280
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.215.0",
|
|
@@ -295,6 +302,9 @@
|
|
|
295
302
|
"validator": "^13.15.35"
|
|
296
303
|
},
|
|
297
304
|
"peerDependenciesMeta": {
|
|
305
|
+
"@duckdb/node-api": {
|
|
306
|
+
"optional": true
|
|
307
|
+
},
|
|
298
308
|
"@hono/otel": {
|
|
299
309
|
"optional": true
|
|
300
310
|
},
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-canvas
|
|
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.
|
|
5
|
+
metadata:
|
|
6
|
+
author: cyanheads
|
|
7
|
+
version: "1.0"
|
|
8
|
+
audience: external
|
|
9
|
+
type: reference
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
`DataCanvas` is a primitive for **storage stashes, canvas computes**. The existing `IStorageProvider` is a key/value abstraction — it can stash blobs but exposes no analytical surface. `DataCanvas` is the analytical surface: register tabular data from upstream APIs, run SQL across multiple registered tables, and export results as CSV/Parquet/JSON.
|
|
15
|
+
|
|
16
|
+
**Tier 3** — `@duckdb/node-api` is an optional peer dependency. Servers that don't enable canvas pay zero install cost. Lazy-loaded on first use.
|
|
17
|
+
|
|
18
|
+
**Disabled by default.** Set `CANVAS_PROVIDER_TYPE=duckdb` to enable. Otherwise `core.canvas` is `undefined`.
|
|
19
|
+
|
|
20
|
+
**Cloudflare Workers:** unsupported. DuckDB has no V8-isolate build. Setting `CANVAS_PROVIDER_TYPE=duckdb` on a Worker fails closed with a `ConfigurationError` at init time.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Imports
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import type { DataCanvas, CanvasInstance, ColumnSchema } from '@cyanheads/mcp-ts-core/canvas';
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The framework wires the optional service onto `CoreServices`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
interface CoreServices {
|
|
34
|
+
canvas?: DataCanvas; // present when CANVAS_PROVIDER_TYPE !== 'none'
|
|
35
|
+
// ... other services
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## The token-sharing model
|
|
42
|
+
|
|
43
|
+
A canvas is identified by an opaque 10-character URL-safe `canvasId` (~10¹⁸ keyspace). Tools that touch canvas state accept an optional `canvas_id` input parameter:
|
|
44
|
+
|
|
45
|
+
| Caller passes | Result |
|
|
46
|
+
|:--------------|:-------|
|
|
47
|
+
| **Omitted** | Framework mints a fresh canvasId, returns it in the tool output. Caller surfaces it to the user / next tool call / another agent. |
|
|
48
|
+
| **Existing id (own tenant)** | Resolves to that canvas, slides TTL forward, returns `isNew: false`. |
|
|
49
|
+
| **Existing id (other tenant)** | Throws `NotFound` — uniform with unknown to avoid leaking existence across tenants. |
|
|
50
|
+
| **Unknown id** | Throws `NotFound` with a hint to omit the parameter on retry. |
|
|
51
|
+
|
|
52
|
+
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.**
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Lifecycle
|
|
57
|
+
|
|
58
|
+
| Behavior | Default | Override |
|
|
59
|
+
|:---------|:--------|:---------|
|
|
60
|
+
| Sliding TTL | 24 h, extended on every operation | `CANVAS_TTL_MS` |
|
|
61
|
+
| Absolute cap from creation | 7 days | `CANVAS_ABSOLUTE_CAP_MS` |
|
|
62
|
+
| Per-tenant active cap | 100 canvases | `CANVAS_MAX_CANVASES_PER_TENANT` |
|
|
63
|
+
| Sweeper interval | 60 s | `CANVAS_SWEEPER_INTERVAL_MS` (0 to disable) |
|
|
64
|
+
| Persistence | In-memory only | — (v1; restart drops all canvases) |
|
|
65
|
+
|
|
66
|
+
The sweeper runs as an `unref`'d `setInterval` — does not keep the event loop alive on its own. Shutdown via `core.canvas.shutdown(ctx)` (called automatically from `ServerHandle.shutdown()`) stops the sweeper and tears down every active DuckDB instance.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## API
|
|
71
|
+
|
|
72
|
+
### `canvas.acquire(maybeId, ctx, options?) → CanvasInstance`
|
|
73
|
+
|
|
74
|
+
Resolves an existing canvas or creates a new one. Returns a {@link CanvasInstance} bound to `(canvasId, tenantId)`. Subsequent operations don't repeat them.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const instance = await ctx.core.canvas!.acquire(input.canvas_id, ctx);
|
|
78
|
+
// instance.canvasId — surface to the agent
|
|
79
|
+
// instance.isNew — true on first call
|
|
80
|
+
// instance.expiresAt — ISO 8601 after sliding extension
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `instance.registerTable(name, rows, options?)`
|
|
84
|
+
|
|
85
|
+
Register an in-memory or async-iterable rowset as a canvas table.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
await instance.registerTable('germplasm', rows);
|
|
89
|
+
|
|
90
|
+
// Explicit schema for AsyncIterable (required — sniffer can't peek).
|
|
91
|
+
await instance.registerTable('big_dataset', asyncRows, {
|
|
92
|
+
schema: [
|
|
93
|
+
{ name: 'id', type: 'BIGINT' },
|
|
94
|
+
{ name: 'label', type: 'VARCHAR', nullable: true },
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**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.
|
|
100
|
+
|
|
101
|
+
### `instance.query(sql, options?)`
|
|
102
|
+
|
|
103
|
+
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.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const result = await instance.query(`
|
|
107
|
+
SELECT germplasmName, COUNT(*) AS n
|
|
108
|
+
FROM germplasm GROUP BY germplasmName ORDER BY n DESC
|
|
109
|
+
`);
|
|
110
|
+
|
|
111
|
+
// Materialize a join result for follow-up queries.
|
|
112
|
+
const joined = await instance.query(`
|
|
113
|
+
SELECT g.germplasmName, o.value
|
|
114
|
+
FROM germplasm g JOIN observations o ON g.germplasmDbId = o.germplasmDbId
|
|
115
|
+
`, { registerAs: 'g_with_obs', preview: 10 });
|
|
116
|
+
// joined.tableName === 'g_with_obs'; joined.rows.length === 10; joined.rowCount === <full count>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`registerAs` rejects with `Conflict` if the target name already exists — drop it first.
|
|
120
|
+
|
|
121
|
+
**Read-only enforcement** (three layers):
|
|
122
|
+
1. Statement count (must be 1) via `extractStatements`.
|
|
123
|
+
2. Statement type (must be `SELECT`) via `prepared.statementType`.
|
|
124
|
+
3. EXPLAIN-plan walk against an allowlisted set of physical operators.
|
|
125
|
+
|
|
126
|
+
Any layer's rejection throws `ValidationError` with a structured `data.reason`. File-reading scans (`READ_CSV`, `READ_PARQUET`, `READ_JSON`), DDL (`CREATE_*`, `DROP_*`, `ALTER_*`), DML (`INSERT`, `UPDATE`, `DELETE`), exports (`COPY_TO_FILE`), and utility statements (`PRAGMA`, `ATTACH`, `LOAD`, `SET`) are all rejected.
|
|
127
|
+
|
|
128
|
+
### `instance.export(tableName, target, options?)`
|
|
129
|
+
|
|
130
|
+
Export a canvas table. Path-based exports are sandboxed to `CANVAS_EXPORT_PATH` (default `./.canvas-exports`). Absolute paths and `..` traversal are rejected.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
// Path target — written inside the sandbox.
|
|
134
|
+
await instance.export('g_with_obs', { format: 'parquet', path: 'observations.parquet' });
|
|
135
|
+
|
|
136
|
+
// Stream target — copied to a temp file in the sandbox, piped to the stream, unlinked.
|
|
137
|
+
await instance.export('g_with_obs', { format: 'csv', stream: writableStream });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `instance.describe(options?)` / `instance.drop(name)` / `instance.clear()`
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const tables = await instance.describe();
|
|
144
|
+
// [{ name: 'germplasm', rowCount: 200, columns: [...] }, ...]
|
|
145
|
+
|
|
146
|
+
await instance.drop('staging_table'); // false if missing
|
|
147
|
+
await instance.clear(); // returns count dropped
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Cancellation
|
|
151
|
+
|
|
152
|
+
`registerTable`, `query`, and `export` accept `options.signal: AbortSignal`. The provider opens a fresh DuckDB connection per query/export so `connection.interrupt()` cancels exactly the in-flight work without disturbing other ops on the same canvas.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Result row shape
|
|
157
|
+
|
|
158
|
+
Rows are returned via DuckDB's `getRowObjectsJson()` for JSON-safe serialization:
|
|
159
|
+
|
|
160
|
+
| DuckDB type | JS type returned |
|
|
161
|
+
|:------------|:-----------------|
|
|
162
|
+
| `VARCHAR`, `JSON` | `string` |
|
|
163
|
+
| `INTEGER`, `DOUBLE` | `number` |
|
|
164
|
+
| `BIGINT` | `string` (lossless for values outside JS Number range) |
|
|
165
|
+
| `BOOLEAN` | `boolean` |
|
|
166
|
+
| `DATE`, `TIMESTAMP` | `string` |
|
|
167
|
+
| `BLOB` | `string` (base64) |
|
|
168
|
+
| `NULL` | `null` |
|
|
169
|
+
|
|
170
|
+
If your tool surfaces row data via `structuredContent`, the JSON-safe shape flows through unchanged.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Configuration
|
|
175
|
+
|
|
176
|
+
| Env Var | `AppConfig` field | Default |
|
|
177
|
+
|:--------|:-----------------|:--------|
|
|
178
|
+
| `CANVAS_PROVIDER_TYPE` | `canvas.providerType` | `none` (also: `duckdb`) |
|
|
179
|
+
| `CANVAS_DEFAULT_MEMORY_LIMIT_MB` | `canvas.defaultMemoryLimitMb` | `1024` |
|
|
180
|
+
| `CANVAS_EXPORT_PATH` | `canvas.exportRootPath` | `./.canvas-exports` |
|
|
181
|
+
| `CANVAS_MAX_CANVASES_PER_TENANT` | `canvas.maxCanvasesPerTenant` | `100` |
|
|
182
|
+
| `CANVAS_TTL_MS` | `canvas.ttlMs` | `86_400_000` (24 h) |
|
|
183
|
+
| `CANVAS_ABSOLUTE_CAP_MS` | `canvas.absoluteCapMs` | `604_800_000` (7 d) |
|
|
184
|
+
| `CANVAS_SWEEPER_INTERVAL_MS` | `canvas.sweeperIntervalMs` | `60_000` |
|
|
185
|
+
| `CANVAS_DEFAULT_ROW_LIMIT` | `canvas.defaultRowLimit` | `10_000` |
|
|
186
|
+
| `CANVAS_SCHEMA_SNIFF_ROWS` | `canvas.schemaSniffRows` | `100` |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Consumer tool template
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
194
|
+
|
|
195
|
+
export const fetchAndStage = tool('fetch_and_stage_germplasm', {
|
|
196
|
+
description: 'Fetch germplasm matching a query and stage it on a DataCanvas for follow-up SQL.',
|
|
197
|
+
input: z.object({
|
|
198
|
+
query: z.string().describe('Search query'),
|
|
199
|
+
canvas_id: z
|
|
200
|
+
.string()
|
|
201
|
+
.optional()
|
|
202
|
+
.describe(
|
|
203
|
+
'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.',
|
|
204
|
+
),
|
|
205
|
+
}),
|
|
206
|
+
output: z.object({
|
|
207
|
+
canvas_id: z.string().describe('Canvas ID — pass to subsequent tool calls'),
|
|
208
|
+
is_new_canvas: z.boolean().describe('True if a new canvas was created'),
|
|
209
|
+
table_name: z.string().describe('Canvas table where rows were registered'),
|
|
210
|
+
row_count: z.number().describe('Rows registered'),
|
|
211
|
+
expires_at: z.string().describe('ISO 8601 expiry after sliding 24h window'),
|
|
212
|
+
}),
|
|
213
|
+
async handler(input, ctx) {
|
|
214
|
+
const canvas = ctx.core.canvas;
|
|
215
|
+
if (!canvas) {
|
|
216
|
+
throw new Error('DataCanvas is not enabled. Set CANVAS_PROVIDER_TYPE=duckdb.');
|
|
217
|
+
}
|
|
218
|
+
const instance = await canvas.acquire(input.canvas_id, ctx);
|
|
219
|
+
const rows = await fetchGermplasm(input.query);
|
|
220
|
+
const tableInfo = await instance.registerTable('germplasm', rows);
|
|
221
|
+
return {
|
|
222
|
+
canvas_id: instance.canvasId,
|
|
223
|
+
is_new_canvas: instance.isNew,
|
|
224
|
+
table_name: tableInfo.tableName,
|
|
225
|
+
row_count: tableInfo.rowCount,
|
|
226
|
+
expires_at: instance.expiresAt,
|
|
227
|
+
};
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Trade-offs
|
|
235
|
+
|
|
236
|
+
- **DuckDB only in v1.** Polars/SQLite/DataFusion don't fit the "agent writes ad-hoc SQL across N registered tables" shape.
|
|
237
|
+
- **In-memory only.** Server restart drops all canvases. For public-data servers, restart is rare and re-fetching upstream data is cheap. Disk persistence is a v2 concern.
|
|
238
|
+
- **Single process.** Tokens issued by one process are not portable to another. Multi-process distributed canvases are out of scope.
|
|
239
|
+
- **Read-only relative to upstream.** Canvas mutations (register, drop, clear, query+registerAs) all stay behind typed methods. Arbitrary SQL cannot mutate.
|
|
240
|
+
- **No OTel in v1.** Canvas operations are not instrumented at the framework level. Add manually via `ctx.log` if needed.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Platform support
|
|
245
|
+
|
|
246
|
+
| Platform | Status |
|
|
247
|
+
|:---------|:-------|
|
|
248
|
+
| Linux x64 / arm64 | Supported |
|
|
249
|
+
| macOS x64 / arm64 | Supported |
|
|
250
|
+
| Windows x64 | Supported |
|
|
251
|
+
| Windows arm64 | **Not supported** (DuckDB upstream limitation) |
|
|
252
|
+
| Cloudflare Workers | **Not supported** — fail-closed at init time |
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Related skills
|
|
257
|
+
|
|
258
|
+
- `add-tool` — scaffold a new MCP tool definition (use the canvas template above)
|
|
259
|
+
- `api-config` — full env var reference
|
|
260
|
+
- `api-workers` — Worker fail-closed behavior
|
|
@@ -99,6 +99,24 @@ Activated when `OAUTH_PROXY_AUTHORIZATION_URL` or `OAUTH_PROXY_TOKEN_URL` is set
|
|
|
99
99
|
| `STORAGE_PROVIDER_TYPE` | `storage.providerType` | `in-memory` | `in-memory` \| `filesystem` \| `supabase` \| `cloudflare-r2` \| `cloudflare-kv` \| `cloudflare-d1`; aliases: `mem`, `fs` |
|
|
100
100
|
| `STORAGE_FILESYSTEM_PATH` | `storage.filesystemPath` | `./.storage` | Used only when `providerType` is `filesystem` |
|
|
101
101
|
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Canvas (DataCanvas primitive — Tier 3, optional peer dep `@duckdb/node-api`)
|
|
105
|
+
|
|
106
|
+
| Env Var | `AppConfig` field | Default | Notes |
|
|
107
|
+
|:--------|:-----------------|:--------|:------|
|
|
108
|
+
| `CANVAS_PROVIDER_TYPE` | `canvas.providerType` | `none` | `none` \| `duckdb`. Set to `duckdb` to enable `core.canvas`. Fails closed on Cloudflare Workers (DuckDB has no V8-isolate build). |
|
|
109
|
+
| `CANVAS_DEFAULT_MEMORY_LIMIT_MB` | `canvas.defaultMemoryLimitMb` | `1024` | Per-canvas DuckDB `memory_limit` PRAGMA value, in MB. |
|
|
110
|
+
| `CANVAS_EXPORT_PATH` | `canvas.exportRootPath` | `./.canvas-exports` | Sandbox root for path-targeted exports. Absolute paths and `..` traversal are rejected. |
|
|
111
|
+
| `CANVAS_MAX_CANVASES_PER_TENANT` | `canvas.maxCanvasesPerTenant` | `100` | Active canvas cap per tenant; throws `RateLimited` when exceeded. |
|
|
112
|
+
| `CANVAS_TTL_MS` | `canvas.ttlMs` | `86400000` | Sliding TTL (24 h). Every operation extends the expiry. |
|
|
113
|
+
| `CANVAS_ABSOLUTE_CAP_MS` | `canvas.absoluteCapMs` | `604800000` | Absolute cap from creation (7 d). Sliding window clamps to this. |
|
|
114
|
+
| `CANVAS_SWEEPER_INTERVAL_MS` | `canvas.sweeperIntervalMs` | `60000` | Background sweep interval. Set to `0` to disable. |
|
|
115
|
+
| `CANVAS_DEFAULT_ROW_LIMIT` | `canvas.defaultRowLimit` | `10000` | Default cap on rows materialized into a query response. |
|
|
116
|
+
| `CANVAS_SCHEMA_SNIFF_ROWS` | `canvas.schemaSniffRows` | `100` | Rows to materialize for schema inference when `schema` is omitted. |
|
|
117
|
+
|
|
118
|
+
**Platform support:** Linux/macOS/Windows × x64 supported, Linux/macOS arm64 supported. Windows arm64 unsupported (DuckDB upstream). See `api-canvas` skill for the full DataCanvas reference.
|
|
119
|
+
|
|
102
120
|
#### Supabase (optional sub-object)
|
|
103
121
|
|
|
104
122
|
Activated when both `SUPABASE_URL` and `SUPABASE_ANON_KEY` are set.
|
|
@@ -171,3 +171,9 @@ export function getServerConfig() {
|
|
|
171
171
|
**`in-memory` storage is volatile.** Data stored with the `in-memory` provider is lost between cold starts and is not shared across Worker instances. Use `cloudflare-kv`, `cloudflare-r2`, or `cloudflare-d1` for any state that must persist or be shared.
|
|
172
172
|
|
|
173
173
|
**Node-only utilities throw in Workers.** `scheduler` (`node-cron`), `sanitizePath` (fs-based), and `filesystem` storage provider all throw `ConfigurationError` when called from a Worker. Guard with `runtimeCaps.isNode` or avoid entirely.
|
|
174
|
+
|
|
175
|
+
**DataCanvas is unavailable in Workers.** DuckDB has no V8-isolate build, so `core.canvas` is always `undefined` on Workers. Setting `CANVAS_PROVIDER_TYPE=duckdb` (the only non-default value) in `wrangler.toml` triggers a fail-closed `ConfigurationError` at init time:
|
|
176
|
+
|
|
177
|
+
> `DuckDB canvas requires Node.js or Bun. Set CANVAS_PROVIDER_TYPE=none or omit it for Cloudflare Workers deployment.`
|
|
178
|
+
|
|
179
|
+
Leave the env unset (or set to `none`) for Worker deployments. Tools that conditionally use canvas should check `if (!ctx.core.canvas) { ... }` and surface a clear "feature unavailable on this deployment" message. See `api-canvas` for the full DataCanvas reference.
|
|
@@ -172,6 +172,7 @@ Every issue needs exactly one primary label. Stack secondary labels on top when
|
|
|
172
172
|
| `performance` | Memory, CPU, latency, or resource usage |
|
|
173
173
|
| `security` | Vulnerability, CVE, or hardening work |
|
|
174
174
|
| `breaking-change` | Fix/feature will break public API; requires a major bump |
|
|
175
|
+
| `surplus-token-idea` | Worth exploring when token budget allows |
|
|
175
176
|
|
|
176
177
|
Combine labels: `--label "bug" --label "regression"`.
|
|
177
178
|
|
|
@@ -158,6 +158,7 @@ Every issue needs exactly one primary label. Stack secondary labels on top when
|
|
|
158
158
|
| `performance` | Memory, CPU, latency, or resource usage |
|
|
159
159
|
| `security` | Vulnerability, CVE, or hardening work |
|
|
160
160
|
| `breaking-change` | Change will break public API; requires a major bump |
|
|
161
|
+
| `surplus-token-idea` | Worth exploring when token budget allows |
|
|
161
162
|
|
|
162
163
|
Combine labels: `--label "bug" --label "regression"`.
|
|
163
164
|
|
|
@@ -168,6 +169,7 @@ gh label create regression --color e99695 --description "Worked before, broken a
|
|
|
168
169
|
gh label create performance --color 5319e7 --description "Memory, CPU, latency, or resource usage"
|
|
169
170
|
gh label create security --color b60205 --description "Vulnerability, CVE, or hardening work"
|
|
170
171
|
gh label create breaking-change --color d93f0b --description "Change will break public API; requires a major bump"
|
|
172
|
+
gh label create surplus-token-idea --color FF10F0 --description "Worth exploring when token budget allows"
|
|
171
173
|
```
|
|
172
174
|
|
|
173
175
|
### Attaching logs or large output
|
|
@@ -13,6 +13,7 @@ body:
|
|
|
13
13
|
- `performance` — memory, CPU, latency, or resource usage
|
|
14
14
|
- `security` — vulnerability, CVE, or hardening work
|
|
15
15
|
- `breaking-change` — fix will break public API
|
|
16
|
+
- `surplus-token-idea` — worth exploring when token budget allows
|
|
16
17
|
|
|
17
18
|
If a label doesn't exist in this repo yet, create it once: `gh label create <name>`.
|
|
18
19
|
|
|
@@ -10,6 +10,7 @@ body:
|
|
|
10
10
|
- `performance` — improves memory, CPU, latency, or resource usage
|
|
11
11
|
- `security` — hardens the security posture
|
|
12
12
|
- `breaking-change` — will break public API; requires a major bump
|
|
13
|
+
- `surplus-token-idea` — worth exploring when token budget allows
|
|
13
14
|
|
|
14
15
|
If a label doesn't exist in this repo yet, create it once: `gh label create <name>`.
|
|
15
16
|
|