@cyanheads/mcp-ts-core 0.13.7 → 0.13.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/AGENTS.md +19 -15
- package/CLAUDE.md +19 -15
- package/README.md +4 -2
- package/changelog/0.13.x/0.13.8.md +101 -0
- package/changelog/0.13.x/0.13.9.md +113 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +39 -9
- package/dist/config/index.js.map +1 -1
- package/dist/core/app.d.ts +6 -3
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +20 -6
- package/dist/core/app.js.map +1 -1
- package/dist/core/context.d.ts +25 -1
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +13 -3
- package/dist/core/context.js.map +1 -1
- package/dist/core/serverManifest.d.ts +6 -0
- package/dist/core/serverManifest.d.ts.map +1 -1
- package/dist/core/serverManifest.js +6 -0
- package/dist/core/serverManifest.js.map +1 -1
- package/dist/core/worker.d.ts +2 -0
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js +2 -0
- package/dist/core/worker.js.map +1 -1
- package/dist/linter/rules/enrichment-rules.d.ts +3 -2
- package/dist/linter/rules/enrichment-rules.d.ts.map +1 -1
- package/dist/linter/rules/enrichment-rules.js +9 -2
- package/dist/linter/rules/enrichment-rules.js.map +1 -1
- package/dist/linter/rules/handler-body-rules.d.ts.map +1 -1
- package/dist/linter/rules/handler-body-rules.js +10 -4
- package/dist/linter/rules/handler-body-rules.js.map +1 -1
- package/dist/linter/rules/schema-rules.d.ts +5 -0
- package/dist/linter/rules/schema-rules.d.ts.map +1 -1
- package/dist/linter/rules/schema-rules.js +44 -17
- package/dist/linter/rules/schema-rules.js.map +1 -1
- package/dist/linter/rules/tool-rules.d.ts +2 -1
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +36 -1
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/mcp-server/inputRequired.d.ts +14 -5
- package/dist/mcp-server/inputRequired.d.ts.map +1 -1
- package/dist/mcp-server/inputRequired.js +15 -8
- package/dist/mcp-server/inputRequired.js.map +1 -1
- package/dist/mcp-server/outputContract.d.ts +33 -0
- package/dist/mcp-server/outputContract.d.ts.map +1 -0
- package/dist/mcp-server/outputContract.js +43 -0
- package/dist/mcp-server/outputContract.js.map +1 -0
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +10 -2
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts +163 -40
- package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/inputPrevalidation.js +330 -114
- package/dist/mcp-server/tools/utils/inputPrevalidation.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +39 -15
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +361 -93
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.js +4 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.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 +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 +2 -5
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +65 -9
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.js +2 -2
- package/dist/mcp-server/transports/http/sessionStore.js.map +1 -1
- package/dist/mcp-server/transports/stdio/stdioTransport.d.ts +9 -5
- package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/stdio/stdioTransport.js +9 -5
- package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts +6 -2
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js +8 -4
- 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 +7 -5
- 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 +2 -2
- package/dist/services/canvas/core/canvasFactory.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +82 -18
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +645 -344
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts +11 -7
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.js +19 -16
- package/dist/services/canvas/providers/duckdb/exportWriter.js.map +1 -1
- package/dist/services/llm/providers/openrouter.provider.js +1 -1
- package/dist/services/llm/providers/openrouter.provider.js.map +1 -1
- package/dist/services/mirror/core/defineMirror.d.ts +1 -0
- package/dist/services/mirror/core/defineMirror.d.ts.map +1 -1
- package/dist/services/mirror/core/defineMirror.js +1 -0
- package/dist/services/mirror/core/defineMirror.js.map +1 -1
- package/dist/services/speech/providers/elevenlabs.provider.js +3 -3
- package/dist/services/speech/providers/elevenlabs.provider.js.map +1 -1
- package/dist/services/speech/providers/whisper.provider.d.ts.map +1 -1
- package/dist/services/speech/providers/whisper.provider.js +5 -5
- package/dist/services/speech/providers/whisper.provider.js.map +1 -1
- package/dist/storage/core/StorageService.d.ts.map +1 -1
- package/dist/storage/core/StorageService.js +3 -6
- package/dist/storage/core/StorageService.js.map +1 -1
- package/dist/storage/core/storageFactory.d.ts.map +1 -1
- package/dist/storage/core/storageFactory.js +12 -15
- package/dist/storage/core/storageFactory.js.map +1 -1
- package/dist/storage/core/storageValidation.d.ts +13 -13
- package/dist/storage/core/storageValidation.d.ts.map +1 -1
- package/dist/storage/core/storageValidation.js +49 -125
- package/dist/storage/core/storageValidation.js.map +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.js +5 -3
- 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/kvProvider.js +1 -1
- package/dist/storage/providers/cloudflare/kvProvider.js.map +1 -1
- package/dist/storage/providers/cloudflare/r2Provider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/r2Provider.js +3 -3
- package/dist/storage/providers/cloudflare/r2Provider.js.map +1 -1
- package/dist/storage/providers/fileSystem/fileSystemProvider.js +4 -4
- package/dist/storage/providers/fileSystem/fileSystemProvider.js.map +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.js +6 -5
- package/dist/storage/providers/inMemory/inMemoryProvider.js.map +1 -1
- package/dist/testing/fuzz.d.ts.map +1 -1
- package/dist/testing/fuzz.js +7 -1
- package/dist/testing/fuzz.js.map +1 -1
- package/dist/testing/index.d.ts +15 -2
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +51 -6
- package/dist/testing/index.js.map +1 -1
- package/dist/types-global/errors.d.ts +7 -4
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/types-global/errors.js.map +1 -1
- package/dist/utils/formatting/codeSpan.d.ts +27 -0
- package/dist/utils/formatting/codeSpan.d.ts.map +1 -0
- package/dist/utils/formatting/codeSpan.js +42 -0
- package/dist/utils/formatting/codeSpan.js.map +1 -0
- package/dist/utils/formatting/diffFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/diffFormatter.js +7 -15
- package/dist/utils/formatting/diffFormatter.js.map +1 -1
- package/dist/utils/formatting/markdownBuilder.d.ts +12 -5
- package/dist/utils/formatting/markdownBuilder.d.ts.map +1 -1
- package/dist/utils/formatting/markdownBuilder.js +14 -2
- package/dist/utils/formatting/markdownBuilder.js.map +1 -1
- package/dist/utils/formatting/tableFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/tableFormatter.js +5 -9
- package/dist/utils/formatting/tableFormatter.js.map +1 -1
- package/dist/utils/formatting/treeFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/treeFormatter.js +5 -9
- package/dist/utils/formatting/treeFormatter.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts +17 -10
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.js +47 -26
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
- package/dist/utils/internal/error-handler/mappings.d.ts +17 -1
- package/dist/utils/internal/error-handler/mappings.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/mappings.js +22 -1
- package/dist/utils/internal/error-handler/mappings.js.map +1 -1
- package/dist/utils/internal/error-handler/types.d.ts +2 -0
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
- package/dist/utils/internal/logger.d.ts +75 -3
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +181 -52
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/performance.d.ts +11 -0
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +46 -12
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/network/fetchWithTimeout.d.ts +11 -5
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +50 -23
- package/dist/utils/network/fetchWithTimeout.js.map +1 -1
- package/dist/utils/network/pacer.d.ts +38 -5
- package/dist/utils/network/pacer.d.ts.map +1 -1
- package/dist/utils/network/pacer.js +87 -25
- package/dist/utils/network/pacer.js.map +1 -1
- package/dist/utils/network/retry.d.ts +16 -8
- package/dist/utils/network/retry.d.ts.map +1 -1
- package/dist/utils/network/retry.js +19 -8
- package/dist/utils/network/retry.js.map +1 -1
- package/dist/utils/overflow/outlineOnOverflow.d.ts +18 -2
- package/dist/utils/overflow/outlineOnOverflow.d.ts.map +1 -1
- package/dist/utils/overflow/outlineOnOverflow.js +28 -3
- package/dist/utils/overflow/outlineOnOverflow.js.map +1 -1
- package/dist/utils/pagination/pagination.d.ts +3 -1
- package/dist/utils/pagination/pagination.d.ts.map +1 -1
- package/dist/utils/pagination/pagination.js +10 -2
- package/dist/utils/pagination/pagination.js.map +1 -1
- package/dist/utils/parsing/csvParser.d.ts.map +1 -1
- package/dist/utils/parsing/csvParser.js +4 -2
- package/dist/utils/parsing/csvParser.js.map +1 -1
- package/dist/utils/parsing/htmlExtractor.js +1 -1
- package/dist/utils/parsing/htmlExtractor.js.map +1 -1
- package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
- package/dist/utils/parsing/jsonParser.js +3 -1
- package/dist/utils/parsing/jsonParser.js.map +1 -1
- package/dist/utils/parsing/xmlParser.d.ts.map +1 -1
- package/dist/utils/parsing/xmlParser.js +3 -1
- package/dist/utils/parsing/xmlParser.js.map +1 -1
- package/dist/utils/parsing/yamlParser.d.ts.map +1 -1
- package/dist/utils/parsing/yamlParser.js +3 -1
- package/dist/utils/parsing/yamlParser.js.map +1 -1
- package/dist/utils/security/idGenerator.d.ts.map +1 -1
- package/dist/utils/security/idGenerator.js +20 -4
- package/dist/utils/security/idGenerator.js.map +1 -1
- package/dist/utils/security/sanitization.d.ts +31 -0
- package/dist/utils/security/sanitization.d.ts.map +1 -1
- package/dist/utils/security/sanitization.js +98 -11
- package/dist/utils/security/sanitization.js.map +1 -1
- package/dist/utils/telemetry/attributes.d.ts +21 -2
- package/dist/utils/telemetry/attributes.d.ts.map +1 -1
- package/dist/utils/telemetry/attributes.js +21 -2
- package/dist/utils/telemetry/attributes.js.map +1 -1
- package/dist/utils/telemetry/instrumentation.d.ts +9 -3
- package/dist/utils/telemetry/instrumentation.d.ts.map +1 -1
- package/dist/utils/telemetry/instrumentation.js +85 -13
- package/dist/utils/telemetry/instrumentation.js.map +1 -1
- package/framework-skills/add-app-tool/SKILL.md +3 -3
- package/framework-skills/add-export/SKILL.md +5 -16
- package/framework-skills/add-prompt/SKILL.md +7 -3
- package/framework-skills/add-resource/SKILL.md +7 -5
- package/framework-skills/add-tool/SKILL.md +12 -10
- package/framework-skills/api-auth/SKILL.md +4 -2
- package/framework-skills/api-canvas/SKILL.md +19 -10
- package/framework-skills/api-config/SKILL.md +9 -6
- package/framework-skills/api-context/SKILL.md +16 -5
- package/framework-skills/api-errors/SKILL.md +23 -17
- package/framework-skills/api-linter/SKILL.md +32 -9
- package/framework-skills/api-mirror/SKILL.md +2 -1
- package/framework-skills/api-telemetry/SKILL.md +34 -14
- package/framework-skills/api-testing/SKILL.md +5 -3
- package/framework-skills/api-utils/SKILL.md +10 -10
- package/framework-skills/api-utils/references/formatting.md +1 -1
- package/framework-skills/api-utils/references/parsing.md +2 -2
- package/framework-skills/api-utils/references/security.md +6 -4
- package/framework-skills/design-mcp-server/SKILL.md +2 -2
- package/framework-skills/field-test/SKILL.md +4 -4
- package/framework-skills/git-wrapup/SKILL.md +12 -7
- package/framework-skills/maintenance/SKILL.md +2 -2
- package/framework-skills/orchestrations/SKILL.md +7 -6
- package/framework-skills/orchestrations/workflows/field-test-fix.md +9 -19
- package/framework-skills/orchestrations/workflows/fix-wrapup-release.md +7 -7
- package/framework-skills/orchestrations/workflows/greenfield-build.md +8 -5
- package/framework-skills/orchestrations/workflows/maintenance-release.md +8 -8
- package/framework-skills/polish-docs-meta/SKILL.md +4 -4
- package/framework-skills/polish-docs-meta/references/readme.md +1 -0
- package/framework-skills/release-and-publish/SKILL.md +7 -5
- package/framework-skills/release-pr-review/SKILL.md +37 -23
- package/framework-skills/report-issue-framework/SKILL.md +7 -5
- package/framework-skills/report-issue-local/SKILL.md +8 -6
- package/framework-skills/security-pass/SKILL.md +8 -8
- package/framework-skills/techniques/SKILL.md +1 -1
- package/framework-skills/techniques/references/outline-on-overflow.md +12 -7
- package/package.json +20 -5
- package/scripts/check-skill-versions.ts +103 -22
- package/scripts/devcheck.ts +11 -9
- package/scripts/lint-mcp.ts +87 -27
- package/scripts/lint-packaging.ts +99 -1
- package/scripts/release-github.ts +117 -5
- package/templates/.env.example +4 -0
- package/templates/Dockerfile +26 -6
- package/templates/_.mcpbignore +2 -0
- package/templates/package.json +1 -0
|
@@ -35,10 +35,19 @@ export declare const ATTR_MCP_TOOL_SUCCESS = "mcp.tool.success";
|
|
|
35
35
|
* dashboards can separate incomplete rounds from completed calls.
|
|
36
36
|
*/
|
|
37
37
|
export declare const ATTR_MCP_TOOL_INPUT_REQUIRED = "mcp.tool.input_required";
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* JSON-RPC error code from the thrown `McpError`, present when `mcp.tool.success` is `false`.
|
|
40
|
+
* Also the code label on `mcp.tool.rejections`, where it is the code the caller received.
|
|
41
|
+
*/
|
|
39
42
|
export declare const ATTR_MCP_TOOL_ERROR_CODE = "mcp.tool.error_code";
|
|
40
43
|
/** Broad error category: 'upstream' (external API), 'server' (internal bug), or 'client' (bad input). */
|
|
41
44
|
export declare const ATTR_MCP_TOOL_ERROR_CATEGORY = "mcp.tool.error_category";
|
|
45
|
+
/**
|
|
46
|
+
* How a measured tool call ended, on `mcp.tool.calls` and `mcp.tool.errors`: `ok` (a result
|
|
47
|
+
* or an `input_required` round), `error`, or `cancelled` (`RequestCancelled`, -32011 — the
|
|
48
|
+
* caller hung up). Separates a hang-up from a failure without moving `mcp.tool.success`.
|
|
49
|
+
*/
|
|
50
|
+
export declare const ATTR_MCP_TOOL_OUTCOME = "mcp.tool.outcome";
|
|
42
51
|
/** Whether the tool returned a result containing partial failures (non-empty `failed` array). */
|
|
43
52
|
export declare const ATTR_MCP_TOOL_PARTIAL_SUCCESS = "mcp.tool.partial_success";
|
|
44
53
|
/** Whether the tool populated agent-facing enrichment (`ctx.enrich`) on this call. */
|
|
@@ -57,7 +66,11 @@ export declare const ATTR_MCP_INPUT_IGNORE_RULE = "mcp.input.ignore_rule";
|
|
|
57
66
|
export declare const ATTR_MCP_INPUT_TARGET = "mcp.input.target";
|
|
58
67
|
/** Which half of the alias stage fired: `declared` or `case_style`. */
|
|
59
68
|
export declare const ATTR_MCP_INPUT_ALIAS_KIND = "mcp.input.alias_kind";
|
|
60
|
-
/**
|
|
69
|
+
/**
|
|
70
|
+
* Which representation repair earned validity: `stringified_array`,
|
|
71
|
+
* `stringified_object`, or `integer_as_string`. A call that needed several
|
|
72
|
+
* kinds counts once under each.
|
|
73
|
+
*/
|
|
61
74
|
export declare const ATTR_MCP_INPUT_COERCION = "mcp.input.coercion";
|
|
62
75
|
/**
|
|
63
76
|
* Author-set label of the outbound pacer a queue metric belongs to
|
|
@@ -177,6 +190,12 @@ export declare const ATTR_MCP_AUTH_SUBJECT = "mcp.auth.subject";
|
|
|
177
190
|
export declare const ATTR_MCP_CONNECTION_TRANSPORT = "mcp.connection.transport";
|
|
178
191
|
/** Classified JSON-RPC error code from ErrorHandler (e.g., `-32001`, `-32602`). */
|
|
179
192
|
export declare const ATTR_MCP_ERROR_CLASSIFIED_CODE = "mcp.error.classified_code";
|
|
193
|
+
/**
|
|
194
|
+
* Origin bucket of the classified code — `upstream`, `server`, or `client` — from the same
|
|
195
|
+
* `getErrorCategory` that fills `mcp.tool.error_category` and `mcp.prompt.error_category`,
|
|
196
|
+
* so it separates the canvas tenant-cap refusal (`server`) from upstream throttling on `-32003`.
|
|
197
|
+
*/
|
|
198
|
+
export declare const ATTR_MCP_ERROR_CATEGORY = "mcp.error.category";
|
|
180
199
|
/**
|
|
181
200
|
* Log level a definition declared for this failure mode: `debug`, `info`,
|
|
182
201
|
* `notice`, or `warning`. Set only on a record whose declared severity
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAE5D,iGAAiG;AACjG,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAMpD;;GAEG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,0DAA0D;AAC1D,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAElE,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAEtE
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,10 +41,19 @@ export const ATTR_MCP_TOOL_SUCCESS = 'mcp.tool.success';
|
|
|
41
41
|
* dashboards can separate incomplete rounds from completed calls.
|
|
42
42
|
*/
|
|
43
43
|
export const ATTR_MCP_TOOL_INPUT_REQUIRED = 'mcp.tool.input_required';
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* JSON-RPC error code from the thrown `McpError`, present when `mcp.tool.success` is `false`.
|
|
46
|
+
* Also the code label on `mcp.tool.rejections`, where it is the code the caller received.
|
|
47
|
+
*/
|
|
45
48
|
export const ATTR_MCP_TOOL_ERROR_CODE = 'mcp.tool.error_code';
|
|
46
49
|
/** Broad error category: 'upstream' (external API), 'server' (internal bug), or 'client' (bad input). */
|
|
47
50
|
export const ATTR_MCP_TOOL_ERROR_CATEGORY = 'mcp.tool.error_category';
|
|
51
|
+
/**
|
|
52
|
+
* How a measured tool call ended, on `mcp.tool.calls` and `mcp.tool.errors`: `ok` (a result
|
|
53
|
+
* or an `input_required` round), `error`, or `cancelled` (`RequestCancelled`, -32011 — the
|
|
54
|
+
* caller hung up). Separates a hang-up from a failure without moving `mcp.tool.success`.
|
|
55
|
+
*/
|
|
56
|
+
export const ATTR_MCP_TOOL_OUTCOME = 'mcp.tool.outcome';
|
|
48
57
|
/** Whether the tool returned a result containing partial failures (non-empty `failed` array). */
|
|
49
58
|
export const ATTR_MCP_TOOL_PARTIAL_SUCCESS = 'mcp.tool.partial_success';
|
|
50
59
|
/** Whether the tool populated agent-facing enrichment (`ctx.enrich`) on this call. */
|
|
@@ -71,7 +80,11 @@ export const ATTR_MCP_INPUT_IGNORE_RULE = 'mcp.input.ignore_rule';
|
|
|
71
80
|
export const ATTR_MCP_INPUT_TARGET = 'mcp.input.target';
|
|
72
81
|
/** Which half of the alias stage fired: `declared` or `case_style`. */
|
|
73
82
|
export const ATTR_MCP_INPUT_ALIAS_KIND = 'mcp.input.alias_kind';
|
|
74
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* Which representation repair earned validity: `stringified_array`,
|
|
85
|
+
* `stringified_object`, or `integer_as_string`. A call that needed several
|
|
86
|
+
* kinds counts once under each.
|
|
87
|
+
*/
|
|
75
88
|
export const ATTR_MCP_INPUT_COERCION = 'mcp.input.coercion';
|
|
76
89
|
// ============================================================================
|
|
77
90
|
// MCP Outbound Pacer Attributes
|
|
@@ -228,6 +241,12 @@ export const ATTR_MCP_CONNECTION_TRANSPORT = 'mcp.connection.transport';
|
|
|
228
241
|
// ============================================================================
|
|
229
242
|
/** Classified JSON-RPC error code from ErrorHandler (e.g., `-32001`, `-32602`). */
|
|
230
243
|
export const ATTR_MCP_ERROR_CLASSIFIED_CODE = 'mcp.error.classified_code';
|
|
244
|
+
/**
|
|
245
|
+
* Origin bucket of the classified code — `upstream`, `server`, or `client` — from the same
|
|
246
|
+
* `getErrorCategory` that fills `mcp.tool.error_category` and `mcp.prompt.error_category`,
|
|
247
|
+
* so it separates the canvas tenant-cap refusal (`server`) from upstream throttling on `-32003`.
|
|
248
|
+
*/
|
|
249
|
+
export const ATTR_MCP_ERROR_CATEGORY = 'mcp.error.category';
|
|
231
250
|
/**
|
|
232
251
|
* Log level a definition declared for this failure mode: `debug`, `info`,
|
|
233
252
|
* `notice`, or `warning`. Set only on a record whose declared severity
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,+EAA+E;AAC/E,yDAAyD;AACzD,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAE5D,iGAAiG;AACjG,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAEpD,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE,wDAAwD;AACxD,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC;AAElE,yEAAyE;AACzE,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE
|
|
1
|
+
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,12 +27,18 @@ export declare let sdk: NodeSDK | null;
|
|
|
27
27
|
* `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, else `OTEL_EXPORTER_OTLP_ENDPOINT` + `v1/traces`)
|
|
28
28
|
* - OTLP metrics exporter + `PeriodicExportingMetricReader` at 15 s intervals (when a metrics
|
|
29
29
|
* endpoint resolves: `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`, else the base + `v1/metrics`)
|
|
30
|
-
* -
|
|
31
|
-
*
|
|
30
|
+
* - OTLP log exporter + `BatchLogRecordProcessor` only when `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`
|
|
31
|
+
* is set (never derived from the base), with the framework logger attached to the Logs API;
|
|
32
|
+
* otherwise no log record processors. Every list is passed explicitly, so `NodeSDK`'s
|
|
33
|
+
* env-driven defaults never export anything the framework config did not ask for
|
|
32
34
|
* - `TraceIdRatioBasedSampler` using `config.openTelemetry.samplingRatio`
|
|
33
35
|
* - Node auto-instrumentations (HTTP enabled, FS disabled)
|
|
34
|
-
* - Pino instrumentation
|
|
36
|
+
* - Pino instrumentation, which reaches only a `pino` loaded after `start()` — the framework
|
|
37
|
+
* logger's records carry `traceId`/`spanId` from the request context instead
|
|
35
38
|
* - Cloud resource attributes via `detectCloudResource()`
|
|
39
|
+
* - One diag logger: the framework's, writing every level to stderr at
|
|
40
|
+
* `config.openTelemetry.logLevel` (aliases resolved). `NodeSDK` would register a console
|
|
41
|
+
* logger of its own when `OTEL_LOG_LEVEL` is set, so its constructor never sees the variable.
|
|
36
42
|
*
|
|
37
43
|
* @returns Promise that resolves when initialization is complete (or was already complete)
|
|
38
44
|
* @throws Error if `NodeSDK.start()` or any lazy import fails; re-thrown after resetting `sdk` to `null`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../../src/utils/telemetry/instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../../src/utils/telemetry/instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAavD;;;;;GAKG;AACH,eAAO,IAAI,GAAG,EAAE,OAAO,GAAG,IAAW,CAAC;AAiGtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CA0K7D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB3E"}
|
|
@@ -4,9 +4,16 @@
|
|
|
4
4
|
* Supports both Node.js (full NodeSDK) and serverless runtimes (lightweight telemetry).
|
|
5
5
|
* @module src/utils/telemetry/instrumentation
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { DiagLogLevel, diag } from '@opentelemetry/api';
|
|
8
8
|
import { config } from '../../config/index.js';
|
|
9
|
+
import { setOtelLogSink } from '../internal/logger.js';
|
|
9
10
|
import { runtimeCaps } from '../internal/runtime.js';
|
|
11
|
+
/**
|
|
12
|
+
* Metric export cadence, and the per-export timeout. The reader clamps a
|
|
13
|
+
* timeout longer than its interval down to it and logs a notice on every boot
|
|
14
|
+
* saying so, so the timeout is set to the interval outright.
|
|
15
|
+
*/
|
|
16
|
+
const METRIC_EXPORT_INTERVAL_MS = 15_000;
|
|
10
17
|
/**
|
|
11
18
|
* The active OpenTelemetry `NodeSDK` instance, or `null` when telemetry is disabled,
|
|
12
19
|
* the runtime is not Node/Bun, or the SDK has been shut down.
|
|
@@ -69,6 +76,36 @@ function detectCloudResource() {
|
|
|
69
76
|
}
|
|
70
77
|
return attrs;
|
|
71
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* A diag logger that writes every level to stderr. `DiagConsoleLogger` sends
|
|
81
|
+
* `info` and `debug` to stdout, which the stdio transport reserves for JSON-RPC.
|
|
82
|
+
*/
|
|
83
|
+
function createStderrDiagLogger(format) {
|
|
84
|
+
const write = (message, ...args) => {
|
|
85
|
+
process.stderr.write(`${format(message, ...args)}\n`);
|
|
86
|
+
};
|
|
87
|
+
return { debug: write, error: write, info: write, verbose: write, warn: write };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Runs `construct` with `OTEL_LOG_LEVEL` absent from `process.env`, restoring
|
|
91
|
+
* it afterwards. `NodeSDK`'s constructor registers a `DiagConsoleLogger` of its
|
|
92
|
+
* own whenever the variable is set: it parses the raw value, so the
|
|
93
|
+
* framework's aliases (`warning`, `err`) read as unknown; it writes info and
|
|
94
|
+
* debug to stdout; and at `DEBUG` it announces its own registration there
|
|
95
|
+
* before anything could replace it. The framework's diag logger already
|
|
96
|
+
* carries the configured level, so the constructor never needs to see it.
|
|
97
|
+
*/
|
|
98
|
+
function withoutOtelLogLevelEnv(construct) {
|
|
99
|
+
const level = process.env.OTEL_LOG_LEVEL;
|
|
100
|
+
delete process.env.OTEL_LOG_LEVEL;
|
|
101
|
+
try {
|
|
102
|
+
return construct();
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
if (level !== undefined)
|
|
106
|
+
process.env.OTEL_LOG_LEVEL = level;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
72
109
|
/**
|
|
73
110
|
* Initializes the OpenTelemetry SDK with runtime-appropriate configuration.
|
|
74
111
|
* Idempotent — safe to call multiple times; subsequent calls return the existing promise or resolve immediately.
|
|
@@ -84,12 +121,18 @@ function detectCloudResource() {
|
|
|
84
121
|
* `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, else `OTEL_EXPORTER_OTLP_ENDPOINT` + `v1/traces`)
|
|
85
122
|
* - OTLP metrics exporter + `PeriodicExportingMetricReader` at 15 s intervals (when a metrics
|
|
86
123
|
* endpoint resolves: `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`, else the base + `v1/metrics`)
|
|
87
|
-
* -
|
|
88
|
-
*
|
|
124
|
+
* - OTLP log exporter + `BatchLogRecordProcessor` only when `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`
|
|
125
|
+
* is set (never derived from the base), with the framework logger attached to the Logs API;
|
|
126
|
+
* otherwise no log record processors. Every list is passed explicitly, so `NodeSDK`'s
|
|
127
|
+
* env-driven defaults never export anything the framework config did not ask for
|
|
89
128
|
* - `TraceIdRatioBasedSampler` using `config.openTelemetry.samplingRatio`
|
|
90
129
|
* - Node auto-instrumentations (HTTP enabled, FS disabled)
|
|
91
|
-
* - Pino instrumentation
|
|
130
|
+
* - Pino instrumentation, which reaches only a `pino` loaded after `start()` — the framework
|
|
131
|
+
* logger's records carry `traceId`/`spanId` from the request context instead
|
|
92
132
|
* - Cloud resource attributes via `detectCloudResource()`
|
|
133
|
+
* - One diag logger: the framework's, writing every level to stderr at
|
|
134
|
+
* `config.openTelemetry.logLevel` (aliases resolved). `NodeSDK` would register a console
|
|
135
|
+
* logger of its own when `OTEL_LOG_LEVEL` is set, so its constructor never sees the variable.
|
|
93
136
|
*
|
|
94
137
|
* @returns Promise that resolves when initialization is complete (or was already complete)
|
|
95
138
|
* @throws Error if `NodeSDK.start()` or any lazy import fails; re-thrown after resetting `sdk` to `null`
|
|
@@ -122,7 +165,7 @@ export async function initializeOpenTelemetry() {
|
|
|
122
165
|
}
|
|
123
166
|
try {
|
|
124
167
|
// Lazy-load Node-specific modules
|
|
125
|
-
const [{ HttpInstrumentation }, { OTLPMetricExporter }, { OTLPTraceExporter }, { PinoInstrumentation }, { resourceFromAttributes }, { PeriodicExportingMetricReader }, { NodeSDK }, { BatchSpanProcessor, TraceIdRatioBasedSampler }, { ATTR_DEPLOYMENT_ENVIRONMENT_NAME, ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION },] = await Promise.all([
|
|
168
|
+
const [{ HttpInstrumentation }, { OTLPMetricExporter }, { OTLPTraceExporter }, { PinoInstrumentation }, { resourceFromAttributes }, { PeriodicExportingMetricReader }, { NodeSDK }, { BatchSpanProcessor, TraceIdRatioBasedSampler }, { ATTR_DEPLOYMENT_ENVIRONMENT_NAME, ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION }, { format },] = await Promise.all([
|
|
126
169
|
import('@opentelemetry/instrumentation-http'),
|
|
127
170
|
import('@opentelemetry/exporter-metrics-otlp-http'),
|
|
128
171
|
import('@opentelemetry/exporter-trace-otlp-http'),
|
|
@@ -132,14 +175,20 @@ export async function initializeOpenTelemetry() {
|
|
|
132
175
|
import('@opentelemetry/sdk-node'),
|
|
133
176
|
import('@opentelemetry/sdk-trace-node'),
|
|
134
177
|
import('@opentelemetry/semantic-conventions'),
|
|
178
|
+
import('node:util'),
|
|
135
179
|
]);
|
|
136
180
|
const otelLogLevelString = config.openTelemetry.logLevel.toUpperCase();
|
|
137
|
-
|
|
138
|
-
|
|
181
|
+
diag.setLogger(createStderrDiagLogger(format), {
|
|
182
|
+
logLevel: DiagLogLevel[otelLogLevelString] ?? DiagLogLevel.INFO,
|
|
183
|
+
// The framework owns diag once OTel is on; replacing an earlier registration
|
|
184
|
+
// (a re-initialization after shutdown included) is not worth a stack trace.
|
|
185
|
+
suppressOverrideMessage: true,
|
|
186
|
+
});
|
|
139
187
|
const tracesEndpoint = config.openTelemetry.tracesEndpoint;
|
|
140
188
|
const metricsEndpoint = config.openTelemetry.metricsEndpoint;
|
|
141
|
-
|
|
142
|
-
|
|
189
|
+
const logsEndpoint = config.openTelemetry.logsEndpoint;
|
|
190
|
+
if (!tracesEndpoint && !metricsEndpoint && !logsEndpoint) {
|
|
191
|
+
diag.warn('OTEL_ENABLED is true, but no OTLP endpoint for traces, metrics, or logs is configured. OpenTelemetry will not export any telemetry. Set OTEL_EXPORTER_OTLP_ENDPOINT, or the signal-specific OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / OTEL_EXPORTER_OTLP_METRICS_ENDPOINT / OTEL_EXPORTER_OTLP_LOGS_ENDPOINT.');
|
|
143
192
|
}
|
|
144
193
|
const resource = resourceFromAttributes({
|
|
145
194
|
[ATTR_SERVICE_NAME]: config.openTelemetry.serviceName,
|
|
@@ -161,22 +210,39 @@ export async function initializeOpenTelemetry() {
|
|
|
161
210
|
diag.info(`Using OTLP exporter for metrics, endpoint: ${metricsEndpoint}`);
|
|
162
211
|
metricReaders.push(new PeriodicExportingMetricReader({
|
|
163
212
|
exporter: new OTLPMetricExporter({ url: metricsEndpoint }),
|
|
164
|
-
exportIntervalMillis:
|
|
213
|
+
exportIntervalMillis: METRIC_EXPORT_INTERVAL_MS,
|
|
214
|
+
exportTimeoutMillis: METRIC_EXPORT_INTERVAL_MS,
|
|
165
215
|
}));
|
|
166
216
|
}
|
|
167
217
|
else {
|
|
168
218
|
diag.info('No OTLP metrics endpoint configured. Metrics will not be exported.');
|
|
169
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* The log packages are optional peers loaded only when log export is
|
|
222
|
+
* asked for, so a deployment without them never reaches these imports.
|
|
223
|
+
*/
|
|
224
|
+
const logRecordProcessors = [];
|
|
225
|
+
let loggerProvider;
|
|
226
|
+
if (logsEndpoint) {
|
|
227
|
+
const [{ BatchLogRecordProcessor }, { OTLPLogExporter }, { logs }] = await Promise.all([
|
|
228
|
+
import('@opentelemetry/sdk-logs'),
|
|
229
|
+
import('@opentelemetry/exporter-logs-otlp-http'),
|
|
230
|
+
import('@opentelemetry/api-logs'),
|
|
231
|
+
]);
|
|
232
|
+
diag.info(`Using OTLP exporter for logs, endpoint: ${logsEndpoint}`);
|
|
233
|
+
logRecordProcessors.push(new BatchLogRecordProcessor({ exporter: new OTLPLogExporter({ url: logsEndpoint }) }));
|
|
234
|
+
loggerProvider = logs;
|
|
235
|
+
}
|
|
170
236
|
/**
|
|
171
237
|
* All three lists are passed explicitly, empty or not: an omitted one
|
|
172
238
|
* makes `NodeSDK` build its own OTLP exporter from `OTEL_*` env vars
|
|
173
239
|
* (defaulting to localhost:4318), exporting outside the framework config.
|
|
174
240
|
*/
|
|
175
|
-
sdk = new NodeSDK({
|
|
241
|
+
sdk = withoutOtelLogLevelEnv(() => new NodeSDK({
|
|
176
242
|
resource,
|
|
177
243
|
spanProcessors,
|
|
178
244
|
metricReaders,
|
|
179
|
-
logRecordProcessors
|
|
245
|
+
logRecordProcessors,
|
|
180
246
|
sampler: new TraceIdRatioBasedSampler(config.openTelemetry.samplingRatio),
|
|
181
247
|
instrumentations: [
|
|
182
248
|
new HttpInstrumentation({
|
|
@@ -189,8 +255,13 @@ export async function initializeOpenTelemetry() {
|
|
|
189
255
|
},
|
|
190
256
|
}),
|
|
191
257
|
],
|
|
192
|
-
});
|
|
258
|
+
}));
|
|
193
259
|
sdk.start();
|
|
260
|
+
// `PinoInstrumentation` never sees the framework's `pino` (imported at module
|
|
261
|
+
// load, before `start()`), so the logger forwards its records to the Logs API itself.
|
|
262
|
+
if (loggerProvider) {
|
|
263
|
+
setOtelLogSink(loggerProvider.getLogger(config.openTelemetry.serviceName, config.openTelemetry.serviceVersion));
|
|
264
|
+
}
|
|
194
265
|
isOtelInitialized = true;
|
|
195
266
|
diag.info(`OpenTelemetry NodeSDK initialized for ${config.openTelemetry.serviceName} v${config.openTelemetry.serviceVersion}`);
|
|
196
267
|
}
|
|
@@ -227,6 +298,7 @@ export async function shutdownOpenTelemetry(timeoutMs = 5000) {
|
|
|
227
298
|
return;
|
|
228
299
|
}
|
|
229
300
|
let timer;
|
|
301
|
+
setOtelLogSink(undefined);
|
|
230
302
|
try {
|
|
231
303
|
const shutdownPromise = sdk.shutdown();
|
|
232
304
|
await new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../src/utils/telemetry/instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../src/utils/telemetry/instrumentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold an MCP App tool + UI resource pair. Use when the user asks to add a tool with interactive UI, create an MCP App, or build a visual/interactive tool.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.7"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -40,7 +40,7 @@ For the full API, Context interface, and error codes, read the framework's `CLAU
|
|
|
40
40
|
4. **Create the app resource** at `src/mcp-server/resources/definitions/{{tool-name}}-ui.app-resource.ts`
|
|
41
41
|
5. **Register both** in the project's existing `createApp()` arrays (directly in `src/index.ts` for fresh scaffolds, or via barrels if the repo already has them)
|
|
42
42
|
6. **Run `bun run devcheck`** — the linter validates `_meta.ui` and cross-checks tool/resource pairing
|
|
43
|
-
7. **Smoke-test** with `bun run rebuild && bun run start:stdio` (or `start:http`)
|
|
43
|
+
7. **Smoke-test** with `bun run rebuild && bun run start:stdio < /dev/null` (or `start:http`) — the `Core services constructed` log record must list the tool in its `tools` field and its UI resource in `resources` (the message text shows only counts)
|
|
44
44
|
|
|
45
45
|
## App Tool Template
|
|
46
46
|
|
|
@@ -235,4 +235,4 @@ If the repo already uses `definitions/index.ts` barrels, update those instead of
|
|
|
235
235
|
- [ ] Both registered in the project's existing `createApp()` arrays (directly or via barrels)
|
|
236
236
|
- [ ] Handler tested directly via `createMockContext()`, or `add-test` skill run to scaffold the test file
|
|
237
237
|
- [ ] `bun run devcheck` passes (linter validates `_meta.ui` and tool/resource pairing)
|
|
238
|
-
- [ ] Smoke-tested with `bun run rebuild && bun run start:stdio` (or `start:http`)
|
|
238
|
+
- [ ] Smoke-tested with `bun run rebuild && bun run start:stdio < /dev/null` (or `start:http`); the `Core services constructed` record lists the tool in `tools` and its UI resource in `resources`
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Add a new subpath export to the @cyanheads/mcp-ts-core package. Use when creating a new public API surface that consumers import from a dedicated subpath (e.g., @cyanheads/mcp-ts-core/newutil).
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.2"
|
|
8
8
|
audience: internal
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -29,18 +29,8 @@ The build uses `tsconfig.build.json` (not `tsconfig.json`) with `rootDir: ./src`
|
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
3. **Update the exports catalog** in both `CLAUDE.md` and `AGENTS.md` — add a row to the table. These files must stay byte-identical; the simplest approach is `cp CLAUDE.md AGENTS.md` after editing
|
|
32
|
-
4. **
|
|
33
|
-
5. **Verify
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# Confirm the compiled file exists at the expected dist path
|
|
37
|
-
ls dist/utils/new-util.js
|
|
38
|
-
|
|
39
|
-
# Confirm the subpath export resolves correctly (tests the exports map, not just the dist file)
|
|
40
|
-
bun -e "import('@cyanheads/mcp-ts-core/newutil').then(m => console.log(Object.keys(m)))"
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
6. **Run `bun run devcheck`** to verify
|
|
32
|
+
4. **Regenerate the public API manifest** — `bun run scripts/public-api-contract-update.ts` rewrites `PUBLIC_RUNTIME_EXPORTS` in `scripts/public-api-contract.ts` from the live barrels; never edit it by hand
|
|
33
|
+
5. **Verify** with `bun run devcheck` and `bun run test:package` — the package lane builds, packs, installs, and imports every subpath in the manifest, so a wrong `dist/` path or a missing export fails there
|
|
44
34
|
|
|
45
35
|
## Naming conventions
|
|
46
36
|
|
|
@@ -56,7 +46,6 @@ The build uses `tsconfig.build.json` (not `tsconfig.json`) with `rootDir: ./src`
|
|
|
56
46
|
- [ ] Subpath added to `package.json` `exports` with `types` and `import` conditions
|
|
57
47
|
- [ ] Exports catalog updated in both `CLAUDE.md` and `AGENTS.md` (must be byte-identical)
|
|
58
48
|
- [ ] If the new export has optional peer dependencies: entries added to both `peerDependencies` and `peerDependenciesMeta` in `package.json`
|
|
59
|
-
- [ ] `bun run
|
|
60
|
-
- [ ] Compiled file exists at expected `dist/` path and subpath import resolves correctly
|
|
61
|
-
- [ ] Integration test at `tests/integration/package-consumer.int.test.ts` updated: new subpath added to the import spec list and `toHaveLength` count incremented
|
|
49
|
+
- [ ] Public API manifest regenerated with `bun run scripts/public-api-contract-update.ts`
|
|
62
50
|
- [ ] `bun run devcheck` passes
|
|
51
|
+
- [ ] `bun run test:package` passes
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new MCP prompt template. Use when the user asks to add a prompt, create a reusable message template, or define a prompt for LLM interactions.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.5"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -21,6 +21,7 @@ Prompts are pure message templates — no `Context`, no auth, no side effects. `
|
|
|
21
21
|
2. **Create the file** at `src/mcp-server/prompts/definitions/{{prompt-name}}.prompt.ts`
|
|
22
22
|
3. **Register** the prompt in the project's existing `createApp()` prompt list (directly in `src/index.ts` for fresh scaffolds, or via a barrel if the repo already has one)
|
|
23
23
|
4. **Run `bun run devcheck`** to verify
|
|
24
|
+
5. **Smoke-test** with `bun run rebuild && bun run start:stdio < /dev/null` — the `Core services constructed` log record must list the new prompt in its `prompts` field (the message text shows only counts); if it doesn't, the prompt never reached `createApp()`
|
|
24
25
|
|
|
25
26
|
## Template
|
|
26
27
|
|
|
@@ -90,10 +91,12 @@ await createApp({
|
|
|
90
91
|
});
|
|
91
92
|
```
|
|
92
93
|
|
|
93
|
-
If the repo already uses `src/mcp-server/prompts/definitions/index.ts`, add the
|
|
94
|
+
If the repo already uses `src/mcp-server/prompts/definitions/index.ts`, add the prompt to that barrel the way it holds the existing ones — it must end up in the array passed to `createApp()`. A bare `export … from` line registers nothing on its own. The standard barrel shape:
|
|
94
95
|
|
|
95
96
|
```typescript
|
|
96
|
-
|
|
97
|
+
import { {{PROMPT_EXPORT}} } from './{{prompt-name}}.prompt.js';
|
|
98
|
+
|
|
99
|
+
export const allPromptDefinitions = [/* existing prompts */, {{PROMPT_EXPORT}}];
|
|
97
100
|
```
|
|
98
101
|
|
|
99
102
|
## Argument autocompletion
|
|
@@ -137,3 +140,4 @@ For an optional argument, wrap the inner schema and apply `.optional()` outside:
|
|
|
137
140
|
- [ ] No side effects — prompts are pure templates
|
|
138
141
|
- [ ] Registered in the project's existing `createApp()` prompt list (directly or via barrel)
|
|
139
142
|
- [ ] `bun run devcheck` passes
|
|
143
|
+
- [ ] Smoke-tested with `bun run rebuild && bun run start:stdio < /dev/null`; the `Core services constructed` record lists the new prompt in its `prompts` field
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new MCP resource definition. Use when the user asks to add a resource, expose data via URI, or create a readable endpoint.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.8"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -22,7 +22,7 @@ Resources use the `resource()` builder from `@cyanheads/mcp-ts-core`. Each resou
|
|
|
22
22
|
3. **Create the file** at `src/mcp-server/resources/definitions/{{resource-name}}.resource.ts`
|
|
23
23
|
4. **Register** the resource in the project's existing `createApp()` resource list (directly in `src/index.ts` for fresh scaffolds, or via a barrel if the repo already has one)
|
|
24
24
|
5. **Run `bun run devcheck`** to verify
|
|
25
|
-
6. **Smoke-test** with `bun run rebuild && bun run start:stdio` (or `start:http`)
|
|
25
|
+
6. **Smoke-test** with `bun run rebuild && bun run start:stdio < /dev/null` (or `start:http`) — the `Core services constructed` log record must list the new resource in its `resources` field (the message text shows only counts); if it doesn't, the resource never reached `createApp()`
|
|
26
26
|
|
|
27
27
|
## Template
|
|
28
28
|
|
|
@@ -103,10 +103,12 @@ await createApp({
|
|
|
103
103
|
});
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
If the repo already uses `src/mcp-server/resources/definitions/index.ts`, add the
|
|
106
|
+
If the repo already uses `src/mcp-server/resources/definitions/index.ts`, add the resource to that barrel the way it holds the existing ones — it must end up in the array passed to `createApp()`. A bare `export … from` line registers nothing on its own. The standard barrel shape:
|
|
107
107
|
|
|
108
108
|
```typescript
|
|
109
|
-
|
|
109
|
+
import { {{RESOURCE_EXPORT}} } from './{{resource-name}}.resource.js';
|
|
110
|
+
|
|
111
|
+
export const allResourceDefinitions = [/* existing resources */, {{RESOURCE_EXPORT}}];
|
|
110
112
|
```
|
|
111
113
|
|
|
112
114
|
### Optional: declarative `errors[]` contract
|
|
@@ -222,4 +224,4 @@ Cacheable operations are `tools/list`, `prompts/list`, `resources/list`, `resour
|
|
|
222
224
|
- [ ] Pagination used for large result sets (`extractCursor`/`paginateArray`) — applies to both `handler` data and `list()` catalogs with many entries
|
|
223
225
|
- [ ] Registered in the project's existing `createApp()` resource list (directly or via barrel)
|
|
224
226
|
- [ ] `bun run devcheck` passes
|
|
225
|
-
- [ ] Smoke-tested with `bun run rebuild && bun run start:stdio` (or `start:http`)
|
|
227
|
+
- [ ] Smoke-tested with `bun run rebuild && bun run start:stdio < /dev/null` (or `start:http`); the `Core services constructed` record lists the new resource in its `resources` field
|
|
@@ -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.31"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -19,8 +19,8 @@ Tools use the `tool()` builder from `@cyanheads/mcp-ts-core`. Each tool lives in
|
|
|
19
19
|
2. **Determine if it needs input the caller may not supply** — a confirmation, a choice, the client's roots — which makes it a multi-round-trip handler (`ctx.requestInput` / `ctx.inputs`, see `api-context`)
|
|
20
20
|
3. **Create the file** at `src/mcp-server/tools/definitions/{{tool-name}}.tool.ts`
|
|
21
21
|
4. **Register** the tool in the project's existing `createApp()` tool list (directly in `src/index.ts` for fresh scaffolds, or via a barrel if the repo already has one)
|
|
22
|
-
5. **Run `bun run devcheck`** to verify —
|
|
23
|
-
6. **Smoke-test** with `bun run rebuild && bun run start:stdio` (or `start:http`)
|
|
22
|
+
5. **Run `bun run devcheck`** to verify — it applies Biome's formatting fixes as it runs
|
|
23
|
+
6. **Smoke-test** with `bun run rebuild && bun run start:stdio < /dev/null` (or `start:http`) — the `Core services constructed` log record must list the new tool in its `tools` field (the message text shows only counts); if it doesn't, the tool never reached `createApp()`
|
|
24
24
|
|
|
25
25
|
## Naming
|
|
26
26
|
|
|
@@ -281,7 +281,7 @@ Two limits worth knowing when you write a schema:
|
|
|
281
281
|
|
|
282
282
|
### Three things the framework fixes before the schema sees the arguments
|
|
283
283
|
|
|
284
|
-
Strict input is right for a misspelling the caller can fix, and wrong when the arguments the model wrote were correct and something between the model and the schema was not. An ordered step inside `parseToolArguments` covers those cases: **drop client-added keys → key aliases → parse → on failure, repair and one re-parse
|
|
284
|
+
Strict input is right for a misspelling the caller can fix, and wrong when the arguments the model wrote were correct and something between the model and the schema was not. An ordered step inside `parseToolArguments` covers those cases: **drop client-added keys → key aliases → parse → on failure, repair and one re-parse**, plus one alias-first retry when that still fails and the drop discarded a key (below). All three stages are on by default and none changes what `tools/list` advertises. A call they rescue carries nothing about them in its response — each change in the attempt your handler receives emits a debug log and a counter (`mcp.input.ignored_key`, `mcp.input.aliased`, `mcp.input.coerced`) instead, so a new client artifact surfaces in telemetry rather than as a failed call. A call they cannot rescue is rejected with the first order's rewrites and underscore-rule drops reported, as `data.input` and as closing hint sentences (`Validated query as targetQuery.`, `Dropped undeclared key _max.`), because the issues name only the keys that were validated and the caller could not otherwise tell a bad value from a moved or discarded key.
|
|
285
285
|
|
|
286
286
|
**1. Client-added root keys are dropped.** Some clients put their own keys inside `arguments`: a placeholder when the model sends none, a call description, a call id, or a `_meta` block that belongs on `params`. The model never wrote them and cannot remove them, so the retry fails identically. An undeclared root key is dropped when it is underscore-prefixed or on the built-in list (`_meta`, `tool_call_description`, `toolCallId`). Three boundaries: a declared key is never dropped (on a union root, that means every variant's keys); an author-opened root is left alone; and a tool declaring any underscore-prefixed key of its own switches the underscore rule off — otherwise a misspelled `_cursor` would vanish silently, which is the failure strict input exists to prevent.
|
|
287
287
|
|
|
@@ -297,9 +297,11 @@ export const drugProfile = tool('drug_profile', {
|
|
|
297
297
|
|
|
298
298
|
Alongside those, an undeclared key whose case-folded form (`-`/`_` stripped, lowercased) names exactly one declared key is rewritten too — `max_results`, `Max-Results`, and `MAXRESULTS` all reach a declared `maxResults`, with nothing declared. Neither half advertises anything: `inputSchema` is byte-identical with or without `inputAliases`, so the canonical key keeps its place in `required` and the model is still told to use it.
|
|
299
299
|
|
|
300
|
-
Declare an alias where the meaning is certain and the mapping is one-to-one — a sibling tool's spelling for the same concept, the upstream API's own name, a shorthand weaker models reach for. It is not fuzzy matching: a key matching no alias and no declared key is still rejected by name, with the accepted-key hint. Four boundaries: a rewrite applies only when the target key is absent (alias *and* target present fails exactly as it does today); an author-opened root is never rewritten; a union root resolves against the variant the discriminator selects, and rewrites nothing when the discriminator is absent or unrecognized; and a `headerParam`-designated target is never rewritten *to* — the SDK cross-checks the `Mcp-Param-<Name>` header against the raw body before dispatch, so a later rewrite would hand your handler a value no intermediary attested. `lint:mcp` rejects an alias that shadows a declared key, names a target that does not exist, or is ambiguous against another alias or key (`input-alias-conflict`).
|
|
300
|
+
Declare an alias where the meaning is certain and the mapping is one-to-one — a sibling tool's spelling for the same concept, the upstream API's own name, a shorthand weaker models reach for. It is not fuzzy matching: a key matching no alias and no declared key is still rejected by name, with the accepted-key hint. Four boundaries: a rewrite applies only when the target key is absent (alias *and* target present fails exactly as it does today); an author-opened root is never rewritten; a union root resolves against the variant the discriminator selects, and rewrites nothing when the discriminator is absent or unrecognized; and a `headerParam`-designated target is never rewritten *to* — the SDK cross-checks the `Mcp-Param-<Name>` header against the raw body before dispatch, so a later rewrite would hand your handler a value no intermediary attested. `lint:mcp` rejects an alias that shadows a declared key, names a target that does not exist or is `headerParam`-designated, or is ambiguous against another alias or key (`input-alias-conflict`).
|
|
301
301
|
|
|
302
|
-
**3. A stringified array is repaired after the parse fails.** `statusFilter: "[\"RECRUITING\"]"` against `z.array(z.string())` is a serialization slip the server can undo with certainty — `JSON.parse` is the exact inverse of the `JSON.stringify` that produced it
|
|
302
|
+
**3. A stringified array or object, or an integer sent for a string, is repaired after the parse fails.** `statusFilter: "[\"RECRUITING\"]"` against `z.array(z.string())`, or `target: "{\"type\":\"path\",\"path\":\"a.md\"}"` against an object or discriminated-union field, is a serialization slip the server can undo with certainty — `JSON.parse` is the exact inverse of the `JSON.stringify` that produced it. So is `station_id: 8654467` against `z.string()`: `String(n)` of a safe integer is the digits the caller sent. That certainty is what separates a repair from the nearest-key guessing strict input refuses. The repair runs *only* on the failure branch, *only* at the paths the rejection's own issues name, once — a value one repair produced is never repaired again, and a number inside one branch of a union field stays as sent — and is kept only if the repaired arguments then pass your schema. So it cannot touch a value that was already valid: a free-text field legitimately holding `"[1,2,3]"` or `"{…}"` is not in the issue list, so it survives untouched even when the same call carries a genuine stringified value in another field. The integer repair is gated further, to issues that say the value failed for being a number (a wrong type, a string-only enum, a union every branch of which refused the type): `-1` against `z.union([z.number().int().positive(), z.string()])` keeps its rejection instead of slipping past your constraint through the string branch, and `-0`, a fraction, or an integer past `Number.MAX_SAFE_INTEGER` is never repaired. Your schema still decides the repaired string — `20260922` against `z.iso.date()` stays rejected. It walks values only: no key is added, dropped, or renamed. When nothing validates, the original rejection is thrown — exactly what the same call gets under `coerce: false`.
|
|
303
|
+
|
|
304
|
+
**When the drop took a key the alias stage wanted.** The drop runs first, so it also discards an underscore spelling of a declared key (`_query` for `query`), a declared `inputAliases: { _q: 'query' }`, and an ignore-listed key a declared alias names. If the call then fails, repair included, the step reruns both stages with the alias stage first, where those keys are rewritten instead, and keeps that retry only if it validates, again with its own repair. The retry never case-folds an ignore-listed key onto a declared one (`_meta` stays the client's even beside a declared `meta`), and still drops an underscore key it cannot resolve. It never changes which calls validate: `{ query: 'abc', _max_results: '12345' }` against an optional `maxResults: z.number()` validates with `_max_results` dropped, so the retry never runs. A call neither order validates gets the retry's rejection, which describes the arguments as the caller meant them: `{ _q: 'ab' }` against `query: z.string().min(3)` reports the too-short `query` and closes `Validated _q as query.`, not a missing `query` beside a dropped `_q`.
|
|
303
305
|
|
|
304
306
|
Turn any stage off per server — there is no per-tool switch:
|
|
305
307
|
|
|
@@ -308,13 +310,13 @@ await createApp({
|
|
|
308
310
|
input: {
|
|
309
311
|
ignoreKeys: ['some_client_field'], // adds to the built-in list; `false` disables the stage
|
|
310
312
|
caseStyleAliases: false, // declared `inputAliases` only
|
|
311
|
-
coerce: false, // never
|
|
313
|
+
coerce: false, // never repair an argument value
|
|
312
314
|
},
|
|
313
315
|
tools: allToolDefinitions,
|
|
314
316
|
});
|
|
315
317
|
```
|
|
316
318
|
|
|
317
|
-
Those three stages are the whole of the framework's input edge: argument **key** names, and
|
|
319
|
+
Those three stages are the whole of the framework's input edge: argument **key** names, and three **value** shapes — a JSON-stringified array or object, which `JSON.parse` inverts with certainty, and a safe integer sent for a string, whose digits `String(n)` restores. Every other value normalization is domain knowledge and belongs to the tool: the case or bare-leaf form of a code, a unit or vocabulary alias, a composite identifier assembled from two arguments, a delimiter-joined list, a spelled-out name. Which variants a given input accepts is decided per input at design time (`design-mcp-server` § *Parameter descriptions*) and applied at the head of the handler, on the unambiguous mappings only.
|
|
318
320
|
|
|
319
321
|
### Multi-mode tools take a discriminated-union input
|
|
320
322
|
|
|
@@ -369,7 +371,7 @@ input: z.object({
|
|
|
369
371
|
|
|
370
372
|
The emitted property carries `"x-mcp-header": "Region"` and nothing else about the field changes — description, type, validation, and requiredness are untouched. Order does not matter: `headerParam(z.string(), 'Region').describe('…')` and `headerParam(z.string().describe('…'), 'Region')` are the same schema.
|
|
371
373
|
|
|
372
|
-
**It mirrors, it does not relocate.** When the body carries a value for a designated property, the matching `Mcp-Param-<Name>` header MUST be present and decode to an equal value; the SDK cross-checks the pair before dispatch and rejects a disagreement with `-32020` (`HeaderMismatch`, HTTP `400`). Absent or `null` in the body means no header is expected. **Your handler still reads the argument from `input`** — there is nothing new to do in the handler body.
|
|
374
|
+
**It mirrors, it does not relocate.** When the body carries a value for a designated property, the matching `Mcp-Param-<Name>` header MUST be present and decode to an equal value; the SDK cross-checks the pair before dispatch and rejects a disagreement with `-32020` (`HeaderMismatch`, HTTP `400`). Absent or `null` in the body means no header is expected. **Your handler still reads the argument from `input`** — there is nothing new to do in the handler body. Browser clients need nothing extra either: the HTTP transport's CORS preflight allows `Mcp-Param-<Name>` for every designation on a registered tool, for each origin `MCP_ALLOWED_ORIGINS` accepts.
|
|
373
375
|
|
|
374
376
|
**Where a designation is legal.** The property must be primitive-typed (`string`, `integer`, `number`, `boolean`) and statically reachable through a chain of `properties` keys. Top-level and nested `z.object()` fields qualify. These do not:
|
|
375
377
|
|
|
@@ -893,4 +895,4 @@ return { items: hits };
|
|
|
893
895
|
- [ ] Registered in the project's existing `createApp()` tool list (directly or via barrel)
|
|
894
896
|
- [ ] Test file created via `add-test` skill, or handler tested directly with `createMockContext()`
|
|
895
897
|
- [ ] `bun run devcheck` passes
|
|
896
|
-
- [ ] Smoke-tested with `bun run rebuild && bun run start:stdio` (or `start:http`)
|
|
898
|
+
- [ ] Smoke-tested with `bun run rebuild && bun run start:stdio < /dev/null` (or `start:http`); the `Core services constructed` record lists the new tool in its `tools` field
|