@cyanheads/mcp-ts-core 0.11.5 → 0.12.1

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 (389) hide show
  1. package/AGENTS.md +27 -23
  2. package/CLAUDE.md +27 -23
  3. package/README.md +10 -10
  4. package/biome.json +1 -1
  5. package/changelog/0.12.x/0.12.0.md +96 -0
  6. package/changelog/0.12.x/0.12.1.md +26 -0
  7. package/dist/cli/init.js +1 -1
  8. package/dist/cli/init.js.map +1 -1
  9. package/dist/config/index.d.ts +9 -18
  10. package/dist/config/index.d.ts.map +1 -1
  11. package/dist/config/index.js +21 -28
  12. package/dist/config/index.js.map +1 -1
  13. package/dist/core/app.d.ts +27 -7
  14. package/dist/core/app.d.ts.map +1 -1
  15. package/dist/core/app.js +28 -28
  16. package/dist/core/app.js.map +1 -1
  17. package/dist/core/context.d.ts +90 -57
  18. package/dist/core/context.d.ts.map +1 -1
  19. package/dist/core/context.js +32 -33
  20. package/dist/core/context.js.map +1 -1
  21. package/dist/core/gcPressure.d.ts.map +1 -1
  22. package/dist/core/gcPressure.js +3 -4
  23. package/dist/core/gcPressure.js.map +1 -1
  24. package/dist/core/index.d.ts +6 -7
  25. package/dist/core/index.d.ts.map +1 -1
  26. package/dist/core/index.js +10 -2
  27. package/dist/core/index.js.map +1 -1
  28. package/dist/core/serverManifest.d.ts +6 -4
  29. package/dist/core/serverManifest.d.ts.map +1 -1
  30. package/dist/core/serverManifest.js +37 -14
  31. package/dist/core/serverManifest.js.map +1 -1
  32. package/dist/core/worker.d.ts.map +1 -1
  33. package/dist/core/worker.js +34 -37
  34. package/dist/core/worker.js.map +1 -1
  35. package/dist/linter/rules/enrichment-rules.d.ts.map +1 -1
  36. package/dist/linter/rules/enrichment-rules.js +5 -2
  37. package/dist/linter/rules/enrichment-rules.js.map +1 -1
  38. package/dist/linter/rules/portability-rules.d.ts +4 -2
  39. package/dist/linter/rules/portability-rules.d.ts.map +1 -1
  40. package/dist/linter/rules/portability-rules.js +33 -4
  41. package/dist/linter/rules/portability-rules.js.map +1 -1
  42. package/dist/linter/rules/schema-rules.d.ts +10 -3
  43. package/dist/linter/rules/schema-rules.d.ts.map +1 -1
  44. package/dist/linter/rules/schema-rules.js +52 -25
  45. package/dist/linter/rules/schema-rules.js.map +1 -1
  46. package/dist/linter/rules/tool-rules.d.ts.map +1 -1
  47. package/dist/linter/rules/tool-rules.js +5 -2
  48. package/dist/linter/rules/tool-rules.js.map +1 -1
  49. package/dist/linter/types.d.ts +2 -1
  50. package/dist/linter/types.d.ts.map +1 -1
  51. package/dist/logs/combined.log +10 -22
  52. package/dist/logs/error.log +6 -18
  53. package/dist/mcp-server/inputRequired.d.ts +52 -0
  54. package/dist/mcp-server/inputRequired.d.ts.map +1 -0
  55. package/dist/mcp-server/inputRequired.js +76 -0
  56. package/dist/mcp-server/inputRequired.js.map +1 -0
  57. package/dist/mcp-server/notifications.d.ts +103 -34
  58. package/dist/mcp-server/notifications.d.ts.map +1 -1
  59. package/dist/mcp-server/notifications.js +104 -29
  60. package/dist/mcp-server/notifications.js.map +1 -1
  61. package/dist/mcp-server/prompts/prompt-registration.d.ts +2 -2
  62. package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -1
  63. package/dist/mcp-server/prompts/prompt-registration.js +15 -5
  64. package/dist/mcp-server/prompts/prompt-registration.js.map +1 -1
  65. package/dist/mcp-server/prompts/utils/promptDefinition.d.ts +1 -1
  66. package/dist/mcp-server/prompts/utils/promptDefinition.d.ts.map +1 -1
  67. package/dist/mcp-server/resources/resource-registration.d.ts +3 -3
  68. package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
  69. package/dist/mcp-server/resources/resource-registration.js +9 -15
  70. package/dist/mcp-server/resources/resource-registration.js.map +1 -1
  71. package/dist/mcp-server/resources/resourceSubscriptions.d.ts +45 -0
  72. package/dist/mcp-server/resources/resourceSubscriptions.d.ts.map +1 -0
  73. package/dist/mcp-server/resources/resourceSubscriptions.js +51 -0
  74. package/dist/mcp-server/resources/resourceSubscriptions.js.map +1 -0
  75. package/dist/mcp-server/resources/utils/resourceDefinition.d.ts +3 -5
  76. package/dist/mcp-server/resources/utils/resourceDefinition.d.ts.map +1 -1
  77. package/dist/mcp-server/resources/utils/resourceDefinition.js +1 -1
  78. package/dist/mcp-server/resources/utils/resourceDefinition.js.map +1 -1
  79. package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +18 -17
  80. package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
  81. package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +39 -39
  82. package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
  83. package/dist/mcp-server/server.d.ts +20 -21
  84. package/dist/mcp-server/server.d.ts.map +1 -1
  85. package/dist/mcp-server/server.js +42 -28
  86. package/dist/mcp-server/server.js.map +1 -1
  87. package/dist/mcp-server/tools/tool-registration.d.ts +11 -33
  88. package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
  89. package/dist/mcp-server/tools/tool-registration.js +18 -243
  90. package/dist/mcp-server/tools/tool-registration.js.map +1 -1
  91. package/dist/mcp-server/tools/utils/schemaShape.d.ts +27 -0
  92. package/dist/mcp-server/tools/utils/schemaShape.d.ts.map +1 -0
  93. package/dist/mcp-server/tools/utils/schemaShape.js +43 -0
  94. package/dist/mcp-server/tools/utils/schemaShape.js.map +1 -0
  95. package/dist/mcp-server/tools/utils/toolDefinition.d.ts +28 -8
  96. package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
  97. package/dist/mcp-server/tools/utils/toolDefinition.js +63 -1
  98. package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
  99. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +54 -20
  100. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
  101. package/dist/mcp-server/tools/utils/toolHandlerFactory.js +156 -44
  102. package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
  103. package/dist/mcp-server/transports/ITransport.d.ts +2 -2
  104. package/dist/mcp-server/transports/ITransport.d.ts.map +1 -1
  105. package/dist/mcp-server/transports/auth/authFactory.js +1 -1
  106. package/dist/mcp-server/transports/auth/authFactory.js.map +1 -1
  107. package/dist/mcp-server/transports/auth/lib/authTypes.d.ts +1 -1
  108. package/dist/mcp-server/transports/auth/lib/authTypes.d.ts.map +1 -1
  109. package/dist/mcp-server/transports/auth/lib/authUtils.d.ts.map +1 -1
  110. package/dist/mcp-server/transports/auth/lib/authUtils.js +5 -13
  111. package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -1
  112. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +5 -11
  113. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -1
  114. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -1
  115. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +9 -22
  116. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
  117. package/dist/mcp-server/transports/heartbeat.d.ts.map +1 -1
  118. package/dist/mcp-server/transports/heartbeat.js +4 -8
  119. package/dist/mcp-server/transports/heartbeat.js.map +1 -1
  120. package/dist/mcp-server/transports/http/eventStore.d.ts +57 -0
  121. package/dist/mcp-server/transports/http/eventStore.d.ts.map +1 -0
  122. package/dist/mcp-server/transports/http/eventStore.js +114 -0
  123. package/dist/mcp-server/transports/http/eventStore.js.map +1 -0
  124. package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
  125. package/dist/mcp-server/transports/http/httpErrorHandler.js +6 -24
  126. package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
  127. package/dist/mcp-server/transports/http/httpServer.d.ts +4 -3
  128. package/dist/mcp-server/transports/http/httpServer.d.ts.map +1 -1
  129. package/dist/mcp-server/transports/http/httpServer.js +16 -33
  130. package/dist/mcp-server/transports/http/httpServer.js.map +1 -1
  131. package/dist/mcp-server/transports/http/httpTransport.d.ts +30 -8
  132. package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
  133. package/dist/mcp-server/transports/http/httpTransport.js +180 -374
  134. package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
  135. package/dist/mcp-server/transports/http/landing-page/assets/styles.d.ts.map +1 -1
  136. package/dist/mcp-server/transports/http/landing-page/assets/styles.js +0 -1
  137. package/dist/mcp-server/transports/http/landing-page/assets/styles.js.map +1 -1
  138. package/dist/mcp-server/transports/http/landing-page/handler.d.ts.map +1 -1
  139. package/dist/mcp-server/transports/http/landing-page/handler.js +4 -8
  140. package/dist/mcp-server/transports/http/landing-page/handler.js.map +1 -1
  141. package/dist/mcp-server/transports/http/landing-page/sections/tools.js +22 -4
  142. package/dist/mcp-server/transports/http/landing-page/sections/tools.js.map +1 -1
  143. package/dist/mcp-server/transports/http/protectedResourceMetadata.d.ts.map +1 -1
  144. package/dist/mcp-server/transports/http/protectedResourceMetadata.js +2 -6
  145. package/dist/mcp-server/transports/http/protectedResourceMetadata.js.map +1 -1
  146. package/dist/mcp-server/transports/http/robotsTxt.js +2 -2
  147. package/dist/mcp-server/transports/http/robotsTxt.js.map +1 -1
  148. package/dist/mcp-server/transports/http/serverCard.d.ts.map +1 -1
  149. package/dist/mcp-server/transports/http/serverCard.js +2 -6
  150. package/dist/mcp-server/transports/http/serverCard.js.map +1 -1
  151. package/dist/mcp-server/transports/http/sessionStore.d.ts +46 -66
  152. package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -1
  153. package/dist/mcp-server/transports/http/sessionStore.js +140 -238
  154. package/dist/mcp-server/transports/http/sessionStore.js.map +1 -1
  155. package/dist/mcp-server/transports/manager.d.ts +21 -4
  156. package/dist/mcp-server/transports/manager.d.ts.map +1 -1
  157. package/dist/mcp-server/transports/manager.js +40 -34
  158. package/dist/mcp-server/transports/manager.js.map +1 -1
  159. package/dist/mcp-server/transports/stdio/stdioTransport.d.ts +24 -31
  160. package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -1
  161. package/dist/mcp-server/transports/stdio/stdioTransport.js +23 -38
  162. package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -1
  163. package/dist/mcp-server/types.d.ts +25 -0
  164. package/dist/mcp-server/types.d.ts.map +1 -0
  165. package/dist/mcp-server/types.js +10 -0
  166. package/dist/mcp-server/types.js.map +1 -0
  167. package/dist/services/canvas/core/CanvasInstance.d.ts +2 -2
  168. package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
  169. package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
  170. package/dist/services/canvas/core/CanvasRegistry.d.ts +4 -4
  171. package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
  172. package/dist/services/canvas/core/CanvasRegistry.js +8 -18
  173. package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
  174. package/dist/services/canvas/core/DataCanvas.d.ts +5 -5
  175. package/dist/services/canvas/core/DataCanvas.d.ts.map +1 -1
  176. package/dist/services/canvas/core/DataCanvas.js +2 -3
  177. package/dist/services/canvas/core/DataCanvas.js.map +1 -1
  178. package/dist/services/canvas/core/IDataCanvasProvider.d.ts +11 -11
  179. package/dist/services/canvas/core/IDataCanvasProvider.d.ts.map +1 -1
  180. package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +11 -11
  181. package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
  182. package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +4 -10
  183. package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
  184. package/dist/services/llm/providers/openrouter.provider.d.ts.map +1 -1
  185. package/dist/services/llm/providers/openrouter.provider.js +2 -5
  186. package/dist/services/llm/providers/openrouter.provider.js.map +1 -1
  187. package/dist/services/mirror/core/defineMirror.js +1 -1
  188. package/dist/services/mirror/core/defineMirror.js.map +1 -1
  189. package/dist/services/mirror/types.d.ts +5 -5
  190. package/dist/services/mirror/types.d.ts.map +1 -1
  191. package/dist/services/speech/providers/elevenlabs.provider.js +1 -1
  192. package/dist/services/speech/providers/elevenlabs.provider.js.map +1 -1
  193. package/dist/services/speech/providers/whisper.provider.js +1 -1
  194. package/dist/services/speech/providers/whisper.provider.js.map +1 -1
  195. package/dist/storage/core/StorageService.d.ts +1 -1
  196. package/dist/storage/core/StorageService.d.ts.map +1 -1
  197. package/dist/storage/core/StorageService.js +12 -20
  198. package/dist/storage/core/StorageService.js.map +1 -1
  199. package/dist/storage/core/storageFactory.d.ts.map +1 -1
  200. package/dist/storage/core/storageFactory.js.map +1 -1
  201. package/dist/storage/core/storageValidation.d.ts +1 -1
  202. package/dist/storage/core/storageValidation.d.ts.map +1 -1
  203. package/dist/storage/core/storageValidation.js +2 -2
  204. package/dist/storage/core/storageValidation.js.map +1 -1
  205. package/dist/storage/providers/cloudflare/d1Provider.d.ts +1 -1
  206. package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -1
  207. package/dist/storage/providers/cloudflare/d1Provider.js +4 -12
  208. package/dist/storage/providers/cloudflare/d1Provider.js.map +1 -1
  209. package/dist/storage/providers/cloudflare/kvProvider.d.ts +1 -1
  210. package/dist/storage/providers/cloudflare/kvProvider.d.ts.map +1 -1
  211. package/dist/storage/providers/cloudflare/kvProvider.js +3 -8
  212. package/dist/storage/providers/cloudflare/kvProvider.js.map +1 -1
  213. package/dist/storage/providers/cloudflare/r2Provider.d.ts +1 -1
  214. package/dist/storage/providers/cloudflare/r2Provider.d.ts.map +1 -1
  215. package/dist/storage/providers/cloudflare/r2Provider.js +3 -8
  216. package/dist/storage/providers/cloudflare/r2Provider.js.map +1 -1
  217. package/dist/storage/providers/inMemory/inMemoryProvider.d.ts +1 -1
  218. package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -1
  219. package/dist/storage/providers/inMemory/inMemoryProvider.js +2 -4
  220. package/dist/storage/providers/inMemory/inMemoryProvider.js.map +1 -1
  221. package/dist/testing/fuzz.d.ts +7 -4
  222. package/dist/testing/fuzz.d.ts.map +1 -1
  223. package/dist/testing/fuzz.js +13 -5
  224. package/dist/testing/fuzz.js.map +1 -1
  225. package/dist/testing/index.d.ts +35 -12
  226. package/dist/testing/index.d.ts.map +1 -1
  227. package/dist/testing/index.js +53 -38
  228. package/dist/testing/index.js.map +1 -1
  229. package/dist/testing/vitest.d.ts +1 -1
  230. package/dist/testing/vitest.d.ts.map +1 -1
  231. package/dist/types-global/errors.d.ts +28 -15
  232. package/dist/types-global/errors.d.ts.map +1 -1
  233. package/dist/types-global/errors.js +8 -1
  234. package/dist/types-global/errors.js.map +1 -1
  235. package/dist/utils/formatting/diffFormatter.d.ts +5 -5
  236. package/dist/utils/formatting/diffFormatter.d.ts.map +1 -1
  237. package/dist/utils/formatting/diffFormatter.js +7 -20
  238. package/dist/utils/formatting/diffFormatter.js.map +1 -1
  239. package/dist/utils/formatting/tableFormatter.d.ts +3 -3
  240. package/dist/utils/formatting/tableFormatter.d.ts.map +1 -1
  241. package/dist/utils/formatting/tableFormatter.js +6 -17
  242. package/dist/utils/formatting/tableFormatter.js.map +1 -1
  243. package/dist/utils/formatting/treeFormatter.d.ts +3 -3
  244. package/dist/utils/formatting/treeFormatter.d.ts.map +1 -1
  245. package/dist/utils/formatting/treeFormatter.js +5 -18
  246. package/dist/utils/formatting/treeFormatter.js.map +1 -1
  247. package/dist/utils/index.d.ts +4 -2
  248. package/dist/utils/index.d.ts.map +1 -1
  249. package/dist/utils/index.js +2 -2
  250. package/dist/utils/index.js.map +1 -1
  251. package/dist/utils/internal/error-handler/errorHandler.d.ts +1 -1
  252. package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
  253. package/dist/utils/internal/error-handler/errorHandler.js +23 -11
  254. package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
  255. package/dist/utils/internal/error-handler/types.d.ts +10 -13
  256. package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
  257. package/dist/utils/internal/logger.d.ts +3 -3
  258. package/dist/utils/internal/logger.d.ts.map +1 -1
  259. package/dist/utils/internal/logger.js +11 -5
  260. package/dist/utils/internal/logger.js.map +1 -1
  261. package/dist/utils/internal/performance.d.ts +13 -5
  262. package/dist/utils/internal/performance.d.ts.map +1 -1
  263. package/dist/utils/internal/performance.js +76 -17
  264. package/dist/utils/internal/performance.js.map +1 -1
  265. package/dist/utils/internal/requestContext.d.ts +92 -55
  266. package/dist/utils/internal/requestContext.d.ts.map +1 -1
  267. package/dist/utils/internal/requestContext.js +120 -40
  268. package/dist/utils/internal/requestContext.js.map +1 -1
  269. package/dist/utils/metrics/tokenCounter.d.ts +3 -3
  270. package/dist/utils/metrics/tokenCounter.d.ts.map +1 -1
  271. package/dist/utils/metrics/tokenCounter.js.map +1 -1
  272. package/dist/utils/network/fetchWithTimeout.d.ts +2 -2
  273. package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
  274. package/dist/utils/network/fetchWithTimeout.js +8 -24
  275. package/dist/utils/network/fetchWithTimeout.js.map +1 -1
  276. package/dist/utils/network/retry.d.ts +2 -2
  277. package/dist/utils/network/retry.d.ts.map +1 -1
  278. package/dist/utils/overflow/outlineOnOverflow.d.ts +1 -1
  279. package/dist/utils/overflow/outlineOnOverflow.d.ts.map +1 -1
  280. package/dist/utils/pagination/pagination.d.ts +3 -3
  281. package/dist/utils/pagination/pagination.d.ts.map +1 -1
  282. package/dist/utils/pagination/pagination.js +3 -3
  283. package/dist/utils/pagination/pagination.js.map +1 -1
  284. package/dist/utils/parsing/csvParser.d.ts +2 -2
  285. package/dist/utils/parsing/csvParser.d.ts.map +1 -1
  286. package/dist/utils/parsing/csvParser.js +4 -8
  287. package/dist/utils/parsing/csvParser.js.map +1 -1
  288. package/dist/utils/parsing/dateParser.d.ts +3 -3
  289. package/dist/utils/parsing/dateParser.d.ts.map +1 -1
  290. package/dist/utils/parsing/dateParser.js +3 -2
  291. package/dist/utils/parsing/dateParser.js.map +1 -1
  292. package/dist/utils/parsing/frontmatterParser.d.ts +2 -2
  293. package/dist/utils/parsing/frontmatterParser.d.ts.map +1 -1
  294. package/dist/utils/parsing/frontmatterParser.js +7 -10
  295. package/dist/utils/parsing/frontmatterParser.js.map +1 -1
  296. package/dist/utils/parsing/htmlExtractor.d.ts +2 -2
  297. package/dist/utils/parsing/htmlExtractor.d.ts.map +1 -1
  298. package/dist/utils/parsing/htmlExtractor.js +6 -11
  299. package/dist/utils/parsing/htmlExtractor.js.map +1 -1
  300. package/dist/utils/parsing/jsonParser.d.ts +2 -2
  301. package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
  302. package/dist/utils/parsing/jsonParser.js +4 -8
  303. package/dist/utils/parsing/jsonParser.js.map +1 -1
  304. package/dist/utils/parsing/pdfParser.d.ts +10 -10
  305. package/dist/utils/parsing/pdfParser.d.ts.map +1 -1
  306. package/dist/utils/parsing/pdfParser.js +26 -89
  307. package/dist/utils/parsing/pdfParser.js.map +1 -1
  308. package/dist/utils/parsing/xmlParser.d.ts +2 -2
  309. package/dist/utils/parsing/xmlParser.d.ts.map +1 -1
  310. package/dist/utils/parsing/xmlParser.js +4 -8
  311. package/dist/utils/parsing/xmlParser.js.map +1 -1
  312. package/dist/utils/parsing/yamlParser.d.ts +2 -2
  313. package/dist/utils/parsing/yamlParser.d.ts.map +1 -1
  314. package/dist/utils/parsing/yamlParser.js +4 -8
  315. package/dist/utils/parsing/yamlParser.js.map +1 -1
  316. package/dist/utils/scheduling/scheduler.d.ts.map +1 -1
  317. package/dist/utils/scheduling/scheduler.js +5 -6
  318. package/dist/utils/scheduling/scheduler.js.map +1 -1
  319. package/dist/utils/security/rateLimiter.d.ts +2 -2
  320. package/dist/utils/security/rateLimiter.d.ts.map +1 -1
  321. package/dist/utils/security/rateLimiter.js +1 -1
  322. package/dist/utils/security/rateLimiter.js.map +1 -1
  323. package/dist/utils/telemetry/attributes.d.ts +23 -7
  324. package/dist/utils/telemetry/attributes.d.ts.map +1 -1
  325. package/dist/utils/telemetry/attributes.js +23 -10
  326. package/dist/utils/telemetry/attributes.js.map +1 -1
  327. package/dist/utils/telemetry/trace.d.ts +3 -3
  328. package/dist/utils/telemetry/trace.d.ts.map +1 -1
  329. package/dist/utils/telemetry/trace.js +4 -2
  330. package/dist/utils/telemetry/trace.js.map +1 -1
  331. package/package.json +22 -26
  332. package/scripts/lint-mcp.ts +1 -3
  333. package/scripts/lint-packaging.ts +1 -1
  334. package/skills/add-service/SKILL.md +2 -2
  335. package/skills/add-test/SKILL.md +42 -20
  336. package/skills/add-tool/SKILL.md +103 -19
  337. package/skills/api-config/SKILL.md +4 -11
  338. package/skills/api-context/SKILL.md +216 -120
  339. package/skills/api-linter/SKILL.md +16 -3
  340. package/skills/api-telemetry/SKILL.md +10 -12
  341. package/skills/api-testing/SKILL.md +53 -52
  342. package/skills/api-workers/SKILL.md +9 -1
  343. package/skills/code-simplifier/SKILL.md +2 -2
  344. package/skills/design-mcp-server/SKILL.md +31 -17
  345. package/skills/field-test/SKILL.md +4 -2
  346. package/skills/polish-docs-meta/SKILL.md +1 -1
  347. package/skills/polish-docs-meta/references/agent-protocol.md +2 -2
  348. package/skills/polish-docs-meta/references/readme.md +1 -1
  349. package/skills/release-and-publish/SKILL.md +3 -1
  350. package/skills/report-issue-framework/SKILL.md +2 -2
  351. package/skills/report-issue-local/SKILL.md +2 -2
  352. package/skills/security-pass/SKILL.md +16 -14
  353. package/skills/tool-defs-analysis/SKILL.md +15 -5
  354. package/templates/.env.example +4 -0
  355. package/templates/AGENTS.md +6 -6
  356. package/templates/CLAUDE.md +6 -6
  357. package/templates/tests/resources/echo.resource.test.ts +16 -9
  358. package/dist/mcp-server/elicitation.d.ts +0 -64
  359. package/dist/mcp-server/elicitation.d.ts.map +0 -1
  360. package/dist/mcp-server/elicitation.js +0 -81
  361. package/dist/mcp-server/elicitation.js.map +0 -1
  362. package/dist/mcp-server/protocolSession.d.ts +0 -34
  363. package/dist/mcp-server/protocolSession.d.ts.map +0 -1
  364. package/dist/mcp-server/protocolSession.js +0 -13
  365. package/dist/mcp-server/protocolSession.js.map +0 -1
  366. package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.d.ts +0 -53
  367. package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.d.ts.map +0 -1
  368. package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.js +0 -65
  369. package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.js.map +0 -1
  370. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts +0 -70
  371. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts.map +0 -1
  372. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js +0 -130
  373. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js.map +0 -1
  374. package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts +0 -109
  375. package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts.map +0 -1
  376. package/dist/mcp-server/tasks/core/storageBackedTaskStore.js +0 -209
  377. package/dist/mcp-server/tasks/core/storageBackedTaskStore.js.map +0 -1
  378. package/dist/mcp-server/tasks/core/taskManager.d.ts +0 -91
  379. package/dist/mcp-server/tasks/core/taskManager.d.ts.map +0 -1
  380. package/dist/mcp-server/tasks/core/taskManager.js +0 -210
  381. package/dist/mcp-server/tasks/core/taskManager.js.map +0 -1
  382. package/dist/mcp-server/tasks/core/taskTypes.d.ts +0 -18
  383. package/dist/mcp-server/tasks/core/taskTypes.d.ts.map +0 -1
  384. package/dist/mcp-server/tasks/core/taskTypes.js +0 -20
  385. package/dist/mcp-server/tasks/core/taskTypes.js.map +0 -1
  386. package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts +0 -101
  387. package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts.map +0 -1
  388. package/dist/mcp-server/tasks/utils/taskToolDefinition.js +0 -14
  389. package/dist/mcp-server/tasks/utils/taskToolDefinition.js.map +0 -1
@@ -4,7 +4,7 @@ description: >
4
4
  Testing patterns for MCP tool/resource handlers using `createMockContext` and Vitest. Covers mock context options, handler testing, McpError assertions, format testing, Vitest config setup, and test isolation conventions.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.8"
7
+ version: "1.9"
8
8
  audience: external
9
9
  type: reference
10
10
  ---
@@ -134,8 +134,8 @@ import { createMockContext } from '@cyanheads/mcp-ts-core/testing';
134
134
  createMockContext() // working ctx.state on tenant 'default'
135
135
  createMockContext({ tenantId: 'test-tenant' }) // explicit tenant scope for ctx.state
136
136
  createMockContext({ errors: myTool.errors }) // attaches typed ctx.fail keyed by the contract reasons
137
- createMockContext({ elicit: vi.fn().mockResolvedValue(...) }) // with elicitation
138
- createMockContext({ progress: true }) // with task progress (ctx.progress populated)
137
+ createMockContext({ inputResponses: { confirm: { action: 'accept', content: { ok: true } } } }) // second round of a multi-round-trip handler
138
+ createMockContext({ requestState: 'opaque-state' }) // seeds ctx.inputs.state()
139
139
  createMockContext({ requestId: 'my-id' }) // override request ID (default: 'test-request-id')
140
140
  createMockContext({ notifyResourceListChanged: () => {} }) // with resource-list change notifier
141
141
  createMockContext({ notifyResourceUpdated: (_uri) => {} }) // with resource update notifier
@@ -149,15 +149,15 @@ createMockContext({ uri: new URL('myscheme://item/123') }) // for resource han
149
149
  ```ts
150
150
  interface MockContextOptions<TErrors extends readonly ErrorContract[] | undefined> {
151
151
  auth?: AuthContext;
152
- elicit?: (message: string, schema: z.ZodObject<z.ZodRawShape>) => Promise<ElicitResult>;
153
152
  errors?: TErrors | undefined;
153
+ inputResponses?: InputResponses | Record<string, unknown>;
154
154
  notifyPromptListChanged?: () => void;
155
155
  notifyResourceListChanged?: () => void;
156
156
  notifyResourceUpdated?: (uri: string) => void;
157
157
  notifyToolListChanged?: () => void;
158
- progress?: boolean;
159
- sessionId?: string;
160
158
  requestId?: string;
159
+ requestState?: unknown;
160
+ sessionId?: string;
161
161
  signal?: AbortSignal;
162
162
  tenantId?: string;
163
163
  uri?: URL;
@@ -166,17 +166,17 @@ interface MockContextOptions<TErrors extends readonly ErrorContract[] | undefine
166
166
 
167
167
  | Option | Effect |
168
168
  |:-------|:-------|
169
- | _(none)_ | Working `ctx.state` on tenant `'default'`; `ctx.elicit`/`ctx.progress` are `undefined` |
169
+ | _(none)_ | Working `ctx.state` on tenant `'default'`; `ctx.inputs` is empty (first round) |
170
170
  | `auth` | Sets `ctx.auth` for scope-checking tests |
171
- | `elicit` | Assigns a function to `ctx.elicit` for testing elicitation calls |
172
171
  | `errors` | Attaches a typed `ctx.fail` against the contract — same wiring the production handler factory uses. Pass `myTool.errors` directly; the return type narrows to `HandlerContext<ReasonOf<…>>`, so the context is assignable to that definition's handler parameter. |
172
+ | `inputResponses` | Seeds `ctx.inputs` with the responses a retried request would carry, keyed by the identifiers the handler's `ctx.requestInput(...)` assigned (see below) |
173
173
  | `notifyPromptListChanged` | Assigns `ctx.notifyPromptListChanged` for prompt-list change notification tests |
174
174
  | `notifyResourceListChanged` | Assigns `ctx.notifyResourceListChanged` for resource notification tests |
175
175
  | `notifyResourceUpdated` | Assigns `ctx.notifyResourceUpdated` for resource update notification tests |
176
176
  | `notifyToolListChanged` | Assigns `ctx.notifyToolListChanged` for tool-list change notification tests |
177
- | `sessionId` | Sets `ctx.sessionId` for handlers that branch on session ID |
178
- | `progress` | Populates `ctx.progress` with real state-tracking implementation (see below) |
179
177
  | `requestId` | Overrides `ctx.requestId` (default: `'test-request-id'`) |
178
+ | `requestState` | Seeds `ctx.inputs.state()` — the opaque state a prior round attached |
179
+ | `sessionId` | Sets `ctx.sessionId` for handlers that branch on session ID |
180
180
  | `signal` | Overrides `ctx.signal` — useful for cancellation testing |
181
181
  | `tenantId` | Scopes `ctx.state` to a specific tenant. Defaults to `'default'` — the value stdio (and HTTP with `MCP_AUTH_MODE=none`) resolves |
182
182
  | `uri` | Sets `ctx.uri` for resource handler testing |
@@ -200,28 +200,54 @@ await expect(ctx.state.set('cache:v1:abc', {})).rejects.toThrow(McpError);
200
200
 
201
201
  Reach for `createInMemoryStorage()` when a service takes a `StorageService` directly — it builds the same pair.
202
202
 
203
- ### Mock progress
203
+ ### Mock inputs
204
204
 
205
- When `progress: true`, `ctx.progress` is a real state-tracking object — not `vi.fn()` spies. It maintains internal state accessible via inspection properties:
205
+ `ctx.requestInput` is the real implementation: it throws an `InputRequiredSignal` the production handler factories convert into an `input_required` result. In a unit test the handler is called directly, so that signal surfaces as a thrown value — which is exactly how you assert the first round.
206
206
 
207
207
  ```ts
208
- const ctx = createMockContext({ progress: true });
209
- // ctx.progress is typed as ContextProgress, but the mock exposes internal state:
210
- const progress = ctx.progress as ContextProgress & {
211
- _total: number;
212
- _completed: number;
213
- _messages: string[];
214
- };
215
-
216
- await ctx.progress!.setTotal(10);
217
- await ctx.progress!.increment(3);
218
- await ctx.progress!.update('step message');
219
-
220
- expect(progress._total).toBe(10);
221
- expect(progress._completed).toBe(3);
222
- expect(progress._messages).toContain('step message');
208
+ import { isInputRequiredSignal } from '@cyanheads/mcp-ts-core';
209
+
210
+ it('asks for confirmation on the first round', async () => {
211
+ const ctx = createMockContext();
212
+ await expect(myTool.handler(myTool.input.parse({ path: '/tmp/x' }), ctx))
213
+ .rejects.toSatisfy(isInputRequiredSignal);
214
+ });
223
215
  ```
224
216
 
217
+ To assert on *what* was requested, catch it and read `error.result` — the `input_required` result the handler factory would have returned:
218
+
219
+ ```ts
220
+ async function requestedInput(input: ToolInput, options: MockContextOptions = {}) {
221
+ try {
222
+ await myTool.handler(input, createMockContext(options));
223
+ } catch (error) {
224
+ if (isInputRequiredSignal(error)) return error.result;
225
+ throw error;
226
+ }
227
+ throw new Error('Expected the handler to request input.');
228
+ }
229
+ ```
230
+
231
+ `inputResponses` drives the second round. `ctx.inputs.accepted(key, schema)` and `.view(key)` read it with the same helpers production uses, so a wrong response shape fails in the test:
232
+
233
+ ```ts
234
+ it('proceeds once the user accepts', async () => {
235
+ const ctx = createMockContext({
236
+ inputResponses: { confirm: { action: 'accept', content: { confirm: true } } },
237
+ });
238
+ await expect(myTool.handler(input, ctx)).resolves.toMatchObject({ deleted: '/tmp/x' });
239
+ });
240
+
241
+ it('stops when the user declines', async () => {
242
+ const ctx = createMockContext({
243
+ inputResponses: { confirm: { action: 'decline' } },
244
+ });
245
+ await expect(myTool.handler(input, ctx)).rejects.toThrow(McpError);
246
+ });
247
+ ```
248
+
249
+ `ctx.inputs.dropped` is always `[]` on a mock context — the drop only happens in the SDK's wire decoding, so cover it in an integration test rather than a unit one.
250
+
225
251
  ### Mock logger
226
252
 
227
253
  `ctx.log` captures all log calls for inspection. Import `MockContextLogger` from `@cyanheads/mcp-ts-core/testing` and cast `ctx.log` to access the `.calls` array (the cast is necessary because `createMockContext` returns `Context`, which types `log` as `ContextLogger`):
@@ -273,31 +299,6 @@ Parse input through `myTool.input.parse(...)` to validate against the Zod schema
273
299
 
274
300
  ---
275
301
 
276
- ## Testing with optional capabilities
277
-
278
- ```ts
279
- it('uses elicitation when available', async () => {
280
- const elicit = vi.fn().mockResolvedValue({
281
- action: 'accept',
282
- content: { format: 'json' },
283
- });
284
- const ctx = createMockContext({ elicit });
285
- const input = myTool.input.parse({ query: 'hello' });
286
- await myTool.handler(input, ctx);
287
- expect(elicit).toHaveBeenCalledOnce();
288
- });
289
-
290
- it('handles missing elicitation gracefully', async () => {
291
- // ctx.elicit is undefined — handler must check before calling
292
- const ctx = createMockContext();
293
- const input = myTool.input.parse({ query: 'hello' });
294
- // Should not throw even when ctx.elicit is absent
295
- await expect(myTool.handler(input, ctx)).resolves.toBeDefined();
296
- });
297
- ```
298
-
299
- ---
300
-
301
302
  ## Testing with form-based client payloads
302
303
 
303
304
  LLM clients only send populated fields. **Form-based clients** (MCP Inspector, web UIs) submit the full schema shape — optional object fields arrive with empty-string inner values instead of `undefined`. Both are valid MCP usage. Test that handlers handle both gracefully.
@@ -4,7 +4,7 @@ description: >
4
4
  Cloudflare Workers deployment using `createWorkerHandler` from `@cyanheads/mcp-ts-core/worker`. Covers the full handler signature, binding types, CloudflareBindings extensibility, runtime compatibility guards, and wrangler.toml requirements.
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
  ---
@@ -212,6 +212,14 @@ export function getServerConfig() {
212
212
 
213
213
  Leave the env unset (or set to `none`) for Worker deployments. Tools that conditionally use canvas should check the module-level accessor (`if (!getCanvas()) { ... }`) and surface a clear "feature unavailable on this deployment" message. See `api-canvas` for the full DataCanvas reference and setup wiring pattern.
214
214
 
215
+ **The default notification bus is per-isolate.** `core.notify` and the modern era's `subscriptions/listen` streams share a change-event bus that defaults to in-process — which on Workers means one bus per isolate, so a background emission reaches only the listeners that happen to live in the isolate that produced it. Handler-time `ctx.notify*` is unaffected (the listen stream and the handler are the same request). For fan-out that must cross isolates, supply a bus of your own, backed by a Durable Object or another shared channel:
216
+
217
+ ```ts
218
+ createWorkerHandler({ tools, eventBus: myDurableObjectBackedBus });
219
+ ```
220
+
221
+ The interface is the SDK's `ServerEventBus` — `publish(event)` and `subscribe(listener)`. See `api-context`'s notification section for what publishes onto it.
222
+
215
223
  ---
216
224
 
217
225
  ## Testing Workers with miniflare
@@ -4,7 +4,7 @@ description: >
4
4
  Post-session code review and cleanup against a working tree of changes. Analyzes `git diff` to simplify, consolidate, and align changed code with the existing codebase — modernize syntax, remove unnecessary complexity, consolidate duplicated logic, catch efficiency issues. Use after a substantive working session, or when asked to clean up, simplify, reduce slop, consolidate, modernize, tighten up, or de-slop code. For `@cyanheads/mcp-ts-core` projects, includes specific transformations for tool/resource/prompt definitions, the ctx pattern, error factories, and framework idioms.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.2"
7
+ version: "1.3"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -62,7 +62,7 @@ Evaluate the changes across these dimensions. Not every dimension applies to eve
62
62
 
63
63
  - **Error throwing patterns** — Prefer framework error factories (`McpError`, `validationError`, `notFound`, `httpErrorFromResponse`) over raw `throw new Error()`. Tool handlers should throw — the framework catches, classifies, and instruments.
64
64
  - **Error codes** — `InvalidParams` only for malformed JSON-RPC params shape. `ValidationError` for domain validation. `NotFound` for missing entities. Don't conflate them.
65
- - **Ctx usage** — Use `ctx.log`, `ctx.state`, `ctx.elicit` — don't reach for global loggers or request-scoped storage directly. The `ctx` pattern carries tenant scope and OTel context.
65
+ - **Ctx usage** — Use `ctx.log`, `ctx.state`, `ctx.enrich` — don't reach for global loggers or request-scoped storage directly. The `ctx` pattern carries tenant scope and OTel context.
66
66
  - **Zod schemas** — Every tool input/output field needs `.describe()`. Zod 4 requires `z.record(z.string(), z.string())` not `z.record(z.string())`. Use `.optional()` rather than `.nullish()` unless null is semantically distinct from absent.
67
67
  - **Tool annotations** — `readOnlyHint`, `idempotentHint`, `openWorldHint` should reflect reality. A read-only tool with `readOnlyHint: false` gives clients the wrong picture.
68
68
  - **`exactOptionalPropertyTypes` boundaries** — If a downstream type insists on the field being present-or-not-present (not present-as-undefined), use a mapped widening type at the boundary. The pattern is documented in the framework.
@@ -4,7 +4,7 @@ description: >
4
4
  Design the tool surface, resources, and service layer for a new MCP server. Use when starting a new server, planning a major feature expansion, or when the user describes a domain/API they want to expose via MCP. Produces a design doc at docs/design.md that drives implementation.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "2.21"
7
+ version: "2.22"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -141,7 +141,7 @@ Most tools follow the `{server}_{verb}_{noun}` default — one focused responsib
141
141
 
142
142
  | Shape | Purpose | Typical form | Examples |
143
143
  |:------|:--------|:-------------|:---------|
144
- | **Workflow** | Multi-step orchestration that replaces a common agent chain | N upstream calls (often parallelized); may elicit confirmation; may need mid-flow cleanup | `clinicaltrials_find_studies` (search → filter → rank) |
144
+ | **Workflow** | Multi-step orchestration that replaces a common agent chain | N upstream calls (often parallelized); may request confirmation; may need mid-flow cleanup | `clinicaltrials_find_studies` (search → filter → rank) |
145
145
  | **Instruction** | State-aware procedural guidance — advice, not action | Static markdown + a few live-state fetches, `readOnlyHint: true`, outputs `nextToolSuggestions` pre-filling the recommended follow-up. No writes. | `git_wrapup_instructions` |
146
146
  | **Reference** | Decode opaque domain vocabulary — codes, enums, identifier formats, coverage windows — so agents can build valid inputs for the rest of the surface | Static tables or one cached fetch (often zero upstream calls); consolidate N lists under one `topic` enum; `readOnlyHint: true`, `openWorldHint: false` when offline | `medcode_list_systems`, `osv_list_ecosystems` |
147
147
 
@@ -269,20 +269,34 @@ A reference tool is the surface's decoder ring: which codes exist, what they mea
269
269
 
270
270
  Tools that perform multi-step mutations (the Workflow shape) have two safety considerations beyond single-call tools. Both are about giving the agent — and the human behind it — a chance to catch a bad invocation before it commits.
271
271
 
272
- **Elicit-guarded destructive modes with annotation fallback.** When a workflow's `mode` parameter switches between safe and destructive arms (`draft` vs `send`, `plan` vs `apply`), gate the destructive arm behind `ctx.elicit` when the client supports it, so a human confirms before the irreversible step fires. Elicitation isn't universally available — headless stdio sessions and many non-interactive clients don't expose it. Fall back on `destructiveHint: true` in annotations so those clients' approval flows still surface the risk. Document the fallback in the handler so maintainers don't assume elicit always runs:
272
+ **Confirmation-gated destructive modes, with an annotation fallback.** When a workflow's `mode` parameter switches between safe and destructive arms (`draft` vs `send`, `plan` vs `apply`), gate the destructive arm on a confirmation the handler asks for via `ctx.requestInput(...)`, so a human approves before the irreversible step fires. The handler is re-entered with the answer on `ctx.inputs`; it does not `await` mid-call.
273
+
274
+ The gate is always *reachable* — `ctx.requestInput` is present on every transport and both protocol eras — but it is not always *answerable*: a client that never fulfils the `input_required` result simply doesn't retry, and the destructive step never runs. Keep `destructiveHint: true` in annotations so those clients' own approval flows still surface the risk.
273
275
 
274
276
  ```ts
275
- annotations: { destructiveHint: true }, // fallback for clients without elicit
277
+ annotations: { destructiveHint: true }, // client-side approval flows still see the risk
276
278
  // ...
277
- async handler(input, ctx) {
278
- if (input.mode === 'apply' && ctx.elicit) {
279
- const confirm = await ctx.elicit(
280
- `Apply migration affecting ${affectedRowCount} rows in production? Cannot be rolled back automatically.`,
281
- z.object({ confirmed: z.literal(true).describe('Type true to apply.') }),
282
- );
283
- if (confirm.action !== 'accept') throw new Error('Migration cancelled by user.');
279
+ const Confirm = z.object({ confirmed: z.literal(true).describe('Type true to apply.') });
280
+
281
+ handler(input, ctx) {
282
+ if (input.mode === 'apply') {
283
+ // A decline is terminal — re-asking would loop until the round budget runs out.
284
+ const view = ctx.inputs.view('confirm');
285
+ if (view.kind === 'elicit' && view.action !== 'accept') {
286
+ throw validationError('Migration cancelled by user.');
287
+ }
288
+ if (!ctx.inputs.accepted('confirm', Confirm)) {
289
+ return ctx.requestInput({
290
+ inputRequests: {
291
+ confirm: inputRequired.elicit({
292
+ message: `Apply migration affecting ${affectedRowCount} rows in production? Cannot be rolled back automatically.`,
293
+ requestedSchema: Confirm,
294
+ }),
295
+ },
296
+ });
297
+ }
284
298
  }
285
- // destructive step proceeds; destructiveHint covers clients that skipped elicit
299
+ // destructive step proceeds
286
300
  }
287
301
  ```
288
302
 
@@ -622,13 +636,13 @@ Each step is independently testable.
622
636
 
623
637
  Keep it concise. The design doc is a working reference, not a spec document — enough to orient a developer (or agent) implementing the server, not more.
624
638
 
625
- **Workflow Analysis example.** For multi-step workflow tools, document the upstream call sequence in a table — it drives several downstream decisions during implementation: the service-layer method shape, retry boundaries, where cleanup or elicit belongs, and what post-action state to fetch for the response.
639
+ **Workflow Analysis example.** For multi-step workflow tools, document the upstream call sequence in a table — it drives several downstream decisions during implementation: the service-layer method shape, retry boundaries, where cleanup or the confirmation round belongs, and what post-action state to fetch for the response.
626
640
 
627
- `deploy_release` (5–8 upstream calls, plus elicit):
641
+ `deploy_release` (5–8 upstream calls, plus a confirmation round):
628
642
 
629
643
  | # | Call | Purpose | Mode gate |
630
644
  |:--|:-----|:--------|:----------|
631
- | 0 | `ctx.elicit` confirmation | Human approval before promote | `promote` (when available) |
645
+ | 0 | `ctx.requestInput` confirmation | Human approval before promote | `promote` |
632
646
  | 1 | `POST /releases` | Create release record | always |
633
647
  | 2 | `PUT /releases/{id}/artifacts` | Attach build artifacts | always |
634
648
  | 3 | `GET /releases/{id}/preflight` | Health checks, smoke tests | always |
@@ -638,7 +652,7 @@ Keep it concise. The design doc is a working reference, not a spec document —
638
652
  | 7 | `GET /releases/{id}` | Post-action state for response | always |
639
653
  | — | `DELETE /releases/{id}/canary-traffic` | Cleanup canary if mid-flow error | on error + `cleanupOnError` |
640
654
 
641
- The table surfaces design questions early: should the elicit happen before or after the artifacts are attached? Does cleanup drop the canary on any failure, or only failures past the promote step? What does the response body need from the final GET — version, traffic percentage, health summary? Answering these during design is far cheaper than mid-implementation.
655
+ The table surfaces design questions early: should the confirmation round happen before or after the artifacts are attached? Does cleanup drop the canary on any failure, or only failures past the promote step? What does the response body need from the final GET — version, traffic percentage, health summary? Answering these during design is far cheaper than mid-implementation.
642
656
 
643
657
  ### 9. Confirm and Proceed
644
658
 
@@ -687,7 +701,7 @@ Items without an `If …:` prefix apply to every design. Conditional items only
687
701
  - [ ] **If an upstream API has no native search but the relevant set is bounded:** MCP-side list filtering considered — a distinct local filter param (`filter`/`nameContains`, not `query`), filtering the full set, strict token match (fuzzy only when a caller needs typo tolerance)
688
702
  - [ ] **If the server has workflow tools:** call-flow documented (upstream sequence + mode arms) in design doc's Workflow Analysis
689
703
  - [ ] **If state-aware procedural guidance adds value:** instruction tool considered with `nextToolSuggestions` pre-filled from diagnostics
690
- - [ ] **If workflow tools have destructive modes:** destructive arm guarded by `ctx.elicit` when available, with `destructiveHint` annotation as fallback for non-interactive clients
704
+ - [ ] **If workflow tools have destructive modes:** destructive arm gated on a `ctx.requestInput` confirmation read back from `ctx.inputs`, with `destructiveHint` annotation so clients that never fulfil the round still surface the risk
691
705
  - [ ] **If a parameter determines blast radius:** safe default set (e.g., `mode: 'preview'`, `dryRun: true`, `confirmCount` required)
692
706
  - [ ] **App tools default to no.** If one was proposed, verified there's a real human-in-the-loop in an MCP Apps-capable client justifying the iframe/CSP/`format()`-twin maintenance cost — otherwise dropped in favor of a standard tool
693
707
  - [ ] **If the server exposes resources:** URIs use `{param}` templates, pagination planned for large lists
@@ -4,7 +4,7 @@ description: >
4
4
  Exercise tools, resources, and prompts against a live HTTP server via MCP JSON-RPC over curl. Starts the server, surfaces the catalog, runs real and adversarial inputs, and produces a tight report with concrete findings and numbered follow-up options. Use after adding or modifying definitions, or when the user asks to test, try out, or verify their MCP surface.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "2.8"
7
+ version: "2.9"
8
8
  audience: external
9
9
  type: debug
10
10
  ---
@@ -243,7 +243,9 @@ mcp_init <url-from-mcp_start>
243
243
 
244
244
  Runs `initialize`, sends `notifications/initialized`, prints `sid=<id>` to capture for `mcp_call`, plus the protocol version the server negotiated.
245
245
 
246
- The helper requests the SDK's current protocol version. **If `protocol=` comes back older than `requested=`, the server capped it** — every call after that exercises an older protocol than a current client would negotiate. Note it as a `bug` finding and check the pinned `@modelcontextprotocol/sdk` version; don't quietly test the downgraded surface. To deliberately test an older version, set `MCP_FIELD_TEST_PROTOCOL`.
246
+ The helper requests the newest `initialize`-negotiated revision the SDK supports (`2025-11-25`). **If `protocol=` comes back older than `requested=`, the server capped it** — every call after that exercises an older protocol than a current client would negotiate. Note it as a `bug` finding and check the pinned `@modelcontextprotocol/server` version; don't quietly test the downgraded surface. To deliberately test an older version, set `MCP_FIELD_TEST_PROTOCOL`.
247
+
248
+ This exercises the **2025-era arm**: `initialize` negotiates the revision, the server mints an `Mcp-Session-Id`, and every later call rides that session. The [2026-07-28 revision](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports) is not in the `initialize` ladder at all — it is selected per request by the `io.modelcontextprotocol/protocolVersion` key in the request's own `_meta` envelope, and carries no session. Curl-based field testing therefore covers the sessionful leg; exercise the per-request leg from a real 2026-era client or an integration test.
247
249
 
248
250
  ### 3. Surface the catalog
249
251
 
@@ -4,7 +4,7 @@ description: >
4
4
  Finalize documentation and project metadata for a ship-ready MCP server. Use after implementation is complete, tests pass, and devcheck is clean. Safe to run at any stage — each step checks current state and only acts on what still needs work.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "2.11"
7
+ version: "2.12"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -31,7 +31,7 @@ Also check for stale framework references — servers migrated from `mcp-ts-temp
31
31
  Pick examples that:
32
32
 
33
33
  - Show the most common or important capability
34
- - Demonstrate any non-trivial patterns the server uses (e.g., `ctx.state`, `ctx.elicit`, `task: true`, services)
34
+ - Demonstrate any non-trivial patterns the server uses (e.g., `ctx.state`, `ctx.requestInput` / `ctx.inputs`, `ctx.enrich`, services)
35
35
  - Include a handler with real business logic, not just passthrough
36
36
 
37
37
  Keep 1-2 examples per primitive type (tool, resource, prompt). Don't list every definition — the README handles that.
@@ -46,7 +46,7 @@ Compare the structure diagram against the actual directory layout. If it still r
46
46
 
47
47
  ### 4. Update the Context Table
48
48
 
49
- Review the `ctx` feature table. Remove rows for features the server doesn't use (e.g., `ctx.elicit` if no tools call it). Add any custom context usage that's become important. The table should reflect what this server actually uses, not the full framework surface.
49
+ Review the `ctx` feature table. Remove rows for features the server doesn't use (e.g., `ctx.requestInput` / `ctx.inputs` if no handler collects extra input). Add any custom context usage that's become important. The table should reflect what this server actually uses, not the full framework surface.
50
50
 
51
51
  ### 5. Update Server Config Example
52
52
 
@@ -78,7 +78,7 @@ The header tagline must match the `package.json` `description`.
78
78
  | Version | info | Always — link to `CHANGELOG.md` |
79
79
  | License | info | Always |
80
80
  | Docker | info | Published to ghcr.io or Docker Hub |
81
- | MCP SDK | info | Always — show the `@modelcontextprotocol/sdk` version |
81
+ | MCP SDK | info | Always — show the `@modelcontextprotocol/server` version |
82
82
  | npm | info | Published to npm |
83
83
  | TypeScript | info | Always |
84
84
  | Bun | info | If using Bun (standard for this framework) |
@@ -4,7 +4,7 @@ description: >
4
4
  Ship a release end-to-end across every registry the project targets (npm, MCP Registry, GitHub Releases for `.mcpb` bundles, GHCR). Runs the final verification gate, pushes commits and tags, then publishes to each applicable destination. Assumes git wrapup (version bumps, changelog, commit, annotated tag) is already complete — this skill is the post-wrapup publish workflow. Retries transient network failures on publish steps; halts with a partial-state report when retries are exhausted or the failure is terminal.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "2.11"
7
+ version: "2.12"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -199,6 +199,8 @@ Skip any destination that was skipped in its step.
199
199
 
200
200
  Confirm each published artifact is actually live — don't rely on a successful push exit code alone. For each destination that succeeded:
201
201
 
202
+ **Never disable the sandbox to complete a verification.** A verification `curl` — most often the MCP Registry one — can come back blocked by a sandbox network restriction while npm and GHCR pass. Do **not** set `dangerouslyDisableSandbox` or otherwise route around the restriction; report the block and let the orchestrator verify from its own session. **A blocked verification is not evidence of a failed publish** — when the publish step itself reported success, report the two facts separately rather than treating the block as something to defeat.
203
+
202
204
  - **npm**: `npm view <package.json#name>@<version> version` — must return the version string
203
205
  - **MCP Registry**: `curl -s "https://registry.modelcontextprotocol.io/v0.1/servers/<mcpName>/versions/<version>"` — must return HTTP 200 with `server.version` matching `<version>` (`mcpName` is the `name` field from `server.json`; URL-encode `/` as `%2F`). The search endpoint (`/v0.1/servers?search=`) paginates and may not include the latest version for packages with many releases — always use the direct version lookup.
204
206
  - **GitHub Release**: `gh release view v<VERSION> -R <OWNER>/<REPO> --json assets --jq '.assets[].name'` — must list the `.mcpb` file
@@ -4,7 +4,7 @@ description: >
4
4
  File a bug or feature request against @cyanheads/mcp-ts-core when you hit a framework issue. Use when a builder, utility, context method, or config behaves contrary to the documented API — not for server-specific application bugs.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.8"
7
+ version: "1.9"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -15,7 +15,7 @@ You've isolated a problem to `@cyanheads/mcp-ts-core` itself — not your server
15
15
 
16
16
  - Framework builder (`tool()`, `resource()`, `prompt()`) rejects valid input or produces incorrect output
17
17
  - `createApp()` or `createWorkerHandler()` fails on a valid config
18
- - `Context` properties (`ctx.log`, `ctx.state`, `ctx.elicit`, etc.) behave contrary to docs
18
+ - `Context` properties (`ctx.log`, `ctx.state`, `ctx.inputs`, etc.) behave contrary to docs
19
19
  - A utility from `/utils`, `/errors`, `/auth`, `/storage`, `/services` returns wrong results or throws unexpectedly
20
20
  - Type exports are incorrect or missing (compile error on documented usage)
21
21
  - The definition linter (`bun run lint:mcp`) produces false positives or misses real violations
@@ -4,7 +4,7 @@ description: >
4
4
  File a bug or feature request against this MCP server's own repo. Use for server-specific issues — tool logic, service integrations, config problems, or domain bugs that aren't caused by the framework.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.6"
7
+ version: "1.7"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -277,7 +277,7 @@ Not sure where the bug lives? Quick checks:
277
277
  | Error in `src/mcp-server/tools/` or `src/services/` | | Yes |
278
278
  | Same bug reproduces with a bare `tool()` definition (no services) | Yes | |
279
279
  | Bug disappears when you swap in a dummy handler | | Yes |
280
- | `ctx.state`, `ctx.log`, `ctx.elicit` behave wrong on any tool | Yes | |
280
+ | `ctx.state`, `ctx.log`, `ctx.inputs` behave wrong on any tool | Yes | |
281
281
  | Only one specific tool/resource is affected | | Yes |
282
282
 
283
283
  When genuinely ambiguous, file against this server's repo and note that it might be a framework issue. The maintainer can transfer it upstream.
@@ -4,7 +4,7 @@ description: >
4
4
  Review an MCP server for common security gaps: LLM-facing surfaces as injection vector (tools, resources, prompts, descriptions), scope blast radius, destructive ops without consent, upstream auth shape, input sinks (URL / path / roots / shell / schema strictness / ReDoS), tenant isolation, leakage through errors and telemetry, unbounded resources, and HTTP-mode deployment surface. Use before a release, after a batch of handler changes, or when the user asks for a security review, audit, or hardening pass. Produces grouped findings and a numbered options list.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.6"
7
+ version: "1.7"
8
8
  audience: external
9
9
  type: audit
10
10
  ---
@@ -44,7 +44,7 @@ find src/mcp-server/prompts/definitions -name "*.prompt.ts" 2>/dev/null | sort
44
44
  find src/services -maxdepth 1 -mindepth 1 -type d | sort
45
45
  ```
46
46
 
47
- Note: tool / resource / prompt counts, auth mode, storage provider, upstream APIs, which tools have `destructiveHint`, which handlers use `ctx.elicit`, which services hold module-scope state, whether the server reads `roots`.
47
+ Note: tool / resource / prompt counts, auth mode, storage provider, upstream APIs, which tools have `destructiveHint`, which handlers request a consent round via `ctx.requestInput`, which services hold module-scope state, whether the server reads `roots`.
48
48
 
49
49
  **If transport is streamable HTTP or SSE**, also capture:
50
50
 
@@ -108,25 +108,27 @@ grep -rn "auth: \[" src/mcp-server/tools/definitions/
108
108
 
109
109
  **Smell:** every tool shares the same scope string. Or: `MCP_AUTH_DISABLE_SCOPE_CHECKS=true` set without a documented compensating ACL — confirm the deployment relies on a meaningful access control layer below the framework before approving.
110
110
 
111
- #### Axis 3 — Destructive ops without elicit
111
+ #### Axis 3 — Destructive ops without a consent round
112
112
 
113
- `ctx.elicit` moves consent off the LLM and onto the user. Destructive tools without it trust the LLM not to be tricked.
113
+ `ctx.requestInput` moves consent off the LLM and onto the user: the handler returns an `input_required` result and only runs the side effect once it is re-entered with an accepted response. Destructive tools without that round trust the LLM not to be tricked.
114
114
 
115
115
  **Look in:** handlers with `destructiveHint: true` or side-effecting verbs in names (`delete_*`, `send_*`, `pay_*`, `publish_*`, `drop_*`).
116
116
 
117
117
  ```bash
118
118
  grep -rn "destructiveHint" src/mcp-server/tools/definitions/
119
- grep -rn "ctx.elicit" src/mcp-server/tools/definitions/
119
+ grep -rn "ctx.requestInput\|ctx.inputs" src/mcp-server/tools/definitions/
120
120
  ```
121
121
 
122
122
  **Check:**
123
123
 
124
- - Each destructive handler calls `ctx.elicit` before the side effect?
125
- - Fallback when elicit is unavailable — **proceeds on the tool annotations, and says so in the tool description?** Do NOT require a refusal here: `ctx.elicit` is `undefined` on *every* Streamable HTTP request (the transport builds a fresh `McpServer` per request, so the SDK never records the client's capabilities — mcp-ts-core#312), so a refusing fallback makes the gated tools permanently unusable on the hosted transport. That is an outage, not a hardening. What IS in scope: a **declined or unparseable** elicit response must never proceed, and any doc claiming the gate protects "clients that support elicitation" must name the HTTP limitation or it overstates the control.
126
- - Elicit **response** validated against a Zod schema before use? The returned payload is LLM-mediated, not user-direct — "user confirmed" does not mean "user authored these exact fields."
127
- - Consent is scoped to the specific target (e.g., record ID rendered in the prompt), not a generic "proceed?"
124
+ - Each destructive handler reads `ctx.inputs` for the confirmation and returns `ctx.requestInput(...)` before the side effect?
125
+ - The confirmation **response** is validated — `ctx.inputs.accepted(key, Schema)` with a schema, not the bare overload. The SDK never re-validates a response against the schema its request advertised, and the payload is LLM-mediated: "user confirmed" does not mean "user authored these exact fields."
126
+ - A **declined or cancelled** response is terminal — checked via `ctx.inputs.view(key)` and thrown on, never re-asked (a re-ask loops until the round budget runs out) and never treated as consent.
127
+ - Consent is scoped to the specific target (e.g., record ID rendered in the message), not a generic "proceed?"
128
+ - Any `requestState` carried across rounds is integrity-protected if it influences authorization, resource access, or which target gets mutated. It round-trips through the client and comes back attacker-controlled; the SDK does not sign or verify it.
129
+ - **The weak point is answerability, not availability.** `ctx.requestInput` is present on every transport and both protocol eras — the 2025-era shim issues the real `elicitation/create` round trip, the 2026-07-28 client fulfils the embedded request directly. A client that never retries simply leaves the destructive step un-run, which fails safe. Keep `destructiveHint: true` so client-side approval flows still surface the risk, and do not accept "proceed anyway when the round is unavailable" as a fallback — there is no such state to detect.
128
130
 
129
- **Smell:** `destructiveHint: true` file with no `ctx.elicit?.(...)` in it. Or: `const { confirmed } = await ctx.elicit(...)` without a schema — `confirmed` could be anything.
131
+ **Smell:** `destructiveHint: true` file with no `ctx.requestInput` in it. Or `ctx.inputs.accepted('confirm')` with no schema argument — the content could be anything. Or a handler that re-issues the same request after a `decline`.
130
132
 
131
133
  #### Axis 4 — Upstream auth shape
132
134
 
@@ -295,7 +297,7 @@ Group by severity. Each 3–5 lines.
295
297
  | Severity | Meaning |
296
298
  |:---------|:--------|
297
299
  | **critical** | Exploitable now: auth bypass, exfiltration, arbitrary code/file/network access |
298
- | **high** | Structural gap with clear attacker benefit even without immediate PoC (destructive op without elicit, admin scope on read tool, SSRF-capable URL input) |
300
+ | **high** | Structural gap with clear attacker benefit even without immediate PoC (destructive op without a consent round, admin scope on read tool, SSRF-capable URL input) |
299
301
  | **medium** | Defense-in-depth gap weakening a boundary (missing per-tenant rate limit, error carries upstream response) |
300
302
  | **low** | Hardening / polish (tighter output schema, narrower error data, minor comment) |
301
303
 
@@ -314,7 +316,7 @@ Numbered, cherry-pickable.
314
316
 
315
317
  ```
316
318
  1. Add SSRF guard to `fetch_url.tool.ts` — block private IPs + non-http schemes (critical, #1)
317
- 2. Gate `delete_record.tool.ts` behind `ctx.elicit` (high, #3)
319
+ 2. Gate `delete_record.tool.ts` behind a `ctx.requestInput` confirmation round (high, #3)
318
320
  3. Split `admin` into `record:read` + `record:write` across 4 tools (high, #4)
319
321
  4. Move `const tokenCache = new Map()` out of module scope in `auth-service.ts` (medium, #7)
320
322
  5. Cap pagination loop in `list_all_tickets` at 1000 items (medium, #9)
@@ -328,12 +330,12 @@ End with:
328
330
  ## Checklist
329
331
 
330
332
  - [ ] Scope confirmed (whole server / module / diff)
331
- - [ ] Map built: tools / resources / prompts, services, upstream APIs, auth mode, elicit / roots usage
333
+ - [ ] Map built: tools / resources / prompts, services, upstream APIs, auth mode, consent-round / roots usage
332
334
  - [ ] Deployment surface reviewed (if HTTP): bind address, Origin allowlist, session ID, unauth routes, auth-spec compliance
333
335
  - [ ] `fuzzTool` started in parallel
334
336
  - [ ] Axis 1 — LLM-facing surfaces (tool / resource / prompt output + descriptions) framed and static
335
337
  - [ ] Axis 2 — scope granularity audited
336
- - [ ] Axis 3 — destructive ops verified to elicit, elicit response schema-validated
338
+ - [ ] Axis 3 — destructive ops verified to gate on a `ctx.requestInput` round, the response schema-validated, decline/cancel terminal
337
339
  - [ ] Axis 4 — upstream auth + token passthrough reviewed
338
340
  - [ ] Axis 5 — input sinks (URL / path / roots / shell / proto / schema strictness / ReDoS) checked
339
341
  - [ ] Axis 6 — tenant isolation: module-scope state swept
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: tool-defs-analysis
3
3
  description: >
4
- Read-only audit of MCP definition language across an existing surface — tools, resources, prompts, server instructions. Walks every definition file and checks 15 categories the LLM reads to decide whether and how to call: voice & tense, internal leaks, audience leaks, defaults, recovery hints, field descriptions, cross-references, sparsity, examples, structure, mutator observability, unit-bearing numeric names, validator-enforced constraints, annotations truthfulness, single-line strings — then a cross-surface pass: naming taxonomy, parameter vocabulary, tool overlap, instructions drift, length outliers. Produces grouped findings with file:line citations and a numbered options list. Use during polish, after a refactor, or before a release. Complements `field-test` (behavior testing) and `security-pass` (security audit).
4
+ Read-only audit of MCP definition language across an existing surface — tools, resources, prompts, server instructions. Walks every definition file and checks 16 categories the LLM reads to decide whether and how to call: voice & tense, internal leaks, audience leaks, defaults, recovery hints, field descriptions, cross-references, sparsity, examples, structure, mutator observability, unit-bearing numeric names, validator-enforced constraints, annotations truthfulness, single-line strings, exclusive modes in the schema — then a cross-surface pass: naming taxonomy, parameter vocabulary, tool overlap, instructions drift, length outliers. Produces grouped findings with file:line citations and a numbered options list. Use during polish, after a refactor, or before a release. Complements `field-test` (behavior testing) and `security-pass` (security audit).
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.4"
7
+ version: "1.5"
8
8
  audience: external
9
9
  type: audit
10
10
  ---
@@ -22,7 +22,7 @@ This skill is the **review-time pass** for that drift. Read each definition the
22
22
  | `security-pass` | Injection, scopes, input sinks |
23
23
  | `tool-defs-analysis` (this) | LLM-facing language across the existing surface |
24
24
 
25
- `field-test` already audits descriptions for implementation leaks, meta-coaching, and consumer-aware phrasing during its catalog step — that's a fast shallow pass alongside live tool calls. This skill is the deeper review: 15 categories, every field, every recovery hint, every default value, with file:line citations — plus a cross-surface pass for the drift no single file shows.
25
+ `field-test` already audits descriptions for implementation leaks, meta-coaching, and consumer-aware phrasing during its catalog step — that's a fast shallow pass alongside live tool calls. This skill is the deeper review: 16 categories, every field, every recovery hint, every default value, with file:line citations — plus a cross-surface pass for the drift no single file shows.
26
26
 
27
27
  **Read-only.** This skill produces a report; the maintainer applies fixes. While running it, do not run git, do not stage or commit, do not update the changelog, do not run `devcheck`, do not invoke wrapup or release workflows. Fixes flow through the normal authoring path (edit the definition, then re-run this skill if you want to verify).
28
28
 
@@ -57,7 +57,7 @@ The `*tool.ts` / `*resource.ts` patterns also catch `*.app-tool.ts` / `*.app-res
57
57
 
58
58
  Use `TaskCreate` — one task per file. Mark each complete after its findings are captured.
59
59
 
60
- ### 2. Walk the 15 categories per file
60
+ ### 2. Walk the 16 categories per file
61
61
 
62
62
  Read each definition file in full. Apply every category — most files trip more than one. Capture each hit with `file:line`, the offending excerpt, and a one-line fix.
63
63
 
@@ -201,6 +201,16 @@ Field-test catches this in its leak audit; this skill is the more thorough pass.
201
201
 
202
202
  **Fix:** collapse to one single-line string literal.
203
203
 
204
+ #### 16. Exclusive modes in the schema
205
+
206
+ **Look in:** input schemas where two or more optional fields are alternatives rather than additions — the describes say "provide either X or Y", "ignored when Z is set", "one of".
207
+
208
+ **Check:** the exclusivity is in the schema, as a `z.discriminatedUnion` on a mode literal, so each branch advertises its own `required` list and the model reads which arguments go together. A mutex that lives only in prose reaches a weaker model unreliably: it fills both, or neither, and the handler answers with a validation error for a rule the schema said nothing about.
209
+
210
+ **Smell:** every field optional with a describe explaining when to omit it; a handler opening with `if (!a && !b) throw` / `if (a && b) throw`; a `mode`/`kind`/`by` enum whose value decides which *other* fields are required.
211
+
212
+ **Fix:** `input: z.discriminatedUnion('mode', [...])` — see the `add-tool` skill. Not every all-optional schema qualifies: fields that genuinely compose (independent filters, pagination) stay flat.
213
+
204
214
  ### 3. Cross-surface pass
205
215
 
206
216
  The per-file walk misses drift that only shows between files. After it, sweep the whole surface:
@@ -260,7 +270,7 @@ End with:
260
270
  - [ ] Scope confirmed (whole server / module / specific files)
261
271
  - [ ] Severity floor applied — nits suppressed if user requested
262
272
  - [ ] Inventory built — every `*.tool.ts`, `*.app-tool.ts`, `*.resource.ts`, `*.app-resource.ts`, `*.prompt.ts` listed; server `instructions` located if set
263
- - [ ] Each file walked through all 15 categories (per-file, not 15 separate passes)
273
+ - [ ] Each file walked through all 16 categories (per-file, not 16 separate passes)
264
274
  - [ ] Cross-surface pass run — naming taxonomy, parameter vocabulary, tool overlap, instructions drift, length outliers
265
275
  - [ ] **Read-only:** no git, no commits, no changelog edits, no `devcheck`, no wrapup invoked during the audit
266
276
  - [ ] Findings carry file:line citation, excerpt, issue, fix — excerpts verbatim, line numbers verified
@@ -15,6 +15,10 @@
15
15
 
16
16
  # ── Session ──────────────────────────────────────────────────────────
17
17
  # MCP_SESSION_MODE=stateful # stateful | stateless (default: stateful)
18
+ # MCP_HTTP_RESUMABILITY=false # SSE replay on a dropped stateful stream. Default: true.
19
+ # Kill switch only — no effect on stateless serving.
20
+ # MCP_HTTP_RESUMABILITY_MAX_EVENTS=512 # Retained per session, oldest evicted first
21
+ # MCP_HTTP_RESUMABILITY_TTL_MS=300000 # How long a retained event stays replayable
18
22
 
19
23
  # ── Memory ───────────────────────────────────────────────────────────
20
24
  # MCP_GC_PRESSURE_INTERVAL_MS=0 # Opt-in forced Bun.gc(true) interval, ms (Bun only). Drains old-gen backlog