@cyanheads/mcp-ts-core 0.10.16 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +2 -2
- package/biome.json +1 -1
- package/changelog/0.10.x/0.10.17.md +41 -0
- package/changelog/0.11.x/0.11.0.md +69 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/config/index.d.ts +111 -108
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +14 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/parseEnvConfig.js.map +1 -1
- package/dist/core/app.js.map +1 -1
- package/dist/core/gcPressure.d.ts.map +1 -1
- package/dist/core/serverManifest.d.ts +1 -1
- package/dist/core/serverManifest.d.ts.map +1 -1
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js.map +1 -1
- package/dist/linter/rules/format-parity-rules.js.map +1 -1
- package/dist/linter/rules/portability-rules.js.map +1 -1
- package/dist/logs/combined.log +8 -8
- package/dist/logs/error.log +4 -4
- package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.d.ts +53 -0
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.d.ts.map +1 -0
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.js +65 -0
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.js.map +1 -0
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts +30 -2
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts.map +1 -1
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js +65 -4
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js.map +1 -1
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts.map +1 -1
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.js.map +1 -1
- package/dist/mcp-server/tasks/core/taskManager.d.ts.map +1 -1
- package/dist/mcp-server/tasks/core/taskManager.js +6 -2
- package/dist/mcp-server/tasks/core/taskManager.js.map +1 -1
- package/dist/mcp-server/tasks/core/taskTypes.d.ts +7 -0
- package/dist/mcp-server/tasks/core/taskTypes.d.ts.map +1 -1
- package/dist/mcp-server/tasks/core/taskTypes.js +7 -0
- package/dist/mcp-server/tasks/core/taskTypes.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +1 -2
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
- package/dist/mcp-server/transports/heartbeat.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/handler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/robotsTxt.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/serverCard.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.js.map +1 -1
- package/dist/mcp-server/transports/manager.d.ts.map +1 -1
- package/dist/mcp-server/transports/manager.js.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
- package/dist/services/canvas/core/DataCanvas.d.ts.map +1 -1
- package/dist/services/canvas/core/DataCanvas.js.map +1 -1
- package/dist/services/canvas/core/canvasFactory.d.ts.map +1 -1
- package/dist/services/canvas/core/canvasFactory.js +1 -0
- package/dist/services/canvas/core/canvasFactory.js.map +1 -1
- package/dist/services/canvas/core/sqlGate.d.ts +10 -10
- package/dist/services/canvas/core/sqlGate.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +16 -0
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +25 -7
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts +4 -2
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.js +4 -2
- package/dist/services/canvas/providers/duckdb/exportWriter.js.map +1 -1
- package/dist/services/graph/core/GraphService.d.ts.map +1 -1
- package/dist/services/graph/core/GraphService.js.map +1 -1
- package/dist/services/llm/providers/openrouter.provider.d.ts.map +1 -1
- package/dist/services/llm/providers/openrouter.provider.js.map +1 -1
- package/dist/services/mirror/sqlite/handle.js.map +1 -1
- package/dist/services/speech/core/SpeechService.d.ts.map +1 -1
- package/dist/services/speech/core/SpeechService.js.map +1 -1
- package/dist/services/speech/providers/elevenlabs.provider.d.ts.map +1 -1
- package/dist/services/speech/providers/whisper.provider.d.ts.map +1 -1
- package/dist/storage/core/StorageService.d.ts.map +1 -1
- package/dist/storage/core/StorageService.js.map +1 -1
- package/dist/storage/core/storageFactory.js.map +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.js.map +1 -1
- package/dist/storage/providers/cloudflare/kvProvider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/r2Provider.d.ts.map +1 -1
- package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts.map +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -1
- package/dist/storage/providers/supabase/supabaseProvider.d.ts.map +1 -1
- package/dist/storage/providers/supabase/supabaseProvider.js.map +1 -1
- package/dist/testing/fuzz.js.map +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/vitest.d.ts +1 -1
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/utils/formatting/diffFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/html.d.ts.map +1 -1
- package/dist/utils/formatting/html.js.map +1 -1
- package/dist/utils/formatting/markdownBuilder.d.ts.map +1 -1
- package/dist/utils/formatting/tableFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/tableFormatter.js.map +1 -1
- package/dist/utils/formatting/treeFormatter.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/logger.d.ts +19 -3
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +51 -21
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/dist/utils/internal/telemetryMessages.d.ts +4 -4
- package/dist/utils/internal/telemetryMessages.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +33 -16
- package/dist/utils/network/fetchWithTimeout.js.map +1 -1
- package/dist/utils/network/httpError.js.map +1 -1
- package/dist/utils/network/retry.js.map +1 -1
- package/dist/utils/pagination/pagination.d.ts.map +1 -1
- package/dist/utils/parsing/csvParser.d.ts.map +1 -1
- package/dist/utils/parsing/dateParser.d.ts.map +1 -1
- package/dist/utils/parsing/frontmatterParser.d.ts.map +1 -1
- package/dist/utils/parsing/htmlExtractor.d.ts.map +1 -1
- package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
- package/dist/utils/parsing/jsonParser.js.map +1 -1
- package/dist/utils/parsing/pdfParser.d.ts.map +1 -1
- package/dist/utils/parsing/pdfParser.js.map +1 -1
- package/dist/utils/parsing/xmlParser.d.ts.map +1 -1
- package/dist/utils/parsing/yamlParser.d.ts.map +1 -1
- package/dist/utils/scheduling/scheduler.d.ts.map +1 -1
- package/dist/utils/security/idGenerator.d.ts.map +1 -1
- package/dist/utils/security/idGenerator.js.map +1 -1
- package/dist/utils/security/rateLimiter.d.ts.map +1 -1
- package/dist/utils/security/rateLimiter.js.map +1 -1
- package/dist/utils/security/sanitization.d.ts.map +1 -1
- package/dist/utils/security/sanitization.js.map +1 -1
- package/package.json +43 -34
- package/scripts/check-dependency-specifiers.ts +13 -7
- package/scripts/clean-mcpb.ts +48 -15
- package/scripts/lint-packaging.ts +36 -13
- package/skills/api-canvas/SKILL.md +4 -3
- package/skills/api-config/SKILL.md +2 -1
- package/skills/field-test/SKILL.md +71 -28
- package/templates/AGENTS.md +1 -1
- package/templates/CLAUDE.md +1 -1
- package/templates/package.json +5 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/mcp-ts-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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
|
"files": [
|
|
@@ -193,18 +193,18 @@
|
|
|
193
193
|
"publish-mcp": "mcp-publisher login github -token \"$(security find-generic-password -a \"$USER\" -s mcp-publisher-github-pat -w)\" && mcp-publisher publish"
|
|
194
194
|
},
|
|
195
195
|
"devDependencies": {
|
|
196
|
-
"@biomejs/biome": "2.5.
|
|
196
|
+
"@biomejs/biome": "2.5.5",
|
|
197
197
|
"@cloudflare/vitest-pool-workers": "^0.18.6",
|
|
198
198
|
"@cloudflare/workers-types": "5.20260706.1",
|
|
199
|
-
"@duckdb/node-api": "^1.5.
|
|
199
|
+
"@duckdb/node-api": "^1.5.5-r.1",
|
|
200
200
|
"@hono/otel": "^1.1.2",
|
|
201
|
-
"@opentelemetry/exporter-metrics-otlp-http": "^0.
|
|
202
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
203
|
-
"@opentelemetry/instrumentation-http": "^0.
|
|
201
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.221.0",
|
|
202
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.221.0",
|
|
203
|
+
"@opentelemetry/instrumentation-http": "^0.221.0",
|
|
204
204
|
"@opentelemetry/instrumentation-pino": "^0.66.0",
|
|
205
205
|
"@opentelemetry/resources": "^2.10.0",
|
|
206
206
|
"@opentelemetry/sdk-metrics": "^2.10.0",
|
|
207
|
-
"@opentelemetry/sdk-node": "^0.
|
|
207
|
+
"@opentelemetry/sdk-node": "^0.221.0",
|
|
208
208
|
"@opentelemetry/sdk-trace-node": "^2.10.0",
|
|
209
209
|
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
210
210
|
"@socketsecurity/bun-security-scanner": "^1.1.2",
|
|
@@ -216,14 +216,14 @@
|
|
|
216
216
|
"@types/validator": "^13.15.10",
|
|
217
217
|
"@vitest/coverage-istanbul": "4.1.10",
|
|
218
218
|
"@vitest/ui": "4.1.10",
|
|
219
|
-
"better-sqlite3": "^
|
|
219
|
+
"better-sqlite3": "^13.0.1",
|
|
220
220
|
"bun-types": "^1.3.14",
|
|
221
221
|
"chrono-node": "^2.10.1",
|
|
222
222
|
"clipboardy": "^5.3.1",
|
|
223
223
|
"defuddle": "^0.19.2",
|
|
224
224
|
"depcheck": "^1.4.7",
|
|
225
225
|
"diff": "^9.0.0",
|
|
226
|
-
"execa": "^
|
|
226
|
+
"execa": "^10.0.0",
|
|
227
227
|
"fast-check": "^4.9.0",
|
|
228
228
|
"fast-xml-parser": "^5.10.1",
|
|
229
229
|
"ignore": "^7.0.6",
|
|
@@ -239,7 +239,8 @@
|
|
|
239
239
|
"sanitize-html": "^2.17.6",
|
|
240
240
|
"tsc-alias": "^1.9.1",
|
|
241
241
|
"typedoc": "^0.28.20",
|
|
242
|
-
"typescript": "^
|
|
242
|
+
"typescript": "^7.0.2",
|
|
243
|
+
"typescript-v6": "npm:typescript@^6.0.3",
|
|
243
244
|
"unpdf": "^1.6.2",
|
|
244
245
|
"validator": "^13.15.35",
|
|
245
246
|
"vite": "8.1.5",
|
|
@@ -307,34 +308,34 @@
|
|
|
307
308
|
"zod": "^4.4.3"
|
|
308
309
|
},
|
|
309
310
|
"peerDependencies": {
|
|
310
|
-
"@duckdb/node-api": "^1.5.
|
|
311
|
-
"@hono/otel": "^1.1.
|
|
312
|
-
"@opentelemetry/instrumentation-http": "^0.
|
|
313
|
-
"@opentelemetry/exporter-metrics-otlp-http": "^0.
|
|
314
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
315
|
-
"@opentelemetry/instrumentation-pino": "^0.
|
|
316
|
-
"@opentelemetry/resources": "^2.
|
|
317
|
-
"@opentelemetry/sdk-metrics": "^2.
|
|
318
|
-
"@opentelemetry/sdk-node": "^0.
|
|
319
|
-
"@opentelemetry/sdk-trace-node": "^2.
|
|
320
|
-
"@opentelemetry/semantic-conventions": "^1.
|
|
321
|
-
"@supabase/supabase-js": "^2.
|
|
322
|
-
"better-sqlite3": "^
|
|
323
|
-
"chrono-node": "^2.
|
|
324
|
-
"defuddle": "^0.
|
|
311
|
+
"@duckdb/node-api": "^1.5.5-r.1",
|
|
312
|
+
"@hono/otel": "^1.1.2",
|
|
313
|
+
"@opentelemetry/instrumentation-http": "^0.221.0",
|
|
314
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.221.0",
|
|
315
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.221.0",
|
|
316
|
+
"@opentelemetry/instrumentation-pino": "^0.66.0",
|
|
317
|
+
"@opentelemetry/resources": "^2.10.0",
|
|
318
|
+
"@opentelemetry/sdk-metrics": "^2.10.0",
|
|
319
|
+
"@opentelemetry/sdk-node": "^0.221.0",
|
|
320
|
+
"@opentelemetry/sdk-trace-node": "^2.10.0",
|
|
321
|
+
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
322
|
+
"@supabase/supabase-js": "^2.110.8",
|
|
323
|
+
"better-sqlite3": "^13.0.1",
|
|
324
|
+
"chrono-node": "^2.10.1",
|
|
325
|
+
"defuddle": "^0.19.2",
|
|
325
326
|
"diff": "^9.0.0",
|
|
326
|
-
"fast-check": "^4.
|
|
327
|
+
"fast-check": "^4.9.0",
|
|
327
328
|
"vitest": ">=4.0.0",
|
|
328
|
-
"fast-xml-parser": "^5.
|
|
329
|
-
"js-yaml": "^5.2.
|
|
330
|
-
"linkedom": "^0.18.
|
|
331
|
-
"node-cron": "^4.
|
|
332
|
-
"openai": "^6.
|
|
333
|
-
"papaparse": "^5.5.
|
|
329
|
+
"fast-xml-parser": "^5.10.1",
|
|
330
|
+
"js-yaml": "^5.2.2",
|
|
331
|
+
"linkedom": "^0.18.13",
|
|
332
|
+
"node-cron": "^4.6.0",
|
|
333
|
+
"openai": "^6.48.0",
|
|
334
|
+
"papaparse": "^5.5.4",
|
|
334
335
|
"partial-json": "^0.1.7",
|
|
335
336
|
"pdf-lib": "^1.17.1",
|
|
336
|
-
"sanitize-html": "^2.17.
|
|
337
|
-
"unpdf": "^1.6.
|
|
337
|
+
"sanitize-html": "^2.17.6",
|
|
338
|
+
"unpdf": "^1.6.2",
|
|
338
339
|
"validator": "^13.15.35",
|
|
339
340
|
"zod": "^4.4.3"
|
|
340
341
|
},
|
|
@@ -426,5 +427,13 @@
|
|
|
426
427
|
"vitest": {
|
|
427
428
|
"optional": true
|
|
428
429
|
}
|
|
430
|
+
},
|
|
431
|
+
"overrides": {
|
|
432
|
+
"brace-expansion": "^2.1.2",
|
|
433
|
+
"postcss": "^8.5.22",
|
|
434
|
+
"protobufjs": "^7.6.5",
|
|
435
|
+
"sharp": "^0.35.3",
|
|
436
|
+
"fast-uri": "^3.1.4",
|
|
437
|
+
"@hono/node-server": "^2.0.11"
|
|
429
438
|
}
|
|
430
439
|
}
|
|
@@ -12,11 +12,16 @@
|
|
|
12
12
|
* Section-specific rules — `peer`/`optional` may legitimately float to "any
|
|
13
13
|
* host version", so `*` and dist-tags are allowed there; `latest` never is:
|
|
14
14
|
*
|
|
15
|
-
* | specifier | dependencies / devDependencies | peer / optional |
|
|
16
|
-
*
|
|
17
|
-
* | latest | fail
|
|
18
|
-
* | * | fail
|
|
19
|
-
* | next / beta / canary / rc | fail
|
|
15
|
+
* | specifier | dependencies / devDependencies / overrides | peer / optional |
|
|
16
|
+
* |---------------------------|:------------------------------------------:|:---------------:|
|
|
17
|
+
* | latest | fail | fail |
|
|
18
|
+
* | * | fail | allow |
|
|
19
|
+
* | next / beta / canary / rc | fail | allow |
|
|
20
|
+
*
|
|
21
|
+
* `overrides` is held to the strict rule for a sharper reason than the rest: an
|
|
22
|
+
* override exists to force a transitive off a known-vulnerable version, so a
|
|
23
|
+
* floating specifier there re-resolves the very pin the entry was added to
|
|
24
|
+
* hold — the advisory silently returns while the block still looks present.
|
|
20
25
|
*
|
|
21
26
|
* Only the `workspaces` section of `bun.lock` is inspected — the `packages`
|
|
22
27
|
* section records third-party packages' own nested declarations, which can
|
|
@@ -41,6 +46,7 @@ const DEP_SECTIONS = [
|
|
|
41
46
|
'devDependencies',
|
|
42
47
|
'peerDependencies',
|
|
43
48
|
'optionalDependencies',
|
|
49
|
+
'overrides',
|
|
44
50
|
] as const;
|
|
45
51
|
type DepSection = (typeof DEP_SECTIONS)[number];
|
|
46
52
|
|
|
@@ -67,7 +73,7 @@ function isFloating(specifier: string, section: DepSection): boolean {
|
|
|
67
73
|
return spec === '*' || FLOATING_DIST_TAGS.has(spec);
|
|
68
74
|
}
|
|
69
75
|
|
|
70
|
-
/** Scan
|
|
76
|
+
/** Scan every dependency-declaring section of one manifest object. */
|
|
71
77
|
function scanManifest(manifest: SectionedManifest, label: string): Offender[] {
|
|
72
78
|
const offenders: Offender[] = [];
|
|
73
79
|
for (const section of DEP_SECTIONS) {
|
|
@@ -138,7 +144,7 @@ function parseJsonc<T>(text: string): T {
|
|
|
138
144
|
|
|
139
145
|
const offenders: Offender[] = [];
|
|
140
146
|
|
|
141
|
-
// ── package.json (
|
|
147
|
+
// ── package.json (every dependency-declaring section) ──
|
|
142
148
|
const pkgPath = resolve(ROOT, 'package.json');
|
|
143
149
|
if (existsSync(pkgPath)) {
|
|
144
150
|
try {
|
package/scripts/clean-mcpb.ts
CHANGED
|
@@ -6,10 +6,14 @@
|
|
|
6
6
|
*
|
|
7
7
|
* 1. `mcpb clean <bundle>` — official dev-dependency prune + manifest
|
|
8
8
|
* validation (a measured real-world bundle dropped 61 MB → 12.9 MB).
|
|
9
|
-
* 2. Exact-name strip of
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* 2. Exact-name strip of two entry classes nested under `node_modules/`,
|
|
10
|
+
* which root-anchored `.mcpbignore` patterns cannot reach by design
|
|
11
|
+
* (issues #146/#207):
|
|
12
|
+
* a. Dependency-shipped agent docs — `skills/`, `.claude/`, `.agents/`
|
|
13
|
+
* trees and stray `SKILL.md` files (issue #230).
|
|
14
|
+
* b. Platform-specific native bindings, which would otherwise lock the
|
|
15
|
+
* bundle to the build host's platform and push it past the 25 MB cap
|
|
16
|
+
* registries enforce (issue #274).
|
|
13
17
|
* 3. Re-list and assert zero matching entries remain.
|
|
14
18
|
*
|
|
15
19
|
* Entry names are passed to `zip -d` with `-nw` (no-wildcard) so they match
|
|
@@ -34,11 +38,33 @@ import { fileURLToPath } from 'node:url';
|
|
|
34
38
|
export const AGENT_DOC_ENTRY =
|
|
35
39
|
/^node_modules\/.*(?:\/skills\/|\/\.claude\/|\/\.agents\/|\/SKILL\.md$)/;
|
|
36
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Platform-specific native binding packages, which must not ship in a bundle.
|
|
43
|
+
* KEEP IN SYNC with `NATIVE_BINDING_ENTRY` in `scripts/lint-packaging.ts`
|
|
44
|
+
* (post-bundle content check) — a unit test asserts the two are identical.
|
|
45
|
+
*
|
|
46
|
+
* `mcpb pack` archives the whole project directory, so a native dependency
|
|
47
|
+
* contributes the build host's platform slice and nothing else — for
|
|
48
|
+
* `@duckdb/node-api` that is a ~108 MB `libduckdb` shared library. The bundle
|
|
49
|
+
* then runs only on the platform it was packed on, contradicting the
|
|
50
|
+
* cross-platform "Install in Claude Desktop" badge, and blows past the 25 MB
|
|
51
|
+
* cap registries enforce. Stripping them keeps the bundle portable and small;
|
|
52
|
+
* DuckDB is an optional peer loaded through `lazyImport`, so a server whose
|
|
53
|
+
* canvas is disabled (`CANVAS_PROVIDER_TYPE=none`, the default) is unaffected
|
|
54
|
+
* and one that enables it gets the helper's actionable install hint.
|
|
55
|
+
*/
|
|
56
|
+
export const NATIVE_BINDING_ENTRY = /^node_modules\/@duckdb\/node-bindings-[^/]+\//;
|
|
57
|
+
|
|
37
58
|
/** Filter a bundle entry listing down to the agent-doc entries to strip. */
|
|
38
59
|
export function filterAgentDocEntries(entries: string[]): string[] {
|
|
39
60
|
return entries.filter((entry) => AGENT_DOC_ENTRY.test(entry));
|
|
40
61
|
}
|
|
41
62
|
|
|
63
|
+
/** Filter a bundle entry listing down to the native-binding entries to strip. */
|
|
64
|
+
export function filterNativeBindingEntries(entries: string[]): string[] {
|
|
65
|
+
return entries.filter((entry) => NATIVE_BINDING_ENTRY.test(entry));
|
|
66
|
+
}
|
|
67
|
+
|
|
42
68
|
/** Listing a 12k-entry bundle exceeds execFileSync's 1 MB default buffer. */
|
|
43
69
|
const MAX_LIST_BUFFER = 64 * 1024 * 1024;
|
|
44
70
|
|
|
@@ -81,35 +107,42 @@ function main(): void {
|
|
|
81
107
|
process.exit(1);
|
|
82
108
|
}
|
|
83
109
|
|
|
84
|
-
// 2. Exact-name strip of dependency-shipped agent docs.
|
|
85
|
-
let
|
|
110
|
+
// 2. Exact-name strip of dependency-shipped agent docs and platform natives.
|
|
111
|
+
let agentDocs: string[] = [];
|
|
112
|
+
let natives: string[] = [];
|
|
86
113
|
try {
|
|
87
|
-
|
|
114
|
+
const entries = listEntries(bundle);
|
|
115
|
+
agentDocs = filterAgentDocEntries(entries);
|
|
116
|
+
natives = filterNativeBindingEntries(entries);
|
|
117
|
+
const doomed = [...agentDocs, ...natives];
|
|
88
118
|
for (let i = 0; i < doomed.length; i += DELETE_BATCH) {
|
|
89
119
|
run('zip', ['-q', '-d', '-nw', bundle, ...doomed.slice(i, i + DELETE_BATCH)]);
|
|
90
120
|
}
|
|
91
121
|
} catch (err) {
|
|
92
122
|
if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
93
|
-
console.error(
|
|
94
|
-
'✗ Info-ZIP `zip`/`unzip` not found on PATH — required for the agent-doc strip.',
|
|
95
|
-
);
|
|
123
|
+
console.error('✗ Info-ZIP `zip`/`unzip` not found on PATH — required for the strip step.');
|
|
96
124
|
} else {
|
|
97
|
-
console.error(`✗
|
|
125
|
+
console.error(`✗ Bundle strip failed: ${err instanceof Error ? err.message : err}`);
|
|
98
126
|
}
|
|
99
127
|
process.exit(1);
|
|
100
128
|
}
|
|
101
129
|
|
|
102
|
-
// 3. Verify: zero matching entries remain.
|
|
103
|
-
const
|
|
130
|
+
// 3. Verify: zero matching entries remain in either class.
|
|
131
|
+
const remainingEntries = listEntries(bundle);
|
|
132
|
+
const remaining = [
|
|
133
|
+
...filterAgentDocEntries(remainingEntries),
|
|
134
|
+
...filterNativeBindingEntries(remainingEntries),
|
|
135
|
+
];
|
|
104
136
|
if (remaining.length > 0) {
|
|
105
|
-
console.error(`✗ ${remaining.length}
|
|
137
|
+
console.error(`✗ ${remaining.length} entries still present after strip, e.g.:`);
|
|
106
138
|
for (const entry of remaining.slice(0, 5)) console.error(` ${entry}`);
|
|
107
139
|
process.exit(1);
|
|
108
140
|
}
|
|
109
141
|
|
|
110
142
|
const sizeAfter = statSync(bundle).size;
|
|
111
143
|
console.log(
|
|
112
|
-
`Bundle cleaned: ${mb(sizeBefore)} → ${mb(sizeAfter)}
|
|
144
|
+
`Bundle cleaned: ${mb(sizeBefore)} → ${mb(sizeAfter)} ` +
|
|
145
|
+
`(${agentDocs.length} agent-doc, ${natives.length} native-binding entries stripped).`,
|
|
113
146
|
);
|
|
114
147
|
}
|
|
115
148
|
|
|
@@ -111,6 +111,13 @@ export const CRITICAL_RUNTIME_PATHS = [
|
|
|
111
111
|
export const AGENT_DOC_ENTRY =
|
|
112
112
|
/^node_modules\/.*(?:\/skills\/|\/\.claude\/|\/\.agents\/|\/SKILL\.md$)/;
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Platform-specific native binding packages that must not ship in a bundle.
|
|
116
|
+
* KEEP IN SYNC with `NATIVE_BINDING_ENTRY` in `scripts/clean-mcpb.ts` (the
|
|
117
|
+
* strip step this check verifies) — a unit test asserts the two are identical.
|
|
118
|
+
*/
|
|
119
|
+
export const NATIVE_BINDING_ENTRY = /^node_modules\/@duckdb\/node-bindings-[^/]+\//;
|
|
120
|
+
|
|
114
121
|
/** The canonical in-code identity pair — both must equal the unscoped package name. */
|
|
115
122
|
const IDENTITY_PAIR = ['name', 'title'] as const;
|
|
116
123
|
|
|
@@ -225,21 +232,37 @@ export async function checkBundleContent(raw: string): Promise<string[]> {
|
|
|
225
232
|
|
|
226
233
|
/**
|
|
227
234
|
* Check 8: a built bundle must contain zero `node_modules/**` agent-doc
|
|
228
|
-
* entries. `scripts/clean-mcpb.ts`
|
|
229
|
-
*
|
|
235
|
+
* entries and zero platform-specific native bindings. `scripts/clean-mcpb.ts`
|
|
236
|
+
* (wired into the `bundle` script) strips both after `mcpb pack`.
|
|
230
237
|
*/
|
|
231
238
|
export function checkBundleEntries(entries: string[], bundleLabel: string): string[] {
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
const sampleOf = (offending: string[]) =>
|
|
240
|
+
offending
|
|
241
|
+
.slice(0, 5)
|
|
242
|
+
.map((entry) => `\n ${entry}`)
|
|
243
|
+
.join('');
|
|
244
|
+
|
|
245
|
+
const errors: string[] = [];
|
|
246
|
+
|
|
247
|
+
const agentDocs = entries.filter((entry) => AGENT_DOC_ENTRY.test(entry));
|
|
248
|
+
if (agentDocs.length > 0) {
|
|
249
|
+
errors.push(
|
|
250
|
+
`${bundleLabel} contains ${agentDocs.length} node_modules agent-doc entries ` +
|
|
251
|
+
`(dependency-shipped skills/, .claude/, .agents/, SKILL.md) — re-run the \`bundle\` ` +
|
|
252
|
+
`script (scripts/clean-mcpb.ts strips them):${sampleOf(agentDocs)}`,
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const natives = entries.filter((entry) => NATIVE_BINDING_ENTRY.test(entry));
|
|
257
|
+
if (natives.length > 0) {
|
|
258
|
+
errors.push(
|
|
259
|
+
`${bundleLabel} contains ${natives.length} platform-specific native binding entries — ` +
|
|
260
|
+
`the bundle would run only on the platform it was packed on. Re-run the \`bundle\` ` +
|
|
261
|
+
`script (scripts/clean-mcpb.ts strips them):${sampleOf(natives)}`,
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return errors;
|
|
243
266
|
}
|
|
244
267
|
|
|
245
268
|
/**
|
|
@@ -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: "
|
|
7
|
+
version: "2.0"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -205,7 +205,7 @@ const result = await instance.query("SELECT total FROM sales_by_region WHERE reg
|
|
|
205
205
|
|
|
206
206
|
### `instance.importFrom(sourceCanvasId, sourceTableName, options?)`
|
|
207
207
|
|
|
208
|
-
Copy a table from another canvas the caller controls into this one. The lifecycle wrapper validates tenancy on both ids before the provider sees either. Round-trips through a
|
|
208
|
+
Copy a table from another canvas the caller controls into this one. The lifecycle wrapper validates tenancy on both ids before the provider sees either. Round-trips through a Parquet file under the scratch root (`CANVAS_TEMP_PATH`) so `TIMESTAMP`/`DATE`/`BLOB` columns survive losslessly.
|
|
209
209
|
|
|
210
210
|
```ts
|
|
211
211
|
const imported = await target.importFrom(source.canvasId, 'orders', { asName: 'orders_copy' });
|
|
@@ -222,7 +222,7 @@ Export a canvas table. Path-based exports are sandboxed to `CANVAS_EXPORT_PATH`
|
|
|
222
222
|
// Path target — written inside the sandbox.
|
|
223
223
|
await instance.export('g_with_obs', { format: 'parquet', path: 'observations.parquet' });
|
|
224
224
|
|
|
225
|
-
// Stream target — copied to a
|
|
225
|
+
// Stream target — copied to a file under the scratch root, piped to the stream, unlinked.
|
|
226
226
|
await instance.export('g_with_obs', { format: 'csv', stream: writableStream });
|
|
227
227
|
```
|
|
228
228
|
|
|
@@ -274,6 +274,7 @@ If your tool surfaces row data via `structuredContent`, the JSON-safe shape flow
|
|
|
274
274
|
| `CANVAS_PROVIDER_TYPE` | `canvas.providerType` | `none` (also: `duckdb`) |
|
|
275
275
|
| `CANVAS_DEFAULT_MEMORY_LIMIT_MB` | `canvas.defaultMemoryLimitMb` | `1024` |
|
|
276
276
|
| `CANVAS_EXPORT_PATH` | `canvas.exportRootPath` | `./.canvas-exports` |
|
|
277
|
+
| `CANVAS_TEMP_PATH` | `canvas.tempRootPath` | `<os.tmpdir()>/mcp-canvas` |
|
|
277
278
|
| `CANVAS_MAX_CANVASES_PER_TENANT` | `canvas.maxCanvasesPerTenant` | `100` |
|
|
278
279
|
| `CANVAS_TTL_MS` | `canvas.ttlMs` | `86_400_000` (24 h) |
|
|
279
280
|
| `CANVAS_ABSOLUTE_CAP_MS` | `canvas.absoluteCapMs` | `604_800_000` (7 d) |
|
|
@@ -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.9"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -125,6 +125,7 @@ Activated when `OAUTH_PROXY_AUTHORIZATION_URL` or `OAUTH_PROXY_TOKEN_URL` is set
|
|
|
125
125
|
| `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). |
|
|
126
126
|
| `CANVAS_DEFAULT_MEMORY_LIMIT_MB` | `canvas.defaultMemoryLimitMb` | `1024` | Per-canvas DuckDB `memory_limit` PRAGMA value, in MB. |
|
|
127
127
|
| `CANVAS_EXPORT_PATH` | `canvas.exportRootPath` | `./.canvas-exports` | Sandbox root for path-targeted exports. Absolute paths and `..` traversal are rejected. |
|
|
128
|
+
| `CANVAS_TEMP_PATH` | `canvas.tempRootPath` | `<os.tmpdir()>/mcp-canvas` | Scratch root: DuckDB's `temp_directory` for queries that spill past `memory_limit`, plus the transient files behind stream exports and the spillover round-trip. Never resolves to the process cwd — DuckDB's own cwd-relative `.tmp` default fails on a non-root or read-only container rootfs. |
|
|
128
129
|
| `CANVAS_MAX_CANVASES_PER_TENANT` | `canvas.maxCanvasesPerTenant` | `100` | Active canvas cap per tenant; throws `RateLimited` when exceeded. |
|
|
129
130
|
| `CANVAS_TTL_MS` | `canvas.ttlMs` | `86400000` | Sliding TTL (24 h). Every operation extends the expiry. |
|
|
130
131
|
| `CANVAS_ABSOLUTE_CAP_MS` | `canvas.absoluteCapMs` | `604800000` | Absolute cap from creation (7 d). Sliding window clamps to this. |
|