effect 4.0.7 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (679) hide show
  1. package/README.md +1 -1
  2. package/dist/BigDecimal.d.ts.map +1 -1
  3. package/dist/BigDecimal.js +3 -0
  4. package/dist/BigDecimal.js.map +1 -1
  5. package/dist/Channel.d.ts +12 -6
  6. package/dist/Channel.d.ts.map +1 -1
  7. package/dist/Channel.js +9 -3
  8. package/dist/Channel.js.map +1 -1
  9. package/dist/Config.d.ts +7 -1
  10. package/dist/Config.d.ts.map +1 -1
  11. package/dist/Config.js.map +1 -1
  12. package/dist/Context.d.ts +18 -1
  13. package/dist/Context.d.ts.map +1 -1
  14. package/dist/Context.js +27 -8
  15. package/dist/Context.js.map +1 -1
  16. package/dist/Cron.d.ts +81 -11
  17. package/dist/Cron.d.ts.map +1 -1
  18. package/dist/Cron.js +101 -26
  19. package/dist/Cron.js.map +1 -1
  20. package/dist/Duration.d.ts +78 -0
  21. package/dist/Duration.d.ts.map +1 -1
  22. package/dist/Duration.js +123 -0
  23. package/dist/Duration.js.map +1 -1
  24. package/dist/Effect.d.ts +164 -7
  25. package/dist/Effect.d.ts.map +1 -1
  26. package/dist/Effect.js +11 -1
  27. package/dist/Effect.js.map +1 -1
  28. package/dist/FileSystem.d.ts +59 -4
  29. package/dist/FileSystem.d.ts.map +1 -1
  30. package/dist/FileSystem.js +9 -2
  31. package/dist/FileSystem.js.map +1 -1
  32. package/dist/Glob.d.ts +165 -0
  33. package/dist/Glob.d.ts.map +1 -0
  34. package/dist/Glob.js +127 -0
  35. package/dist/Glob.js.map +1 -0
  36. package/dist/Match.d.ts +86 -0
  37. package/dist/Match.d.ts.map +1 -1
  38. package/dist/Match.js +72 -0
  39. package/dist/Match.js.map +1 -1
  40. package/dist/Pool.d.ts +51 -0
  41. package/dist/Pool.d.ts.map +1 -1
  42. package/dist/Pool.js +59 -9
  43. package/dist/Pool.js.map +1 -1
  44. package/dist/Random.d.ts.map +1 -1
  45. package/dist/Random.js +3 -3
  46. package/dist/Random.js.map +1 -1
  47. package/dist/RcMap.d.ts.map +1 -1
  48. package/dist/RcMap.js +8 -2
  49. package/dist/RcMap.js.map +1 -1
  50. package/dist/Schedule.d.ts +18 -1
  51. package/dist/Schedule.d.ts.map +1 -1
  52. package/dist/Schedule.js +7 -2
  53. package/dist/Schedule.js.map +1 -1
  54. package/dist/Schema.d.ts +666 -41
  55. package/dist/Schema.d.ts.map +1 -1
  56. package/dist/Schema.js +650 -0
  57. package/dist/Schema.js.map +1 -1
  58. package/dist/SchemaGetter.d.ts +6 -1
  59. package/dist/SchemaGetter.d.ts.map +1 -1
  60. package/dist/SchemaGetter.js +22 -11
  61. package/dist/SchemaGetter.js.map +1 -1
  62. package/dist/SchemaRepresentation.d.ts +14 -0
  63. package/dist/SchemaRepresentation.d.ts.map +1 -1
  64. package/dist/SchemaRepresentation.js +16 -0
  65. package/dist/SchemaRepresentation.js.map +1 -1
  66. package/dist/SchemaTransformation.d.ts +8 -3
  67. package/dist/SchemaTransformation.d.ts.map +1 -1
  68. package/dist/SchemaTransformation.js +6 -3
  69. package/dist/SchemaTransformation.js.map +1 -1
  70. package/dist/ScopedCache.d.ts.map +1 -1
  71. package/dist/ScopedCache.js +5 -7
  72. package/dist/ScopedCache.js.map +1 -1
  73. package/dist/Semaphore.d.ts +130 -0
  74. package/dist/Semaphore.d.ts.map +1 -1
  75. package/dist/Semaphore.js +40 -0
  76. package/dist/Semaphore.js.map +1 -1
  77. package/dist/Stream.d.ts +13 -4
  78. package/dist/Stream.d.ts.map +1 -1
  79. package/dist/Stream.js +9 -0
  80. package/dist/Stream.js.map +1 -1
  81. package/dist/Terminal.d.ts +18 -1
  82. package/dist/Terminal.d.ts.map +1 -1
  83. package/dist/Terminal.js +1 -1
  84. package/dist/Terminal.js.map +1 -1
  85. package/dist/ai/AiError.d.ts +43 -116
  86. package/dist/ai/AiError.d.ts.map +1 -1
  87. package/dist/ai/AiError.js +53 -72
  88. package/dist/ai/AiError.js.map +1 -1
  89. package/dist/ai/Decision.d.ts +196 -15
  90. package/dist/ai/Decision.d.ts.map +1 -1
  91. package/dist/ai/Decision.js +130 -0
  92. package/dist/ai/Decision.js.map +1 -1
  93. package/dist/ai/DecisionModel.d.ts +54 -13
  94. package/dist/ai/DecisionModel.d.ts.map +1 -1
  95. package/dist/ai/DecisionModel.js +123 -12
  96. package/dist/ai/DecisionModel.js.map +1 -1
  97. package/dist/ai/McpServer.d.ts +630 -29
  98. package/dist/ai/McpServer.d.ts.map +1 -1
  99. package/dist/ai/McpServer.js +562 -116
  100. package/dist/ai/McpServer.js.map +1 -1
  101. package/dist/ai/McpTest.d.ts +130 -0
  102. package/dist/ai/McpTest.d.ts.map +1 -0
  103. package/dist/ai/McpTest.js +237 -0
  104. package/dist/ai/McpTest.js.map +1 -0
  105. package/dist/ai/Response.d.ts +1 -25
  106. package/dist/ai/Response.d.ts.map +1 -1
  107. package/dist/ai/Response.js +1 -10
  108. package/dist/ai/Response.js.map +1 -1
  109. package/dist/ai/Tool.d.ts +19 -1
  110. package/dist/ai/Tool.d.ts.map +1 -1
  111. package/dist/ai/Tool.js.map +1 -1
  112. package/dist/ai/index.d.ts +5 -0
  113. package/dist/ai/index.d.ts.map +1 -1
  114. package/dist/ai/index.js +5 -0
  115. package/dist/ai/index.js.map +1 -1
  116. package/dist/ai/internal/mcpCore.js +17 -12
  117. package/dist/ai/internal/mcpCore.js.map +1 -1
  118. package/dist/ai/internal/mcpProtocol/v2024_11_05.js +4 -5
  119. package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
  120. package/dist/ai/internal/mcpProtocol/v2025_03_26.js +4 -5
  121. package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
  122. package/dist/ai/internal/mcpProtocol/v2025_06_18.js +4 -5
  123. package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
  124. package/dist/ai/internal/mcpProtocol/v2025_11_25.js +4 -5
  125. package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
  126. package/dist/ai/internal/mcpProtocol/v2026_07_28.js +18 -10
  127. package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
  128. package/dist/ai/internal/mcpProtocol.js +13 -0
  129. package/dist/ai/internal/mcpProtocol.js.map +1 -1
  130. package/dist/ai/internal/mcpRuntime.js +5 -3
  131. package/dist/ai/internal/mcpRuntime.js.map +1 -1
  132. package/dist/ai/internal/mcpStatefulRuntime.js +6 -1
  133. package/dist/ai/internal/mcpStatefulRuntime.js.map +1 -1
  134. package/dist/cli/Argument.d.ts +6 -0
  135. package/dist/cli/Argument.d.ts.map +1 -1
  136. package/dist/cli/Argument.js +2 -0
  137. package/dist/cli/Argument.js.map +1 -1
  138. package/dist/cli/CliOutput.d.ts +65 -1
  139. package/dist/cli/CliOutput.d.ts.map +1 -1
  140. package/dist/cli/CliOutput.js +94 -37
  141. package/dist/cli/CliOutput.js.map +1 -1
  142. package/dist/cli/Command.d.ts +23 -0
  143. package/dist/cli/Command.d.ts.map +1 -1
  144. package/dist/cli/Command.js +8 -0
  145. package/dist/cli/Command.js.map +1 -1
  146. package/dist/cli/Flag.d.ts +107 -0
  147. package/dist/cli/Flag.d.ts.map +1 -1
  148. package/dist/cli/Flag.js +37 -0
  149. package/dist/cli/Flag.js.map +1 -1
  150. package/dist/cli/HelpDoc.d.ts +15 -1
  151. package/dist/cli/HelpDoc.d.ts.map +1 -1
  152. package/dist/cli/Param.d.ts +6 -0
  153. package/dist/cli/Param.d.ts.map +1 -1
  154. package/dist/cli/Param.js +2 -0
  155. package/dist/cli/Param.js.map +1 -1
  156. package/dist/cli/Primitive.d.ts +14 -0
  157. package/dist/cli/Primitive.d.ts.map +1 -1
  158. package/dist/cli/Primitive.js +15 -1
  159. package/dist/cli/Primitive.js.map +1 -1
  160. package/dist/cli/Prompt.d.ts +1 -0
  161. package/dist/cli/Prompt.d.ts.map +1 -1
  162. package/dist/cli/Prompt.js +1 -0
  163. package/dist/cli/Prompt.js.map +1 -1
  164. package/dist/cli/internal/help.d.ts.map +1 -1
  165. package/dist/cli/internal/help.js +17 -10
  166. package/dist/cli/internal/help.js.map +1 -1
  167. package/dist/cluster/Sharding.d.ts.map +1 -1
  168. package/dist/cluster/Sharding.js +90 -28
  169. package/dist/cluster/Sharding.js.map +1 -1
  170. package/dist/cluster/ShardingConfig.d.ts +72 -6
  171. package/dist/cluster/ShardingConfig.d.ts.map +1 -1
  172. package/dist/cluster/ShardingConfig.js +4 -0
  173. package/dist/cluster/ShardingConfig.js.map +1 -1
  174. package/dist/cluster/SingleRunner.d.ts +3 -3
  175. package/dist/cluster/SingleRunner.d.ts.map +1 -1
  176. package/dist/cluster/SingleRunner.js +1 -1
  177. package/dist/cluster/SqlMessageStorage.d.ts +37 -6
  178. package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
  179. package/dist/cluster/SqlMessageStorage.js +34 -7
  180. package/dist/cluster/SqlMessageStorage.js.map +1 -1
  181. package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
  182. package/dist/cluster/SqlRunnerStorage.js +23 -8
  183. package/dist/cluster/SqlRunnerStorage.js.map +1 -1
  184. package/dist/crypto/Aead.d.ts +322 -0
  185. package/dist/crypto/Aead.d.ts.map +1 -0
  186. package/dist/crypto/Aead.js +331 -0
  187. package/dist/crypto/Aead.js.map +1 -0
  188. package/dist/crypto/Cipher.d.ts +235 -0
  189. package/dist/crypto/Cipher.d.ts.map +1 -0
  190. package/dist/crypto/Cipher.js +233 -0
  191. package/dist/crypto/Cipher.js.map +1 -0
  192. package/dist/crypto/CryptoError.d.ts +212 -0
  193. package/dist/crypto/CryptoError.d.ts.map +1 -0
  194. package/dist/crypto/CryptoError.js +202 -0
  195. package/dist/crypto/CryptoError.js.map +1 -0
  196. package/dist/crypto/Digest.d.ts +143 -0
  197. package/dist/crypto/Digest.d.ts.map +1 -0
  198. package/dist/crypto/Digest.js +146 -0
  199. package/dist/crypto/Digest.js.map +1 -0
  200. package/dist/crypto/Kdf.d.ts +220 -0
  201. package/dist/crypto/Kdf.d.ts.map +1 -0
  202. package/dist/crypto/Kdf.js +212 -0
  203. package/dist/crypto/Kdf.js.map +1 -0
  204. package/dist/crypto/KeyAgreement.d.ts +323 -0
  205. package/dist/crypto/KeyAgreement.d.ts.map +1 -0
  206. package/dist/crypto/KeyAgreement.js +303 -0
  207. package/dist/crypto/KeyAgreement.js.map +1 -0
  208. package/dist/crypto/KeyFormat.d.ts +309 -0
  209. package/dist/crypto/KeyFormat.d.ts.map +1 -0
  210. package/dist/crypto/KeyFormat.js +556 -0
  211. package/dist/crypto/KeyFormat.js.map +1 -0
  212. package/dist/crypto/KeyWrap.d.ts +389 -0
  213. package/dist/crypto/KeyWrap.d.ts.map +1 -0
  214. package/dist/crypto/KeyWrap.js +381 -0
  215. package/dist/crypto/KeyWrap.js.map +1 -0
  216. package/dist/crypto/Mac.d.ts +277 -0
  217. package/dist/crypto/Mac.d.ts.map +1 -0
  218. package/dist/crypto/Mac.js +288 -0
  219. package/dist/crypto/Mac.js.map +1 -0
  220. package/dist/crypto/SecureRandom.d.ts +340 -0
  221. package/dist/crypto/SecureRandom.d.ts.map +1 -0
  222. package/dist/crypto/SecureRandom.js +257 -0
  223. package/dist/crypto/SecureRandom.js.map +1 -0
  224. package/dist/crypto/Signature.d.ts +448 -0
  225. package/dist/crypto/Signature.d.ts.map +1 -0
  226. package/dist/crypto/Signature.js +484 -0
  227. package/dist/crypto/Signature.js.map +1 -0
  228. package/dist/crypto/WebCrypto.d.ts +61 -0
  229. package/dist/crypto/WebCrypto.d.ts.map +1 -0
  230. package/dist/crypto/WebCrypto.js +63 -0
  231. package/dist/crypto/WebCrypto.js.map +1 -0
  232. package/dist/crypto/index.d.ts +65 -0
  233. package/dist/crypto/index.d.ts.map +1 -0
  234. package/dist/crypto/index.js +66 -0
  235. package/dist/crypto/index.js.map +1 -0
  236. package/dist/crypto/internal/asymmetric.d.ts +2 -0
  237. package/dist/crypto/internal/asymmetric.d.ts.map +1 -0
  238. package/dist/crypto/internal/asymmetric.js +210 -0
  239. package/dist/crypto/internal/asymmetric.js.map +1 -0
  240. package/dist/crypto/internal/chacha.d.ts +46 -0
  241. package/dist/crypto/internal/chacha.d.ts.map +1 -0
  242. package/dist/crypto/internal/chacha.js +885 -0
  243. package/dist/crypto/internal/chacha.js.map +1 -0
  244. package/dist/crypto/internal/der.d.ts +6 -0
  245. package/dist/crypto/internal/der.d.ts.map +1 -0
  246. package/dist/crypto/internal/der.js +86 -0
  247. package/dist/crypto/internal/der.js.map +1 -0
  248. package/dist/crypto/internal/digest.d.ts +2 -0
  249. package/dist/crypto/internal/digest.d.ts.map +1 -0
  250. package/dist/crypto/internal/digest.js +15 -0
  251. package/dist/crypto/internal/digest.js.map +1 -0
  252. package/dist/crypto/internal/key.d.ts +2 -0
  253. package/dist/crypto/internal/key.d.ts.map +1 -0
  254. package/dist/crypto/internal/key.js +170 -0
  255. package/dist/crypto/internal/key.js.map +1 -0
  256. package/dist/crypto/internal/md5.d.ts +39 -0
  257. package/dist/crypto/internal/md5.d.ts.map +1 -0
  258. package/dist/crypto/internal/md5.js +179 -0
  259. package/dist/crypto/internal/md5.js.map +1 -0
  260. package/dist/crypto/internal/webCrypto.d.ts +2 -0
  261. package/dist/crypto/internal/webCrypto.d.ts.map +1 -0
  262. package/dist/crypto/internal/webCrypto.js +111 -0
  263. package/dist/crypto/internal/webCrypto.js.map +1 -0
  264. package/dist/encoding/Base64Url.d.ts.map +1 -1
  265. package/dist/encoding/Base64Url.js +3 -2
  266. package/dist/encoding/Base64Url.js.map +1 -1
  267. package/dist/encoding/Csv.d.ts +608 -0
  268. package/dist/encoding/Csv.d.ts.map +1 -0
  269. package/dist/encoding/Csv.js +718 -0
  270. package/dist/encoding/Csv.js.map +1 -0
  271. package/dist/encoding/Hex.d.ts +3 -2
  272. package/dist/encoding/Hex.d.ts.map +1 -1
  273. package/dist/encoding/Hex.js +3 -2
  274. package/dist/encoding/Hex.js.map +1 -1
  275. package/dist/encoding/SchemaBinary.d.ts.map +1 -1
  276. package/dist/encoding/SchemaBinary.js +42 -4
  277. package/dist/encoding/SchemaBinary.js.map +1 -1
  278. package/dist/encoding/Toml.d.ts +17 -3
  279. package/dist/encoding/Toml.d.ts.map +1 -1
  280. package/dist/encoding/Toml.js +104 -16
  281. package/dist/encoding/Toml.js.map +1 -1
  282. package/dist/encoding/Yaml.d.ts +8 -1
  283. package/dist/encoding/Yaml.d.ts.map +1 -1
  284. package/dist/encoding/Yaml.js +54 -18
  285. package/dist/encoding/Yaml.js.map +1 -1
  286. package/dist/encoding/index.d.ts +5 -0
  287. package/dist/encoding/index.d.ts.map +1 -1
  288. package/dist/encoding/index.js +5 -0
  289. package/dist/encoding/index.js.map +1 -1
  290. package/dist/eventlog/EventJournal.d.ts.map +1 -1
  291. package/dist/eventlog/EventJournal.js +6 -3
  292. package/dist/eventlog/EventJournal.js.map +1 -1
  293. package/dist/eventlog/EventLog.d.ts +119 -4
  294. package/dist/eventlog/EventLog.d.ts.map +1 -1
  295. package/dist/eventlog/EventLog.js +200 -12
  296. package/dist/eventlog/EventLog.js.map +1 -1
  297. package/dist/eventlog/EventLogEncryption.d.ts +41 -4
  298. package/dist/eventlog/EventLogEncryption.d.ts.map +1 -1
  299. package/dist/eventlog/EventLogEncryption.js +83 -64
  300. package/dist/eventlog/EventLogEncryption.js.map +1 -1
  301. package/dist/eventlog/EventLogMessage.d.ts +279 -0
  302. package/dist/eventlog/EventLogMessage.d.ts.map +1 -1
  303. package/dist/eventlog/EventLogMessage.js +217 -1
  304. package/dist/eventlog/EventLogMessage.js.map +1 -1
  305. package/dist/eventlog/EventLogRemote.d.ts +200 -28
  306. package/dist/eventlog/EventLogRemote.d.ts.map +1 -1
  307. package/dist/eventlog/EventLogRemote.js +186 -16
  308. package/dist/eventlog/EventLogRemote.js.map +1 -1
  309. package/dist/eventlog/EventLogServer.d.ts +3 -0
  310. package/dist/eventlog/EventLogServer.d.ts.map +1 -1
  311. package/dist/eventlog/EventLogServer.js +18 -10
  312. package/dist/eventlog/EventLogServer.js.map +1 -1
  313. package/dist/eventlog/EventLogServerEncrypted.d.ts +326 -5
  314. package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
  315. package/dist/eventlog/EventLogServerEncrypted.js +769 -14
  316. package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
  317. package/dist/eventlog/EventLogSessionAuth.d.ts +5 -3
  318. package/dist/eventlog/EventLogSessionAuth.d.ts.map +1 -1
  319. package/dist/eventlog/EventLogSessionAuth.js +41 -64
  320. package/dist/eventlog/EventLogSessionAuth.js.map +1 -1
  321. package/dist/eventlog/EventRow.d.ts +4 -0
  322. package/dist/eventlog/EventRow.d.ts.map +1 -1
  323. package/dist/eventlog/EventRow.js +12 -2
  324. package/dist/eventlog/EventRow.js.map +1 -1
  325. package/dist/eventlog/SqlEventJournal.js +2 -2
  326. package/dist/eventlog/SqlEventJournal.js.map +1 -1
  327. package/dist/eventlog/SqlEventLogServerEncrypted.d.ts +21 -5
  328. package/dist/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
  329. package/dist/eventlog/SqlEventLogServerEncrypted.js +1048 -113
  330. package/dist/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
  331. package/dist/eventlog/SqlEventLogServerUnencrypted.js +2 -2
  332. package/dist/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
  333. package/dist/eventlog/internal/batches.d.ts +12 -0
  334. package/dist/eventlog/internal/batches.d.ts.map +1 -0
  335. package/dist/eventlog/internal/batches.js +26 -0
  336. package/dist/eventlog/internal/batches.js.map +1 -0
  337. package/dist/eventlog/internal/compaction.d.ts +38 -0
  338. package/dist/eventlog/internal/compaction.d.ts.map +1 -0
  339. package/dist/eventlog/internal/compaction.js +33 -0
  340. package/dist/eventlog/internal/compaction.js.map +1 -0
  341. package/dist/eventlog/internal/identityRootSecretDerivation.js +66 -67
  342. package/dist/eventlog/internal/identityRootSecretDerivation.js.map +1 -1
  343. package/dist/eventlog/internal/remoteCompaction.d.ts +31 -0
  344. package/dist/eventlog/internal/remoteCompaction.d.ts.map +1 -0
  345. package/dist/eventlog/internal/remoteCompaction.js +76 -0
  346. package/dist/eventlog/internal/remoteCompaction.js.map +1 -0
  347. package/dist/http/Cookies.d.ts +172 -0
  348. package/dist/http/Cookies.d.ts.map +1 -1
  349. package/dist/http/Cookies.js +143 -1
  350. package/dist/http/Cookies.js.map +1 -1
  351. package/dist/http/FetchHttpClient.d.ts +26 -2
  352. package/dist/http/FetchHttpClient.d.ts.map +1 -1
  353. package/dist/http/FetchHttpClient.js +78 -15
  354. package/dist/http/FetchHttpClient.js.map +1 -1
  355. package/dist/http/HttpClient.d.ts +79 -8
  356. package/dist/http/HttpClient.d.ts.map +1 -1
  357. package/dist/http/HttpClient.js +65 -5
  358. package/dist/http/HttpClient.js.map +1 -1
  359. package/dist/http/HttpClientRequest.d.ts +9 -5
  360. package/dist/http/HttpClientRequest.d.ts.map +1 -1
  361. package/dist/http/HttpClientRequest.js +2 -3
  362. package/dist/http/HttpClientRequest.js.map +1 -1
  363. package/dist/http/HttpClientResponse.d.ts.map +1 -1
  364. package/dist/http/HttpClientResponse.js +3 -2
  365. package/dist/http/HttpClientResponse.js.map +1 -1
  366. package/dist/http/HttpMethod.d.ts +7 -1
  367. package/dist/http/HttpMethod.d.ts.map +1 -1
  368. package/dist/http/HttpMethod.js +3 -8
  369. package/dist/http/HttpMethod.js.map +1 -1
  370. package/dist/http/HttpServerRequest.d.ts +5 -2
  371. package/dist/http/HttpServerRequest.d.ts.map +1 -1
  372. package/dist/http/HttpServerRequest.js +6 -17
  373. package/dist/http/HttpServerRequest.js.map +1 -1
  374. package/dist/http/HttpServerResponse.d.ts.map +1 -1
  375. package/dist/http/HttpServerResponse.js +3 -2
  376. package/dist/http/HttpServerResponse.js.map +1 -1
  377. package/dist/http/HttpTraceContext.d.ts +2 -1
  378. package/dist/http/HttpTraceContext.d.ts.map +1 -1
  379. package/dist/http/HttpTraceContext.js +7 -5
  380. package/dist/http/HttpTraceContext.js.map +1 -1
  381. package/dist/http/ProblemDetails.d.ts +96 -0
  382. package/dist/http/ProblemDetails.d.ts.map +1 -0
  383. package/dist/http/ProblemDetails.js +98 -0
  384. package/dist/http/ProblemDetails.js.map +1 -0
  385. package/dist/http/index.d.ts +5 -0
  386. package/dist/http/index.d.ts.map +1 -1
  387. package/dist/http/index.js +5 -0
  388. package/dist/http/index.js.map +1 -1
  389. package/dist/http/internal/decompression.js +3 -2
  390. package/dist/http/internal/decompression.js.map +1 -1
  391. package/dist/http/internal/urlParams.js +8 -0
  392. package/dist/http/internal/urlParams.js.map +1 -1
  393. package/dist/http-api/HttpApiBuilder.js +19 -5
  394. package/dist/http-api/HttpApiBuilder.js.map +1 -1
  395. package/dist/http-api/HttpApiClient.d.ts +63 -0
  396. package/dist/http-api/HttpApiClient.d.ts.map +1 -1
  397. package/dist/http-api/HttpApiClient.js +51 -0
  398. package/dist/http-api/HttpApiClient.js.map +1 -1
  399. package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
  400. package/dist/http-api/HttpApiEndpoint.js +14 -5
  401. package/dist/http-api/HttpApiEndpoint.js.map +1 -1
  402. package/dist/http-api/HttpApiError.d.ts +185 -13
  403. package/dist/http-api/HttpApiError.d.ts.map +1 -1
  404. package/dist/http-api/HttpApiError.js +128 -0
  405. package/dist/http-api/HttpApiError.js.map +1 -1
  406. package/dist/http-api/HttpApiMiddleware.d.ts +64 -17
  407. package/dist/http-api/HttpApiMiddleware.d.ts.map +1 -1
  408. package/dist/http-api/HttpApiMiddleware.js +85 -1
  409. package/dist/http-api/HttpApiMiddleware.js.map +1 -1
  410. package/dist/http-api/HttpApiSchema.d.ts +76 -14
  411. package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
  412. package/dist/http-api/HttpApiSchema.js +53 -0
  413. package/dist/http-api/HttpApiSchema.js.map +1 -1
  414. package/dist/index.d.ts +5 -5
  415. package/dist/index.d.ts.map +1 -1
  416. package/dist/index.js +5 -5
  417. package/dist/index.js.map +1 -1
  418. package/dist/internal/effect.js +25 -14
  419. package/dist/internal/effect.js.map +1 -1
  420. package/dist/internal/glob.d.ts +2 -0
  421. package/dist/internal/glob.d.ts.map +1 -0
  422. package/dist/internal/glob.js +630 -0
  423. package/dist/internal/glob.js.map +1 -0
  424. package/dist/internal/matcher.js +10 -0
  425. package/dist/internal/matcher.js.map +1 -1
  426. package/dist/internal/persistence.js +9 -0
  427. package/dist/internal/persistence.js.map +1 -1
  428. package/dist/internal/rcRef.js +4 -1
  429. package/dist/internal/rcRef.js.map +1 -1
  430. package/dist/internal/schema/toCodeDocument.js +6 -3
  431. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  432. package/dist/internal/trie.js +42 -13
  433. package/dist/internal/trie.js.map +1 -1
  434. package/dist/internal/ulid.js +41 -0
  435. package/dist/internal/ulid.js.map +1 -1
  436. package/dist/internal/uuid.js +52 -8
  437. package/dist/internal/uuid.js.map +1 -1
  438. package/dist/internal/version.js +1 -1
  439. package/dist/observability/Otlp.d.ts +15 -4
  440. package/dist/observability/Otlp.d.ts.map +1 -1
  441. package/dist/observability/Otlp.js +10 -0
  442. package/dist/observability/Otlp.js.map +1 -1
  443. package/dist/observability/OtlpResource.d.ts +7 -0
  444. package/dist/observability/OtlpResource.d.ts.map +1 -1
  445. package/dist/observability/OtlpResource.js +11 -1
  446. package/dist/observability/OtlpResource.js.map +1 -1
  447. package/dist/persistence/KeyValueStore.d.ts +47 -2
  448. package/dist/persistence/KeyValueStore.d.ts.map +1 -1
  449. package/dist/persistence/KeyValueStore.js +129 -18
  450. package/dist/persistence/KeyValueStore.js.map +1 -1
  451. package/dist/persistence/PersistedQueue.d.ts +9 -0
  452. package/dist/persistence/PersistedQueue.d.ts.map +1 -1
  453. package/dist/persistence/PersistedQueue.js +94 -52
  454. package/dist/persistence/PersistedQueue.js.map +1 -1
  455. package/dist/persistence/Persistence.d.ts +10 -4
  456. package/dist/persistence/Persistence.d.ts.map +1 -1
  457. package/dist/persistence/Persistence.js +18 -11
  458. package/dist/persistence/Persistence.js.map +1 -1
  459. package/dist/process/ChildProcess.d.ts +207 -67
  460. package/dist/process/ChildProcess.d.ts.map +1 -1
  461. package/dist/process/ChildProcess.js +56 -158
  462. package/dist/process/ChildProcess.js.map +1 -1
  463. package/dist/process/ChildProcessSpawner.d.ts +5 -0
  464. package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
  465. package/dist/process/ChildProcessSpawner.js.map +1 -1
  466. package/dist/process/CommandLine.d.ts +294 -0
  467. package/dist/process/CommandLine.d.ts.map +1 -0
  468. package/dist/process/CommandLine.js +481 -0
  469. package/dist/process/CommandLine.js.map +1 -0
  470. package/dist/process/index.d.ts +5 -0
  471. package/dist/process/index.d.ts.map +1 -1
  472. package/dist/process/index.js +5 -0
  473. package/dist/process/index.js.map +1 -1
  474. package/dist/reactivity/Atom.d.ts +2 -1
  475. package/dist/reactivity/Atom.d.ts.map +1 -1
  476. package/dist/reactivity/Atom.js +3 -4
  477. package/dist/reactivity/Atom.js.map +1 -1
  478. package/dist/reactivity/AtomRegistry.js.map +1 -1
  479. package/dist/rpc/RpcClient.d.ts +16 -1
  480. package/dist/rpc/RpcClient.d.ts.map +1 -1
  481. package/dist/rpc/RpcClient.js +50 -16
  482. package/dist/rpc/RpcClient.js.map +1 -1
  483. package/dist/rpc/RpcMessage.d.ts +10 -1
  484. package/dist/rpc/RpcMessage.d.ts.map +1 -1
  485. package/dist/rpc/RpcMessage.js +1 -0
  486. package/dist/rpc/RpcMessage.js.map +1 -1
  487. package/dist/rpc/RpcSerialization.d.ts.map +1 -1
  488. package/dist/rpc/RpcSerialization.js +6 -0
  489. package/dist/rpc/RpcSerialization.js.map +1 -1
  490. package/dist/rpc/RpcServer.d.ts +31 -0
  491. package/dist/rpc/RpcServer.d.ts.map +1 -1
  492. package/dist/rpc/RpcServer.js +139 -66
  493. package/dist/rpc/RpcServer.js.map +1 -1
  494. package/dist/schema/Model.d.ts +14 -0
  495. package/dist/schema/Model.d.ts.map +1 -1
  496. package/dist/schema/Model.js +18 -3
  497. package/dist/schema/Model.js.map +1 -1
  498. package/dist/sql/Migrator.d.ts +0 -19
  499. package/dist/sql/Migrator.d.ts.map +1 -1
  500. package/dist/sql/Migrator.js +3 -48
  501. package/dist/sql/Migrator.js.map +1 -1
  502. package/dist/sql/MigratorFileSystem.d.ts +21 -0
  503. package/dist/sql/MigratorFileSystem.d.ts.map +1 -0
  504. package/dist/sql/MigratorFileSystem.js +57 -0
  505. package/dist/sql/MigratorFileSystem.js.map +1 -0
  506. package/dist/sql/SqlClient.d.ts.map +1 -1
  507. package/dist/sql/SqlClient.js +5 -9
  508. package/dist/sql/SqlClient.js.map +1 -1
  509. package/dist/sql/Statement.d.ts +20 -6
  510. package/dist/sql/Statement.d.ts.map +1 -1
  511. package/dist/sql/Statement.js +0 -13
  512. package/dist/sql/Statement.js.map +1 -1
  513. package/dist/sql/index.js +1 -1
  514. package/dist/testing/index.d.ts +0 -5
  515. package/dist/testing/index.d.ts.map +1 -1
  516. package/dist/testing/index.js +0 -5
  517. package/dist/testing/index.js.map +1 -1
  518. package/dist/workflow/internal/crypto.js +9 -8
  519. package/dist/workflow/internal/crypto.js.map +1 -1
  520. package/package.json +3 -1
  521. package/src/BigDecimal.ts +3 -0
  522. package/src/Channel.ts +17 -11
  523. package/src/Config.ts +7 -1
  524. package/src/Context.ts +34 -10
  525. package/src/Cron.ts +178 -29
  526. package/src/Duration.ts +140 -0
  527. package/src/Effect.ts +914 -85
  528. package/src/FileSystem.ts +65 -4
  529. package/src/Glob.ts +205 -0
  530. package/src/Match.ts +127 -0
  531. package/src/Pool.ts +73 -15
  532. package/src/Random.ts +3 -3
  533. package/src/RcMap.ts +5 -1
  534. package/src/Schedule.ts +26 -3
  535. package/src/Schema.ts +1189 -62
  536. package/src/SchemaGetter.ts +27 -11
  537. package/src/SchemaRepresentation.ts +19 -0
  538. package/src/SchemaTransformation.ts +8 -3
  539. package/src/ScopedCache.ts +5 -9
  540. package/src/Semaphore.ts +141 -0
  541. package/src/Stream.ts +15 -6
  542. package/src/Terminal.ts +19 -1
  543. package/src/ai/AiError.ts +56 -80
  544. package/src/ai/Decision.ts +257 -6
  545. package/src/ai/DecisionModel.ts +171 -28
  546. package/src/ai/McpServer.ts +1269 -286
  547. package/src/ai/McpTest.ts +380 -0
  548. package/src/ai/Response.ts +2 -22
  549. package/src/ai/Tool.ts +27 -8
  550. package/src/ai/index.ts +6 -0
  551. package/src/ai/internal/mcpCore.ts +78 -44
  552. package/src/ai/internal/mcpProtocol/v2024_11_05.ts +4 -7
  553. package/src/ai/internal/mcpProtocol/v2025_03_26.ts +4 -7
  554. package/src/ai/internal/mcpProtocol/v2025_06_18.ts +4 -7
  555. package/src/ai/internal/mcpProtocol/v2025_11_25.ts +4 -7
  556. package/src/ai/internal/mcpProtocol/v2026_07_28.ts +15 -10
  557. package/src/ai/internal/mcpProtocol.ts +29 -0
  558. package/src/ai/internal/mcpRuntime.ts +9 -5
  559. package/src/ai/internal/mcpStatefulRuntime.ts +14 -2
  560. package/src/cli/Argument.ts +6 -0
  561. package/src/cli/CliOutput.ts +117 -49
  562. package/src/cli/Command.ts +23 -0
  563. package/src/cli/Flag.ts +107 -0
  564. package/src/cli/HelpDoc.ts +18 -1
  565. package/src/cli/Param.ts +6 -0
  566. package/src/cli/Primitive.ts +16 -1
  567. package/src/cli/Prompt.ts +1 -0
  568. package/src/cli/internal/help.ts +21 -9
  569. package/src/cluster/Sharding.ts +93 -26
  570. package/src/cluster/ShardingConfig.ts +41 -3
  571. package/src/cluster/SingleRunner.ts +3 -3
  572. package/src/cluster/SqlMessageStorage.ts +49 -17
  573. package/src/cluster/SqlRunnerStorage.ts +37 -27
  574. package/src/crypto/Aead.ts +517 -0
  575. package/src/crypto/Cipher.ts +326 -0
  576. package/src/crypto/CryptoError.ts +242 -0
  577. package/src/crypto/Digest.ts +167 -0
  578. package/src/crypto/Kdf.ts +315 -0
  579. package/src/crypto/KeyAgreement.ts +489 -0
  580. package/src/crypto/KeyFormat.ts +712 -0
  581. package/src/crypto/KeyWrap.ts +639 -0
  582. package/src/crypto/Mac.ts +386 -0
  583. package/src/crypto/SecureRandom.ts +459 -0
  584. package/src/crypto/Signature.ts +673 -0
  585. package/src/crypto/WebCrypto.ts +64 -0
  586. package/src/crypto/index.ts +78 -0
  587. package/src/crypto/internal/asymmetric.ts +329 -0
  588. package/src/crypto/internal/chacha.ts +1088 -0
  589. package/src/crypto/internal/der.ts +110 -0
  590. package/src/crypto/internal/digest.ts +16 -0
  591. package/src/crypto/internal/key.ts +235 -0
  592. package/src/crypto/internal/md5.ts +170 -0
  593. package/src/crypto/internal/webCrypto.ts +150 -0
  594. package/src/encoding/Base64Url.ts +5 -2
  595. package/src/encoding/Csv.ts +1298 -0
  596. package/src/encoding/Hex.ts +3 -2
  597. package/src/encoding/SchemaBinary.ts +40 -4
  598. package/src/encoding/Toml.ts +85 -20
  599. package/src/encoding/Yaml.ts +61 -18
  600. package/src/encoding/index.ts +6 -0
  601. package/src/eventlog/EventJournal.ts +4 -3
  602. package/src/eventlog/EventLog.ts +340 -15
  603. package/src/eventlog/EventLogEncryption.ts +118 -110
  604. package/src/eventlog/EventLogMessage.ts +273 -1
  605. package/src/eventlog/EventLogRemote.ts +367 -23
  606. package/src/eventlog/EventLogServer.ts +23 -8
  607. package/src/eventlog/EventLogServerEncrypted.ts +1130 -67
  608. package/src/eventlog/EventLogSessionAuth.ts +56 -70
  609. package/src/eventlog/EventRow.ts +12 -3
  610. package/src/eventlog/SqlEventJournal.ts +2 -2
  611. package/src/eventlog/SqlEventLogServerEncrypted.ts +1244 -136
  612. package/src/eventlog/SqlEventLogServerUnencrypted.ts +2 -2
  613. package/src/eventlog/internal/batches.ts +30 -0
  614. package/src/eventlog/internal/compaction.ts +64 -0
  615. package/src/eventlog/internal/identityRootSecretDerivation.ts +93 -123
  616. package/src/eventlog/internal/remoteCompaction.ts +92 -0
  617. package/src/http/Cookies.ts +281 -1
  618. package/src/http/FetchHttpClient.ts +88 -16
  619. package/src/http/HttpClient.ts +89 -22
  620. package/src/http/HttpClientRequest.ts +12 -9
  621. package/src/http/HttpClientResponse.ts +3 -2
  622. package/src/http/HttpMethod.ts +10 -2
  623. package/src/http/HttpServerRequest.ts +15 -30
  624. package/src/http/HttpServerResponse.ts +3 -2
  625. package/src/http/HttpTraceContext.ts +7 -4
  626. package/src/http/ProblemDetails.ts +149 -0
  627. package/src/http/index.ts +6 -0
  628. package/src/http/internal/decompression.ts +4 -4
  629. package/src/http/internal/urlParams.ts +8 -0
  630. package/src/http-api/HttpApiBuilder.ts +24 -12
  631. package/src/http-api/HttpApiClient.ts +67 -1
  632. package/src/http-api/HttpApiEndpoint.ts +14 -5
  633. package/src/http-api/HttpApiError.ts +250 -0
  634. package/src/http-api/HttpApiMiddleware.ts +95 -1
  635. package/src/http-api/HttpApiSchema.ts +105 -14
  636. package/src/index.ts +6 -6
  637. package/src/internal/effect.ts +34 -18
  638. package/src/internal/glob.ts +736 -0
  639. package/src/internal/matcher.ts +17 -0
  640. package/src/internal/persistence.ts +11 -0
  641. package/src/internal/rcRef.ts +4 -1
  642. package/src/internal/schema/toCodeDocument.ts +7 -3
  643. package/src/internal/trie.ts +43 -14
  644. package/src/internal/ulid.ts +44 -0
  645. package/src/internal/uuid.ts +57 -16
  646. package/src/internal/version.ts +1 -1
  647. package/src/observability/Otlp.ts +21 -4
  648. package/src/observability/OtlpResource.ts +9 -1
  649. package/src/persistence/KeyValueStore.ts +219 -22
  650. package/src/persistence/PersistedQueue.ts +128 -59
  651. package/src/persistence/Persistence.ts +20 -13
  652. package/src/process/ChildProcess.ts +255 -260
  653. package/src/process/ChildProcessSpawner.ts +5 -0
  654. package/src/process/CommandLine.ts +630 -0
  655. package/src/process/index.ts +6 -0
  656. package/src/reactivity/Atom.ts +5 -5
  657. package/src/reactivity/AtomRegistry.ts +1 -1
  658. package/src/rpc/RpcClient.ts +62 -26
  659. package/src/rpc/RpcMessage.ts +10 -1
  660. package/src/rpc/RpcSerialization.ts +3 -0
  661. package/src/rpc/RpcServer.ts +176 -78
  662. package/src/schema/Model.ts +26 -3
  663. package/src/sql/Migrator.ts +4 -63
  664. package/src/sql/MigratorFileSystem.ts +71 -0
  665. package/src/sql/SqlClient.ts +2 -16
  666. package/src/sql/Statement.ts +8 -7
  667. package/src/sql/index.ts +1 -1
  668. package/src/testing/index.ts +0 -6
  669. package/src/workflow/internal/crypto.ts +15 -11
  670. package/dist/Crypto.d.ts +0 -244
  671. package/dist/Crypto.d.ts.map +0 -1
  672. package/dist/Crypto.js +0 -139
  673. package/dist/Crypto.js.map +0 -1
  674. package/dist/testing/TestCrypto.d.ts +0 -73
  675. package/dist/testing/TestCrypto.d.ts.map +0 -1
  676. package/dist/testing/TestCrypto.js +0 -87
  677. package/dist/testing/TestCrypto.js.map +0 -1
  678. package/src/Crypto.ts +0 -347
  679. package/src/testing/TestCrypto.ts +0 -94
@@ -16,6 +16,7 @@ import * as Cause from "../Cause.js";
16
16
  import * as Context from "../Context.js";
17
17
  import * as Data from "../Data.js";
18
18
  import * as Deferred from "../Deferred.js";
19
+ import * as Duration from "../Duration.js";
19
20
  import * as Effect from "../Effect.js";
20
21
  import * as ErrorReporter from "../ErrorReporter.js";
21
22
  import * as Exit from "../Exit.js";
@@ -43,6 +44,7 @@ import * as Schema from "../Schema.js";
43
44
  import * as SchemaAST from "../SchemaAST.js";
44
45
  import * as Scope from "../Scope.js";
45
46
  import * as Stream from "../Stream.js";
47
+ import * as Tracer from "../Tracer.js";
46
48
  import * as AiError from "./AiError.js";
47
49
  import * as McpCore from "./internal/mcpCore.js";
48
50
  import * as McpProtocolInternal from "./internal/mcpProtocol.js";
@@ -106,8 +108,18 @@ const toInternalServerNotification = message => {
106
108
  return undefined;
107
109
  }
108
110
  };
109
- // Request services must come from the invocation, including when a handler is registered during a request.
110
- const omitRequestServices = /*#__PURE__*/Context.omit(McpRequestContext, McpServerClient, HttpServerRequest.HttpServerRequest, CurrentLogLevel);
111
+ const middlewareKeyPrefix = "effect/ai/McpServer/Middleware-";
112
+ // Do not capture request services or middleware stacks at registration.
113
+ const requestServiceKeys = /*#__PURE__*/new Set([McpRequestContext.key, McpServerClient.key, HttpServerRequest.HttpServerRequest.key, HttpServerRequest.ParsedSearchParams.key, HttpRouter.RouteContext.key, CurrentLogLevel.key, Scope.Scope.key, Tracer.ParentSpan.key]);
114
+ const omitRequestServices = context => {
115
+ const services = new Map();
116
+ for (const [key, value] of context.mapUnsafe) {
117
+ if (!requestServiceKeys.has(key) && !key.startsWith(middlewareKeyPrefix)) {
118
+ services.set(key, value);
119
+ }
120
+ }
121
+ return Context.makeUnsafe(services);
122
+ };
111
123
  const provideInvocationContext = (effect, invocation) => {
112
124
  let provided = Effect.provideService(effect, McpRequestContext, invocation.requestContext);
113
125
  const requestMetadata = invocation.requestContext.requestMetadata;
@@ -117,6 +129,329 @@ const provideInvocationContext = (effect, invocation) => {
117
129
  }
118
130
  return invocation.serverClient === undefined ? provided : Effect.provideService(provided, McpServerClient, invocation.serverClient);
119
131
  };
132
+ const MiddlewareTypeId = "~effect/ai/McpServer/Middleware";
133
+ /**
134
+ * Creates MCP middleware that runs around `tools/call`, `resources/read`,
135
+ * `prompts/get` and `completion/complete` requests.
136
+ *
137
+ * **Details**
138
+ *
139
+ * Middleware is how request-level dependencies are satisfied: declare the
140
+ * services it provides with `middleware<{ provides: S }>()` and provide them to
141
+ * the handler effect. It receives the request headers, session id and request
142
+ * context, so it can resolve the current user per request.
143
+ *
144
+ * Pass a function, or an Effect that builds the function. Services the Effect
145
+ * reads are requirements of the middleware layer. Services the function reads
146
+ * per request, other than `McpRequestContext`, are per-request requirements
147
+ * of the result; see {@link Middleware} for how they are met.
148
+ *
149
+ * Failures must be `McpErrorBase` values. A middleware failure is sent as a
150
+ * JSON-RPC error with its `code`, `message` and `data`, never as a tool
151
+ * result. Pick custom codes from the implementation-defined range
152
+ * (-32000 to -32019): any numeric `code` is sent as is. Defects are logged,
153
+ * reported to the `ErrorReporter` and sent as `InternalError("Internal error")`.
154
+ * Interruption propagates.
155
+ *
156
+ * Local middleware runs inside global middleware, and middleware provided both
157
+ * locally and globally runs once. Middleware never runs for `initialize`. It
158
+ * runs for list requests only when it wraps a {@link visibility}, so that the
159
+ * visibility check can read the services it provides.
160
+ *
161
+ * **Example** (Resolving the current user per request)
162
+ *
163
+ * ```ts
164
+ * import { Context, Effect, Layer, Schema } from "effect"
165
+ * import { McpSchema, McpServer, Tool, Toolkit } from "effect/ai"
166
+ *
167
+ * class CurrentUser extends Context.Service<CurrentUser, { readonly id: string }>()("CurrentUser") {}
168
+ *
169
+ * class Unauthorized extends Schema.Error<Unauthorized>("Unauthorized")({
170
+ * ...McpSchema.McpErrorBase.fields,
171
+ * _tag: Schema.tag("Unauthorized"),
172
+ * code: Schema.tag(-32001)
173
+ * }) {}
174
+ *
175
+ * const WhoAmI = Tool.make("WhoAmI", { success: Schema.String, dependencies: [CurrentUser] })
176
+ * const Tools = Toolkit.make(WhoAmI)
177
+ *
178
+ * const Auth = McpServer.middleware<{ provides: CurrentUser }>()((effect, { headers }) => {
179
+ * const token = headers["authorization"]
180
+ * return token === undefined
181
+ * ? Effect.fail(new Unauthorized({ message: "Missing credentials" }))
182
+ * : Effect.provideService(effect, CurrentUser, { id: token })
183
+ * })
184
+ *
185
+ * const Registrations = McpServer.toolkit(Tools).pipe(
186
+ * Layer.provide(Auth.layer),
187
+ * Layer.provide(Tools.toLayer({
188
+ * WhoAmI: () => Effect.map(CurrentUser, (user) => user.id)
189
+ * }))
190
+ * )
191
+ * ```
192
+ *
193
+ * @stability unstable
194
+ * @category middleware
195
+ * @since 4.0.0
196
+ */
197
+ export const middleware = function () {
198
+ if (arguments.length === 0) {
199
+ return makeMiddleware;
200
+ }
201
+ return makeMiddleware(arguments[0], arguments[1]);
202
+ };
203
+ /**
204
+ * Creates middleware that hides registrations per request.
205
+ *
206
+ * **Details**
207
+ *
208
+ * The check runs for every registration the middleware is provided to, on list
209
+ * requests and on calls, reads, gets and completions. When it returns `false`
210
+ * the registration is left out of list results, and requests for it fail as if
211
+ * it was not registered.
212
+ *
213
+ * The result is a `Middleware` and composes like one. The check receives the
214
+ * same {@link MiddlewareOptions} as middleware, and services it reads per
215
+ * request, other than `McpRequestContext`, are met the same way. Scope a
216
+ * visibility to some tools by providing its layer to their toolkit only, or
217
+ * branch on `target`.
218
+ *
219
+ * On a list request, the check and the middleware outside the innermost
220
+ * visibility run once for each registration. Middleware inside it does not
221
+ * run. A failure of that middleware or of a check fails the whole list
222
+ * request. It never hides a registration.
223
+ *
224
+ * Unlike `EnabledWhen`, a visibility runs the middleware around it on list
225
+ * requests, and middleware sees requests for hidden registrations.
226
+ *
227
+ * **Example** (Hiding admin tools from other users)
228
+ *
229
+ * ```ts
230
+ * import { Context, Effect, Layer, Schema } from "effect"
231
+ * import { McpServer, Tool, Toolkit } from "effect/ai"
232
+ *
233
+ * class CurrentUser extends Context.Service<CurrentUser, { readonly isAdmin: boolean }>()("CurrentUser") {}
234
+ *
235
+ * const AdminTools = Toolkit.make(Tool.make("DeleteUser", { success: Schema.String }))
236
+ *
237
+ * const Auth = McpServer.middleware<{ provides: CurrentUser }>()((effect, { headers }) =>
238
+ * Effect.provideService(effect, CurrentUser, { isAdmin: headers["x-role"] === "admin" })
239
+ * )
240
+ * const AdminOnly = McpServer.visibility(() => Effect.map(CurrentUser, (user) => user.isAdmin))
241
+ *
242
+ * const Registrations = McpServer.toolkit(AdminTools).pipe(
243
+ * Layer.provide(AdminOnly.combine(Auth).layer),
244
+ * Layer.provide(AdminTools.toLayer({ DeleteUser: () => Effect.succeed("deleted") }))
245
+ * )
246
+ * ```
247
+ *
248
+ * @see {@link middleware} for providing the services a check reads
249
+ *
250
+ * @stability unstable
251
+ * @category middleware
252
+ * @since 4.0.0
253
+ */
254
+ export const visibility = (check, options) => makeMiddleware(Effect.isEffect(check) ? Effect.map(check, makeGate) : makeGate(check), options);
255
+ // Raised by a visibility gate. It is left out of the types because `makeInvoke`
256
+ // replaces it with the not-found error of the request. It still has the shape
257
+ // of an MCP error, since middleware outside the gate sees it as one.
258
+ class Hidden extends /*#__PURE__*/Data.TaggedError("effect/ai/McpServer/Hidden") {}
259
+ const failHidden = /*#__PURE__*/Effect.fail(/*#__PURE__*/new Hidden({
260
+ code: McpSchema.INVALID_PARAMS_ERROR_CODE,
261
+ message: "Not found"
262
+ }));
263
+ // Marks the middleware functions created by `visibility`.
264
+ const gates = /*#__PURE__*/new WeakSet();
265
+ const makeGate = check => {
266
+ const gate = (effect, options) => Effect.flatMap(check(options), visible => visible ? effect : failHidden);
267
+ gates.add(gate);
268
+ return gate;
269
+ };
270
+ class MiddlewareFn extends /*#__PURE__*/Context.Service()("effect/ai/McpServer/MiddlewareFn") {}
271
+ const makeMiddleware = (fn, options) => {
272
+ const middleware = new MiddlewareImpl(Effect.isEffect(fn) ? Layer.effect(MiddlewareFn)(fn) : Layer.succeed(MiddlewareFn, fn));
273
+ return options?.global ? middleware.layerGlobal : middleware;
274
+ };
275
+ let middlewareId = 0;
276
+ class MiddlewareImpl {
277
+ [MiddlewareTypeId] = {};
278
+ layer;
279
+ layerGlobal;
280
+ layerFn;
281
+ dependencies;
282
+ constructor(layerFn, dependencies) {
283
+ this.layerFn = layerFn;
284
+ this.dependencies = dependencies;
285
+ const contextKey = `${middlewareKeyPrefix}${++middlewareId}`;
286
+ this.layer = Layer.effectContext(Effect.gen(function* () {
287
+ const stack = [yield* MiddlewareFn];
288
+ if (dependencies) {
289
+ const memoMap = yield* Layer.CurrentMemoMap;
290
+ const scope = yield* Effect.scope;
291
+ stack.push(...getMiddleware(yield* Layer.buildWithMemoMap(dependencies, memoMap, scope)));
292
+ }
293
+ return Context.makeUnsafe(new Map([[contextKey, stack]]));
294
+ })).pipe(Layer.provide(layerFn));
295
+ this.layerGlobal = Layer.effectDiscard(Effect.gen(function* () {
296
+ const stack = Context.getOrUndefinedUnsafe(yield* Effect.context(), contextKey);
297
+ const {
298
+ globalMiddleware
299
+ } = internalState.get(yield* McpServer);
300
+ yield* Effect.acquireRelease(Effect.sync(() => {
301
+ globalMiddleware.push(...stack);
302
+ }), () => Effect.sync(() => {
303
+ for (const fn of stack) {
304
+ const index = globalMiddleware.indexOf(fn);
305
+ if (index !== -1) globalMiddleware.splice(index, 1);
306
+ }
307
+ }));
308
+ })).pipe(Layer.provide(this.layer));
309
+ }
310
+ combine(other) {
311
+ return new MiddlewareImpl(this.layerFn, this.dependencies ? Layer.provideMerge(this.dependencies, other.layer) : other.layer);
312
+ }
313
+ }
314
+ // The innermost middleware comes first.
315
+ const getMiddleware = context => {
316
+ const stacks = [];
317
+ let maxLength = 0;
318
+ for (const [key, value] of context.mapUnsafe) {
319
+ if (key.startsWith(middlewareKeyPrefix)) {
320
+ stacks.push(value);
321
+ maxLength = Math.max(maxLength, value.length);
322
+ }
323
+ }
324
+ const unique = new Set();
325
+ for (let i = maxLength - 1; i >= 0; i--) {
326
+ for (const stack of stacks) {
327
+ if (i < stack.length) unique.add(stack[i]);
328
+ }
329
+ }
330
+ return Arr.fromIterable(unique).reverse();
331
+ };
332
+ const isMcpError = error => Predicate.hasProperty(error, "code") && typeof error.code === "number" && Predicate.hasProperty(error, "message") && typeof error.message === "string";
333
+ // Distinguishes handler failures from failures raised or rewritten by middleware.
334
+ const HandlerFailure = /*#__PURE__*/Context.Reference("effect/ai/McpServer/HandlerFailure", {
335
+ defaultValue: () => false
336
+ });
337
+ const handlerFailure = /*#__PURE__*/Context.make(HandlerFailure, true);
338
+ const internalError = /*#__PURE__*/new InternalError({
339
+ message: "Internal error"
340
+ });
341
+ const rejectWith = error => Effect.fail(new McpCore.RequestRejected({
342
+ code: error.code,
343
+ message: error.message,
344
+ data: error.data,
345
+ error
346
+ }));
347
+ const notFound = (method, target) => {
348
+ switch (method) {
349
+ case "tools/call":
350
+ return new McpCore.ToolNotFound({
351
+ name: target
352
+ });
353
+ case "resources/read":
354
+ return new McpCore.ResourceNotFound({
355
+ uri: target
356
+ });
357
+ case "prompts/get":
358
+ return new McpCore.PromptNotFound({
359
+ name: target
360
+ });
361
+ case "completion/complete":
362
+ return new InvalidParams({
363
+ message: "Unknown completion reference or argument"
364
+ });
365
+ }
366
+ };
367
+ const isHidden = error => error instanceof Hidden;
368
+ // Recovers a request rejected by a visibility gate. Any other cause, including
369
+ // one that also holds an interrupt, is propagated unchanged.
370
+ const catchHidden = onHidden => self => Effect.catchCause(self, cause => {
371
+ const failure = Cause.findFail(cause);
372
+ return !Cause.hasInterrupts(cause) && Result.isSuccess(failure) && isHidden(failure.success.error) ? onHidden() : Effect.failCause(cause);
373
+ });
374
+ // The innermost middleware comes first. Middleware provided both locally and
375
+ // globally runs once, at its outermost position.
376
+ const middlewareStack = (localMiddleware, globalMiddleware) => {
377
+ if (globalMiddleware.length === 0) {
378
+ return localMiddleware;
379
+ }
380
+ if (localMiddleware.length === 0) {
381
+ return globalMiddleware;
382
+ }
383
+ const stack = [...localMiddleware, ...globalMiddleware];
384
+ return stack.filter((fn, index) => stack.lastIndexOf(fn) === index);
385
+ };
386
+ // Runs a handler inside middleware. The handler's own failures pass through, a
387
+ // visibility gate fails with `Hidden`, and other failures become
388
+ // `RequestRejected`: middleware failures as JSON-RPC errors, anything else as
389
+ // a reported internal error.
390
+ const runMiddleware = (handler, middleware, invocation, request) => {
391
+ const effect = middleware.length === 0 ? handler : Effect.withFiber(fiber => {
392
+ const headers = Context.getOrUndefined(fiber.context, HttpServerRequest.HttpServerRequest)?.headers ?? Headers.empty;
393
+ const options = {
394
+ ...request,
395
+ requestContext: invocation.requestContext,
396
+ headers,
397
+ sessionId: headers[MCP_SESSION_ID_HEADER]
398
+ };
399
+ const handled = Effect.catchCause(handler, cause => Effect.failCause(Cause.annotate(cause, handlerFailure)));
400
+ return middleware.reduce((effect, fn) => fn(effect, options), handled);
401
+ });
402
+ return provideInvocationContext(effect, invocation).pipe(Effect.catchCause(cause => {
403
+ if (Cause.hasInterrupts(cause)) {
404
+ return Effect.failCause(cause);
405
+ }
406
+ const failure = Cause.findFail(cause);
407
+ if (Result.isSuccess(failure) && !Cause.hasDies(cause)) {
408
+ const error = failure.success.error;
409
+ if (isHidden(error)) {
410
+ return Effect.fail(error);
411
+ }
412
+ if (middleware.length === 0 || Context.get(Cause.reasonAnnotations(failure.success), HandlerFailure)) {
413
+ return Effect.failCause(cause);
414
+ }
415
+ if (isMcpError(error)) {
416
+ return rejectWith(error);
417
+ }
418
+ }
419
+ return Effect.logError(cause).pipe(Effect.andThen(ErrorReporter.report(cause)), Effect.andThen(rejectWith(internalError)));
420
+ }));
421
+ };
422
+ // Request services override captured services; global middleware wraps local middleware.
423
+ const makeInvoke = (context, globalMiddleware) => {
424
+ const services = context === undefined ? Context.empty() : omitRequestServices(context);
425
+ const localMiddleware = context === undefined ? [] : getMiddleware(context);
426
+ const invoke = (handler, invocation, request) => runMiddleware(services.mapUnsafe.size === 0 ? handler : Effect.updateContext(handler, context => Context.merge(services, context)), middlewareStack(localMiddleware, globalMiddleware), invocation, request).pipe(catchHidden(() => Effect.fail(notFound(request.method, request.target))));
427
+ // On list requests only the middleware outside the innermost visibility runs.
428
+ const visible = (method, target) => invocation => {
429
+ const middleware = middlewareStack(localMiddleware, globalMiddleware);
430
+ const innermost = middleware.findIndex(fn => gates.has(fn));
431
+ if (innermost === -1) {
432
+ return Effect.succeed(true);
433
+ }
434
+ return runMiddleware(Effect.void, middleware.slice(innermost), invocation, {
435
+ method,
436
+ target,
437
+ payload: undefined
438
+ }).pipe(Effect.as(true), catchHidden(() => Effect.succeed(false)));
439
+ };
440
+ return {
441
+ invoke,
442
+ visible
443
+ };
444
+ };
445
+ // Applies the `EnabledWhen` annotation of a registration.
446
+ const isEnabled = annotations => {
447
+ const enabledWhen = Context.getOrUndefined(annotations, EnabledWhen);
448
+ return profile => enabledWhen === undefined || enabledWhen({
449
+ protocolVersion: profile.protocolVersion,
450
+ capabilities: profile.clientCapabilities,
451
+ clientInfo: profile.clientInfo
452
+ });
453
+ };
454
+ const rejectedError = rejected => Effect.fail(rejected.error);
120
455
  /**
121
456
  * Service that stores and serves an MCP server's registered tools, resources,
122
457
  * prompts, completions, and outgoing notifications.
@@ -144,6 +479,7 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
144
479
  const resourceTemplates = [];
145
480
  const prompts = [];
146
481
  const notificationsQueue = yield* Queue.make();
482
+ const globalMiddleware = [];
147
483
  const notificationDelivery = {
148
484
  consumers: 0,
149
485
  listChangeRevision: 0,
@@ -233,18 +569,22 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
233
569
  } else {
234
570
  tools[existingIndex] = options;
235
571
  }
236
- const enabledWhen = Context.getOrUndefined(options.annotations, EnabledWhen);
572
+ const {
573
+ invoke,
574
+ visible
575
+ } = makeInvoke(options.services, globalMiddleware);
237
576
  yield* internalCore.tools.register({
238
577
  descriptor: new McpTool({
239
578
  ...options.tool,
240
579
  title: options.tool.title ?? options.tool.annotations?.title
241
580
  }),
242
- isVisible: profile => enabledWhen === undefined || enabledWhen({
243
- protocolVersion: profile.protocolVersion,
244
- capabilities: profile.clientCapabilities,
245
- clientInfo: profile.clientInfo
246
- }),
247
- handle: (call, invocation) => provideInvocationContext(options.handle(call.arguments), invocation).pipe(Effect.catchTags({
581
+ visible: visible("tools/list", options.tool.name),
582
+ isVisible: isEnabled(options.annotations),
583
+ handle: (call, invocation) => invoke(options.handle(call.arguments), invocation, {
584
+ method: "tools/call",
585
+ target: call.name,
586
+ payload: call
587
+ }).pipe(Effect.catchTags({
248
588
  InternalError: error => Effect.fail(new McpCore.ToolExecutionError({
249
589
  name: options.tool.name,
250
590
  message: error.message
@@ -259,9 +599,9 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
259
599
  }),
260
600
  callTool: Effect.fnUntraced(function* (request) {
261
601
  const client = yield* McpServerClient;
262
- const result = yield* internalCore.tools.call(request, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.mapError(error => new InvalidParams({
602
+ const result = yield* internalCore.tools.call(request, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catch(error => error._tag === "RequestRejected" ? rejectedError(error) : Effect.fail(new InvalidParams({
263
603
  message: error._tag === "ToolNotFound" ? `Tool '${error.name}' not found` : error.message
264
- })));
604
+ }))));
265
605
  if (result._tag === "InputRequired") {
266
606
  return yield* new InvalidParams({
267
607
  message: "Client input is not supported by this MCP protocol"
@@ -284,17 +624,21 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
284
624
  } else {
285
625
  resources[existingIndex] = options;
286
626
  }
627
+ const {
628
+ invoke,
629
+ visible
630
+ } = makeInvoke(options.services, globalMiddleware);
287
631
  yield* internalCore.resources.register({
288
632
  descriptor: options.resource,
289
- isVisible: profile => {
290
- const enabledWhen = Context.getOrUndefined(options.annotations, EnabledWhen);
291
- return enabledWhen === undefined || enabledWhen({
292
- protocolVersion: profile.protocolVersion,
293
- capabilities: profile.clientCapabilities,
294
- clientInfo: profile.clientInfo
295
- });
296
- },
297
- read: invocation => provideInvocationContext(options.handle, invocation)
633
+ visible: visible("resources/list", options.resource.uri),
634
+ isVisible: isEnabled(options.annotations),
635
+ read: invocation => invoke(options.handle, invocation, {
636
+ method: "resources/read",
637
+ target: options.resource.uri,
638
+ payload: {
639
+ uri: options.resource.uri
640
+ }
641
+ })
298
642
  });
299
643
  yield* notifications.client["notifications/resources/list_changed"]({});
300
644
  }),
@@ -303,6 +647,7 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
303
647
  completions,
304
648
  handle,
305
649
  routerPath,
650
+ services,
306
651
  template
307
652
  }) {
308
653
  const existingIndex = resourceTemplates.findIndex(({
@@ -319,18 +664,16 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
319
664
  annotations
320
665
  };
321
666
  }
667
+ const {
668
+ invoke,
669
+ visible
670
+ } = makeInvoke(services, globalMiddleware);
322
671
  const templateMatcher = makeUriMatcher();
323
672
  templateMatcher.add(routerPath, true);
324
673
  yield* internalCore.resources.registerTemplate({
325
674
  descriptor: template,
326
- isVisible: profile => {
327
- const enabledWhen = Context.getOrUndefined(annotations, EnabledWhen);
328
- return enabledWhen === undefined || enabledWhen({
329
- protocolVersion: profile.protocolVersion,
330
- capabilities: profile.clientCapabilities,
331
- clientInfo: profile.clientInfo
332
- });
333
- },
675
+ visible: visible("resources/templates/list", template.uriTemplate),
676
+ isVisible: isEnabled(annotations),
334
677
  match: uri => {
335
678
  const match = templateMatcher.find(uri);
336
679
  if (match === undefined) {
@@ -342,10 +685,20 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
342
685
  }
343
686
  return params;
344
687
  },
345
- read: (uri, params, invocation) => provideInvocationContext(handle(uri, Array.from(params)), invocation)
688
+ read: (uri, params, invocation) => invoke(handle(uri, Array.from(params)), invocation, {
689
+ method: "resources/read",
690
+ target: uri,
691
+ payload: {
692
+ uri
693
+ }
694
+ })
346
695
  });
347
696
  for (const [param, handle] of Object.entries(completions)) {
348
- yield* internalCore.completions.register(`resource/${template.uriTemplate}/${param}`, (request, invocation) => provideInvocationContext(handle(request.argument.value, request.context), invocation).pipe(Effect.map(result => ({
697
+ yield* internalCore.completions.register(`resource/${template.uriTemplate}/${param}`, (request, invocation) => invoke(handle(request.argument.value, request.context), invocation, {
698
+ method: "completion/complete",
699
+ target: template.uriTemplate,
700
+ payload: request
701
+ }).pipe(Effect.map(result => ({
349
702
  values: result.completion.values,
350
703
  total: result.completion.total,
351
704
  hasMore: result.completion.hasMore,
@@ -356,9 +709,12 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
356
709
  }),
357
710
  findResource: Effect.fnUntraced(function* (uri) {
358
711
  const client = yield* McpServerClient;
359
- return yield* internalCore.resources.read(uri, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTag("ResourceNotFound", error => Effect.fail(new InvalidParams({
360
- message: `Resource '${error.uri}' not found`
361
- }))));
712
+ return yield* internalCore.resources.read(uri, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTags({
713
+ ResourceNotFound: error => Effect.fail(new InvalidParams({
714
+ message: `Resource '${error.uri}' not found`
715
+ })),
716
+ RequestRejected: rejectedError
717
+ }));
362
718
  }),
363
719
  get prompts() {
364
720
  return prompts;
@@ -372,20 +728,29 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
372
728
  } else {
373
729
  prompts[existingIndex] = options;
374
730
  }
731
+ const {
732
+ invoke,
733
+ visible
734
+ } = makeInvoke(options.services, globalMiddleware);
375
735
  yield* internalCore.prompts.register({
376
736
  descriptor: options.prompt,
377
- isVisible: profile => {
378
- const enabledWhen = Context.getOrUndefined(options.annotations, EnabledWhen);
379
- return enabledWhen === undefined || enabledWhen({
380
- protocolVersion: profile.protocolVersion,
381
- capabilities: profile.clientCapabilities,
382
- clientInfo: profile.clientInfo
383
- });
384
- },
385
- get: (params, invocation) => provideInvocationContext(options.handle(params), invocation).pipe(Effect.map(result => Predicate.isTagged(result, "InputRequired") ? McpCore.OperationOutcome.InputRequired(result) : McpCore.OperationOutcome.Complete(result)))
737
+ visible: visible("prompts/list", options.prompt.name),
738
+ isVisible: isEnabled(options.annotations),
739
+ get: (params, invocation) => invoke(options.handle(params), invocation, {
740
+ method: "prompts/get",
741
+ target: options.prompt.name,
742
+ payload: {
743
+ name: options.prompt.name,
744
+ arguments: params
745
+ }
746
+ }).pipe(Effect.map(result => Predicate.isTagged(result, "InputRequired") ? McpCore.OperationOutcome.InputRequired(result) : McpCore.OperationOutcome.Complete(result)))
386
747
  });
387
748
  for (const [param, handle] of Object.entries(options.completions)) {
388
- yield* internalCore.completions.register(`prompt/${options.prompt.name}/${param}`, (request, invocation) => provideInvocationContext(handle(request.argument.value, request.context), invocation).pipe(Effect.map(result => ({
749
+ yield* internalCore.completions.register(`prompt/${options.prompt.name}/${param}`, (request, invocation) => invoke(handle(request.argument.value, request.context), invocation, {
750
+ method: "completion/complete",
751
+ target: options.prompt.name,
752
+ payload: request
753
+ }).pipe(Effect.map(result => ({
389
754
  values: result.completion.values,
390
755
  total: result.completion.total,
391
756
  hasMore: result.completion.hasMore,
@@ -399,9 +764,12 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
399
764
  name
400
765
  }) {
401
766
  const client = yield* McpServerClient;
402
- const outcome = yield* internalCore.prompts.get(name, params ?? {}, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTag("PromptNotFound", () => new InvalidParams({
403
- message: `Prompt '${name}' not found`
404
- })));
767
+ const outcome = yield* internalCore.prompts.get(name, params ?? {}, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTags({
768
+ PromptNotFound: () => new InvalidParams({
769
+ message: `Prompt '${name}' not found`
770
+ }),
771
+ RequestRejected: rejectedError
772
+ }));
405
773
  return outcome._tag === "Complete" ? outcome.value : yield* new InvalidParams({
406
774
  message: "Client input is not supported by this MCP protocol"
407
775
  });
@@ -419,7 +787,7 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
419
787
  },
420
788
  argument: complete.argument,
421
789
  context: complete.context
422
- }, McpProtocolInternal.invocationFromClient(client));
790
+ }, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTag("RequestRejected", rejectedError));
423
791
  return {
424
792
  _meta: result.metadata,
425
793
  completion: {
@@ -433,12 +801,19 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
433
801
  internalState.set(service, {
434
802
  core: internalCore,
435
803
  notifications: notificationsQueue,
436
- notificationDelivery
804
+ notificationDelivery,
805
+ globalMiddleware
437
806
  });
438
807
  return service;
439
808
  });
440
809
  /**
441
- * Layer that provides the MCP server and client services.
810
+ * Layer that provides the MCP server service.
811
+ *
812
+ * **Details**
813
+ *
814
+ * It doesn't run a transport or discharge request-level dependencies. Use it
815
+ * to call registrations in process, providing their request-level
816
+ * dependencies with MCP middleware.
442
817
  *
443
818
  * @stability unstable
444
819
  * @since 4.0.0
@@ -452,6 +827,26 @@ const cancelledResponses = /*#__PURE__*/new WeakMap();
452
827
  const httpPostResponses = /*#__PURE__*/new WeakMap();
453
828
  const requestKey = requestId => `${typeof requestId}:${requestId}`;
454
829
  class McpClientKey extends Data.Class {}
830
+ // Converts each hint to the wire's nonnegative integer `ttlMs` once, when the server is built.
831
+ const normalizeCacheHints = cacheHints => {
832
+ if (cacheHints === undefined) return Effect.succeed(undefined);
833
+ const normalized = {};
834
+ for (const [name, hint] of Object.entries(cacheHints)) {
835
+ if (hint === undefined) continue;
836
+ const ttlMs = Option.match(Duration.fromInput(hint.ttl), {
837
+ onNone: () => NaN,
838
+ onSome: ttl => Math.floor(Duration.toMillis(ttl))
839
+ });
840
+ if (!Number.isSafeInteger(ttlMs) || ttlMs < 0 || hint.cacheScope !== "private") {
841
+ return Effect.fail(new Cause.IllegalArgumentError(`McpServer cacheHints.${name} must have a finite, nonnegative ttl and a "private" cacheScope`));
842
+ }
843
+ normalized[name] = {
844
+ ttlMs,
845
+ cacheScope: "private"
846
+ };
847
+ }
848
+ return Effect.succeed(normalized);
849
+ };
455
850
  /**
456
851
  * Runs an MCP server over the current `RpcServer.Protocol`.
457
852
  *
@@ -466,9 +861,13 @@ class McpClientKey extends Data.Class {}
466
861
  * @since 4.0.0
467
862
  */
468
863
  export const run = /*#__PURE__*/Effect.fnUntraced(function* (options) {
864
+ const cacheHints = yield* normalizeCacheHints(options.cacheHints);
469
865
  const runtimeOption = yield* Effect.serviceOption(McpRuntime.ServerRuntime);
470
866
  const runtime = Option.isSome(runtimeOption) ? runtimeOption.value : yield* McpRuntime.make(options.protocols);
471
- return yield* runWithRuntime(options, runtime, "custom");
867
+ return yield* runWithRuntime({
868
+ ...options,
869
+ cacheHints
870
+ }, runtime, "custom");
472
871
  });
473
872
  const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtime, transport, requestScoped) {
474
873
  const protocol = yield* RpcServer.Protocol;
@@ -975,7 +1374,7 @@ const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtim
975
1374
  if (requestContext?.clientId !== clientId || !isLoggingLevel(level) || McpSchema.LoggingLevel.literals.indexOf(notification.level) < McpSchema.LoggingLevel.literals.indexOf(level)) {
976
1375
  return;
977
1376
  }
978
- } else if (!runtime.canDeliver(clientId, (requestContext?.clientId === clientId ? requestHeaders : undefined) ?? clientStates.get(clientId)?.sessionHeaders ?? Headers.empty, notification, defaultLogLevel)) {
1377
+ } else if (!runtime.canDeliver(clientId, (requestContext?.clientId === clientId ? requestHeaders : undefined) ?? clientStates.get(clientId)?.sessionHeaders ?? Headers.empty, notification, defaultLogLevel, listChangeRevision)) {
979
1378
  return;
980
1379
  }
981
1380
  const rpc = selectedProtocol.serverNotificationRpcs.requests.get(projected.tag);
@@ -1028,6 +1427,11 @@ const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtim
1028
1427
  * `McpServer.layer`, so registration layers can use the `McpServer` service
1029
1428
  * while the server is running.
1030
1429
  *
1430
+ * Pass registration layers as `registrations` to build them before the server
1431
+ * reads its first request. The transport discharges the request-level
1432
+ * dependencies it supplies (see `ProvidedServices`); any other `McpRequest`
1433
+ * marker stays in the layer's requirements and must be met by MCP middleware.
1434
+ *
1031
1435
  * **Gotchas**
1032
1436
  *
1033
1437
  * Unlike `layerStdio` and `layerHttp`, this layer does not install a concrete
@@ -1043,9 +1447,13 @@ const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtim
1043
1447
  */
1044
1448
  export const layer = options => layerWithRuntime(options, "custom").pipe(Layer.provide(McpRuntime.layer(options.protocols)));
1045
1449
  const layerWithRuntime = (options, transport) => Layer.effectDiscard(Effect.gen(function* () {
1450
+ const cacheHints = yield* normalizeCacheHints(options.cacheHints);
1046
1451
  const runtime = yield* McpRuntime.ServerRuntime;
1047
- yield* Effect.forkScoped(runWithRuntime(options, runtime, transport));
1048
- })).pipe(Layer.provideMerge(McpServer.layer));
1452
+ yield* Effect.forkScoped(runWithRuntime({
1453
+ ...options,
1454
+ cacheHints
1455
+ }, runtime, transport));
1456
+ })).pipe(Layer.provide(options.registrations ?? Layer.empty), Layer.provideMerge(McpServer.layer));
1049
1457
  /**
1050
1458
  * Creates a layer that runs an MCP server over standard input and output.
1051
1459
  *
@@ -1061,6 +1469,11 @@ const layerWithRuntime = (options, transport) => Layer.effectDiscard(Effect.gen(
1061
1469
  * `McpRequestContext` and legacy `McpServerClient` services to handlers, and
1062
1470
  * requires `Stdio`.
1063
1471
  *
1472
+ * Pass registration layers as `registrations` to build them before the server
1473
+ * reads its first request. The transport discharges the request-level
1474
+ * dependencies it supplies (see `ProvidedServices`); any other `McpRequest`
1475
+ * marker stays in the layer's requirements and must be met by MCP middleware.
1476
+ *
1064
1477
  * @see {@link layer} for running over an existing `RpcServer.Protocol`
1065
1478
  * @see {@link layerHttp} for the single-endpoint HTTP transport
1066
1479
  *
@@ -1161,6 +1574,13 @@ const mcpStdioSerialization = protocols => {
1161
1574
  * serverless hosts where execution must belong to each request, use
1162
1575
  * `layerHttpRequestScoped` instead.
1163
1576
  *
1577
+ * Pass registration layers as `registrations` to build them before the
1578
+ * endpoint serves its first request. The transport discharges the
1579
+ * request-level dependencies it supplies (see `ProvidedServices`) and converts
1580
+ * the remaining `McpRequest` markers into `HttpRouter.Request` markers, so
1581
+ * `HttpRouter.middleware` can provide them, for example to authenticate the
1582
+ * request and resolve the current user.
1583
+ *
1164
1584
  * `layerHttp` always implements the single-endpoint Streamable HTTP topology.
1165
1585
  * Using `v2024_11_05` here is a custom compatibility transport for that
1166
1586
  * revision's schema. It does not implement the historical two-endpoint
@@ -1210,6 +1630,10 @@ export const layerHttp = options => {
1210
1630
  * Configuring a sessionful protocol through an untyped caller fails layer
1211
1631
  * construction with `IllegalArgumentError`.
1212
1632
  *
1633
+ * Registrations passed as `registrations` are built once, before the routes
1634
+ * are added, and shared by every POST. Remaining `McpRequest` markers become
1635
+ * `HttpRouter.Request` markers, as with `layerHttp`.
1636
+ *
1213
1637
  * @see {@link layerHttp} for the long-lived HTTP transport and HTTP admission policy
1214
1638
  *
1215
1639
  * @stability unstable
@@ -1222,6 +1646,10 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
1222
1646
  if (stateful !== undefined) {
1223
1647
  return yield* new Cause.IllegalArgumentError(`McpServer.layerHttpRequestScoped does not support the sessionful MCP protocol ${stateful.protocolVersion}`);
1224
1648
  }
1649
+ const serverOptions = {
1650
+ ...options,
1651
+ cacheHints: yield* normalizeCacheHints(options.cacheHints)
1652
+ };
1225
1653
  const server = yield* McpServer;
1226
1654
  const {
1227
1655
  core,
@@ -1235,7 +1663,7 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
1235
1663
  subscribeServerNotifications: Effect.die("Subscriptions are disabled for request-scoped MCP servers"),
1236
1664
  getListChangeRevision: () => notificationDelivery.listChangeRevision,
1237
1665
  defaultLogLevel: yield* CurrentLogLevel,
1238
- serverInfo: options
1666
+ serverInfo: serverOptions
1239
1667
  });
1240
1668
  yield* Effect.acquireRelease(Effect.sync(() => {
1241
1669
  notificationDelivery.requestEndpoints++;
@@ -1250,7 +1678,7 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
1250
1678
  protocol
1251
1679
  } = yield* RpcServer.makeProtocolWithHttpEffect().pipe(Effect.provideService(RpcSerialization.RpcSerialization, mcpHttpSerialization));
1252
1680
  const notifications = yield* Queue.make();
1253
- yield* runWithRuntime(options, runtime, "http", {
1681
+ yield* runWithRuntime(serverOptions, runtime, "http", {
1254
1682
  notifications,
1255
1683
  handlers
1256
1684
  }).pipe(Effect.provideService(RpcServer.Protocol, protocol), Effect.provideService(McpServer, server), Effect.forkScoped({
@@ -1258,7 +1686,7 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
1258
1686
  }));
1259
1687
  return yield* Effect.provideService(httpEffect, RequestNotificationQueue, notifications);
1260
1688
  }));
1261
- })).pipe(Layer.provideMerge(McpServer.layer), Layer.provide(McpRuntime.layer(options.protocols)));
1689
+ })).pipe(Layer.provide(options.registrations ?? Layer.empty), Layer.provideMerge(McpServer.layer), Layer.provide(McpRuntime.layer(options.protocols)));
1262
1690
  const layerMcpProtocolHttp = options => Layer.effect(RpcServer.Protocol)(Effect.gen(function* () {
1263
1691
  const {
1264
1692
  httpEffect,
@@ -1480,6 +1908,13 @@ const toolResultContent = encoded => encoded === undefined ? [] : [{
1480
1908
  /**
1481
1909
  * Registers a `Toolkit` with the `McpServer`.
1482
1910
  *
1911
+ * **Details**
1912
+ *
1913
+ * The MCP middleware in the current context, provided with
1914
+ * `Effect.provide(middleware.layer)`, runs around every call to the toolkit.
1915
+ *
1916
+ * @see {@link ToolkitRequirements} for which services are request-level
1917
+ *
1483
1918
  * @stability unstable
1484
1919
  * @category handlers
1485
1920
  * @since 4.0.0
@@ -1500,12 +1935,11 @@ export const registerToolkit = /*#__PURE__*/Effect.fnUntraced(function* (toolkit
1500
1935
  }
1501
1936
  return Context.makeUnsafe(services);
1502
1937
  }));
1503
- const services = omitRequestServices(yield* Effect.context());
1504
- const reportCause = cause => Effect.provideContext(ErrorReporter.report(cause), services);
1938
+ const services = yield* Effect.context();
1505
1939
  // Interruption propagates; anything else is logged, reported and scrubbed.
1506
1940
  const internalToolError = cause => {
1507
1941
  const failure = Cause.findFail(cause);
1508
- return Result.isFailure(failure) && !Cause.hasDies(cause) ? Effect.failCause(failure.failure) : Effect.logError(cause).pipe(Effect.andThen(reportCause(cause)), Effect.as(toolErrorResult(INTERNAL_TOOL_ERROR_MESSAGE)));
1942
+ return Result.isFailure(failure) && !Cause.hasDies(cause) ? Effect.failCause(failure.failure) : Effect.logError(cause).pipe(Effect.andThen(ErrorReporter.report(cause)), Effect.as(toolErrorResult(INTERNAL_TOOL_ERROR_MESSAGE)));
1509
1943
  };
1510
1944
  const registrations = [];
1511
1945
  for (const tool of Object.values(built.tools)) {
@@ -1570,8 +2004,9 @@ export const registerToolkit = /*#__PURE__*/Effect.fnUntraced(function* (toolkit
1570
2004
  isError: result.isFailure,
1571
2005
  structuredContent: result.isFailure ? undefined : result.encodedResult,
1572
2006
  content: toolResultContent(result.encodedResult)
1573
- }))), Effect.catchCause(handleCause), Effect.provideContext(services));
1574
- }
2007
+ }))), Effect.catchCause(handleCause));
2008
+ },
2009
+ services
1575
2010
  });
1576
2011
  }
1577
2012
  for (const registration of registrations) {
@@ -1598,13 +2033,31 @@ const toolJsonSchema = (schema, strict) => {
1598
2033
  };
1599
2034
  };
1600
2035
  /**
1601
- * Registers an `AiToolkit` with the `McpServer`.
2036
+ * Creates a layer that registers a `Toolkit` with the `McpServer`.
2037
+ *
2038
+ * **Details**
2039
+ *
2040
+ * The layer requires `McpServer`. Pass it to a transport through the
2041
+ * `registrations` option, or provide the transport layer to it.
2042
+ *
2043
+ * @see {@link ToolkitRequirements} for which services are request-level
1602
2044
  *
1603
2045
  * @stability unstable
1604
2046
  * @category layers
1605
2047
  * @since 4.0.0
1606
2048
  */
1607
- export const toolkit = toolkit => Layer.effectDiscard(registerToolkit(toolkit)).pipe(Layer.provide(McpServer.layer));
2049
+ export const toolkit = toolkit => Layer.effectDiscard(registerToolkit(toolkit));
2050
+ // Leave defects and interruption to makeInvoke; convert only expected failures.
2051
+ const handlerFailureToInternalError = cause => Cause.hasDies(cause) || Cause.hasInterrupts(cause) ? Effect.failCause(cause) : Effect.fail(new InternalError({
2052
+ message: Cause.prettyErrors(cause)[0].message
2053
+ }));
2054
+ const completionHandler = (handle, encodeValues) => (input, context) => handle(input, context).pipe(Effect.flatMap(encodeValues), Effect.map(values => ({
2055
+ completion: {
2056
+ values: values,
2057
+ total: values.length,
2058
+ hasMore: false
2059
+ }
2060
+ })), Effect.catchCause(handlerFailureToInternalError));
1608
2061
  /**
1609
2062
  * Registers an MCP resource or resource template from an Effect program.
1610
2063
  *
@@ -1618,19 +2071,15 @@ export const registerResource = function () {
1618
2071
  if (arguments.length === 1) {
1619
2072
  const options = arguments[0];
1620
2073
  return Effect.gen(function* () {
1621
- const services = omitRequestServices(yield* Effect.context());
2074
+ const services = yield* Effect.context();
1622
2075
  const registry = yield* McpServer;
1623
2076
  yield* registry.addResource({
1624
2077
  resource: new Resource({
1625
2078
  ...options,
1626
2079
  annotations: options
1627
2080
  }),
1628
- handle: options.content.pipe(Effect.provideContext(services), Effect.map(content => resolveResourceContent(options.uri, content)), Effect.catchCause(cause => {
1629
- const prettyError = Cause.prettyErrors(cause)[0];
1630
- return Effect.fail(new InternalError({
1631
- message: prettyError.message
1632
- }));
1633
- })),
2081
+ services,
2082
+ handle: options.content.pipe(Effect.map(content => resolveResourceContent(options.uri, content)), Effect.catchCause(handlerFailureToInternalError)),
1634
2083
  annotations: options.annotations ?? Context.empty()
1635
2084
  });
1636
2085
  });
@@ -1642,7 +2091,7 @@ export const registerResource = function () {
1642
2091
  uriPath
1643
2092
  } = compileUriTemplate(...arguments);
1644
2093
  return Effect.fnUntraced(function* (options) {
1645
- const services = omitRequestServices(yield* Effect.context());
2094
+ const services = yield* Effect.context();
1646
2095
  const registry = yield* McpServer;
1647
2096
  const decode = Schema.decodeUnknownEffect(schema);
1648
2097
  const template = new ResourceTemplate({
@@ -1652,41 +2101,32 @@ export const registerResource = function () {
1652
2101
  });
1653
2102
  const completions = Object.create(null);
1654
2103
  for (const [param, handle] of Object.entries(options.completion ?? {})) {
1655
- const encodeArray = Schema.encodeUnknownEffect(Schema.Array(params[param]));
1656
- const handler = (input, context) => handle(input, context).pipe(Effect.flatMap(encodeArray), Effect.map(values => ({
1657
- completion: {
1658
- values: values,
1659
- total: values.length,
1660
- hasMore: false
1661
- }
1662
- })), Effect.catchCause(cause => {
1663
- const prettyError = Cause.prettyErrors(cause)[0];
1664
- return Effect.fail(new InternalError({
1665
- message: prettyError.message
1666
- }));
1667
- }), Effect.provideContext(services));
1668
- completions[param] = handler;
2104
+ completions[param] = completionHandler(handle, Schema.encodeUnknownEffect(Schema.Array(params[param])));
1669
2105
  }
1670
2106
  yield* registry.addResourceTemplate({
1671
2107
  template,
1672
2108
  routerPath,
1673
2109
  completions,
2110
+ services,
1674
2111
  annotations: options.annotations ?? Context.empty(),
1675
2112
  handle: (uri, params) => decode(params).pipe(Effect.mapError(error => new InvalidParams({
1676
2113
  message: error.message
1677
- })), Effect.flatMap(params => options.content(uri, ...params).pipe(Effect.map(content => resolveResourceContent(uri, content)), Effect.catchCause(cause => {
1678
- const prettyError = Cause.prettyErrors(cause)[0];
1679
- return Effect.fail(new InternalError({
1680
- message: prettyError.message
1681
- }));
1682
- }))), Effect.provideContext(services))
2114
+ })), Effect.flatMap(params => options.content(uri, ...params).pipe(Effect.map(content => resolveResourceContent(uri, content)), Effect.catchCause(handlerFailureToInternalError))))
1683
2115
  });
1684
2116
  });
1685
2117
  };
1686
2118
  /**
1687
2119
  * Creates a layer that registers an MCP resource or resource template.
1688
2120
  *
2121
+ * **Details**
2122
+ *
2123
+ * Services read by the content and completion handlers are request-level, so
2124
+ * providing them with `Layer.provide` doesn't satisfy them. Read
2125
+ * construction-time services in an enclosing `Layer.unwrap` and close over
2126
+ * them, and provide per-request services with MCP middleware.
2127
+ *
1689
2128
  * @see {@link registerResource} for the Effect-level resource registration API
2129
+ * @see {@link middleware} for providing request-level dependencies
1690
2130
  *
1691
2131
  * @stability unstable
1692
2132
  * @category layers
@@ -1694,10 +2134,10 @@ export const registerResource = function () {
1694
2134
  */
1695
2135
  export const resource = function () {
1696
2136
  if (arguments.length === 1) {
1697
- return Layer.effectDiscard(registerResource(arguments[0])).pipe(Layer.provide(McpServer.layer));
2137
+ return Layer.effectDiscard(registerResource(arguments[0]));
1698
2138
  }
1699
2139
  const register = registerResource(...arguments);
1700
- return options => Layer.effectDiscard(register(options)).pipe(Layer.provide(McpServer.layer));
2140
+ return options => Layer.effectDiscard(register(options));
1701
2141
  };
1702
2142
  /**
1703
2143
  * Registers an MCP prompt from an Effect program.
@@ -1733,36 +2173,19 @@ export const registerPrompt = options => {
1733
2173
  const completion = options.completion ?? {};
1734
2174
  return Effect.gen(function* () {
1735
2175
  const registry = yield* McpServer;
1736
- const services = omitRequestServices(yield* Effect.context());
2176
+ const services = yield* Effect.context();
1737
2177
  const completions = Object.create(null);
1738
2178
  for (const [param, handle] of Object.entries(completion)) {
1739
- const encodeArray = Schema.encodeEffect(Schema.Array(props[param]));
1740
- const handler = (input, context) => handle(input, context).pipe(Effect.flatMap(encodeArray), Effect.map(values => ({
1741
- completion: {
1742
- values: values,
1743
- total: values.length,
1744
- hasMore: false
1745
- }
1746
- })), Effect.catchCause(cause => {
1747
- const prettyError = Cause.prettyErrors(cause)[0];
1748
- return Effect.fail(new InternalError({
1749
- message: prettyError.message
1750
- }));
1751
- }), Effect.provide(services));
1752
- completions[param] = handler;
2179
+ completions[param] = completionHandler(handle, Schema.encodeUnknownEffect(Schema.Array(props[param])));
1753
2180
  }
1754
2181
  yield* registry.addPrompt({
1755
2182
  prompt,
1756
2183
  completions,
2184
+ services,
1757
2185
  annotations: options.annotations ?? Context.empty(),
1758
2186
  handle: params => decode(params).pipe(Effect.mapError(error => new InvalidParams({
1759
2187
  message: error.message
1760
- })), Effect.flatMap(params => options.content(params).pipe(Effect.catchCause(cause => {
1761
- const prettyError = Cause.prettyErrors(cause)[0];
1762
- return Effect.fail(new InternalError({
1763
- message: prettyError.message
1764
- }));
1765
- }))), Effect.map(messages => {
2188
+ })), Effect.flatMap(params => options.content(params).pipe(Effect.catchCause(handlerFailureToInternalError))), Effect.map(messages => {
1766
2189
  messages = typeof messages === "string" ? [{
1767
2190
  role: "user",
1768
2191
  content: TextContent.make({
@@ -1773,20 +2196,28 @@ export const registerPrompt = options => {
1773
2196
  messages,
1774
2197
  description: prompt.description
1775
2198
  });
1776
- }), Effect.provideContext(services))
2199
+ }))
1777
2200
  });
1778
2201
  });
1779
2202
  };
1780
2203
  /**
1781
2204
  * Creates a layer that registers an MCP prompt.
1782
2205
  *
2206
+ * **Details**
2207
+ *
2208
+ * Services read by the content and completion handlers are request-level, so
2209
+ * providing them with `Layer.provide` doesn't satisfy them. Read
2210
+ * construction-time services in an enclosing `Layer.unwrap` and close over
2211
+ * them, and provide per-request services with MCP middleware.
2212
+ *
1783
2213
  * @see {@link registerPrompt} for the Effect-level prompt registration API
2214
+ * @see {@link middleware} for providing request-level dependencies
1784
2215
  *
1785
2216
  * @stability unstable
1786
2217
  * @category layers
1787
2218
  * @since 4.0.0
1788
2219
  */
1789
- export const prompt = options => Layer.effectDiscard(registerPrompt(options)).pipe(Layer.provide(McpServer.layer));
2220
+ export const prompt = options => Layer.effectDiscard(registerPrompt(options));
1790
2221
  /**
1791
2222
  * Collects structured input from the current MCP client and decodes the
1792
2223
  * accepted response with `schema`.
@@ -1834,6 +2265,21 @@ export const elicit = /*#__PURE__*/Effect.fnUntraced(function* (options) {
1834
2265
  * @since 4.0.0
1835
2266
  */
1836
2267
  export const clientCapabilities = /*#__PURE__*/McpRequestContext.useSync(_ => _.clientCapabilities);
2268
+ /**
2269
+ * Decodes an `Mcp-Name` header, including base64-wrapped values.
2270
+ * Returns `undefined` for malformed values.
2271
+ *
2272
+ * **Details**
2273
+ *
2274
+ * Use in `HttpRouter.middleware` to identify the tool, prompt or resource
2275
+ * targeted by a `2026-07-28` request. Earlier protocols carry the name only
2276
+ * in the JSON-RPC body.
2277
+ *
2278
+ * @stability unstable
2279
+ * @category decoding
2280
+ * @since 4.0.0
2281
+ */
2282
+ export const decodeNameHeader = value => McpProtocolInternal.decodeRoutingHeader(value);
1837
2283
  // -----------------------------------------------------------------------------
1838
2284
  // Internal
1839
2285
  // -----------------------------------------------------------------------------