@cyanheads/mcp-ts-core 0.1.0-beta.12

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 (485) hide show
  1. package/CLAUDE.md +583 -0
  2. package/LICENSE +201 -0
  3. package/README.md +287 -0
  4. package/biome.json +103 -0
  5. package/dist/app.d.ts +82 -0
  6. package/dist/app.d.ts.map +1 -0
  7. package/dist/app.js +222 -0
  8. package/dist/app.js.map +1 -0
  9. package/dist/cli/init.d.ts +8 -0
  10. package/dist/cli/init.d.ts.map +1 -0
  11. package/dist/cli/init.js +161 -0
  12. package/dist/cli/init.js.map +1 -0
  13. package/dist/config/index.d.ts +349 -0
  14. package/dist/config/index.d.ts.map +1 -0
  15. package/dist/config/index.js +464 -0
  16. package/dist/config/index.js.map +1 -0
  17. package/dist/context.d.ts +119 -0
  18. package/dist/context.d.ts.map +1 -0
  19. package/dist/context.js +144 -0
  20. package/dist/context.js.map +1 -0
  21. package/dist/index.d.ts +8 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +9 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/mcp-server/prompts/prompt-registration.d.ts +33 -0
  26. package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -0
  27. package/dist/mcp-server/prompts/prompt-registration.js +91 -0
  28. package/dist/mcp-server/prompts/prompt-registration.js.map +1 -0
  29. package/dist/mcp-server/prompts/utils/newPromptDefinition.d.ts +49 -0
  30. package/dist/mcp-server/prompts/utils/newPromptDefinition.d.ts.map +1 -0
  31. package/dist/mcp-server/prompts/utils/newPromptDefinition.js +39 -0
  32. package/dist/mcp-server/prompts/utils/newPromptDefinition.js.map +1 -0
  33. package/dist/mcp-server/prompts/utils/promptDefinition.d.ts +37 -0
  34. package/dist/mcp-server/prompts/utils/promptDefinition.d.ts.map +1 -0
  35. package/dist/mcp-server/prompts/utils/promptDefinition.js +2 -0
  36. package/dist/mcp-server/prompts/utils/promptDefinition.js.map +1 -0
  37. package/dist/mcp-server/resources/resource-registration.d.ts +27 -0
  38. package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -0
  39. package/dist/mcp-server/resources/resource-registration.js +85 -0
  40. package/dist/mcp-server/resources/resource-registration.js.map +1 -0
  41. package/dist/mcp-server/resources/utils/newResourceDefinition.d.ts +84 -0
  42. package/dist/mcp-server/resources/utils/newResourceDefinition.d.ts.map +1 -0
  43. package/dist/mcp-server/resources/utils/newResourceDefinition.js +40 -0
  44. package/dist/mcp-server/resources/utils/newResourceDefinition.js.map +1 -0
  45. package/dist/mcp-server/resources/utils/newResourceHandlerFactory.d.ts +32 -0
  46. package/dist/mcp-server/resources/utils/newResourceHandlerFactory.d.ts.map +1 -0
  47. package/dist/mcp-server/resources/utils/newResourceHandlerFactory.js +103 -0
  48. package/dist/mcp-server/resources/utils/newResourceHandlerFactory.js.map +1 -0
  49. package/dist/mcp-server/resources/utils/resourceDefinition.d.ts +94 -0
  50. package/dist/mcp-server/resources/utils/resourceDefinition.d.ts.map +1 -0
  51. package/dist/mcp-server/resources/utils/resourceDefinition.js +2 -0
  52. package/dist/mcp-server/resources/utils/resourceDefinition.js.map +1 -0
  53. package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +14 -0
  54. package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -0
  55. package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +111 -0
  56. package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -0
  57. package/dist/mcp-server/roots/roots-registration.d.ts +22 -0
  58. package/dist/mcp-server/roots/roots-registration.d.ts.map +1 -0
  59. package/dist/mcp-server/roots/roots-registration.js +25 -0
  60. package/dist/mcp-server/roots/roots-registration.js.map +1 -0
  61. package/dist/mcp-server/server.d.ts +34 -0
  62. package/dist/mcp-server/server.d.ts.map +1 -0
  63. package/dist/mcp-server/server.js +62 -0
  64. package/dist/mcp-server/server.js.map +1 -0
  65. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts +42 -0
  66. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts.map +1 -0
  67. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js +70 -0
  68. package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js.map +1 -0
  69. package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts +109 -0
  70. package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts.map +1 -0
  71. package/dist/mcp-server/tasks/core/storageBackedTaskStore.js +209 -0
  72. package/dist/mcp-server/tasks/core/storageBackedTaskStore.js.map +1 -0
  73. package/dist/mcp-server/tasks/core/taskManager.d.ts +103 -0
  74. package/dist/mcp-server/tasks/core/taskManager.d.ts.map +1 -0
  75. package/dist/mcp-server/tasks/core/taskManager.js +144 -0
  76. package/dist/mcp-server/tasks/core/taskManager.js.map +1 -0
  77. package/dist/mcp-server/tasks/core/taskTypes.d.ts +11 -0
  78. package/dist/mcp-server/tasks/core/taskTypes.d.ts.map +1 -0
  79. package/dist/mcp-server/tasks/core/taskTypes.js +13 -0
  80. package/dist/mcp-server/tasks/core/taskTypes.js.map +1 -0
  81. package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts +108 -0
  82. package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts.map +1 -0
  83. package/dist/mcp-server/tasks/utils/taskToolDefinition.js +14 -0
  84. package/dist/mcp-server/tasks/utils/taskToolDefinition.js.map +1 -0
  85. package/dist/mcp-server/tools/tool-registration.d.ts +49 -0
  86. package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -0
  87. package/dist/mcp-server/tools/tool-registration.js +269 -0
  88. package/dist/mcp-server/tools/tool-registration.js.map +1 -0
  89. package/dist/mcp-server/tools/utils/newToolDefinition.d.ts +73 -0
  90. package/dist/mcp-server/tools/utils/newToolDefinition.d.ts.map +1 -0
  91. package/dist/mcp-server/tools/utils/newToolDefinition.js +45 -0
  92. package/dist/mcp-server/tools/utils/newToolDefinition.js.map +1 -0
  93. package/dist/mcp-server/tools/utils/newToolHandlerFactory.d.ts +33 -0
  94. package/dist/mcp-server/tools/utils/newToolHandlerFactory.d.ts.map +1 -0
  95. package/dist/mcp-server/tools/utils/newToolHandlerFactory.js +107 -0
  96. package/dist/mcp-server/tools/utils/newToolHandlerFactory.js.map +1 -0
  97. package/dist/mcp-server/tools/utils/toolDefinition.d.ts +118 -0
  98. package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -0
  99. package/dist/mcp-server/tools/utils/toolDefinition.js +2 -0
  100. package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -0
  101. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +34 -0
  102. package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -0
  103. package/dist/mcp-server/tools/utils/toolHandlerFactory.js +68 -0
  104. package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -0
  105. package/dist/mcp-server/transports/ITransport.d.ts +15 -0
  106. package/dist/mcp-server/transports/ITransport.d.ts.map +1 -0
  107. package/dist/mcp-server/transports/ITransport.js +2 -0
  108. package/dist/mcp-server/transports/ITransport.js.map +1 -0
  109. package/dist/mcp-server/transports/auth/authFactory.d.ts +11 -0
  110. package/dist/mcp-server/transports/auth/authFactory.d.ts.map +1 -0
  111. package/dist/mcp-server/transports/auth/authFactory.js +43 -0
  112. package/dist/mcp-server/transports/auth/authFactory.js.map +1 -0
  113. package/dist/mcp-server/transports/auth/authMiddleware.d.ts +24 -0
  114. package/dist/mcp-server/transports/auth/authMiddleware.d.ts.map +1 -0
  115. package/dist/mcp-server/transports/auth/authMiddleware.js +69 -0
  116. package/dist/mcp-server/transports/auth/authMiddleware.js.map +1 -0
  117. package/dist/mcp-server/transports/auth/lib/authContext.d.ts +34 -0
  118. package/dist/mcp-server/transports/auth/lib/authContext.d.ts.map +1 -0
  119. package/dist/mcp-server/transports/auth/lib/authContext.js +25 -0
  120. package/dist/mcp-server/transports/auth/lib/authContext.js.map +1 -0
  121. package/dist/mcp-server/transports/auth/lib/authTypes.d.ts +19 -0
  122. package/dist/mcp-server/transports/auth/lib/authTypes.d.ts.map +1 -0
  123. package/dist/mcp-server/transports/auth/lib/authTypes.js +2 -0
  124. package/dist/mcp-server/transports/auth/lib/authTypes.js.map +1 -0
  125. package/dist/mcp-server/transports/auth/lib/authUtils.d.ts +18 -0
  126. package/dist/mcp-server/transports/auth/lib/authUtils.d.ts.map +1 -0
  127. package/dist/mcp-server/transports/auth/lib/authUtils.js +64 -0
  128. package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -0
  129. package/dist/mcp-server/transports/auth/lib/checkScopes.d.ts +25 -0
  130. package/dist/mcp-server/transports/auth/lib/checkScopes.d.ts.map +1 -0
  131. package/dist/mcp-server/transports/auth/lib/checkScopes.js +34 -0
  132. package/dist/mcp-server/transports/auth/lib/checkScopes.js.map +1 -0
  133. package/dist/mcp-server/transports/auth/lib/claimParser.d.ts +34 -0
  134. package/dist/mcp-server/transports/auth/lib/claimParser.d.ts.map +1 -0
  135. package/dist/mcp-server/transports/auth/lib/claimParser.js +58 -0
  136. package/dist/mcp-server/transports/auth/lib/claimParser.js.map +1 -0
  137. package/dist/mcp-server/transports/auth/lib/withAuth.d.ts +25 -0
  138. package/dist/mcp-server/transports/auth/lib/withAuth.d.ts.map +1 -0
  139. package/dist/mcp-server/transports/auth/lib/withAuth.js +30 -0
  140. package/dist/mcp-server/transports/auth/lib/withAuth.js.map +1 -0
  141. package/dist/mcp-server/transports/auth/strategies/authStrategy.d.ts +18 -0
  142. package/dist/mcp-server/transports/auth/strategies/authStrategy.d.ts.map +1 -0
  143. package/dist/mcp-server/transports/auth/strategies/authStrategy.js +2 -0
  144. package/dist/mcp-server/transports/auth/strategies/authStrategy.js.map +1 -0
  145. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts +14 -0
  146. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts.map +1 -0
  147. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +86 -0
  148. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -0
  149. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts +14 -0
  150. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -0
  151. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +113 -0
  152. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -0
  153. package/dist/mcp-server/transports/http/httpErrorHandler.d.ts +25 -0
  154. package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -0
  155. package/dist/mcp-server/transports/http/httpErrorHandler.js +112 -0
  156. package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -0
  157. package/dist/mcp-server/transports/http/httpTransport.d.ts +47 -0
  158. package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -0
  159. package/dist/mcp-server/transports/http/httpTransport.js +396 -0
  160. package/dist/mcp-server/transports/http/httpTransport.js.map +1 -0
  161. package/dist/mcp-server/transports/http/httpTypes.d.ts +17 -0
  162. package/dist/mcp-server/transports/http/httpTypes.d.ts.map +1 -0
  163. package/dist/mcp-server/transports/http/httpTypes.js +2 -0
  164. package/dist/mcp-server/transports/http/httpTypes.js.map +1 -0
  165. package/dist/mcp-server/transports/http/protectedResourceMetadata.d.ts +21 -0
  166. package/dist/mcp-server/transports/http/protectedResourceMetadata.d.ts.map +1 -0
  167. package/dist/mcp-server/transports/http/protectedResourceMetadata.js +44 -0
  168. package/dist/mcp-server/transports/http/protectedResourceMetadata.js.map +1 -0
  169. package/dist/mcp-server/transports/http/sessionIdUtils.d.ts +33 -0
  170. package/dist/mcp-server/transports/http/sessionIdUtils.d.ts.map +1 -0
  171. package/dist/mcp-server/transports/http/sessionIdUtils.js +54 -0
  172. package/dist/mcp-server/transports/http/sessionIdUtils.js.map +1 -0
  173. package/dist/mcp-server/transports/http/sessionStore.d.ts +87 -0
  174. package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -0
  175. package/dist/mcp-server/transports/http/sessionStore.js +209 -0
  176. package/dist/mcp-server/transports/http/sessionStore.js.map +1 -0
  177. package/dist/mcp-server/transports/manager.d.ts +22 -0
  178. package/dist/mcp-server/transports/manager.d.ts.map +1 -0
  179. package/dist/mcp-server/transports/manager.js +62 -0
  180. package/dist/mcp-server/transports/manager.js.map +1 -0
  181. package/dist/mcp-server/transports/stdio/stdioTransport.d.ts +44 -0
  182. package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -0
  183. package/dist/mcp-server/transports/stdio/stdioTransport.js +63 -0
  184. package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -0
  185. package/dist/services/graph/core/GraphService.d.ts +205 -0
  186. package/dist/services/graph/core/GraphService.d.ts.map +1 -0
  187. package/dist/services/graph/core/GraphService.js +231 -0
  188. package/dist/services/graph/core/GraphService.js.map +1 -0
  189. package/dist/services/graph/core/IGraphProvider.d.ts +295 -0
  190. package/dist/services/graph/core/IGraphProvider.d.ts.map +1 -0
  191. package/dist/services/graph/core/IGraphProvider.js +8 -0
  192. package/dist/services/graph/core/IGraphProvider.js.map +1 -0
  193. package/dist/services/graph/types.d.ts +107 -0
  194. package/dist/services/graph/types.d.ts.map +1 -0
  195. package/dist/services/graph/types.js +8 -0
  196. package/dist/services/graph/types.js.map +1 -0
  197. package/dist/services/llm/core/ILlmProvider.d.ts +86 -0
  198. package/dist/services/llm/core/ILlmProvider.d.ts.map +1 -0
  199. package/dist/services/llm/core/ILlmProvider.js +2 -0
  200. package/dist/services/llm/core/ILlmProvider.js.map +1 -0
  201. package/dist/services/llm/providers/openrouter.provider.d.ts +187 -0
  202. package/dist/services/llm/providers/openrouter.provider.d.ts.map +1 -0
  203. package/dist/services/llm/providers/openrouter.provider.js +302 -0
  204. package/dist/services/llm/providers/openrouter.provider.js.map +1 -0
  205. package/dist/services/llm/types.d.ts +16 -0
  206. package/dist/services/llm/types.d.ts.map +1 -0
  207. package/dist/services/llm/types.js +9 -0
  208. package/dist/services/llm/types.js.map +1 -0
  209. package/dist/services/speech/core/ISpeechProvider.d.ts +92 -0
  210. package/dist/services/speech/core/ISpeechProvider.d.ts.map +1 -0
  211. package/dist/services/speech/core/ISpeechProvider.js +34 -0
  212. package/dist/services/speech/core/ISpeechProvider.js.map +1 -0
  213. package/dist/services/speech/core/SpeechService.d.ts +87 -0
  214. package/dist/services/speech/core/SpeechService.d.ts.map +1 -0
  215. package/dist/services/speech/core/SpeechService.js +135 -0
  216. package/dist/services/speech/core/SpeechService.js.map +1 -0
  217. package/dist/services/speech/providers/elevenlabs.provider.d.ts +77 -0
  218. package/dist/services/speech/providers/elevenlabs.provider.d.ts.map +1 -0
  219. package/dist/services/speech/providers/elevenlabs.provider.js +199 -0
  220. package/dist/services/speech/providers/elevenlabs.provider.js.map +1 -0
  221. package/dist/services/speech/providers/whisper.provider.d.ts +94 -0
  222. package/dist/services/speech/providers/whisper.provider.d.ts.map +1 -0
  223. package/dist/services/speech/providers/whisper.provider.js +240 -0
  224. package/dist/services/speech/providers/whisper.provider.js.map +1 -0
  225. package/dist/services/speech/types.d.ts +173 -0
  226. package/dist/services/speech/types.d.ts.map +1 -0
  227. package/dist/services/speech/types.js +8 -0
  228. package/dist/services/speech/types.js.map +1 -0
  229. package/dist/storage/core/IStorageProvider.d.ts +159 -0
  230. package/dist/storage/core/IStorageProvider.d.ts.map +1 -0
  231. package/dist/storage/core/IStorageProvider.js +2 -0
  232. package/dist/storage/core/IStorageProvider.js.map +1 -0
  233. package/dist/storage/core/StorageService.d.ts +22 -0
  234. package/dist/storage/core/StorageService.d.ts.map +1 -0
  235. package/dist/storage/core/StorageService.js +151 -0
  236. package/dist/storage/core/StorageService.js.map +1 -0
  237. package/dist/storage/core/storageFactory.d.ts +66 -0
  238. package/dist/storage/core/storageFactory.d.ts.map +1 -0
  239. package/dist/storage/core/storageFactory.js +122 -0
  240. package/dist/storage/core/storageFactory.js.map +1 -0
  241. package/dist/storage/core/storageValidation.d.ts +77 -0
  242. package/dist/storage/core/storageValidation.d.ts.map +1 -0
  243. package/dist/storage/core/storageValidation.js +303 -0
  244. package/dist/storage/core/storageValidation.js.map +1 -0
  245. package/dist/storage/providers/cloudflare/d1Provider.d.ts +94 -0
  246. package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -0
  247. package/dist/storage/providers/cloudflare/d1Provider.js +347 -0
  248. package/dist/storage/providers/cloudflare/d1Provider.js.map +1 -0
  249. package/dist/storage/providers/cloudflare/kvProvider.d.ts +21 -0
  250. package/dist/storage/providers/cloudflare/kvProvider.d.ts.map +1 -0
  251. package/dist/storage/providers/cloudflare/kvProvider.js +183 -0
  252. package/dist/storage/providers/cloudflare/kvProvider.js.map +1 -0
  253. package/dist/storage/providers/cloudflare/r2Provider.d.ts +28 -0
  254. package/dist/storage/providers/cloudflare/r2Provider.d.ts.map +1 -0
  255. package/dist/storage/providers/cloudflare/r2Provider.js +222 -0
  256. package/dist/storage/providers/cloudflare/r2Provider.js.map +1 -0
  257. package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts +20 -0
  258. package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts.map +1 -0
  259. package/dist/storage/providers/fileSystem/fileSystemProvider.js +282 -0
  260. package/dist/storage/providers/fileSystem/fileSystemProvider.js.map +1 -0
  261. package/dist/storage/providers/inMemory/inMemoryProvider.d.ts +21 -0
  262. package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -0
  263. package/dist/storage/providers/inMemory/inMemoryProvider.js +139 -0
  264. package/dist/storage/providers/inMemory/inMemoryProvider.js.map +1 -0
  265. package/dist/storage/providers/supabase/supabase.types.d.ts +49 -0
  266. package/dist/storage/providers/supabase/supabase.types.d.ts.map +1 -0
  267. package/dist/storage/providers/supabase/supabase.types.js +8 -0
  268. package/dist/storage/providers/supabase/supabase.types.js.map +1 -0
  269. package/dist/storage/providers/supabase/supabaseProvider.d.ts +24 -0
  270. package/dist/storage/providers/supabase/supabaseProvider.d.ts.map +1 -0
  271. package/dist/storage/providers/supabase/supabaseProvider.js +209 -0
  272. package/dist/storage/providers/supabase/supabaseProvider.js.map +1 -0
  273. package/dist/testing/index.d.ts +53 -0
  274. package/dist/testing/index.d.ts.map +1 -0
  275. package/dist/testing/index.js +132 -0
  276. package/dist/testing/index.js.map +1 -0
  277. package/dist/types-global/errors.d.ts +83 -0
  278. package/dist/types-global/errors.d.ts.map +1 -0
  279. package/dist/types-global/errors.js +113 -0
  280. package/dist/types-global/errors.js.map +1 -0
  281. package/dist/utils/formatting/diffFormatter.d.ts +227 -0
  282. package/dist/utils/formatting/diffFormatter.d.ts.map +1 -0
  283. package/dist/utils/formatting/diffFormatter.js +369 -0
  284. package/dist/utils/formatting/diffFormatter.js.map +1 -0
  285. package/dist/utils/formatting/index.d.ts +9 -0
  286. package/dist/utils/formatting/index.d.ts.map +1 -0
  287. package/dist/utils/formatting/index.js +9 -0
  288. package/dist/utils/formatting/index.js.map +1 -0
  289. package/dist/utils/formatting/markdownBuilder.d.ts +543 -0
  290. package/dist/utils/formatting/markdownBuilder.d.ts.map +1 -0
  291. package/dist/utils/formatting/markdownBuilder.js +674 -0
  292. package/dist/utils/formatting/markdownBuilder.js.map +1 -0
  293. package/dist/utils/formatting/tableFormatter.d.ts +261 -0
  294. package/dist/utils/formatting/tableFormatter.d.ts.map +1 -0
  295. package/dist/utils/formatting/tableFormatter.js +456 -0
  296. package/dist/utils/formatting/tableFormatter.js.map +1 -0
  297. package/dist/utils/formatting/treeFormatter.d.ts +344 -0
  298. package/dist/utils/formatting/treeFormatter.d.ts.map +1 -0
  299. package/dist/utils/formatting/treeFormatter.js +400 -0
  300. package/dist/utils/formatting/treeFormatter.js.map +1 -0
  301. package/dist/utils/internal/encoding.d.ts +42 -0
  302. package/dist/utils/internal/encoding.d.ts.map +1 -0
  303. package/dist/utils/internal/encoding.js +87 -0
  304. package/dist/utils/internal/encoding.js.map +1 -0
  305. package/dist/utils/internal/error-handler/errorHandler.d.ts +140 -0
  306. package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -0
  307. package/dist/utils/internal/error-handler/errorHandler.js +318 -0
  308. package/dist/utils/internal/error-handler/errorHandler.js.map +1 -0
  309. package/dist/utils/internal/error-handler/helpers.d.ts +98 -0
  310. package/dist/utils/internal/error-handler/helpers.d.ts.map +1 -0
  311. package/dist/utils/internal/error-handler/helpers.js +214 -0
  312. package/dist/utils/internal/error-handler/helpers.js.map +1 -0
  313. package/dist/utils/internal/error-handler/mappings.d.ts +85 -0
  314. package/dist/utils/internal/error-handler/mappings.d.ts.map +1 -0
  315. package/dist/utils/internal/error-handler/mappings.js +234 -0
  316. package/dist/utils/internal/error-handler/mappings.js.map +1 -0
  317. package/dist/utils/internal/error-handler/types.d.ts +160 -0
  318. package/dist/utils/internal/error-handler/types.d.ts.map +1 -0
  319. package/dist/utils/internal/error-handler/types.js +6 -0
  320. package/dist/utils/internal/error-handler/types.js.map +1 -0
  321. package/dist/utils/internal/health.d.ts +60 -0
  322. package/dist/utils/internal/health.d.ts.map +1 -0
  323. package/dist/utils/internal/health.js +46 -0
  324. package/dist/utils/internal/health.js.map +1 -0
  325. package/dist/utils/internal/logger.d.ts +300 -0
  326. package/dist/utils/internal/logger.d.ts.map +1 -0
  327. package/dist/utils/internal/logger.js +573 -0
  328. package/dist/utils/internal/logger.js.map +1 -0
  329. package/dist/utils/internal/performance.d.ts +78 -0
  330. package/dist/utils/internal/performance.d.ts.map +1 -0
  331. package/dist/utils/internal/performance.js +227 -0
  332. package/dist/utils/internal/performance.js.map +1 -0
  333. package/dist/utils/internal/requestContext.d.ts +200 -0
  334. package/dist/utils/internal/requestContext.d.ts.map +1 -0
  335. package/dist/utils/internal/requestContext.js +163 -0
  336. package/dist/utils/internal/requestContext.js.map +1 -0
  337. package/dist/utils/internal/runtime.d.ts +49 -0
  338. package/dist/utils/internal/runtime.d.ts.map +1 -0
  339. package/dist/utils/internal/runtime.js +90 -0
  340. package/dist/utils/internal/runtime.js.map +1 -0
  341. package/dist/utils/internal/startupBanner.d.ts +23 -0
  342. package/dist/utils/internal/startupBanner.d.ts.map +1 -0
  343. package/dist/utils/internal/startupBanner.js +34 -0
  344. package/dist/utils/internal/startupBanner.js.map +1 -0
  345. package/dist/utils/metrics/tokenCounter.d.ts +97 -0
  346. package/dist/utils/metrics/tokenCounter.d.ts.map +1 -0
  347. package/dist/utils/metrics/tokenCounter.js +162 -0
  348. package/dist/utils/metrics/tokenCounter.js.map +1 -0
  349. package/dist/utils/network/fetchWithTimeout.d.ts +91 -0
  350. package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -0
  351. package/dist/utils/network/fetchWithTimeout.js +305 -0
  352. package/dist/utils/network/fetchWithTimeout.js.map +1 -0
  353. package/dist/utils/pagination/pagination.d.ts +157 -0
  354. package/dist/utils/pagination/pagination.d.ts.map +1 -0
  355. package/dist/utils/pagination/pagination.js +191 -0
  356. package/dist/utils/pagination/pagination.js.map +1 -0
  357. package/dist/utils/parsing/csvParser.d.ts +84 -0
  358. package/dist/utils/parsing/csvParser.d.ts.map +1 -0
  359. package/dist/utils/parsing/csvParser.js +132 -0
  360. package/dist/utils/parsing/csvParser.js.map +1 -0
  361. package/dist/utils/parsing/dateParser.d.ts +103 -0
  362. package/dist/utils/parsing/dateParser.d.ts.map +1 -0
  363. package/dist/utils/parsing/dateParser.js +142 -0
  364. package/dist/utils/parsing/dateParser.js.map +1 -0
  365. package/dist/utils/parsing/frontmatterParser.d.ts +91 -0
  366. package/dist/utils/parsing/frontmatterParser.d.ts.map +1 -0
  367. package/dist/utils/parsing/frontmatterParser.js +163 -0
  368. package/dist/utils/parsing/frontmatterParser.js.map +1 -0
  369. package/dist/utils/parsing/index.d.ts +15 -0
  370. package/dist/utils/parsing/index.d.ts.map +1 -0
  371. package/dist/utils/parsing/index.js +15 -0
  372. package/dist/utils/parsing/index.js.map +1 -0
  373. package/dist/utils/parsing/jsonParser.d.ts +115 -0
  374. package/dist/utils/parsing/jsonParser.d.ts.map +1 -0
  375. package/dist/utils/parsing/jsonParser.js +177 -0
  376. package/dist/utils/parsing/jsonParser.js.map +1 -0
  377. package/dist/utils/parsing/pdfParser.d.ts +563 -0
  378. package/dist/utils/parsing/pdfParser.d.ts.map +1 -0
  379. package/dist/utils/parsing/pdfParser.js +775 -0
  380. package/dist/utils/parsing/pdfParser.js.map +1 -0
  381. package/dist/utils/parsing/thinkBlock.d.ts +31 -0
  382. package/dist/utils/parsing/thinkBlock.d.ts.map +1 -0
  383. package/dist/utils/parsing/thinkBlock.js +31 -0
  384. package/dist/utils/parsing/thinkBlock.js.map +1 -0
  385. package/dist/utils/parsing/xmlParser.d.ts +69 -0
  386. package/dist/utils/parsing/xmlParser.d.ts.map +1 -0
  387. package/dist/utils/parsing/xmlParser.js +140 -0
  388. package/dist/utils/parsing/xmlParser.js.map +1 -0
  389. package/dist/utils/parsing/yamlParser.d.ts +64 -0
  390. package/dist/utils/parsing/yamlParser.d.ts.map +1 -0
  391. package/dist/utils/parsing/yamlParser.js +129 -0
  392. package/dist/utils/parsing/yamlParser.js.map +1 -0
  393. package/dist/utils/scheduling/scheduler.d.ts +174 -0
  394. package/dist/utils/scheduling/scheduler.d.ts.map +1 -0
  395. package/dist/utils/scheduling/scheduler.js +248 -0
  396. package/dist/utils/scheduling/scheduler.js.map +1 -0
  397. package/dist/utils/security/idGenerator.d.ts +189 -0
  398. package/dist/utils/security/idGenerator.d.ts.map +1 -0
  399. package/dist/utils/security/idGenerator.js +301 -0
  400. package/dist/utils/security/idGenerator.js.map +1 -0
  401. package/dist/utils/security/index.d.ts +8 -0
  402. package/dist/utils/security/index.d.ts.map +1 -0
  403. package/dist/utils/security/index.js +8 -0
  404. package/dist/utils/security/index.js.map +1 -0
  405. package/dist/utils/security/rateLimiter.d.ts +171 -0
  406. package/dist/utils/security/rateLimiter.d.ts.map +1 -0
  407. package/dist/utils/security/rateLimiter.js +294 -0
  408. package/dist/utils/security/rateLimiter.js.map +1 -0
  409. package/dist/utils/security/sanitization.d.ts +430 -0
  410. package/dist/utils/security/sanitization.d.ts.map +1 -0
  411. package/dist/utils/security/sanitization.js +759 -0
  412. package/dist/utils/security/sanitization.js.map +1 -0
  413. package/dist/utils/telemetry/index.d.ts +12 -0
  414. package/dist/utils/telemetry/index.d.ts.map +1 -0
  415. package/dist/utils/telemetry/index.js +12 -0
  416. package/dist/utils/telemetry/index.js.map +1 -0
  417. package/dist/utils/telemetry/instrumentation.d.ts +62 -0
  418. package/dist/utils/telemetry/instrumentation.d.ts.map +1 -0
  419. package/dist/utils/telemetry/instrumentation.js +223 -0
  420. package/dist/utils/telemetry/instrumentation.js.map +1 -0
  421. package/dist/utils/telemetry/metrics.d.ts +170 -0
  422. package/dist/utils/telemetry/metrics.d.ts.map +1 -0
  423. package/dist/utils/telemetry/metrics.js +205 -0
  424. package/dist/utils/telemetry/metrics.js.map +1 -0
  425. package/dist/utils/telemetry/semconv.d.ts +147 -0
  426. package/dist/utils/telemetry/semconv.d.ts.map +1 -0
  427. package/dist/utils/telemetry/semconv.js +159 -0
  428. package/dist/utils/telemetry/semconv.js.map +1 -0
  429. package/dist/utils/telemetry/trace.d.ts +141 -0
  430. package/dist/utils/telemetry/trace.d.ts.map +1 -0
  431. package/dist/utils/telemetry/trace.js +193 -0
  432. package/dist/utils/telemetry/trace.js.map +1 -0
  433. package/dist/utils/types/guards.d.ts +209 -0
  434. package/dist/utils/types/guards.d.ts.map +1 -0
  435. package/dist/utils/types/guards.js +229 -0
  436. package/dist/utils/types/guards.js.map +1 -0
  437. package/dist/utils/types/index.d.ts +6 -0
  438. package/dist/utils/types/index.d.ts.map +1 -0
  439. package/dist/utils/types/index.js +6 -0
  440. package/dist/utils/types/index.js.map +1 -0
  441. package/dist/worker.d.ts +59 -0
  442. package/dist/worker.d.ts.map +1 -0
  443. package/dist/worker.js +216 -0
  444. package/dist/worker.js.map +1 -0
  445. package/package.json +377 -0
  446. package/skills/README.md +38 -0
  447. package/skills/add-export/SKILL.md +49 -0
  448. package/skills/add-prompt/SKILL.md +97 -0
  449. package/skills/add-provider/SKILL.md +53 -0
  450. package/skills/add-resource/SKILL.md +107 -0
  451. package/skills/add-service/SKILL.md +113 -0
  452. package/skills/add-tool/SKILL.md +110 -0
  453. package/skills/api-auth/SKILL.md +173 -0
  454. package/skills/api-config/SKILL.md +68 -0
  455. package/skills/api-context/SKILL.md +321 -0
  456. package/skills/api-errors/SKILL.md +146 -0
  457. package/skills/api-services/SKILL.md +24 -0
  458. package/skills/api-services/references/graph.md +124 -0
  459. package/skills/api-services/references/llm.md +46 -0
  460. package/skills/api-services/references/speech.md +72 -0
  461. package/skills/api-testing/SKILL.md +263 -0
  462. package/skills/api-utils/SKILL.md +106 -0
  463. package/skills/api-utils/references/formatting.md +237 -0
  464. package/skills/api-utils/references/parsing.md +263 -0
  465. package/skills/api-utils/references/security.md +226 -0
  466. package/skills/api-workers/SKILL.md +165 -0
  467. package/skills/devcheck/SKILL.md +31 -0
  468. package/skills/maintenance/SKILL.md +52 -0
  469. package/skills/migrate-mcp-ts-template/SKILL.md +131 -0
  470. package/skills/release/SKILL.md +67 -0
  471. package/skills/setup/SKILL.md +89 -0
  472. package/skills/walkthrough-init/SKILL.md +50 -0
  473. package/templates/.env.example +17 -0
  474. package/templates/AGENTS.md +113 -0
  475. package/templates/CLAUDE.md +113 -0
  476. package/templates/_tsconfig.json +33 -0
  477. package/templates/biome.template.json +43 -0
  478. package/templates/package.json +26 -0
  479. package/templates/src/index.ts +16 -0
  480. package/templates/src/mcp-server/prompts/definitions/echo.prompt.ts +19 -0
  481. package/templates/src/mcp-server/resources/definitions/echo.resource.ts +30 -0
  482. package/templates/src/mcp-server/tools/definitions/echo.tool.ts +24 -0
  483. package/templates/vitest.config.ts +12 -0
  484. package/tsconfig.base.json +44 -0
  485. package/vitest.config.base.ts +38 -0
@@ -0,0 +1,72 @@
1
+ # Speech Service (`services/speech`)
2
+
3
+ ## `ISpeechProvider` interface
4
+
5
+ The provider interface — implemented by ElevenLabs (TTS) and Whisper (STT):
6
+
7
+ | Member | Type | Notes |
8
+ |:-------|:-----|:------|
9
+ | `.textToSpeech(opts)` | `Promise<TextToSpeechResult>` | Synthesize speech from text |
10
+ | `.speechToText(opts)` | `Promise<SpeechToTextResult>` | Transcribe audio to text |
11
+ | `.getVoices()` | `Promise<Voice[]>` | List available voices (TTS providers only) |
12
+ | `.healthCheck()` | `Promise<boolean>` | Liveness check |
13
+ | `.supportsTTS` | `boolean` | Check before calling `textToSpeech` |
14
+ | `.supportsSTT` | `boolean` | Check before calling `speechToText` |
15
+ | `.name` | `string` | Provider identifier (e.g., `'elevenlabs'`) |
16
+
17
+ ## `SpeechService` orchestrator
18
+
19
+ `SpeechService` does **not** expose `textToSpeech`/`speechToText` directly. It manages independent TTS and STT provider instances. Access the underlying providers via accessors:
20
+
21
+ | Method | Return | Notes |
22
+ |:-------|:-------|:------|
23
+ | `.getTTSProvider()` | `ISpeechProvider` | Throws `McpError(InvalidRequest)` if no TTS provider configured |
24
+ | `.getSTTProvider()` | `ISpeechProvider` | Throws `McpError(InvalidRequest)` if no STT provider configured |
25
+ | `.hasTTS()` | `boolean` | Check if TTS is available |
26
+ | `.hasSTT()` | `boolean` | Check if STT is available |
27
+ | `.healthCheck()` | `Promise<{ tts: boolean; stt: boolean }>` | Checks both providers in parallel |
28
+
29
+ ## Providers
30
+
31
+ | Provider | Capability | Tier 3 peer |
32
+ |:---------|:-----------|:------------|
33
+ | `ElevenLabsProvider` | TTS only (`supportsTTS: true`, `supportsSTT: false`) | ElevenLabs API (direct HTTP) |
34
+ | `WhisperProvider` | STT only (`supportsTTS: false`, `supportsSTT: true`) | `openai` (Whisper API). 25MB file size limit. |
35
+
36
+ ## Configuration
37
+
38
+ | Env Var | Purpose |
39
+ |:--------|:--------|
40
+ | `SPEECH_TTS_ENABLED` | Enable TTS (`true`/`false`) |
41
+ | `SPEECH_TTS_API_KEY` | TTS provider API key (e.g., ElevenLabs) |
42
+ | `SPEECH_TTS_DEFAULT_MODEL_ID` | Default TTS model ID |
43
+ | `SPEECH_TTS_DEFAULT_VOICE_ID` | Default TTS voice ID |
44
+ | `SPEECH_STT_ENABLED` | Enable STT (`true`/`false`) |
45
+ | `SPEECH_STT_API_KEY` | STT provider API key (e.g., OpenAI) |
46
+
47
+ ## Usage
48
+
49
+ ```ts
50
+ // Text-to-Speech — access the provider, then call methods on it
51
+ const ttsProvider = speechService.getTTSProvider();
52
+ const ttsResult = await ttsProvider.textToSpeech({
53
+ text: 'Hello, world!',
54
+ voice: 'some-voice-id',
55
+ outputFormat: 'mp3_44100_128',
56
+ });
57
+
58
+ // Speech-to-Text
59
+ const sttProvider = speechService.getSTTProvider();
60
+ const sttResult = await sttProvider.speechToText({
61
+ audioData: buffer,
62
+ mimeType: 'audio/mp3',
63
+ language: 'en',
64
+ });
65
+
66
+ // List available voices
67
+ const voices = await ttsProvider.getVoices();
68
+
69
+ // Health check
70
+ const health = await speechService.healthCheck();
71
+ // health: { tts: boolean, stt: boolean }
72
+ ```
@@ -0,0 +1,263 @@
1
+ ---
2
+ name: api-testing
3
+ description: >
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
+ metadata:
6
+ author: cyanheads
7
+ version: "1.0"
8
+ audience: external
9
+ type: reference
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ Tests target handler behavior directly — call `handler(input, ctx)`, assert on the return value or thrown error. The framework's handler factory (try/catch, formatting, telemetry) is not involved. Use `createMockContext` from `@cyanheads/mcp-ts-core/testing` to construct the `ctx` argument.
15
+
16
+ **Philosophy:** Test behavior, not implementation. Refactors should not break tests. Colocate test files with source (`foo.tool.ts` → `foo.tool.test.ts`). Integration tests at I/O boundaries over unit tests of internals.
17
+
18
+ ---
19
+
20
+ ## `createMockContext` options
21
+
22
+ ```ts
23
+ import { createMockContext } from '@cyanheads/mcp-ts-core/testing';
24
+
25
+ createMockContext() // minimal — ctx.state operations throw without tenantId
26
+ createMockContext({ tenantId: 'test-tenant' }) // enables ctx.state (tenant-scoped in-memory storage)
27
+ createMockContext({ sample: vi.fn().mockResolvedValue(...) }) // with MCP sampling
28
+ createMockContext({ elicit: vi.fn().mockResolvedValue(...) }) // with elicitation
29
+ createMockContext({ progress: true }) // with task progress (ctx.progress populated)
30
+ createMockContext({ requestId: 'my-id' }) // override request ID (default: 'test-request-id')
31
+ createMockContext({ signal: controller.signal }) // custom AbortSignal
32
+ createMockContext({ auth: { clientId: 'test', scopes: [] } }) // with auth context
33
+ createMockContext({ uri: new URL('myscheme://item/123') }) // for resource handler testing
34
+ ```
35
+
36
+ `MockContextOptions` interface:
37
+
38
+ ```ts
39
+ interface MockContextOptions {
40
+ auth?: AuthContext;
41
+ elicit?: (message: string, schema: z.ZodObject<z.ZodRawShape>) => Promise<ElicitResult>;
42
+ progress?: boolean;
43
+ requestId?: string;
44
+ sample?: (messages: SamplingMessage[], opts?: SamplingOpts) => Promise<CreateMessageResult>;
45
+ signal?: AbortSignal;
46
+ tenantId?: string;
47
+ uri?: URL;
48
+ }
49
+ ```
50
+
51
+ | Option | Effect |
52
+ |:-------|:-------|
53
+ | _(none)_ | Minimal context — `ctx.state` operations throw without `tenantId`; `ctx.elicit`/`ctx.sample`/`ctx.progress` are `undefined` |
54
+ | `auth` | Sets `ctx.auth` for scope-checking tests |
55
+ | `elicit` | Assigns a function to `ctx.elicit` for testing elicitation calls |
56
+ | `progress` | Populates `ctx.progress` with real state-tracking implementation (see below) |
57
+ | `requestId` | Overrides `ctx.requestId` (default: `'test-request-id'`) |
58
+ | `sample` | Assigns a function to `ctx.sample` for testing sampling calls |
59
+ | `signal` | Overrides `ctx.signal` — useful for cancellation testing |
60
+ | `tenantId` | Sets `ctx.tenantId` and enables `ctx.state` operations with in-memory storage |
61
+ | `uri` | Sets `ctx.uri` for resource handler testing |
62
+
63
+ ### Mock progress
64
+
65
+ When `progress: true`, `ctx.progress` is a real state-tracking object — not `vi.fn()` spies. It maintains internal state accessible via inspection properties:
66
+
67
+ ```ts
68
+ const ctx = createMockContext({ progress: true });
69
+ // ctx.progress is typed as ContextProgress, but the mock exposes internal state:
70
+ const progress = ctx.progress as ContextProgress & {
71
+ _total: number;
72
+ _completed: number;
73
+ _messages: string[];
74
+ };
75
+
76
+ await ctx.progress!.setTotal(10);
77
+ await ctx.progress!.increment(3);
78
+ await ctx.progress!.update('step message');
79
+
80
+ expect(progress._total).toBe(10);
81
+ expect(progress._completed).toBe(3);
82
+ expect(progress._messages).toContain('step message');
83
+ ```
84
+
85
+ ### Mock logger
86
+
87
+ `ctx.log` captures all log calls for inspection:
88
+
89
+ ```ts
90
+ const ctx = createMockContext();
91
+ const log = ctx.log as ContextLogger & {
92
+ calls: Array<{ level: string; msg: string; data?: unknown }>;
93
+ };
94
+
95
+ await myTool.handler(input, ctx);
96
+ expect(log.calls.some(c => c.level === 'info' && c.msg.includes('Processing'))).toBe(true);
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Full test example
102
+
103
+ ```ts
104
+ // src/mcp-server/tools/definitions/my-tool.tool.test.ts
105
+ import { describe, expect, it, vi } from 'vitest';
106
+ import { createMockContext } from '@cyanheads/mcp-ts-core/testing';
107
+ import { McpError } from '@cyanheads/mcp-ts-core/errors';
108
+ import { myTool } from '@/mcp-server/tools/definitions/my-tool.tool.js';
109
+
110
+ describe('myTool', () => {
111
+ it('returns expected output', async () => {
112
+ const ctx = createMockContext();
113
+ const input = myTool.input.parse({ query: 'hello' });
114
+ const result = await myTool.handler(input, ctx);
115
+ expect(result.result).toBe('Found: hello');
116
+ });
117
+
118
+ it('throws McpError on invalid state', async () => {
119
+ const ctx = createMockContext();
120
+ const input = myTool.input.parse({ query: 'TRIGGER_ERROR' });
121
+ await expect(myTool.handler(input, ctx)).rejects.toThrow(McpError);
122
+ });
123
+
124
+ it('formats response correctly', () => {
125
+ const result = { result: 'test' };
126
+ const blocks = myTool.format!(result);
127
+ expect(blocks[0].type).toBe('text');
128
+ });
129
+ });
130
+ ```
131
+
132
+ Key points:
133
+
134
+ - Parse input through `myTool.input.parse(...)` — validates against the Zod schema and produces the typed input the handler expects.
135
+ - Call `myTool.handler(input, ctx)` directly — not through the MCP SDK or any framework wrapper.
136
+ - Assert on the return value for happy paths; use `.rejects.toThrow(McpError)` for error paths.
137
+ - Test `format` separately if the tool defines one — it is a pure function and needs no `ctx`.
138
+
139
+ ---
140
+
141
+ ## Testing with optional capabilities
142
+
143
+ ```ts
144
+ it('uses elicitation when available', async () => {
145
+ const elicit = vi.fn().mockResolvedValue({
146
+ action: 'accept',
147
+ data: { format: 'json' },
148
+ });
149
+ const ctx = createMockContext({ elicit });
150
+ const input = myTool.input.parse({ query: 'hello' });
151
+ await myTool.handler(input, ctx);
152
+ expect(elicit).toHaveBeenCalledOnce();
153
+ });
154
+
155
+ it('uses sampling when available', async () => {
156
+ const sample = vi.fn().mockResolvedValue({
157
+ role: 'assistant',
158
+ content: { type: 'text', text: 'Summary text' },
159
+ });
160
+ const ctx = createMockContext({ sample });
161
+ const input = myTool.input.parse({ query: 'summarize this' });
162
+ const result = await myTool.handler(input, ctx);
163
+ expect(result.summary).toBeDefined();
164
+ });
165
+
166
+ it('handles missing elicitation gracefully', async () => {
167
+ // ctx.elicit is undefined — handler must check before calling
168
+ const ctx = createMockContext();
169
+ const input = myTool.input.parse({ query: 'hello' });
170
+ // Should not throw even when ctx.elicit is absent
171
+ await expect(myTool.handler(input, ctx)).resolves.toBeDefined();
172
+ });
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Vitest config
178
+
179
+ ```ts
180
+ // vitest.config.ts
181
+ import { defineConfig } from 'vitest/config';
182
+ import tsconfigPaths from 'vite-tsconfig-paths';
183
+
184
+ export default defineConfig({
185
+ plugins: [tsconfigPaths()],
186
+ ssr: {
187
+ noExternal: ['zod'],
188
+ },
189
+ test: {
190
+ globals: true,
191
+ environment: 'node',
192
+ setupFiles: ['./tests/setup.ts'],
193
+ exclude: ['tests/integration/**', 'node_modules/**'],
194
+ pool: 'forks',
195
+ maxWorkers: 4,
196
+ isolate: true,
197
+ coverage: {
198
+ provider: 'istanbul',
199
+ reporter: ['text', 'json', 'html'],
200
+ include: ['src/**/*.ts'],
201
+ exclude: ['src/**/*.d.ts'],
202
+ thresholds: {
203
+ lines: 80,
204
+ functions: 75,
205
+ branches: 70,
206
+ statements: 80,
207
+ },
208
+ },
209
+ },
210
+ });
211
+ ```
212
+
213
+ Key points:
214
+ - `tsconfigPaths()` resolves the `@/` path alias from `tsconfig.json` — no manual `resolve.alias` needed.
215
+ - `ssr: { noExternal: ['zod'] }` fixes Vite SSR transform issues with Zod 4.
216
+ - Integration tests (in `tests/integration/`) are excluded from the default run; they have their own config.
217
+ - `pool: 'forks'` with `isolate: true` prevents mock pollution between test files.
218
+ - `setupFiles` points to `tests/setup.ts` for any global test setup (e.g., env vars).
219
+
220
+ ---
221
+
222
+ ## Test isolation
223
+
224
+ **Construct dependencies fresh in `beforeEach`.** Never share mutable state across tests.
225
+
226
+ ```ts
227
+ import { beforeEach, describe, expect, it } from 'vitest';
228
+ import { initMyService } from '@/services/my-domain/my-service.js';
229
+
230
+ describe('myTool with service', () => {
231
+ beforeEach(() => {
232
+ // Re-initialize with a fresh instance before each test
233
+ initMyService(mockConfig, mockStorage);
234
+ });
235
+
236
+ it('calls service correctly', async () => {
237
+ const ctx = createMockContext({ tenantId: 'test-tenant' });
238
+ // ...
239
+ });
240
+ });
241
+ ```
242
+
243
+ - Re-init services with `initMyService()` (or equivalent) per test suite — the module-level singleton must be reset so tests don't share state.
244
+ - Vitest runs test files in separate worker threads — parallel file execution is safe by default.
245
+ - Use `createMockContext({ tenantId })` whenever the handler accesses `ctx.state` — omitting `tenantId` causes `ctx.state` to throw.
246
+
247
+ ---
248
+
249
+ ## McpError assertions
250
+
251
+ ```ts
252
+ import { McpError, JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
253
+
254
+ it('throws NotFound for missing resource', async () => {
255
+ const ctx = createMockContext();
256
+ const input = myTool.input.parse({ id: 'nonexistent' });
257
+ await expect(myTool.handler(input, ctx)).rejects.toMatchObject({
258
+ code: JsonRpcErrorCode.NotFound,
259
+ });
260
+ });
261
+ ```
262
+
263
+ Use `.rejects.toThrow(McpError)` to assert type only. Use `.rejects.toMatchObject({ code: ... })` when the specific error code matters.
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: api-utils
3
+ description: >
4
+ API reference for all `@cyanheads/mcp-ts-core/utils/*` subpath exports. Use when looking up utility method signatures, options, peer dependencies, or usage patterns.
5
+ metadata:
6
+ author: cyanheads
7
+ version: "2.0"
8
+ audience: external
9
+ type: reference
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ Utility subpath exports from `@cyanheads/mcp-ts-core/utils/*`. Complex utilities with rich APIs have dedicated reference files; simpler utilities are documented inline below.
15
+
16
+ **Tier 3** = optional peer dependency. Install as needed (e.g., `bun add js-yaml`). All Tier 3 methods are **async** (lazy-load deps on first call).
17
+
18
+ ## References
19
+
20
+ | Reference | Path | Subpath | Covers |
21
+ |:----------|:-----|:--------|:-------|
22
+ | Formatting | `references/formatting.md` | `utils/formatting` | `markdown()`, `MarkdownBuilder`, `diffFormatter`, `tableFormatter`, `treeFormatter` — builder patterns, option types, style variants, usage examples |
23
+ | Parsing | `references/parsing.md` | `utils/parsing` | `yamlParser`, `xmlParser`, `csvParser`, `jsonParser`, `pdfParser`, `dateParser`, `frontmatterParser` — method signatures, option types, peer deps, `Allow` flags, PDF workflows |
24
+ | Security | `references/security.md` | `utils/security` | `sanitization`, `RateLimiter`, `IdGenerator` — config types, method details, sensitive fields, usage examples |
25
+
26
+ ---
27
+
28
+ ## `@cyanheads/mcp-ts-core/utils/network`
29
+
30
+ | Export | API | Notes |
31
+ |:-------|:----|:------|
32
+ | `fetchWithTimeout` | `(url, timeoutMs, context: RequestContext, options?: FetchWithTimeoutOptions) -> Promise<Response>` | Wraps `fetch` with `AbortController` timeout. `FetchWithTimeoutOptions` extends `RequestInit` (minus `signal`) and adds `rejectPrivateIPs?: boolean` and `signal?: AbortSignal` (external cancellation). SSRF protection: blocks RFC 1918, loopback, link-local, CGNAT, cloud metadata. DNS validation on Node; hostname-only on Workers. Manual redirect following (max 5) with per-hop SSRF check. |
33
+
34
+ ---
35
+
36
+ ## `@cyanheads/mcp-ts-core/utils/pagination`
37
+
38
+ | Export | API | Notes |
39
+ |:-------|:----|:------|
40
+ | `extractCursor` | `(params?) -> string \| undefined` | Extracts opaque cursor string from MCP request params. Checks `params.cursor` then `params._meta.cursor`. Returns `undefined` when no cursor is present. Does not decode. |
41
+ | `paginateArray` | `<T>(items, cursorStr, defaultPageSize, maxPageSize, context: RequestContext) -> PaginatedResult<T>` | Decodes cursor, slices array, returns `{ items, nextCursor?, totalCount }`. `nextCursor` omitted on last page. Throws `McpError(InvalidParams)` on invalid cursor. |
42
+ | `encodeCursor` | `(state: PaginationState) -> string` | Encodes `{ offset, limit, ...extra }` to opaque base64url string. |
43
+ | `decodeCursor` | `(cursor, context: RequestContext) -> PaginationState` | Decodes opaque base64url cursor. Throws `McpError(InvalidParams)` if malformed. |
44
+
45
+ ---
46
+
47
+ ## `@cyanheads/mcp-ts-core/utils/runtime`
48
+
49
+ | Export | API | Notes |
50
+ |:-------|:----|:------|
51
+ | `runtimeCaps` | `RuntimeCapabilities` object | Snapshot at import time. Fields: `isNode`, `isBun`, `isWorkerLike`, `isBrowserLike`, `hasProcess`, `hasBuffer`, `hasTextEncoder`, `hasPerformanceNow`. All booleans, never throw. |
52
+
53
+ ---
54
+
55
+ ## `@cyanheads/mcp-ts-core/utils/scheduling`
56
+
57
+ | Export | API | Notes |
58
+ |:-------|:----|:------|
59
+ | `schedulerService` | `.schedule(id, schedule, taskFunction, description) -> Promise<Job>` `.start(id) -> void` `.stop(id) -> void` `.remove(id) -> void` `.listJobs() -> Job[]` | **Async** `schedule()` — Tier 3 peer: `node-cron`. **Node-only** (throws `ConfigurationError` in Workers). Jobs start in stopped state; call `start(id)` to activate. Skips overlapping executions. Each tick gets fresh `RequestContext`. `Job: { id, schedule, description, isRunning, task }`. `taskFunction: (context: RequestContext) => void | Promise<void>`. |
60
+
61
+ ---
62
+
63
+ ## `@cyanheads/mcp-ts-core/utils/types`
64
+
65
+ The `utils/types` subpath exports only two guards. The full set of guards lives in the internal module and is not part of the public API.
66
+
67
+ | Export | Signature | Notes |
68
+ |:-------|:----------|:------|
69
+ | `isErrorWithCode` | `(error: unknown) -> error is Error & { code: unknown }` | Type guard — `true` when value is an `Error` instance with a `code` property |
70
+ | `isRecord` | `(value: unknown) -> value is Record<string, unknown>` | Type guard for plain objects (non-null, non-array) |
71
+
72
+ ---
73
+
74
+ ## `@cyanheads/mcp-ts-core/utils/logger`
75
+
76
+ | Export | API | Notes |
77
+ |:-------|:----|:------|
78
+ | `logger` | Pino instance. `.debug()` `.info()` `.notice()` `.warning()` `.error()` `.fatal()` | Global structured logger. Use `ctx.log` in handlers instead. `logger` is for lifecycle/background contexts (startup, shutdown, `setup()`). Auto-redacts sensitive fields. |
79
+
80
+ ---
81
+
82
+ ## `@cyanheads/mcp-ts-core/utils/requestContext`
83
+
84
+ | Export | API | Notes |
85
+ |:-------|:----|:------|
86
+ | `requestContextService` | `.createRequestContext(opts?) -> RequestContext` `.createFromHeaders(headers, fallback?) -> RequestContext` | Creates tracing context with `requestId`, `timestamp`, `traceId`, `spanId`, `tenantId`, `auth`. Internal — most consumers use `ctx` from handlers. |
87
+ | `RequestContext` | Type: `{ requestId, timestamp, operation?, traceId?, spanId?, tenantId?, auth? }` | Request tracing metadata. |
88
+
89
+ ---
90
+
91
+ ## `@cyanheads/mcp-ts-core/utils/errorHandler`
92
+
93
+ | Export | API | Notes |
94
+ |:-------|:----|:------|
95
+ | `ErrorHandler` | `.tryCatch<T>(fn, opts) -> Promise<T>` `.handleError(error, opts) -> Error` `.determineErrorCode(error) -> JsonRpcErrorCode` `.mapError(error, mappings, defaultFactory?) -> T \| Error` `.formatError(error) -> Record<string, unknown>` | Service-level error handling. `tryCatch` wraps async or sync `fn`, logs via `handleError`, and always rethrows. No `.tryCatchSync()`. Use in services, NOT in tool handlers (those throw raw `McpError`). Options: `operation`, `context`, `errorCode`, `input`, `rethrow`, `includeStack`, `critical`, `errorMapper`. |
96
+
97
+ ---
98
+
99
+ ## `@cyanheads/mcp-ts-core/utils/telemetry`
100
+
101
+ | Export | Subpath | API | Notes |
102
+ |:-------|:--------|:----|:------|
103
+ | `initInstrumentation` | `telemetry/instrumentation` | `(config) -> void` | Initializes OpenTelemetry SDK with OTLP exporter. Call once at startup. |
104
+ | `metrics` | `telemetry/metrics` | `.recordToolExecution(name, duration, success)` `.recordResourceAccess(uri, duration)` `.getMetrics()` | In-process metrics collection with OTEL integration. |
105
+ | `trace` | `telemetry/trace` | `.startSpan(name, opts?)` `.runInSpan(name, fn)` `.runInContext(fn)` | Tracing helpers wrapping OTEL `@opentelemetry/api`. |
106
+ | `SEMCONV_*` | `telemetry/semconv` | 38 semantic convention constants | Attribute keys following OpenTelemetry semantic conventions. |
@@ -0,0 +1,237 @@
1
+ # Formatting Utilities (`utils/formatting`)
2
+
3
+ ```ts
4
+ import { markdown, MarkdownBuilder, diffFormatter, tableFormatter, treeFormatter } from '@cyanheads/mcp-ts-core/utils/formatting';
5
+ ```
6
+
7
+ ---
8
+
9
+ ## `markdown()` / `MarkdownBuilder`
10
+
11
+ `markdown()` is a factory shorthand for `new MarkdownBuilder()`. Fluent builder — all methods return `this` except `build()`.
12
+
13
+ ### Methods
14
+
15
+ | Method | Signature | Notes |
16
+ |:-------|:----------|:------|
17
+ | `h1` | `(text, emoji?) -> this` | `# [emoji ]text` |
18
+ | `h2` | `(text, emoji?) -> this` | `## [emoji ]text` |
19
+ | `h3` | `(text, emoji?) -> this` | `### [emoji ]text` |
20
+ | `h4` | `(text, emoji?) -> this` | `#### [emoji ]text` |
21
+ | `keyValue` | `(key, value) -> this` | `**key:** value` |
22
+ | `keyValuePlain` | `(key, value) -> this` | `key: value` (no bold) |
23
+ | `list` | `(items, ordered?) -> this` | `ordered` defaults to `false`; empty arrays silently ignored |
24
+ | `codeBlock` | `(content, language?) -> this` | Fenced block; `language` defaults to `''` |
25
+ | `inlineCode` | `(code) -> this` | Backtick-wrapped; no trailing newline |
26
+ | `paragraph` | `(text) -> this` | Text + `\n\n` |
27
+ | `blockquote` | `(text) -> this` | Each line prefixed with `> ` |
28
+ | `hr` | `() -> this` | `---` |
29
+ | `link` | `(text, url) -> this` | `[text](url)`; no trailing newline |
30
+ | `table` | `(headers, rows) -> this` | GFM table; no-ops if headers or rows empty |
31
+ | `section` | `(title, content) -> this` | H2 heading + callback |
32
+ | `section` | `(title, level, content) -> this` | Heading at level 2/3/4 + callback |
33
+ | `details` | `(summary, details) -> this` | HTML `<details>`/`<summary>` collapsible block |
34
+ | `alert` | `(type, content) -> this` | GFM `[!TYPE]` alert blockquote |
35
+ | `taskList` | `(items) -> this` | GFM checkbox list; `items: Array<{ checked: boolean; text: string }>` |
36
+ | `image` | `(altText, url, title?) -> this` | `![alt](url "title")` |
37
+ | `strikethrough` | `(text) -> this` | `~~text~~`; no trailing newline |
38
+ | `diff` | `(changes) -> this` | ` ```diff ` block; `changes: { additions?: string[]; deletions?: string[]; context?: string[] }` |
39
+ | `badge` | `(label, message, color?) -> this` | shields.io badge image; `color` defaults to `'blue'` |
40
+ | `bold` | `(text) -> this` | `**text**`; no trailing newline |
41
+ | `italic` | `(text) -> this` | `*text*`; no trailing newline |
42
+ | `boldItalic` | `(text) -> this` | `***text***`; no trailing newline |
43
+ | `raw` | `(markdown) -> this` | Appends verbatim |
44
+ | `blankLine` | `() -> this` | Single `\n` |
45
+ | `text` | `(text) -> this` | Plain text, no formatting, no implicit newlines |
46
+ | `when` | `(condition, content) -> this` | Conditional append; `content: () => void` |
47
+ | `reset` | `() -> this` | Clears buffer |
48
+ | `build` | `() -> string` | Returns trimmed joined buffer; does NOT reset |
49
+
50
+ ### Usage
51
+
52
+ ```ts
53
+ const md = markdown()
54
+ .h1('Report', '📊')
55
+ .paragraph('Generated automatically.')
56
+ .section('Results', 3, () => {
57
+ md.table(['Name', 'Score'], [['Alice', '95'], ['Bob', '87']]);
58
+ })
59
+ .when(hasWarnings, () => {
60
+ md.alert('warning', 'Some items need attention.');
61
+ })
62
+ .build();
63
+ ```
64
+
65
+ Inline methods (`bold`, `italic`, `inlineCode`, `link`, `strikethrough`) do not append newlines — combine them with `text()` or `paragraph()` for inline composition.
66
+
67
+ ---
68
+
69
+ ## `diffFormatter`
70
+
71
+ **Tier 3 peer:** `diff` (`bun add diff`). All methods are **async**.
72
+
73
+ ### Types
74
+
75
+ ```ts
76
+ type DiffFormat = 'unified' | 'patch' | 'inline';
77
+
78
+ interface DiffFormatterOptions {
79
+ context?: number; // unchanged lines around changes; default 3
80
+ format?: DiffFormat; // default 'unified'
81
+ includeHeaders?: boolean; // ---/+++ headers (patch only); default true
82
+ oldPath?: string; // file path for old version (headers)
83
+ newPath?: string; // file path for new version (headers)
84
+ showLineNumbers?: boolean; // default true
85
+ }
86
+ ```
87
+
88
+ ### Methods
89
+
90
+ | Method | Signature | Returns |
91
+ |:-------|:----------|:--------|
92
+ | `diff` | `(oldText, newText, options?, context?) -> Promise<string>` | Formatted diff string |
93
+ | `diffLines` | `(oldLines, newLines, options?, context?) -> Promise<string>` | Same as `diff` but accepts pre-split `string[]` arrays |
94
+ | `diffWords` | `(oldText, newText, context?) -> Promise<string>` | Word-level inline diff: `[+added+]` / `[-removed-]` |
95
+ | `getStats` | `(oldText, newText, context?) -> Promise<{ additions, deletions, changes }>` | Line-count stats; `changes = additions + deletions` |
96
+
97
+ ### Format behavior
98
+
99
+ | Format | Output |
100
+ |:-------|:-------|
101
+ | `'unified'` | Hunk headers (`@@`) only — strips `---`/`+++` file headers. Default. |
102
+ | `'patch'` | Full patch with file headers. `includeHeaders: false` strips them. |
103
+ | `'inline'` | No headers or hunk markers. Additions as `[+text+]`, removals as `[-text-]`. |
104
+
105
+ ### Usage
106
+
107
+ ```ts
108
+ const diff = await diffFormatter.diff(oldCode, newCode, {
109
+ format: 'unified',
110
+ context: 5,
111
+ showLineNumbers: true,
112
+ });
113
+
114
+ const stats = await diffFormatter.getStats(oldCode, newCode);
115
+ // { additions: 12, deletions: 3, changes: 15 }
116
+ ```
117
+
118
+ ---
119
+
120
+ ## `tableFormatter`
121
+
122
+ Synchronous — no peer dependency.
123
+
124
+ ### Types
125
+
126
+ ```ts
127
+ type TableStyle = 'markdown' | 'ascii' | 'grid' | 'compact';
128
+ type Alignment = 'left' | 'center' | 'right';
129
+
130
+ interface TableFormatterOptions {
131
+ style?: TableStyle; // default 'markdown'
132
+ alignment?: Record<string, Alignment>; // key = column name or numeric index string
133
+ maxWidth?: number; // truncates at this width; default 50
134
+ minWidth?: number; // default 3
135
+ truncate?: boolean; // truncate with '...' when exceeding maxWidth; default true
136
+ headerStyle?: 'bold' | 'uppercase' | 'none';
137
+ padding?: number; // spaces around cell content; default 1
138
+ }
139
+ ```
140
+
141
+ ### Methods
142
+
143
+ | Method | Signature | Notes |
144
+ |:-------|:----------|:------|
145
+ | `format` | `<T extends Record<string, unknown>>(data, options?, context?) -> string` | Extracts headers from first object's keys; stringifies values. Returns `''` if empty. |
146
+ | `formatRaw` | `(headers, rows, options?, context?) -> string` | Pre-serialized `string[][]`; every row must match `headers.length`. Returns `''` if empty. |
147
+
148
+ ### Styles
149
+
150
+ | Style | Description |
151
+ |:------|:------------|
152
+ | `markdown` | GFM pipes with alignment indicators in separator row |
153
+ | `ascii` | `+`/`-`/`|` box drawing |
154
+ | `grid` | Unicode box drawing (`┌─┬─┐` / `│` / `├─┼─┤` / `└─┴─┘`) |
155
+ | `compact` | Space-separated, no borders |
156
+
157
+ ### Usage
158
+
159
+ ```ts
160
+ // From objects — headers auto-extracted from keys
161
+ const table = tableFormatter.format(
162
+ [{ name: 'Alice', score: 95 }, { name: 'Bob', score: 87 }],
163
+ { style: 'grid', alignment: { score: 'right' } },
164
+ );
165
+
166
+ // From raw arrays
167
+ const raw = tableFormatter.formatRaw(
168
+ ['Name', 'Score'],
169
+ [['Alice', '95'], ['Bob', '87']],
170
+ { style: 'markdown', headerStyle: 'bold' },
171
+ );
172
+ ```
173
+
174
+ ---
175
+
176
+ ## `treeFormatter`
177
+
178
+ Synchronous — no peer dependency.
179
+
180
+ ### Types
181
+
182
+ ```ts
183
+ type TreeStyle = 'unicode' | 'ascii' | 'compact';
184
+
185
+ interface TreeNode {
186
+ name: string; // required, must be non-empty
187
+ children?: TreeNode[]; // presence determines folder vs leaf icon
188
+ metadata?: Record<string, unknown>; // rendered as key=value when showMetadata enabled
189
+ }
190
+
191
+ interface TreeFormatterOptions {
192
+ style?: TreeStyle; // default 'unicode'
193
+ maxDepth?: number; // 0-based cutoff; undefined = no limit
194
+ showMetadata?: boolean; // append metadata after node name; default false
195
+ icons?: boolean; // prefix nodes with icons; default false
196
+ indent?: string; // per-level indent; default ' ' (two spaces)
197
+ folderIcon?: string; // icon for branch nodes; default folder emoji
198
+ fileIcon?: string; // icon for leaf nodes; default page emoji
199
+ }
200
+ ```
201
+
202
+ ### Methods
203
+
204
+ | Method | Signature | Notes |
205
+ |:-------|:----------|:------|
206
+ | `format` | `(root, options?, context?) -> string` | Single tree. Detects and marks circular references as `[Circular Reference]`. |
207
+ | `formatMultiple` | `(roots, options?, context?) -> string` | Forest of trees joined by `\n\n`. `roots` must be non-empty. |
208
+
209
+ ### Styles
210
+
211
+ | Style | Connectors |
212
+ |:------|:-----------|
213
+ | `unicode` | `├──` / `└──` / `│` |
214
+ | `ascii` | `+--` / `\--` / `|` |
215
+ | `compact` | Indented list, no connectors |
216
+
217
+ ### Usage
218
+
219
+ ```ts
220
+ const tree: TreeNode = {
221
+ name: 'src',
222
+ children: [
223
+ { name: 'index.ts' },
224
+ {
225
+ name: 'utils',
226
+ children: [{ name: 'helpers.ts', metadata: { lines: 42 } }],
227
+ },
228
+ ],
229
+ };
230
+
231
+ const output = treeFormatter.format(tree, {
232
+ style: 'unicode',
233
+ icons: true,
234
+ showMetadata: true,
235
+ maxDepth: 3,
236
+ });
237
+ ```