@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.
Files changed (274) hide show
  1. package/AGENTS.md +19 -15
  2. package/CLAUDE.md +19 -15
  3. package/README.md +4 -2
  4. package/changelog/0.13.x/0.13.8.md +101 -0
  5. package/changelog/0.13.x/0.13.9.md +113 -0
  6. package/dist/config/index.d.ts +9 -0
  7. package/dist/config/index.d.ts.map +1 -1
  8. package/dist/config/index.js +39 -9
  9. package/dist/config/index.js.map +1 -1
  10. package/dist/core/app.d.ts +6 -3
  11. package/dist/core/app.d.ts.map +1 -1
  12. package/dist/core/app.js +20 -6
  13. package/dist/core/app.js.map +1 -1
  14. package/dist/core/context.d.ts +25 -1
  15. package/dist/core/context.d.ts.map +1 -1
  16. package/dist/core/context.js +13 -3
  17. package/dist/core/context.js.map +1 -1
  18. package/dist/core/serverManifest.d.ts +6 -0
  19. package/dist/core/serverManifest.d.ts.map +1 -1
  20. package/dist/core/serverManifest.js +6 -0
  21. package/dist/core/serverManifest.js.map +1 -1
  22. package/dist/core/worker.d.ts +2 -0
  23. package/dist/core/worker.d.ts.map +1 -1
  24. package/dist/core/worker.js +2 -0
  25. package/dist/core/worker.js.map +1 -1
  26. package/dist/linter/rules/enrichment-rules.d.ts +3 -2
  27. package/dist/linter/rules/enrichment-rules.d.ts.map +1 -1
  28. package/dist/linter/rules/enrichment-rules.js +9 -2
  29. package/dist/linter/rules/enrichment-rules.js.map +1 -1
  30. package/dist/linter/rules/handler-body-rules.d.ts.map +1 -1
  31. package/dist/linter/rules/handler-body-rules.js +10 -4
  32. package/dist/linter/rules/handler-body-rules.js.map +1 -1
  33. package/dist/linter/rules/schema-rules.d.ts +5 -0
  34. package/dist/linter/rules/schema-rules.d.ts.map +1 -1
  35. package/dist/linter/rules/schema-rules.js +44 -17
  36. package/dist/linter/rules/schema-rules.js.map +1 -1
  37. package/dist/linter/rules/tool-rules.d.ts +2 -1
  38. package/dist/linter/rules/tool-rules.d.ts.map +1 -1
  39. package/dist/linter/rules/tool-rules.js +36 -1
  40. package/dist/linter/rules/tool-rules.js.map +1 -1
  41. package/dist/mcp-server/inputRequired.d.ts +14 -5
  42. package/dist/mcp-server/inputRequired.d.ts.map +1 -1
  43. package/dist/mcp-server/inputRequired.js +15 -8
  44. package/dist/mcp-server/inputRequired.js.map +1 -1
  45. package/dist/mcp-server/outputContract.d.ts +33 -0
  46. package/dist/mcp-server/outputContract.d.ts.map +1 -0
  47. package/dist/mcp-server/outputContract.js +43 -0
  48. package/dist/mcp-server/outputContract.js.map +1 -0
  49. package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
  50. package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +10 -2
  51. package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
  52. package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts +163 -40
  53. package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts.map +1 -1
  54. package/dist/mcp-server/tools/utils/inputPrevalidation.js +330 -114
  55. package/dist/mcp-server/tools/utils/inputPrevalidation.js.map +1 -1
  56. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +39 -15
  57. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
  58. package/dist/mcp-server/tools/utils/toolHandlerFactory.js +361 -93
  59. package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
  60. package/dist/mcp-server/transports/auth/lib/authUtils.js +4 -1
  61. package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -1
  62. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts.map +1 -1
  63. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +1 -1
  64. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -1
  65. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -1
  66. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +2 -5
  67. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
  68. package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
  69. package/dist/mcp-server/transports/http/httpTransport.js +65 -9
  70. package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
  71. package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -1
  72. package/dist/mcp-server/transports/http/sessionStore.js +2 -2
  73. package/dist/mcp-server/transports/http/sessionStore.js.map +1 -1
  74. package/dist/mcp-server/transports/stdio/stdioTransport.d.ts +9 -5
  75. package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -1
  76. package/dist/mcp-server/transports/stdio/stdioTransport.js +9 -5
  77. package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -1
  78. package/dist/services/canvas/core/CanvasRegistry.d.ts +6 -2
  79. package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
  80. package/dist/services/canvas/core/CanvasRegistry.js +8 -4
  81. package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
  82. package/dist/services/canvas/core/DataCanvas.d.ts.map +1 -1
  83. package/dist/services/canvas/core/DataCanvas.js +7 -5
  84. package/dist/services/canvas/core/DataCanvas.js.map +1 -1
  85. package/dist/services/canvas/core/canvasFactory.d.ts.map +1 -1
  86. package/dist/services/canvas/core/canvasFactory.js +2 -2
  87. package/dist/services/canvas/core/canvasFactory.js.map +1 -1
  88. package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +82 -18
  89. package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
  90. package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +645 -344
  91. package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
  92. package/dist/services/canvas/providers/duckdb/exportWriter.d.ts +11 -7
  93. package/dist/services/canvas/providers/duckdb/exportWriter.d.ts.map +1 -1
  94. package/dist/services/canvas/providers/duckdb/exportWriter.js +19 -16
  95. package/dist/services/canvas/providers/duckdb/exportWriter.js.map +1 -1
  96. package/dist/services/llm/providers/openrouter.provider.js +1 -1
  97. package/dist/services/llm/providers/openrouter.provider.js.map +1 -1
  98. package/dist/services/mirror/core/defineMirror.d.ts +1 -0
  99. package/dist/services/mirror/core/defineMirror.d.ts.map +1 -1
  100. package/dist/services/mirror/core/defineMirror.js +1 -0
  101. package/dist/services/mirror/core/defineMirror.js.map +1 -1
  102. package/dist/services/speech/providers/elevenlabs.provider.js +3 -3
  103. package/dist/services/speech/providers/elevenlabs.provider.js.map +1 -1
  104. package/dist/services/speech/providers/whisper.provider.d.ts.map +1 -1
  105. package/dist/services/speech/providers/whisper.provider.js +5 -5
  106. package/dist/services/speech/providers/whisper.provider.js.map +1 -1
  107. package/dist/storage/core/StorageService.d.ts.map +1 -1
  108. package/dist/storage/core/StorageService.js +3 -6
  109. package/dist/storage/core/StorageService.js.map +1 -1
  110. package/dist/storage/core/storageFactory.d.ts.map +1 -1
  111. package/dist/storage/core/storageFactory.js +12 -15
  112. package/dist/storage/core/storageFactory.js.map +1 -1
  113. package/dist/storage/core/storageValidation.d.ts +13 -13
  114. package/dist/storage/core/storageValidation.d.ts.map +1 -1
  115. package/dist/storage/core/storageValidation.js +49 -125
  116. package/dist/storage/core/storageValidation.js.map +1 -1
  117. package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -1
  118. package/dist/storage/providers/cloudflare/d1Provider.js +5 -3
  119. package/dist/storage/providers/cloudflare/d1Provider.js.map +1 -1
  120. package/dist/storage/providers/cloudflare/kvProvider.d.ts.map +1 -1
  121. package/dist/storage/providers/cloudflare/kvProvider.js +1 -1
  122. package/dist/storage/providers/cloudflare/kvProvider.js.map +1 -1
  123. package/dist/storage/providers/cloudflare/r2Provider.d.ts.map +1 -1
  124. package/dist/storage/providers/cloudflare/r2Provider.js +3 -3
  125. package/dist/storage/providers/cloudflare/r2Provider.js.map +1 -1
  126. package/dist/storage/providers/fileSystem/fileSystemProvider.js +4 -4
  127. package/dist/storage/providers/fileSystem/fileSystemProvider.js.map +1 -1
  128. package/dist/storage/providers/inMemory/inMemoryProvider.d.ts +1 -1
  129. package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -1
  130. package/dist/storage/providers/inMemory/inMemoryProvider.js +6 -5
  131. package/dist/storage/providers/inMemory/inMemoryProvider.js.map +1 -1
  132. package/dist/testing/fuzz.d.ts.map +1 -1
  133. package/dist/testing/fuzz.js +7 -1
  134. package/dist/testing/fuzz.js.map +1 -1
  135. package/dist/testing/index.d.ts +15 -2
  136. package/dist/testing/index.d.ts.map +1 -1
  137. package/dist/testing/index.js +51 -6
  138. package/dist/testing/index.js.map +1 -1
  139. package/dist/types-global/errors.d.ts +7 -4
  140. package/dist/types-global/errors.d.ts.map +1 -1
  141. package/dist/types-global/errors.js.map +1 -1
  142. package/dist/utils/formatting/codeSpan.d.ts +27 -0
  143. package/dist/utils/formatting/codeSpan.d.ts.map +1 -0
  144. package/dist/utils/formatting/codeSpan.js +42 -0
  145. package/dist/utils/formatting/codeSpan.js.map +1 -0
  146. package/dist/utils/formatting/diffFormatter.d.ts.map +1 -1
  147. package/dist/utils/formatting/diffFormatter.js +7 -15
  148. package/dist/utils/formatting/diffFormatter.js.map +1 -1
  149. package/dist/utils/formatting/markdownBuilder.d.ts +12 -5
  150. package/dist/utils/formatting/markdownBuilder.d.ts.map +1 -1
  151. package/dist/utils/formatting/markdownBuilder.js +14 -2
  152. package/dist/utils/formatting/markdownBuilder.js.map +1 -1
  153. package/dist/utils/formatting/tableFormatter.d.ts.map +1 -1
  154. package/dist/utils/formatting/tableFormatter.js +5 -9
  155. package/dist/utils/formatting/tableFormatter.js.map +1 -1
  156. package/dist/utils/formatting/treeFormatter.d.ts.map +1 -1
  157. package/dist/utils/formatting/treeFormatter.js +5 -9
  158. package/dist/utils/formatting/treeFormatter.js.map +1 -1
  159. package/dist/utils/index.d.ts +1 -1
  160. package/dist/utils/index.d.ts.map +1 -1
  161. package/dist/utils/index.js.map +1 -1
  162. package/dist/utils/internal/error-handler/errorHandler.d.ts +17 -10
  163. package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
  164. package/dist/utils/internal/error-handler/errorHandler.js +47 -26
  165. package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
  166. package/dist/utils/internal/error-handler/mappings.d.ts +17 -1
  167. package/dist/utils/internal/error-handler/mappings.d.ts.map +1 -1
  168. package/dist/utils/internal/error-handler/mappings.js +22 -1
  169. package/dist/utils/internal/error-handler/mappings.js.map +1 -1
  170. package/dist/utils/internal/error-handler/types.d.ts +2 -0
  171. package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
  172. package/dist/utils/internal/logger.d.ts +75 -3
  173. package/dist/utils/internal/logger.d.ts.map +1 -1
  174. package/dist/utils/internal/logger.js +181 -52
  175. package/dist/utils/internal/logger.js.map +1 -1
  176. package/dist/utils/internal/performance.d.ts +11 -0
  177. package/dist/utils/internal/performance.d.ts.map +1 -1
  178. package/dist/utils/internal/performance.js +46 -12
  179. package/dist/utils/internal/performance.js.map +1 -1
  180. package/dist/utils/network/fetchWithTimeout.d.ts +11 -5
  181. package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
  182. package/dist/utils/network/fetchWithTimeout.js +50 -23
  183. package/dist/utils/network/fetchWithTimeout.js.map +1 -1
  184. package/dist/utils/network/pacer.d.ts +38 -5
  185. package/dist/utils/network/pacer.d.ts.map +1 -1
  186. package/dist/utils/network/pacer.js +87 -25
  187. package/dist/utils/network/pacer.js.map +1 -1
  188. package/dist/utils/network/retry.d.ts +16 -8
  189. package/dist/utils/network/retry.d.ts.map +1 -1
  190. package/dist/utils/network/retry.js +19 -8
  191. package/dist/utils/network/retry.js.map +1 -1
  192. package/dist/utils/overflow/outlineOnOverflow.d.ts +18 -2
  193. package/dist/utils/overflow/outlineOnOverflow.d.ts.map +1 -1
  194. package/dist/utils/overflow/outlineOnOverflow.js +28 -3
  195. package/dist/utils/overflow/outlineOnOverflow.js.map +1 -1
  196. package/dist/utils/pagination/pagination.d.ts +3 -1
  197. package/dist/utils/pagination/pagination.d.ts.map +1 -1
  198. package/dist/utils/pagination/pagination.js +10 -2
  199. package/dist/utils/pagination/pagination.js.map +1 -1
  200. package/dist/utils/parsing/csvParser.d.ts.map +1 -1
  201. package/dist/utils/parsing/csvParser.js +4 -2
  202. package/dist/utils/parsing/csvParser.js.map +1 -1
  203. package/dist/utils/parsing/htmlExtractor.js +1 -1
  204. package/dist/utils/parsing/htmlExtractor.js.map +1 -1
  205. package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
  206. package/dist/utils/parsing/jsonParser.js +3 -1
  207. package/dist/utils/parsing/jsonParser.js.map +1 -1
  208. package/dist/utils/parsing/xmlParser.d.ts.map +1 -1
  209. package/dist/utils/parsing/xmlParser.js +3 -1
  210. package/dist/utils/parsing/xmlParser.js.map +1 -1
  211. package/dist/utils/parsing/yamlParser.d.ts.map +1 -1
  212. package/dist/utils/parsing/yamlParser.js +3 -1
  213. package/dist/utils/parsing/yamlParser.js.map +1 -1
  214. package/dist/utils/security/idGenerator.d.ts.map +1 -1
  215. package/dist/utils/security/idGenerator.js +20 -4
  216. package/dist/utils/security/idGenerator.js.map +1 -1
  217. package/dist/utils/security/sanitization.d.ts +31 -0
  218. package/dist/utils/security/sanitization.d.ts.map +1 -1
  219. package/dist/utils/security/sanitization.js +98 -11
  220. package/dist/utils/security/sanitization.js.map +1 -1
  221. package/dist/utils/telemetry/attributes.d.ts +21 -2
  222. package/dist/utils/telemetry/attributes.d.ts.map +1 -1
  223. package/dist/utils/telemetry/attributes.js +21 -2
  224. package/dist/utils/telemetry/attributes.js.map +1 -1
  225. package/dist/utils/telemetry/instrumentation.d.ts +9 -3
  226. package/dist/utils/telemetry/instrumentation.d.ts.map +1 -1
  227. package/dist/utils/telemetry/instrumentation.js +85 -13
  228. package/dist/utils/telemetry/instrumentation.js.map +1 -1
  229. package/framework-skills/add-app-tool/SKILL.md +3 -3
  230. package/framework-skills/add-export/SKILL.md +5 -16
  231. package/framework-skills/add-prompt/SKILL.md +7 -3
  232. package/framework-skills/add-resource/SKILL.md +7 -5
  233. package/framework-skills/add-tool/SKILL.md +12 -10
  234. package/framework-skills/api-auth/SKILL.md +4 -2
  235. package/framework-skills/api-canvas/SKILL.md +19 -10
  236. package/framework-skills/api-config/SKILL.md +9 -6
  237. package/framework-skills/api-context/SKILL.md +16 -5
  238. package/framework-skills/api-errors/SKILL.md +23 -17
  239. package/framework-skills/api-linter/SKILL.md +32 -9
  240. package/framework-skills/api-mirror/SKILL.md +2 -1
  241. package/framework-skills/api-telemetry/SKILL.md +34 -14
  242. package/framework-skills/api-testing/SKILL.md +5 -3
  243. package/framework-skills/api-utils/SKILL.md +10 -10
  244. package/framework-skills/api-utils/references/formatting.md +1 -1
  245. package/framework-skills/api-utils/references/parsing.md +2 -2
  246. package/framework-skills/api-utils/references/security.md +6 -4
  247. package/framework-skills/design-mcp-server/SKILL.md +2 -2
  248. package/framework-skills/field-test/SKILL.md +4 -4
  249. package/framework-skills/git-wrapup/SKILL.md +12 -7
  250. package/framework-skills/maintenance/SKILL.md +2 -2
  251. package/framework-skills/orchestrations/SKILL.md +7 -6
  252. package/framework-skills/orchestrations/workflows/field-test-fix.md +9 -19
  253. package/framework-skills/orchestrations/workflows/fix-wrapup-release.md +7 -7
  254. package/framework-skills/orchestrations/workflows/greenfield-build.md +8 -5
  255. package/framework-skills/orchestrations/workflows/maintenance-release.md +8 -8
  256. package/framework-skills/polish-docs-meta/SKILL.md +4 -4
  257. package/framework-skills/polish-docs-meta/references/readme.md +1 -0
  258. package/framework-skills/release-and-publish/SKILL.md +7 -5
  259. package/framework-skills/release-pr-review/SKILL.md +37 -23
  260. package/framework-skills/report-issue-framework/SKILL.md +7 -5
  261. package/framework-skills/report-issue-local/SKILL.md +8 -6
  262. package/framework-skills/security-pass/SKILL.md +8 -8
  263. package/framework-skills/techniques/SKILL.md +1 -1
  264. package/framework-skills/techniques/references/outline-on-overflow.md +12 -7
  265. package/package.json +20 -5
  266. package/scripts/check-skill-versions.ts +103 -22
  267. package/scripts/devcheck.ts +11 -9
  268. package/scripts/lint-mcp.ts +87 -27
  269. package/scripts/lint-packaging.ts +99 -1
  270. package/scripts/release-github.ts +117 -5
  271. package/templates/.env.example +4 -0
  272. package/templates/Dockerfile +26 -6
  273. package/templates/_.mcpbignore +2 -0
  274. 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
- /** JSON-RPC error code from the thrown `McpError`, present when `mcp.tool.success` is `false`. */
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
- /** Which representation repair earned validity (`stringified_array`). */
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":"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"}
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
- /** JSON-RPC error code from the thrown `McpError`, present when `mcp.tool.success` is `false`. */
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
- /** Which representation repair earned validity (`stringified_array`). */
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,kGAAkG;AAClG,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAE9D,yGAAyG;AACzG,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE,iGAAiG;AACjG,MAAM,CAAC,MAAM,6BAA6B,GAAG,0BAA0B,CAAC;AAExE,sFAAsF;AACtF,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D,uEAAuE;AACvE,MAAM,CAAC,MAAM,6BAA6B,GAAG,gCAAgC,CAAC;AAE9E,oEAAoE;AACpE,MAAM,CAAC,MAAM,0BAA0B,GAAG,6BAA6B,CAAC;AAExE,+EAA+E;AAC/E,2CAA2C;AAC3C,+EAA+E;AAE/E,4EAA4E;AAC5E,gFAAgF;AAChF,+EAA+E;AAC/E,+EAA+E;AAC/E,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC;AAElE,uFAAuF;AACvF,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,uEAAuE;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE,yEAAyE;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAE5D,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAEpD,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,gFAAgF;AAChF,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D,kFAAkF;AAClF,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;AAEpE,iEAAiE;AACjE,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE,mEAAmE;AACnE,MAAM,CAAC,MAAM,6BAA6B,GAAG,0BAA0B,CAAC;AAExE;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE,gGAAgG;AAChG,MAAM,CAAC,MAAM,gCAAgC,GAAG,6BAA6B,CAAC;AAE9E,iGAAiG;AACjG,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E,+EAA+E;AAC/E,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAEtD,6DAA6D;AAC7D,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;AAEpE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE,uEAAuE;AACvE,MAAM,CAAC,MAAM,6BAA6B,GAAG,0BAA0B,CAAC;AAExE,yFAAyF;AACzF,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;AAEpE;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAE5D,6FAA6F;AAC7F,MAAM,CAAC,MAAM,8BAA8B,GAAG,2BAA2B,CAAC;AAE1E,+FAA+F;AAC/F,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC;AAElE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,8BAA8B,GAAG,2BAA2B,CAAC;AAE1E,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;AAE/E,yFAAyF;AACzF,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,uEAAuE;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,+EAA+E;AAC/E,mCAAmC;AACnC,+EAA+E;AAE/E,0FAA0F;AAC1F,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D,+EAA+E;AAC/E,yBAAyB;AACzB,+EAA+E;AAE/E,2FAA2F;AAC3F,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC;AAElE,0FAA0F;AAC1F,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC;AAElE,oEAAoE;AACpE,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE,4DAA4D;AAC5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAE9D,+EAA+E;AAC/E,mDAAmD;AACnD,2DAA2D;AAC3D,+EAA+E;AAE/E,qFAAqF;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,oEAAoE;AACpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE,uDAAuD;AACvD,MAAM,CAAC,MAAM,8BAA8B,GAAG,2BAA2B,CAAC;AAE1E,sCAAsC;AACtC,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AAE5E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE,qDAAqD;AACrD,MAAM,CAAC,MAAM,6BAA6B,GAAG,0BAA0B,CAAC;AAExE,yEAAyE;AACzE,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC;AAElE,8CAA8C;AAC9C,MAAM,CAAC,MAAM,8BAA8B,GAAG,2BAA2B,CAAC;AAE1E,oDAAoD;AACpD,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AAE5E,qCAAqC;AACrC,MAAM,CAAC,MAAM,8BAA8B,GAAG,2BAA2B,CAAC;AAE1E,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E,mEAAmE;AACnE,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAE9D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE,mEAAmE;AACnE,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;AAEpE,2DAA2D;AAC3D,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAE5D,qEAAqE;AACrE,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;AAEpE,sEAAsE;AACtE,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,qFAAqF;AACrF,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAE9D,kEAAkE;AAClE,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC;AAElE,0DAA0D;AAC1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D,+EAA+E;AAC/E,sBAAsB;AACtB,+EAA+E;AAE/E,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAEtD,kEAAkE;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,oGAAoG;AACpG,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAEtE,kFAAkF;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAEtD,iEAAiE;AACjE,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,+EAA+E;AAC/E,wCAAwC;AACxC,+EAA+E;AAE/E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,6BAA6B,GAAG,0BAA0B,CAAC;AAExE,+EAA+E;AAC/E,sCAAsC;AACtC,+EAA+E;AAE/E,mFAAmF;AACnF,MAAM,CAAC,MAAM,8BAA8B,GAAG,2BAA2B,CAAC;AAE1E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC"}
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
- * - No log record processors, and no metric reader when no metrics endpoint resolves — so
31
- * `NodeSDK`'s env-driven defaults never export anything the framework config did not ask for
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 that injects `trace_id`/`span_id` into log records
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;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAKvD;;;;;GAKG;AACH,eAAO,IAAI,GAAG,EAAE,OAAO,GAAG,IAAW,CAAC;AAmEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkI7D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB3E"}
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 { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';
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
- * - No log record processors, and no metric reader when no metrics endpoint resolves — so
88
- * `NodeSDK`'s env-driven defaults never export anything the framework config did not ask for
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 that injects `trace_id`/`span_id` into log records
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
- const otelLogLevel = DiagLogLevel[otelLogLevelString] ?? DiagLogLevel.INFO;
138
- diag.setLogger(new DiagConsoleLogger(), otelLogLevel);
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
- if (!tracesEndpoint && !metricsEndpoint) {
142
- diag.warn('OTEL_ENABLED is true, but no OTLP endpoint for traces or metrics 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.');
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: 15000,
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":"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"}
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.6"
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.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. **Build** with `bun run build` to generate `dist/` output
33
- 5. **Verify the export** resolves through the package's `exports` map:
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 build` succeeds
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.4"
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 export to that barrel instead:
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
- export { {{PROMPT_EXPORT}} } from './{{prompt-name}}.prompt.js';
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"
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 export to that barrel instead:
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
- export { {{RESOURCE_EXPORT}} } from './{{resource-name}}.resource.js';
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.30"
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 — if Biome reports formatting issues, run `bun run format` to auto-fix, then re-run devcheck
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.** All three stages are on by default, none changes what `tools/list` advertises, and none appears in a response — each emits a debug log and a counter (`mcp.input.ignored_key`, `mcp.input.aliased`, `mcp.input.coerced`) instead, so a new client artifact surfaces in telemetry rather than as a failed call.
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, which is what separates it from the nearest-key guessing strict input refuses. The repair runs *only* on the failure branch, *only* at the paths the rejection's own issues name, and is kept only if the repaired arguments then pass your schema. So it cannot touch a value that was already valid — a free-text field legitimately holding `"[1,2,3]"` is not in the issue list, so it survives untouched even when the same call carries a genuine stringified array in another field. It walks values only: no key is added, dropped, or renamed. When nothing validates, the original rejection is thrown verbatim: same code, message, `data.issues`, and `data.recovery.hint`.
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 retry a failed parse
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 one **value** shape — a JSON-stringified array, which `JSON.parse` inverts with certainty. Every other value normalization is domain knowledge and belongs to the tool: the case or bare-leaf form of a code, a unit or vocabulary alias, a composite identifier assembled from two arguments, a delimiter-joined list, a spelled-out name. Which variants a given input accepts is decided per input at design time (`design-mcp-server` § *Parameter descriptions*) and applied at the head of the handler, on the unambiguous mappings only.
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