effect-agent 0.1.0-beta.9 → 0.1.0-beta.91

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 (538) hide show
  1. package/dist/Agent-CN0EWRsR.d.mts +226 -0
  2. package/dist/Agent-RklVROrm.mjs +83 -0
  3. package/dist/Agent-RklVROrm.mjs.map +1 -0
  4. package/dist/AgentError-CggcAQ7V.d.mts +101 -0
  5. package/dist/AgentPolicy-CetmQrf3.d.mts +96 -0
  6. package/dist/AgentRuntime-CHipL2jG.mjs +4598 -0
  7. package/dist/AgentRuntime-CHipL2jG.mjs.map +1 -0
  8. package/dist/AgentRuntime-uxR_a4VM.d.mts +346 -0
  9. package/dist/AgentUpdates-DMJ-_xow.d.mts +53 -0
  10. package/dist/ContextCompactor-Dxu5zhOL.d.mts +161 -0
  11. package/dist/ContextWindow-DRQ5Mbm2.d.mts +58 -0
  12. package/dist/DurableAgentRuntime-D7gDKGjH.mjs +6368 -0
  13. package/dist/DurableAgentRuntime-D7gDKGjH.mjs.map +1 -0
  14. package/dist/DurableFailpoint-Oinuuedm.d.mts +41 -0
  15. package/dist/DurableStep-Cry_iol4.d.mts +103 -0
  16. package/dist/Ephemeral.d.mts +22 -0
  17. package/dist/Ephemeral.mjs +22 -0
  18. package/dist/Ephemeral.mjs.map +1 -0
  19. package/dist/EventSource-OqS_P9ug.d.mts +51 -0
  20. package/dist/Identifiers-CN2s30fF.d.mts +40 -0
  21. package/dist/MemoryNamespace-BbRW5p71.d.mts +36 -0
  22. package/dist/MemoryReference-B8Q3UJoJ.d.mts +79 -0
  23. package/dist/Messaging-CkcIdt4I.d.mts +490 -0
  24. package/dist/MessagingHost-CRk0kXzT.d.mts +246 -0
  25. package/dist/MessagingHost-CWi_PP3g.mjs +137 -0
  26. package/dist/MessagingHost-CWi_PP3g.mjs.map +1 -0
  27. package/dist/OperationAuthorizer-TzcQtpX5.d.mts +61 -0
  28. package/dist/Output-D6SkedVx.d.mts +25 -0
  29. package/dist/PageCapture-Df8Xwskw.d.mts +583 -0
  30. package/dist/PageScreenshot-BpgZKAxl.d.mts +48 -0
  31. package/dist/PreparedInputAdmission-C4HbjHgl.d.mts +38 -0
  32. package/dist/Receipt-BAHyigAF.d.mts +33 -0
  33. package/dist/Records-BAGkekt8.d.mts +3570 -0
  34. package/dist/RunEvent-DIrzkjLr.d.mts +460 -0
  35. package/dist/RunEventSink-D5aVhISG.d.mts +108 -0
  36. package/dist/RunJournal-Cgg1kNvc.mjs +825 -0
  37. package/dist/RunJournal-Cgg1kNvc.mjs.map +1 -0
  38. package/dist/RunOptions-g1aigcKI.d.mts +915 -0
  39. package/dist/RunPolicyUsage-ClZxyR46.d.mts +21 -0
  40. package/dist/Sandbox-CEsDWBLq.d.mts +173 -0
  41. package/dist/Schedule-H3SEYX9g.d.mts +842 -0
  42. package/dist/Scheduling-C9aIP8zT.mjs +691 -0
  43. package/dist/Scheduling-C9aIP8zT.mjs.map +1 -0
  44. package/dist/Subagent-DyfzHNdv.d.mts +826 -0
  45. package/dist/Subagent-U5qXOFE8.mjs +1469 -0
  46. package/dist/Subagent-U5qXOFE8.mjs.map +1 -0
  47. package/dist/SubagentContract-DdT7Cqe6.d.mts +116 -0
  48. package/dist/SubagentHost-CJUBQlcc.d.mts +140 -0
  49. package/dist/Subscription-BEP8oQO5.d.mts +921 -0
  50. package/dist/SubscriptionInput-vAAOBrK7.d.mts +41 -0
  51. package/dist/Thread-DOBQ0QUY.d.mts +96 -0
  52. package/dist/ThreadHistory-tS1KwxHR.d.mts +60 -0
  53. package/dist/ToolBroker-DWs4tZra.d.mts +133 -0
  54. package/dist/ToolExposure-9uF_Yo0T.mjs +10 -0
  55. package/dist/ToolExposure-9uF_Yo0T.mjs.map +1 -0
  56. package/dist/ToolExposure-C93U1sPu.mjs +30 -0
  57. package/dist/ToolExposure-C93U1sPu.mjs.map +1 -0
  58. package/dist/ToolExposure-UCN12eCd.d.mts +39 -0
  59. package/dist/ToolExposure-r2eOWk4F.d.mts +46 -0
  60. package/dist/ToolExposure.d.mts +8 -0
  61. package/dist/ToolExposure.mjs +21 -0
  62. package/dist/ToolExposure.mjs.map +1 -0
  63. package/dist/ToolReconciler-DQVaJfpE.d.mts +76 -0
  64. package/dist/ToolResult-DmmgoChv.d.mts +61 -0
  65. package/dist/Usage-Dx0aknfk.d.mts +121 -0
  66. package/dist/WakeScheduler-EjUF-GhC.d.mts +56 -0
  67. package/dist/Worker-CaPYykpe.d.mts +228 -0
  68. package/dist/agent-registration-CWDMOAZA.mjs +172 -0
  69. package/dist/agent-registration-CWDMOAZA.mjs.map +1 -0
  70. package/dist/capabilities/Approval.d.mts +114 -0
  71. package/dist/capabilities/Approval.mjs +226 -0
  72. package/dist/capabilities/Approval.mjs.map +1 -0
  73. package/dist/capabilities/Budget.d.mts +112 -0
  74. package/dist/capabilities/Budget.mjs +346 -0
  75. package/dist/capabilities/Budget.mjs.map +1 -0
  76. package/dist/capabilities/CodeMode.d.mts +157 -0
  77. package/dist/capabilities/CodeMode.mjs +522 -0
  78. package/dist/capabilities/CodeMode.mjs.map +1 -0
  79. package/dist/capabilities/Commands.d.mts +55 -0
  80. package/dist/capabilities/Commands.mjs +57 -0
  81. package/dist/capabilities/Commands.mjs.map +1 -0
  82. package/dist/capabilities/ContextTools.d.mts +321 -0
  83. package/dist/capabilities/ContextTools.mjs +126 -0
  84. package/dist/capabilities/ContextTools.mjs.map +1 -0
  85. package/dist/capabilities/Mcp.d.mts +108 -0
  86. package/dist/capabilities/Mcp.mjs +260 -0
  87. package/dist/capabilities/Mcp.mjs.map +1 -0
  88. package/dist/capabilities/McpClient.d.mts +115 -0
  89. package/dist/capabilities/McpClient.mjs +506 -0
  90. package/dist/capabilities/McpClient.mjs.map +1 -0
  91. package/dist/capabilities/MemoryNotes.d.mts +424 -0
  92. package/dist/capabilities/MemoryNotes.mjs +128 -0
  93. package/dist/capabilities/MemoryNotes.mjs.map +1 -0
  94. package/dist/capabilities/Messaging.d.mts +3 -0
  95. package/dist/capabilities/Messaging.mjs +151 -0
  96. package/dist/capabilities/Messaging.mjs.map +1 -0
  97. package/dist/capabilities/ModelContext.d.mts +89 -0
  98. package/dist/capabilities/ModelContext.mjs +168 -0
  99. package/dist/capabilities/ModelContext.mjs.map +1 -0
  100. package/dist/capabilities/Redaction.d.mts +37 -0
  101. package/dist/capabilities/Redaction.mjs +104 -0
  102. package/dist/capabilities/Redaction.mjs.map +1 -0
  103. package/dist/capabilities/Remembering.d.mts +434 -0
  104. package/dist/capabilities/Remembering.mjs +290 -0
  105. package/dist/capabilities/Remembering.mjs.map +1 -0
  106. package/dist/capabilities/RunHooks.d.mts +82 -0
  107. package/dist/capabilities/RunHooks.mjs +144 -0
  108. package/dist/capabilities/RunHooks.mjs.map +1 -0
  109. package/dist/capabilities/SemanticMemory.d.mts +431 -0
  110. package/dist/capabilities/SemanticMemory.mjs +315 -0
  111. package/dist/capabilities/SemanticMemory.mjs.map +1 -0
  112. package/dist/capabilities/Subagent.d.mts +4 -0
  113. package/dist/capabilities/Subagent.mjs +5 -0
  114. package/dist/capabilities/SubagentReservations.d.mts +186 -0
  115. package/dist/capabilities/SubagentReservations.mjs +479 -0
  116. package/dist/capabilities/SubagentReservations.mjs.map +1 -0
  117. package/dist/capabilities/ToolDiscovery.d.mts +109 -0
  118. package/dist/capabilities/ToolDiscovery.mjs +211 -0
  119. package/dist/capabilities/ToolDiscovery.mjs.map +1 -0
  120. package/dist/capabilities/WebCapture.d.mts +163 -0
  121. package/dist/capabilities/WebCapture.mjs +335 -0
  122. package/dist/capabilities/WebCapture.mjs.map +1 -0
  123. package/dist/capabilities/WebSearch.d.mts +71 -0
  124. package/dist/capabilities/WebSearch.mjs +112 -0
  125. package/dist/capabilities/WebSearch.mjs.map +1 -0
  126. package/dist/compaction-C2OTceKw.mjs +505 -0
  127. package/dist/compaction-C2OTceKw.mjs.map +1 -0
  128. package/dist/core/Agent.d.mts +2 -0
  129. package/dist/core/Agent.mjs +2 -0
  130. package/dist/core/AgentError.d.mts +2 -0
  131. package/dist/core/AgentError.mjs +117 -0
  132. package/dist/core/AgentError.mjs.map +1 -0
  133. package/dist/core/AgentPolicy.d.mts +2 -0
  134. package/dist/core/AgentPolicy.mjs +94 -0
  135. package/dist/core/AgentPolicy.mjs.map +1 -0
  136. package/dist/core/AgentUpdates.d.mts +2 -0
  137. package/dist/core/AgentUpdates.mjs +63 -0
  138. package/dist/core/AgentUpdates.mjs.map +1 -0
  139. package/dist/core/IdGenerator.d.mts +26 -0
  140. package/dist/core/IdGenerator.mjs +27 -0
  141. package/dist/core/IdGenerator.mjs.map +1 -0
  142. package/dist/core/Identifiers.d.mts +2 -0
  143. package/dist/core/Identifiers.mjs +43 -0
  144. package/dist/core/Identifiers.mjs.map +1 -0
  145. package/dist/core/Memory.d.mts +57 -0
  146. package/dist/core/Memory.mjs +203 -0
  147. package/dist/core/Memory.mjs.map +1 -0
  148. package/dist/core/MemoryNamespace.d.mts +2 -0
  149. package/dist/core/MemoryNamespace.mjs +116 -0
  150. package/dist/core/MemoryNamespace.mjs.map +1 -0
  151. package/dist/core/MemoryReference.d.mts +2 -0
  152. package/dist/core/MemoryReference.mjs +109 -0
  153. package/dist/core/MemoryReference.mjs.map +1 -0
  154. package/dist/core/MemoryRevalidation.d.mts +65 -0
  155. package/dist/core/MemoryRevalidation.mjs +126 -0
  156. package/dist/core/MemoryRevalidation.mjs.map +1 -0
  157. package/dist/core/MemoryStore.d.mts +186 -0
  158. package/dist/core/MemoryStore.mjs +243 -0
  159. package/dist/core/MemoryStore.mjs.map +1 -0
  160. package/dist/core/Receipt.d.mts +2 -0
  161. package/dist/core/Receipt.mjs +36 -0
  162. package/dist/core/Receipt.mjs.map +1 -0
  163. package/dist/core/RememberingStore.d.mts +1562 -0
  164. package/dist/core/RememberingStore.mjs +190 -0
  165. package/dist/core/RememberingStore.mjs.map +1 -0
  166. package/dist/core/RunEvent.d.mts +2 -0
  167. package/dist/core/RunEvent.mjs +337 -0
  168. package/dist/core/RunEvent.mjs.map +1 -0
  169. package/dist/core/RunPolicyUsage.d.mts +2 -0
  170. package/dist/core/RunPolicyUsage.mjs +21 -0
  171. package/dist/core/RunPolicyUsage.mjs.map +1 -0
  172. package/dist/core/SemanticMemoryIndex.d.mts +826 -0
  173. package/dist/core/SemanticMemoryIndex.mjs +185 -0
  174. package/dist/core/SemanticMemoryIndex.mjs.map +1 -0
  175. package/dist/core/SemanticMemoryRevalidation.d.mts +45 -0
  176. package/dist/core/SemanticMemoryRevalidation.mjs +191 -0
  177. package/dist/core/SemanticMemoryRevalidation.mjs.map +1 -0
  178. package/dist/core/SubagentContract.d.mts +2 -0
  179. package/dist/core/SubagentContract.mjs +148 -0
  180. package/dist/core/SubagentContract.mjs.map +1 -0
  181. package/dist/core/Thread.d.mts +2 -0
  182. package/dist/core/Thread.mjs +250 -0
  183. package/dist/core/Thread.mjs.map +1 -0
  184. package/dist/core/ToolResult.d.mts +2 -0
  185. package/dist/core/ToolResult.mjs +140 -0
  186. package/dist/core/ToolResult.mjs.map +1 -0
  187. package/dist/core/Usage.d.mts +2 -0
  188. package/dist/core/Usage.mjs +319 -0
  189. package/dist/core/Usage.mjs.map +1 -0
  190. package/dist/core/Worker.d.mts +3 -0
  191. package/dist/core/Worker.mjs +147 -0
  192. package/dist/core/Worker.mjs.map +1 -0
  193. package/dist/durable/ActivityStore.d.mts +116 -0
  194. package/dist/durable/ActivityStore.mjs +131 -0
  195. package/dist/durable/ActivityStore.mjs.map +1 -0
  196. package/dist/durable/Admin.d.mts +2 -0
  197. package/dist/durable/Admin.mjs +328 -0
  198. package/dist/durable/Admin.mjs.map +1 -0
  199. package/dist/durable/AgentRegistration.d.mts +2 -0
  200. package/dist/durable/AgentRegistration.mjs +14 -0
  201. package/dist/durable/AgentRegistration.mjs.map +1 -0
  202. package/dist/durable/Certification.d.mts +111 -0
  203. package/dist/durable/Certification.mjs +159 -0
  204. package/dist/durable/Certification.mjs.map +1 -0
  205. package/dist/durable/CommittedActivity.d.mts +62 -0
  206. package/dist/durable/CommittedActivity.mjs +159 -0
  207. package/dist/durable/CommittedActivity.mjs.map +1 -0
  208. package/dist/durable/Digest.d.mts +2 -0
  209. package/dist/durable/Digest.mjs +50 -0
  210. package/dist/durable/Digest.mjs.map +1 -0
  211. package/dist/durable/DurableAgentRuntime.d.mts +3 -0
  212. package/dist/durable/DurableAgentRuntime.mjs +3 -0
  213. package/dist/durable/DurableFailpoint.d.mts +2 -0
  214. package/dist/durable/DurableFailpoint.mjs +94 -0
  215. package/dist/durable/DurableFailpoint.mjs.map +1 -0
  216. package/dist/durable/DurableFailpointTestControl.d.mts +15 -0
  217. package/dist/durable/DurableFailpointTestControl.mjs +19 -0
  218. package/dist/durable/DurableFailpointTestControl.mjs.map +1 -0
  219. package/dist/durable/EventSource.d.mts +2 -0
  220. package/dist/durable/EventSource.mjs +65 -0
  221. package/dist/durable/EventSource.mjs.map +1 -0
  222. package/dist/durable/GitHubWorkflowSource.d.mts +144 -0
  223. package/dist/durable/GitHubWorkflowSource.mjs +209 -0
  224. package/dist/durable/GitHubWorkflowSource.mjs.map +1 -0
  225. package/dist/durable/MessageDelivery.d.mts +492 -0
  226. package/dist/durable/MessageDelivery.mjs +495 -0
  227. package/dist/durable/MessageDelivery.mjs.map +1 -0
  228. package/dist/durable/MessageDeliveryStoreConformance.d.mts +358 -0
  229. package/dist/durable/MessageDeliveryStoreConformance.mjs +243 -0
  230. package/dist/durable/MessageDeliveryStoreConformance.mjs.map +1 -0
  231. package/dist/durable/OperationAuthorizer.d.mts +2 -0
  232. package/dist/durable/OperationAuthorizer.mjs +70 -0
  233. package/dist/durable/OperationAuthorizer.mjs.map +1 -0
  234. package/dist/durable/PersistentHistory.d.mts +16 -0
  235. package/dist/durable/PersistentHistory.mjs +125 -0
  236. package/dist/durable/PersistentHistory.mjs.map +1 -0
  237. package/dist/durable/PreparedInputAdmission.d.mts +2 -0
  238. package/dist/durable/PreparedInputAdmission.mjs +34 -0
  239. package/dist/durable/PreparedInputAdmission.mjs.map +1 -0
  240. package/dist/durable/Records.d.mts +2 -0
  241. package/dist/durable/Records.mjs +795 -0
  242. package/dist/durable/Records.mjs.map +1 -0
  243. package/dist/durable/Recovery.d.mts +2 -0
  244. package/dist/durable/Recovery.mjs +739 -0
  245. package/dist/durable/Recovery.mjs.map +1 -0
  246. package/dist/durable/RunJournal.d.mts +2 -0
  247. package/dist/durable/RunJournal.mjs +2 -0
  248. package/dist/durable/Schedule.d.mts +2 -0
  249. package/dist/durable/Schedule.mjs +382 -0
  250. package/dist/durable/Schedule.mjs.map +1 -0
  251. package/dist/durable/ScheduleStoreConformance.d.mts +18 -0
  252. package/dist/durable/ScheduleStoreConformance.mjs +420 -0
  253. package/dist/durable/ScheduleStoreConformance.mjs.map +1 -0
  254. package/dist/durable/ScheduleTransition.d.mts +24 -0
  255. package/dist/durable/ScheduleTransition.mjs +180 -0
  256. package/dist/durable/ScheduleTransition.mjs.map +1 -0
  257. package/dist/durable/Scheduling.d.mts +54 -0
  258. package/dist/durable/Scheduling.mjs +2 -0
  259. package/dist/durable/SqlMemoryStore.d.mts +30 -0
  260. package/dist/durable/SqlMemoryStore.mjs +436 -0
  261. package/dist/durable/SqlMemoryStore.mjs.map +1 -0
  262. package/dist/durable/SqlMessageDeliveryStore.d.mts +40 -0
  263. package/dist/durable/SqlMessageDeliveryStore.mjs +167 -0
  264. package/dist/durable/SqlMessageDeliveryStore.mjs.map +1 -0
  265. package/dist/durable/SqlStorageV2Upgrade.d.mts +22 -0
  266. package/dist/durable/SqlStorageV2Upgrade.mjs +459 -0
  267. package/dist/durable/SqlStorageV2Upgrade.mjs.map +1 -0
  268. package/dist/durable/SqlSubscriptionStore.d.mts +63 -0
  269. package/dist/durable/SqlSubscriptionStore.mjs +751 -0
  270. package/dist/durable/SqlSubscriptionStore.mjs.map +1 -0
  271. package/dist/durable/SubmissionLedger.d.mts +3 -0
  272. package/dist/durable/SubmissionLedger.mjs +914 -0
  273. package/dist/durable/SubmissionLedger.mjs.map +1 -0
  274. package/dist/durable/SubmissionLedgerConformance.d.mts +30 -0
  275. package/dist/durable/SubmissionLedgerConformance.mjs +1986 -0
  276. package/dist/durable/SubmissionLedgerConformance.mjs.map +1 -0
  277. package/dist/durable/SubmissionStatus.d.mts +2 -0
  278. package/dist/durable/SubmissionStatus.mjs +18 -0
  279. package/dist/durable/SubmissionStatus.mjs.map +1 -0
  280. package/dist/durable/Subscription.d.mts +2 -0
  281. package/dist/durable/Subscription.mjs +360 -0
  282. package/dist/durable/Subscription.mjs.map +1 -0
  283. package/dist/durable/SubscriptionInput.d.mts +2 -0
  284. package/dist/durable/SubscriptionInput.mjs +52 -0
  285. package/dist/durable/SubscriptionInput.mjs.map +1 -0
  286. package/dist/durable/SubscriptionStoreConformance.d.mts +17 -0
  287. package/dist/durable/SubscriptionStoreConformance.mjs +625 -0
  288. package/dist/durable/SubscriptionStoreConformance.mjs.map +1 -0
  289. package/dist/durable/SubscriptionTools.d.mts +273 -0
  290. package/dist/durable/SubscriptionTools.mjs +190 -0
  291. package/dist/durable/SubscriptionTools.mjs.map +1 -0
  292. package/dist/durable/SubscriptionTransition.d.mts +21 -0
  293. package/dist/durable/SubscriptionTransition.mjs +148 -0
  294. package/dist/durable/SubscriptionTransition.mjs.map +1 -0
  295. package/dist/durable/Subscriptions.d.mts +73 -0
  296. package/dist/durable/Subscriptions.mjs +627 -0
  297. package/dist/durable/Subscriptions.mjs.map +1 -0
  298. package/dist/durable/ThreadContextHistory.d.mts +32 -0
  299. package/dist/durable/ThreadContextHistory.mjs +152 -0
  300. package/dist/durable/ThreadContextHistory.mjs.map +1 -0
  301. package/dist/durable/ThreadContextHistoryProjection.d.mts +60 -0
  302. package/dist/durable/ThreadContextHistoryProjection.mjs +149 -0
  303. package/dist/durable/ThreadContextHistoryProjection.mjs.map +1 -0
  304. package/dist/durable/ThreadInvariants.d.mts +74 -0
  305. package/dist/durable/ThreadInvariants.mjs +200 -0
  306. package/dist/durable/ThreadInvariants.mjs.map +1 -0
  307. package/dist/durable/ThreadProjection.d.mts +78 -0
  308. package/dist/durable/ThreadProjection.mjs +158 -0
  309. package/dist/durable/ThreadProjection.mjs.map +1 -0
  310. package/dist/durable/ThreadProjectionMaintenance.d.mts +49 -0
  311. package/dist/durable/ThreadProjectionMaintenance.mjs +33 -0
  312. package/dist/durable/ThreadProjectionMaintenance.mjs.map +1 -0
  313. package/dist/durable/ThreadStore.d.mts +2 -0
  314. package/dist/durable/ThreadStore.mjs +147 -0
  315. package/dist/durable/ThreadStore.mjs.map +1 -0
  316. package/dist/durable/ThreadStoreConformance.d.mts +29 -0
  317. package/dist/durable/ThreadStoreConformance.mjs +248 -0
  318. package/dist/durable/ThreadStoreConformance.mjs.map +1 -0
  319. package/dist/durable/ToolReconciler.d.mts +2 -0
  320. package/dist/durable/ToolReconciler.mjs +81 -0
  321. package/dist/durable/ToolReconciler.mjs.map +1 -0
  322. package/dist/durable/WakeScheduler.d.mts +2 -0
  323. package/dist/durable/WakeScheduler.mjs +85 -0
  324. package/dist/durable/WakeScheduler.mjs.map +1 -0
  325. package/dist/durable/WorkerHost.d.mts +129 -0
  326. package/dist/durable/WorkerHost.mjs +77 -0
  327. package/dist/durable/WorkerHost.mjs.map +1 -0
  328. package/dist/engine/AgentRuntime.d.mts +2 -0
  329. package/dist/engine/AgentRuntime.mjs +2 -0
  330. package/dist/engine/Compaction.d.mts +7 -0
  331. package/dist/engine/Compaction.mjs +16 -0
  332. package/dist/engine/Compaction.mjs.map +1 -0
  333. package/dist/engine/ContextCompactor.d.mts +2 -0
  334. package/dist/engine/ContextCompactor.mjs +119 -0
  335. package/dist/engine/ContextCompactor.mjs.map +1 -0
  336. package/dist/engine/ContextHistory.d.mts +65 -0
  337. package/dist/engine/ContextHistory.mjs +76 -0
  338. package/dist/engine/ContextHistory.mjs.map +1 -0
  339. package/dist/engine/ContextWindow.d.mts +2 -0
  340. package/dist/engine/ContextWindow.mjs +59 -0
  341. package/dist/engine/ContextWindow.mjs.map +1 -0
  342. package/dist/engine/DurableStep.d.mts +2 -0
  343. package/dist/engine/DurableStep.mjs +62 -0
  344. package/dist/engine/DurableStep.mjs.map +1 -0
  345. package/dist/engine/MessagingHost.d.mts +2 -0
  346. package/dist/engine/MessagingHost.mjs +2 -0
  347. package/dist/engine/Output.d.mts +2 -0
  348. package/dist/engine/Output.mjs +8 -0
  349. package/dist/engine/Output.mjs.map +1 -0
  350. package/dist/engine/RunEventSink.d.mts +2 -0
  351. package/dist/engine/RunEventSink.mjs +22 -0
  352. package/dist/engine/RunEventSink.mjs.map +1 -0
  353. package/dist/engine/RunOptions.d.mts +2 -0
  354. package/dist/engine/RunOptions.mjs +122 -0
  355. package/dist/engine/RunOptions.mjs.map +1 -0
  356. package/dist/engine/SubagentHost.d.mts +2 -0
  357. package/dist/engine/SubagentHost.mjs +72 -0
  358. package/dist/engine/SubagentHost.mjs.map +1 -0
  359. package/dist/engine/ThreadHistory.d.mts +2 -0
  360. package/dist/engine/ThreadHistory.mjs +67 -0
  361. package/dist/engine/ThreadHistory.mjs.map +1 -0
  362. package/dist/engine/ToolBroker.d.mts +2 -0
  363. package/dist/engine/ToolBroker.mjs +42 -0
  364. package/dist/engine/ToolBroker.mjs.map +1 -0
  365. package/dist/foreign-diagnostic-DBQ1XHKh.mjs +37 -0
  366. package/dist/foreign-diagnostic-DBQ1XHKh.mjs.map +1 -0
  367. package/dist/index.d.mts +89 -6
  368. package/dist/index.mjs +98 -6
  369. package/dist/output-contract-BC7tjlGw.mjs +84 -0
  370. package/dist/output-contract-BC7tjlGw.mjs.map +1 -0
  371. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  372. package/dist/sandbox/CodeExecutor.d.mts +194 -0
  373. package/dist/sandbox/CodeExecutor.mjs +278 -0
  374. package/dist/sandbox/CodeExecutor.mjs.map +1 -0
  375. package/dist/sandbox/InteractiveBrowser.d.mts +142 -0
  376. package/dist/sandbox/InteractiveBrowser.mjs +165 -0
  377. package/dist/sandbox/InteractiveBrowser.mjs.map +1 -0
  378. package/dist/sandbox/PageCapture.d.mts +2 -0
  379. package/dist/sandbox/PageCapture.mjs +450 -0
  380. package/dist/sandbox/PageCapture.mjs.map +1 -0
  381. package/dist/sandbox/PageCrawl.d.mts +88 -0
  382. package/dist/sandbox/PageCrawl.mjs +124 -0
  383. package/dist/sandbox/PageCrawl.mjs.map +1 -0
  384. package/dist/sandbox/PageScreenshot.d.mts +2 -0
  385. package/dist/sandbox/PageScreenshot.mjs +53 -0
  386. package/dist/sandbox/PageScreenshot.mjs.map +1 -0
  387. package/dist/sandbox/ProtectedBrowser.d.mts +273 -0
  388. package/dist/sandbox/ProtectedBrowser.mjs +287 -0
  389. package/dist/sandbox/ProtectedBrowser.mjs.map +1 -0
  390. package/dist/sandbox/Sandbox.d.mts +2 -0
  391. package/dist/sandbox/Sandbox.mjs +208 -0
  392. package/dist/sandbox/Sandbox.mjs.map +1 -0
  393. package/dist/utf8-BYfhEkcj.mjs +11 -0
  394. package/dist/utf8-BYfhEkcj.mjs.map +1 -0
  395. package/dist/utf8-DchGZRBd.mjs +23 -0
  396. package/dist/utf8-DchGZRBd.mjs.map +1 -0
  397. package/package.json +1 -40
  398. package/src/Ephemeral.ts +17 -0
  399. package/src/ToolExposure.ts +2 -0
  400. package/src/capabilities/Approval.ts +352 -0
  401. package/src/capabilities/Budget.ts +536 -0
  402. package/src/capabilities/CodeMode.ts +1090 -0
  403. package/src/capabilities/Commands.ts +86 -0
  404. package/src/capabilities/ContextTools.ts +184 -0
  405. package/src/capabilities/Mcp.ts +427 -0
  406. package/src/capabilities/McpClient.ts +967 -0
  407. package/src/capabilities/MemoryNotes.ts +174 -0
  408. package/src/capabilities/Messaging.ts +261 -0
  409. package/src/capabilities/ModelContext.ts +354 -0
  410. package/src/capabilities/Redaction.ts +157 -0
  411. package/src/capabilities/Remembering.ts +550 -0
  412. package/src/capabilities/RunHooks.ts +280 -0
  413. package/src/capabilities/SemanticMemory.ts +447 -0
  414. package/src/capabilities/Subagent.ts +2277 -0
  415. package/src/capabilities/SubagentReservations.ts +850 -0
  416. package/src/capabilities/ToolDiscovery.ts +339 -0
  417. package/src/capabilities/WebCapture.ts +722 -0
  418. package/src/capabilities/WebSearch.ts +184 -0
  419. package/src/capabilities/internal/subagent-background.ts +1106 -0
  420. package/src/capabilities/internal/subagent-contract.ts +142 -0
  421. package/src/capabilities/internal/subagent-policy.ts +235 -0
  422. package/src/capabilities/internal/subagent-reporting.ts +261 -0
  423. package/src/capabilities/internal/utf8.ts +10 -0
  424. package/src/core/Agent.ts +575 -0
  425. package/src/core/AgentError.ts +152 -0
  426. package/src/core/AgentPolicy.ts +153 -0
  427. package/src/core/AgentUpdates.ts +100 -0
  428. package/src/core/IdGenerator.ts +39 -0
  429. package/src/core/Identifiers.ts +48 -0
  430. package/src/core/Memory.ts +290 -0
  431. package/src/core/MemoryNamespace.ts +196 -0
  432. package/src/core/MemoryReference.ts +121 -0
  433. package/src/core/MemoryRevalidation.ts +185 -0
  434. package/src/core/MemoryStore.ts +368 -0
  435. package/src/core/Messaging.ts +90 -0
  436. package/src/core/Receipt.ts +42 -0
  437. package/src/core/RememberingStore.ts +300 -0
  438. package/src/core/RunEvent.ts +366 -0
  439. package/src/core/RunPolicyUsage.ts +17 -0
  440. package/src/core/SemanticMemoryIndex.ts +250 -0
  441. package/src/core/SemanticMemoryRevalidation.ts +254 -0
  442. package/src/core/SubagentContract.ts +196 -0
  443. package/src/core/Thread.ts +371 -0
  444. package/src/core/ToolExposure.ts +74 -0
  445. package/src/core/ToolResult.ts +170 -0
  446. package/src/core/Usage.ts +529 -0
  447. package/src/core/Worker.ts +173 -0
  448. package/src/core/internal/agent-updates.ts +32 -0
  449. package/src/core/internal/utf8.ts +23 -0
  450. package/src/durable/ActivityStore.ts +160 -0
  451. package/src/durable/Admin.ts +496 -0
  452. package/src/durable/AgentRegistration.ts +13 -0
  453. package/src/durable/Certification.ts +210 -0
  454. package/src/durable/CommittedActivity.ts +296 -0
  455. package/src/durable/Digest.ts +93 -0
  456. package/src/durable/DurableAgentRuntime.ts +10340 -0
  457. package/src/durable/DurableFailpoint.ts +103 -0
  458. package/src/durable/DurableFailpointTestControl.ts +39 -0
  459. package/src/durable/EventSource.ts +172 -0
  460. package/src/durable/GitHubWorkflowSource.ts +453 -0
  461. package/src/durable/MessageDelivery.ts +708 -0
  462. package/src/durable/MessageDeliveryStoreConformance.ts +363 -0
  463. package/src/durable/OperationAuthorizer.ts +85 -0
  464. package/src/durable/PersistentHistory.ts +260 -0
  465. package/src/durable/PreparedInputAdmission.ts +44 -0
  466. package/src/durable/Records.ts +1010 -0
  467. package/src/durable/Recovery.ts +1018 -0
  468. package/src/durable/RunJournal.ts +1479 -0
  469. package/src/durable/Schedule.ts +504 -0
  470. package/src/durable/ScheduleStoreConformance.ts +638 -0
  471. package/src/durable/ScheduleTransition.ts +265 -0
  472. package/src/durable/Scheduling.ts +1077 -0
  473. package/src/durable/SqlMemoryStore.ts +778 -0
  474. package/src/durable/SqlMessageDeliveryStore.ts +302 -0
  475. package/src/durable/SqlStorageV2Upgrade.ts +500 -0
  476. package/src/durable/SqlSubscriptionStore.ts +1440 -0
  477. package/src/durable/SubmissionLedger.ts +1201 -0
  478. package/src/durable/SubmissionLedgerConformance.ts +4579 -0
  479. package/src/durable/SubmissionStatus.ts +14 -0
  480. package/src/durable/Subscription.ts +544 -0
  481. package/src/durable/SubscriptionInput.ts +144 -0
  482. package/src/durable/SubscriptionStoreConformance.ts +945 -0
  483. package/src/durable/SubscriptionTools.ts +327 -0
  484. package/src/durable/SubscriptionTransition.ts +302 -0
  485. package/src/durable/Subscriptions.ts +1210 -0
  486. package/src/durable/ThreadContextHistory.ts +227 -0
  487. package/src/durable/ThreadContextHistoryProjection.ts +216 -0
  488. package/src/durable/ThreadInvariants.ts +442 -0
  489. package/src/durable/ThreadProjection.ts +269 -0
  490. package/src/durable/ThreadProjectionMaintenance.ts +67 -0
  491. package/src/durable/ThreadStore.ts +242 -0
  492. package/src/durable/ThreadStoreConformance.ts +710 -0
  493. package/src/durable/ToolReconciler.ts +105 -0
  494. package/src/durable/WakeScheduler.ts +134 -0
  495. package/src/durable/WorkerHost.ts +171 -0
  496. package/src/durable/internal/agent-registration.ts +525 -0
  497. package/src/durable/internal/agent-updates.ts +302 -0
  498. package/src/durable/internal/foreign-diagnostic.ts +47 -0
  499. package/src/durable/internal/journal-checkpoint.ts +104 -0
  500. package/src/durable/internal/journal-metadata.ts +107 -0
  501. package/src/durable/internal/messaging-host.ts +608 -0
  502. package/src/durable/internal/schedule-time.ts +303 -0
  503. package/src/durable/internal/storage-v2-layout.ts +163 -0
  504. package/src/durable/internal/storage-v2.ts +73 -0
  505. package/src/durable/internal/worker-host.ts +2467 -0
  506. package/src/durable/internal/worker-runtime.ts +9 -0
  507. package/src/engine/AgentRuntime.ts +37 -0
  508. package/src/engine/Compaction.ts +11 -0
  509. package/src/engine/ContextCompactor.ts +277 -0
  510. package/src/engine/ContextHistory.ts +73 -0
  511. package/src/engine/ContextWindow.ts +72 -0
  512. package/src/engine/DurableStep.ts +132 -0
  513. package/src/engine/MessagingHost.ts +110 -0
  514. package/src/engine/Output.ts +2 -0
  515. package/src/engine/RunEventSink.ts +132 -0
  516. package/src/engine/RunOptions.ts +1077 -0
  517. package/src/engine/SubagentHost.ts +181 -0
  518. package/src/engine/ThreadHistory.ts +120 -0
  519. package/src/engine/ToolBroker.ts +157 -0
  520. package/src/engine/ToolExposure.ts +48 -0
  521. package/src/engine/internal/agent-runtime.ts +10162 -0
  522. package/src/engine/internal/bounded-value.ts +315 -0
  523. package/src/engine/internal/compaction.ts +678 -0
  524. package/src/engine/internal/error-diagnostic.ts +39 -0
  525. package/src/engine/internal/output-contract.ts +173 -0
  526. package/src/engine/internal/primitive-delta.ts +80 -0
  527. package/src/engine/internal/provider-result-staging.ts +211 -0
  528. package/src/engine/internal/tool-derivative.ts +106 -0
  529. package/src/engine/internal/tool-exposure.ts +224 -0
  530. package/src/engine/internal/tool-telemetry.ts +484 -0
  531. package/src/index.ts +97 -22
  532. package/src/sandbox/CodeExecutor.ts +352 -0
  533. package/src/sandbox/InteractiveBrowser.ts +257 -0
  534. package/src/sandbox/PageCapture.ts +692 -0
  535. package/src/sandbox/PageCrawl.ts +148 -0
  536. package/src/sandbox/PageScreenshot.ts +81 -0
  537. package/src/sandbox/ProtectedBrowser.ts +436 -0
  538. package/src/sandbox/Sandbox.ts +241 -0
@@ -0,0 +1,967 @@
1
+ import {
2
+ Cause,
3
+ Context,
4
+ Effect,
5
+ Layer,
6
+ Option,
7
+ Predicate,
8
+ Queue,
9
+ Schema,
10
+ Scope,
11
+ Stream,
12
+ } from "effect";
13
+ import { Tool, Toolkit } from "effect/unstable/ai";
14
+ import * as McpProtocol from "effect/unstable/ai/McpProtocol";
15
+ import * as McpSchema from "effect/unstable/ai/McpSchema";
16
+ import {
17
+ Headers,
18
+ HttpClient,
19
+ HttpClientRequest,
20
+ type HttpClientResponse,
21
+ } from "effect/unstable/http";
22
+ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
23
+ import { RpcClient, RpcClientError, type RpcMessage, RpcSerialization } from "effect/unstable/rpc";
24
+
25
+ import { utf8ByteLength } from "../core/internal/utf8.ts";
26
+ import { ToolExecutionClass, type ToolExecutionClassValue } from "../engine/DurableStep.ts";
27
+ import {
28
+ McpConnectionError,
29
+ McpConnector,
30
+ type McpConnectedServer,
31
+ type McpConnectionRequest,
32
+ McpServerIdentity,
33
+ McpToolOutputSchema,
34
+ } from "./Mcp.ts";
35
+
36
+ // ---------------------------------------------------------------------------
37
+ // MCP client: native Effect AI MCP schemas and protocol adapters, the Effect
38
+ // RPC client, and Effect HTTP / child-process services connect an Agent to a
39
+ // remote MCP server. Discovered tools become dynamic Effect AI Tools whose
40
+ // handlers forward `tools/call`; `connectMcp` still applies every discovery
41
+ // bound before the Toolkit reaches Agent context.
42
+ // ---------------------------------------------------------------------------
43
+
44
+ /** Largest single JSON-RPC message a transport accepts from a server by default. */
45
+ const DEFAULT_MAX_MESSAGE_BYTES = 4 * 1024 * 1024;
46
+ /** Bounded `tools/list` pagination: a server cannot keep a client walking cursors forever. */
47
+ const MAX_TOOL_LIST_PAGES = 64;
48
+ const MCP_SESSION_ID_HEADER = "mcp-session-id";
49
+ const MCP_PROTOCOL_VERSION_HEADER = "mcp-protocol-version";
50
+ const JSON_RPC_METHOD_NOT_FOUND = -32601;
51
+
52
+ /**
53
+ * The protocol revisions this client negotiates, as implemented by Effect AI's
54
+ * native MCP protocol adapters. The newest revision is offered first; a server
55
+ * answering with any other listed revision is accepted, anything else fails.
56
+ */
57
+ export const McpClientProtocolVersion = Schema.Literals([
58
+ McpProtocol.v2025_11_25.protocolVersion,
59
+ McpProtocol.v2025_06_18.protocolVersion,
60
+ McpProtocol.v2025_03_26.protocolVersion,
61
+ McpProtocol.v2024_11_05.protocolVersion,
62
+ ]);
63
+
64
+ export type McpClientProtocolVersion = typeof McpClientProtocolVersion.Type;
65
+
66
+ const OFFERED_PROTOCOL_VERSION: McpClientProtocolVersion = McpProtocol.v2025_11_25.protocolVersion;
67
+
68
+ /** Identity this client presents to servers during `initialize`. */
69
+ export const defaultMcpClientInfo = McpSchema.Implementation.make({
70
+ name: "effect-agent",
71
+ version: "1.0.0",
72
+ });
73
+
74
+ /**
75
+ * The model-visible result of a remote MCP tool call: the server's content
76
+ * blocks and, when the tool declares an `outputSchema`, its structured result.
77
+ * A result with `isError` never becomes this value; it fails the Tool Call.
78
+ */
79
+ export class McpToolResult extends Schema.Class<McpToolResult>(
80
+ "@effect-agent/capabilities/McpToolResult",
81
+ )({
82
+ content: Schema.Array(McpSchema.ContentBlock),
83
+ structuredContent: Schema.optionalKey(Schema.Json),
84
+ }) {}
85
+
86
+ /**
87
+ * Typed failure of one remote MCP tool call. `tool-error` carries the server's
88
+ * error content; the other reasons describe why no trustworthy result exists.
89
+ * None of them claims the remote effect did not happen.
90
+ */
91
+ export class McpToolCallFailed extends Schema.TaggedError<McpToolCallFailed>()(
92
+ "McpToolCallFailed",
93
+ {
94
+ serverId: Schema.NonEmptyString,
95
+ tool: Schema.NonEmptyString,
96
+ reason: Schema.Literals(["tool-error", "invalid-arguments", "protocol-error", "transport"]),
97
+ message: Schema.String,
98
+ content: Schema.optionalKey(Schema.Array(McpSchema.ContentBlock)),
99
+ },
100
+ ) {}
101
+
102
+ /**
103
+ * One reachable MCP server. `protocol` acquires a JSON-RPC transport in the
104
+ * caller's Scope; `R` names the platform services that transport needs so the
105
+ * connector Layer keeps them in its requirements.
106
+ */
107
+ export interface McpServerTransport<R = never> {
108
+ readonly serverId: string;
109
+ /**
110
+ * Whether the server's `readOnlyHint`, `idempotentHint`, and
111
+ * `destructiveHint` may set the framework execution class of its tools.
112
+ * Hints are server-declared and untrusted, so the default leaves every
113
+ * remote tool `uncertain`.
114
+ */
115
+ readonly trustToolAnnotations: boolean;
116
+ readonly protocol: Effect.Effect<
117
+ RpcClient.Protocol["Service"],
118
+ McpConnectionError,
119
+ Scope.Scope | R
120
+ >;
121
+ }
122
+
123
+ /** Streamable HTTP server address. Header values may carry credentials the application owns. */
124
+ export interface McpHttpTransportOptions {
125
+ readonly serverId: string;
126
+ readonly url: string;
127
+ readonly headers?: Headers.Input | undefined;
128
+ /** Largest accepted response message. Defaults to 4 MiB. */
129
+ readonly maxMessageBytes?: number | undefined;
130
+ readonly trustToolAnnotations?: boolean | undefined;
131
+ }
132
+
133
+ /** A local MCP server process speaking newline-delimited JSON-RPC on stdio. */
134
+ export interface McpStdioTransportOptions {
135
+ readonly serverId: string;
136
+ readonly command: string;
137
+ readonly args?: ReadonlyArray<string> | undefined;
138
+ readonly cwd?: string | undefined;
139
+ readonly env?: Readonly<Record<string, string>> | undefined;
140
+ /** Largest accepted stdout frame. Defaults to 4 MiB. */
141
+ readonly maxMessageBytes?: number | undefined;
142
+ readonly trustToolAnnotations?: boolean | undefined;
143
+ }
144
+
145
+ const isNotificationTag = (tag: string): boolean => tag.startsWith("notifications/");
146
+ const isRpcClientError = Schema.is(RpcClientError.RpcClientError);
147
+
148
+ const protocolDefect = (message: string, cause?: unknown): RpcClientError.RpcClientError =>
149
+ new RpcClientError.RpcClientError({
150
+ reason: new RpcClientError.RpcClientDefect({ message, cause }),
151
+ });
152
+
153
+ const InitializeProtocolVersion = Schema.Struct({ protocolVersion: Schema.String });
154
+ const decodeInitializeProtocolVersion = Schema.decodeUnknownOption(InitializeProtocolVersion);
155
+
156
+ const ServerRequest = Schema.Struct({ _tag: Schema.Literal("Request"), tag: Schema.String });
157
+ const isServerRequest = Schema.is(ServerRequest);
158
+
159
+ const isJsonRpcRequest = (message: unknown): message is RpcMessage.RequestEncoded =>
160
+ isServerRequest(message);
161
+
162
+ /** JSON-RPC error a client returns for a server-initiated request it does not serve. */
163
+ const declineServerRequest = (
164
+ request: RpcMessage.RequestEncoded,
165
+ ): RpcMessage.ResponseExitEncoded => ({
166
+ _tag: "Exit",
167
+ requestId: request.id,
168
+ exit: {
169
+ _tag: "Failure",
170
+ cause: [
171
+ {
172
+ _tag: "Fail",
173
+ error: {
174
+ code: JSON_RPC_METHOD_NOT_FOUND,
175
+ message: `Client does not serve ${request.tag}`,
176
+ },
177
+ },
178
+ ],
179
+ },
180
+ });
181
+
182
+ /**
183
+ * Routes one decoded JSON-RPC message. Responses reach the RPC client; server
184
+ * notifications are logged; server requests (sampling, elicitation, roots)
185
+ * are declined fail-closed through `respond` because this client serves none.
186
+ */
187
+ const routeMessage = (
188
+ message: unknown,
189
+ options: {
190
+ readonly clientId: number;
191
+ readonly writeResponse: (
192
+ clientId: number,
193
+ response: RpcMessage.FromServerEncoded,
194
+ ) => Effect.Effect<void>;
195
+ readonly respond: (response: RpcMessage.ResponseExitEncoded) => Effect.Effect<void>;
196
+ readonly onExit: (exit: RpcMessage.ResponseExitEncoded) => void;
197
+ },
198
+ ): Effect.Effect<void> => {
199
+ if (isJsonRpcRequest(message)) {
200
+ if (message.isNotification === true) {
201
+ return Effect.logDebug("Ignoring MCP server notification").pipe(
202
+ Effect.annotateLogs({ method: message.tag }),
203
+ );
204
+ }
205
+
206
+ return options.respond(declineServerRequest(message));
207
+ }
208
+ if (Predicate.hasProperty(message, "_tag") && message._tag === "Exit") {
209
+ options.onExit(message as RpcMessage.ResponseExitEncoded);
210
+ }
211
+
212
+ return options.writeResponse(options.clientId, message as RpcMessage.FromServerEncoded);
213
+ };
214
+
215
+ /** Reads a response body as text while refusing bodies above `maxBytes`. */
216
+ const readBoundedText = Effect.fn("McpHttpTransport.readBoundedText")(function* (
217
+ response: HttpClientResponse.HttpClientResponse,
218
+ maxBytes: number,
219
+ ) {
220
+ const declared = Number(response.headers["content-length"]);
221
+
222
+ if (Number.isFinite(declared) && declared > maxBytes) {
223
+ return yield* protocolDefect(
224
+ `MCP response of ${declared} bytes exceeds the ${maxBytes} byte message bound`,
225
+ );
226
+ }
227
+ const chunks: Array<string> = [];
228
+ let received = 0;
229
+
230
+ yield* response.stream.pipe(
231
+ Stream.decodeText(),
232
+ Stream.runForEach((chunk) => {
233
+ received += utf8ByteLength(chunk);
234
+ if (received > maxBytes) {
235
+ return Effect.fail(
236
+ protocolDefect(`MCP response exceeds the ${maxBytes} byte message bound`),
237
+ );
238
+ }
239
+ chunks.push(chunk);
240
+
241
+ return Effect.void;
242
+ }),
243
+ Effect.mapError((error) =>
244
+ isRpcClientError(error)
245
+ ? error
246
+ : protocolDefect("Could not read the MCP HTTP response", error),
247
+ ),
248
+ );
249
+
250
+ return chunks.join("");
251
+ });
252
+
253
+ /**
254
+ * Delivers the `data` of each `text/event-stream` event as it arrives. Only
255
+ * `data` fields carry JSON-RPC messages; `event`, `id`, `retry`, and comment
256
+ * lines are ignored because this client never resumes a stream, so a server
257
+ * retry directive neither ends the stream nor fails the request. At most
258
+ * `maxBytes` of an unterminated event stays buffered.
259
+ */
260
+ const consumeEventStream = Effect.fn("McpHttpTransport.consumeEventStream")(function* (
261
+ response: HttpClientResponse.HttpClientResponse,
262
+ maxBytes: number,
263
+ deliver: (data: string) => Effect.Effect<void>,
264
+ ) {
265
+ let buffer = "";
266
+ let pendingBytes = 0;
267
+
268
+ const dispatchEvent = (block: string): Effect.Effect<void> => {
269
+ const data = block
270
+ .split(/\r?\n/)
271
+ .filter((line) => line.startsWith("data:"))
272
+ .map((line) => line.slice("data:".length).replace(/^ /, ""))
273
+ .join("\n");
274
+
275
+ return data.length === 0 ? Effect.void : deliver(data);
276
+ };
277
+
278
+ const drain = (final: boolean): Effect.Effect<void> =>
279
+ Effect.suspend(() => {
280
+ const blocks: Array<string> = [];
281
+
282
+ while (true) {
283
+ const match = /\r?\n\r?\n/.exec(buffer);
284
+
285
+ if (match === null) break;
286
+ blocks.push(buffer.slice(0, match.index));
287
+ buffer = buffer.slice(match.index + match[0].length);
288
+ }
289
+ if (final && buffer.length > 0) {
290
+ blocks.push(buffer);
291
+ buffer = "";
292
+ }
293
+ pendingBytes = utf8ByteLength(buffer);
294
+
295
+ return Effect.forEach(blocks, dispatchEvent, { discard: true });
296
+ });
297
+
298
+ yield* response.stream.pipe(
299
+ Stream.decodeText(),
300
+ Stream.runForEach((chunk) => {
301
+ buffer += chunk;
302
+ pendingBytes += utf8ByteLength(chunk);
303
+ if (pendingBytes > maxBytes) {
304
+ return Effect.fail(protocolDefect(`MCP event stream buffered more than ${maxBytes} bytes`));
305
+ }
306
+
307
+ return drain(false);
308
+ }),
309
+ Effect.mapError((error) =>
310
+ isRpcClientError(error)
311
+ ? error
312
+ : protocolDefect("Could not read the MCP event stream", error),
313
+ ),
314
+ );
315
+ yield* drain(true);
316
+ });
317
+
318
+ const makeHttpProtocol = Effect.fn("McpHttpTransport.protocol")(function* (
319
+ options: McpHttpTransportOptions,
320
+ ) {
321
+ const client = yield* HttpClient.HttpClient;
322
+ const serialization = RpcSerialization.jsonRpc();
323
+ const parser = serialization.makeUnsafe();
324
+ const maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;
325
+ const configuredHeaders = Headers.fromInput(options.headers);
326
+ const url = options.url;
327
+ let sessionId: string | undefined;
328
+ let protocolVersion: string | undefined;
329
+ let initializeRequestId: string | number | undefined;
330
+ /** Request ids whose JSON-RPC response has been delivered. */
331
+ const answered = new Set<string | number>();
332
+
333
+ const transportHeaders = (): Headers.Headers =>
334
+ Headers.merge(
335
+ configuredHeaders,
336
+ Headers.fromInput({
337
+ accept: "application/json, text/event-stream",
338
+ ...(sessionId === undefined ? {} : { [MCP_SESSION_ID_HEADER]: sessionId }),
339
+ ...(protocolVersion === undefined
340
+ ? {}
341
+ : { [MCP_PROTOCOL_VERSION_HEADER]: protocolVersion }),
342
+ }),
343
+ );
344
+
345
+ const post = (body: string) =>
346
+ client
347
+ .execute(
348
+ HttpClientRequest.post(url).pipe(
349
+ HttpClientRequest.setHeaders(transportHeaders()),
350
+ HttpClientRequest.bodyText(body, "application/json"),
351
+ ),
352
+ )
353
+ .pipe(
354
+ Effect.mapError((error) =>
355
+ protocolDefect(`MCP HTTP request to ${options.serverId} failed`, error),
356
+ ),
357
+ );
358
+
359
+ // Ending the session is a courtesy to the server; the Scope owns the client.
360
+ yield* Effect.addFinalizer(() =>
361
+ sessionId === undefined
362
+ ? Effect.void
363
+ : client
364
+ .execute(
365
+ HttpClientRequest.delete(url).pipe(HttpClientRequest.setHeaders(transportHeaders())),
366
+ )
367
+ .pipe(Effect.ignore),
368
+ );
369
+
370
+ return yield* RpcClient.Protocol.make((writeResponse) =>
371
+ Effect.sync(() => {
372
+ const encode = (message: unknown): Effect.Effect<string, RpcClientError.RpcClientError> =>
373
+ Effect.suspend(() => {
374
+ const encoded = parser.encode(message);
375
+
376
+ return typeof encoded === "string"
377
+ ? Effect.succeed(encoded)
378
+ : Effect.fail(protocolDefect("Could not encode an MCP JSON-RPC message"));
379
+ });
380
+
381
+ const deliver = (clientId: number, data: string): Effect.Effect<void> =>
382
+ Effect.suspend(() => {
383
+ let messages: ReadonlyArray<unknown>;
384
+
385
+ try {
386
+ messages = parser.decode(data);
387
+ } catch (cause) {
388
+ return writeResponse(clientId, {
389
+ _tag: "ClientProtocolError",
390
+ error: protocolDefect("Could not decode an MCP JSON-RPC message", cause),
391
+ });
392
+ }
393
+
394
+ return Effect.forEach(
395
+ messages,
396
+ (message) =>
397
+ routeMessage(message, {
398
+ clientId,
399
+ writeResponse,
400
+ respond: (response) => encode(response).pipe(Effect.flatMap(post), Effect.ignore),
401
+ onExit: (exit) => {
402
+ answered.add(exit.requestId);
403
+ if (exit.requestId !== initializeRequestId || exit.exit._tag !== "Success") {
404
+ return;
405
+ }
406
+ const decoded = decodeInitializeProtocolVersion(exit.exit.value);
407
+
408
+ if (Option.isSome(decoded)) protocolVersion = decoded.value.protocolVersion;
409
+ },
410
+ }),
411
+ { discard: true },
412
+ );
413
+ });
414
+
415
+ /**
416
+ * Posts one message and delivers whatever the server answers. A request
417
+ * whose HTTP exchange completes without a JSON-RPC response for its id
418
+ * (for example a `202`, an `id: null` error, or a stream that ends
419
+ * early) fails that request instead of leaving its caller waiting.
420
+ */
421
+ const dispatch = Effect.fn("McpHttpTransport.dispatch")(function* (
422
+ clientId: number,
423
+ message: unknown,
424
+ requestId?: string | number,
425
+ ) {
426
+ const response = yield* post(yield* encode(message));
427
+ const responseSession = response.headers[MCP_SESSION_ID_HEADER];
428
+
429
+ if (responseSession !== undefined) sessionId = responseSession;
430
+ if (response.status < 200 || response.status >= 300) {
431
+ return yield* protocolDefect(
432
+ `MCP server ${options.serverId} answered HTTP ${response.status}`,
433
+ );
434
+ }
435
+ const contentType = response.headers["content-type"] ?? "";
436
+
437
+ if (response.status !== 202 && response.status !== 204) {
438
+ if (contentType.startsWith("text/event-stream")) {
439
+ yield* consumeEventStream(response, maxMessageBytes, (data) => deliver(clientId, data));
440
+ } else {
441
+ const text = yield* readBoundedText(response, maxMessageBytes);
442
+
443
+ if (text.length > 0) yield* deliver(clientId, text);
444
+ }
445
+ }
446
+ if (requestId !== undefined && !answered.has(requestId)) {
447
+ yield* writeResponse(clientId, {
448
+ _tag: "Exit",
449
+ requestId,
450
+ exit: {
451
+ _tag: "Failure",
452
+ cause: [
453
+ {
454
+ _tag: "Die",
455
+ defect: `MCP server ${options.serverId} closed the HTTP exchange without answering request ${String(requestId)}`,
456
+ },
457
+ ],
458
+ },
459
+ });
460
+ }
461
+ answered.delete(requestId ?? "");
462
+ });
463
+
464
+ const send: RpcClient.Protocol["Service"]["send"] = (clientId, request) => {
465
+ switch (request._tag) {
466
+ case "Request": {
467
+ if (isNotificationTag(request.tag)) {
468
+ return dispatch(clientId, { ...request, isNotification: true });
469
+ }
470
+ if (request.tag === "initialize") initializeRequestId = request.id;
471
+
472
+ return dispatch(clientId, request, request.id);
473
+ }
474
+ case "Interrupt": {
475
+ return dispatch(clientId, {
476
+ _tag: "Request",
477
+ id: request.requestId,
478
+ tag: "notifications/cancelled",
479
+ payload: { requestId: request.requestId },
480
+ headers: [],
481
+ isNotification: true,
482
+ } satisfies RpcMessage.RequestEncoded);
483
+ }
484
+ case "Ack":
485
+ case "Ping":
486
+ case "Eof": {
487
+ return Effect.void;
488
+ }
489
+ }
490
+ };
491
+
492
+ return {
493
+ send,
494
+ supportsAck: false,
495
+ supportsTransferables: false,
496
+ codecFor: serialization.codecFor,
497
+ };
498
+ }),
499
+ );
500
+ });
501
+
502
+ const makeStdioProtocol = Effect.fn("McpStdioTransport.protocol")(function* (
503
+ options: McpStdioTransportOptions,
504
+ ) {
505
+ const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
506
+ const maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;
507
+ const serialization = RpcSerialization.ndJsonRpc({ maxBufferSize: maxMessageBytes });
508
+ const parser = serialization.makeUnsafe();
509
+
510
+ const handle = yield* spawner
511
+ .spawn(
512
+ ChildProcess.make(options.command, [...(options.args ?? [])], {
513
+ ...(options.cwd === undefined ? {} : { cwd: options.cwd }),
514
+ ...(options.env === undefined ? {} : { env: options.env, extendEnv: true }),
515
+ }),
516
+ )
517
+ .pipe(
518
+ Effect.mapError((cause) =>
519
+ McpConnectionError.make({
520
+ serverId: options.serverId,
521
+ message: `Could not start the MCP server process for ${options.serverId}`,
522
+ cause,
523
+ }),
524
+ ),
525
+ );
526
+
527
+ const outbound = yield* Queue.unbounded<string>();
528
+ // Once the process is gone every later send fails immediately instead of
529
+ // queueing behind a writer that no longer exists.
530
+ let closed: RpcClientError.RpcClientError | undefined;
531
+
532
+ const closedWith = (message: string, cause?: unknown): RpcClientError.RpcClientError =>
533
+ (closed ??= protocolDefect(message, cause));
534
+
535
+ yield* Stream.fromQueue(outbound).pipe(
536
+ Stream.encodeText,
537
+ Stream.run(handle.stdin),
538
+ Effect.matchCauseEffect({
539
+ onSuccess: () =>
540
+ Effect.sync(() => closedWith(`MCP server process ${options.serverId} closed stdin`)),
541
+ onFailure: (cause) =>
542
+ Cause.hasInterruptsOnly(cause)
543
+ ? Effect.void
544
+ : Effect.sync(() =>
545
+ closedWith(
546
+ `Writing to MCP server process ${options.serverId} failed`,
547
+ Cause.squash(cause),
548
+ ),
549
+ ),
550
+ }),
551
+ Effect.forkScoped,
552
+ );
553
+ yield* handle.stderr.pipe(
554
+ Stream.decodeText(),
555
+ Stream.splitLines,
556
+ Stream.runForEach((line) => Effect.logDebug(line)),
557
+ Effect.ignore,
558
+ Effect.annotateLogs({ mcpServerId: options.serverId, stream: "stderr" }),
559
+ Effect.forkScoped,
560
+ );
561
+
562
+ return yield* RpcClient.Protocol.make(
563
+ Effect.fnUntraced(function* (writeResponse, clientIds) {
564
+ const broadcast = (error: RpcClientError.RpcClientError) =>
565
+ Effect.forEach(
566
+ clientIds,
567
+ (clientId) => writeResponse(clientId, { _tag: "ClientProtocolError", error }),
568
+ { discard: true },
569
+ );
570
+
571
+ const deliver = (chunk: Uint8Array): Effect.Effect<void> =>
572
+ Effect.suspend(() => {
573
+ let messages: ReadonlyArray<unknown>;
574
+
575
+ try {
576
+ messages = parser.decode(chunk);
577
+ } catch (cause) {
578
+ return broadcast(protocolDefect("Could not decode an MCP stdio frame", cause));
579
+ }
580
+
581
+ return Effect.forEach(
582
+ messages,
583
+ (message) =>
584
+ Effect.forEach(
585
+ clientIds,
586
+ (clientId) =>
587
+ routeMessage(message, {
588
+ clientId,
589
+ writeResponse,
590
+ respond: (response) => enqueue(response).pipe(Effect.ignore),
591
+ onExit: () => {},
592
+ }),
593
+ { discard: true },
594
+ ),
595
+ { discard: true },
596
+ );
597
+ });
598
+
599
+ const enqueue = (message: unknown): Effect.Effect<void, RpcClientError.RpcClientError> =>
600
+ Effect.suspend(() => {
601
+ if (closed !== undefined) return Effect.fail(closed);
602
+ const encoded = parser.encode(message);
603
+
604
+ if (typeof encoded !== "string") {
605
+ return Effect.fail(protocolDefect("Could not encode an MCP JSON-RPC message"));
606
+ }
607
+
608
+ return Queue.offer(outbound, encoded).pipe(Effect.asVoid);
609
+ });
610
+
611
+ yield* handle.stdout.pipe(
612
+ Stream.runForEach(deliver),
613
+ Effect.matchCauseEffect({
614
+ onSuccess: () =>
615
+ broadcast(closedWith(`MCP server process ${options.serverId} closed stdout`)),
616
+ onFailure: (cause) =>
617
+ Cause.hasInterruptsOnly(cause)
618
+ ? Effect.void
619
+ : broadcast(
620
+ closedWith(
621
+ `Reading MCP server process ${options.serverId} failed`,
622
+ Cause.squash(cause),
623
+ ),
624
+ ),
625
+ }),
626
+ Effect.forkScoped,
627
+ );
628
+
629
+ const send: RpcClient.Protocol["Service"]["send"] = (_clientId, request) => {
630
+ switch (request._tag) {
631
+ case "Request": {
632
+ return enqueue(
633
+ isNotificationTag(request.tag) ? { ...request, isNotification: true } : request,
634
+ );
635
+ }
636
+ case "Interrupt": {
637
+ return enqueue({
638
+ _tag: "Request",
639
+ id: request.requestId,
640
+ tag: "notifications/cancelled",
641
+ payload: { requestId: request.requestId },
642
+ headers: [],
643
+ isNotification: true,
644
+ } satisfies RpcMessage.RequestEncoded);
645
+ }
646
+ case "Ack":
647
+ case "Ping":
648
+ case "Eof": {
649
+ return Effect.void;
650
+ }
651
+ }
652
+ };
653
+
654
+ return {
655
+ send,
656
+ supportsAck: false,
657
+ supportsTransferables: false,
658
+ codecFor: serialization.codecFor,
659
+ };
660
+ }),
661
+ );
662
+ });
663
+
664
+ /** Streamable HTTP transport for one remote MCP server; requires `HttpClient`. */
665
+ export const McpHttpTransport = {
666
+ make: (options: McpHttpTransportOptions): McpServerTransport<HttpClient.HttpClient> => ({
667
+ serverId: options.serverId,
668
+ trustToolAnnotations: options.trustToolAnnotations ?? false,
669
+ protocol: makeHttpProtocol(options),
670
+ }),
671
+ } as const;
672
+
673
+ /** stdio transport for one local MCP server process; requires `ChildProcessSpawner`. */
674
+ export const McpStdioTransport = {
675
+ make: (
676
+ options: McpStdioTransportOptions,
677
+ ): McpServerTransport<ChildProcessSpawner.ChildProcessSpawner> => ({
678
+ serverId: options.serverId,
679
+ trustToolAnnotations: options.trustToolAnnotations ?? false,
680
+ protocol: makeStdioProtocol(options),
681
+ }),
682
+ } as const;
683
+
684
+ /**
685
+ * Effect AI Tool derived from one discovered MCP tool. Its parameters are the
686
+ * server's JSON Schema, so handlers receive `unknown` and the server validates
687
+ * arguments; `Tool.getJsonSchema` still advertises the discovered schema. A
688
+ * failed call returns `McpToolCallFailed` to the model as a failed tool result.
689
+ */
690
+ export type McpTool = Tool.Tool<
691
+ string,
692
+ {
693
+ readonly parameters: typeof Schema.Unknown;
694
+ readonly success: typeof McpToolResult;
695
+ readonly failure: typeof McpToolCallFailed;
696
+ readonly failureMode: "return";
697
+ }
698
+ >;
699
+
700
+ /** Toolkit of discovered MCP tools; every member forwards `tools/call` to its server. */
701
+ export type McpToolkit = Toolkit.Toolkit<Record<string, McpTool>>;
702
+
703
+ const executionClassFor = (
704
+ annotations: McpSchema.ToolAnnotations | undefined,
705
+ ): ToolExecutionClassValue => {
706
+ if (annotations === undefined) return "uncertain";
707
+ if (annotations.readOnlyHint) return "readonly";
708
+ if (annotations.idempotentHint && !annotations.destructiveHint) return "idempotent";
709
+
710
+ return "uncertain";
711
+ };
712
+
713
+ const makeMcpTool = (tool: McpSchema.Tool, trustToolAnnotations: boolean): McpTool => {
714
+ let dynamic: McpTool = Tool.dynamic(tool.name, {
715
+ ...(tool.description === undefined ? {} : { description: tool.description }),
716
+ parameters: tool.inputSchema,
717
+ success: McpToolResult,
718
+ failure: McpToolCallFailed,
719
+ // MCP reports tool errors inside results so the model can self-correct;
720
+ // `return` hands the typed failure to the model the same way.
721
+ failureMode: "return",
722
+ });
723
+
724
+ const title = tool.title ?? tool.annotations?.title;
725
+
726
+ if (title !== undefined) dynamic = dynamic.annotate(Tool.Title, title);
727
+ dynamic = dynamic.annotate(McpToolOutputSchema, Option.fromNullishOr(tool.outputSchema));
728
+ if (tool.annotations !== undefined) {
729
+ dynamic = dynamic
730
+ .annotate(Tool.Readonly, tool.annotations.readOnlyHint)
731
+ .annotate(Tool.Destructive, tool.annotations.destructiveHint)
732
+ .annotate(Tool.Idempotent, tool.annotations.idempotentHint)
733
+ .annotate(Tool.OpenWorld, tool.annotations.openWorldHint);
734
+ }
735
+ if (trustToolAnnotations) {
736
+ dynamic = dynamic.annotate(ToolExecutionClass, executionClassFor(tool.annotations));
737
+ }
738
+
739
+ return dynamic;
740
+ };
741
+
742
+ const ToolArguments = Schema.Record(Schema.String, Schema.Json);
743
+ const decodeToolArguments = Schema.decodeUnknownEffect(ToolArguments);
744
+
745
+ const errorText = (content: ReadonlyArray<typeof McpSchema.ContentBlock.Type>): string =>
746
+ content
747
+ .flatMap((block) => (block.type === "text" ? [block.text] : []))
748
+ .join("\n")
749
+ .slice(0, 4 * 1024);
750
+
751
+ const describeDefect = (defect: unknown): string =>
752
+ (Predicate.hasProperty(defect, "message") && Predicate.isString(defect.message)
753
+ ? defect.message
754
+ : String(defect)
755
+ ).slice(0, 4 * 1024);
756
+
757
+ const connectionError = (serverId: string, message: string) => (cause: unknown) =>
758
+ McpConnectionError.make({ serverId, message, cause });
759
+
760
+ /**
761
+ * Keeps every non-interrupt outcome of one protocol step typed: expected
762
+ * failures and defects (such as an undecodable server reply) both become the
763
+ * connection error, so a misbehaving server cannot crash the connector.
764
+ */
765
+ const failClosed =
766
+ (serverId: string, message: string) =>
767
+ <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, McpConnectionError, R> =>
768
+ self.pipe(
769
+ Effect.mapError(connectionError(serverId, message)),
770
+ Effect.catchDefect((defect) => Effect.fail(connectionError(serverId, message)(defect))),
771
+ );
772
+
773
+ const connectServer = Effect.fn("McpClient.connect")(function* <R>(
774
+ transport: McpServerTransport<R>,
775
+ request: McpConnectionRequest,
776
+ clientInfo: McpSchema.Implementation,
777
+ ): Effect.fn.Return<McpConnectedServer, McpConnectionError, Scope.Scope | R> {
778
+ const serverId = transport.serverId;
779
+ const protocol = yield* transport.protocol;
780
+
781
+ const client = yield* RpcClient.make(McpSchema.ClientRpcs, {
782
+ spanPrefix: "McpClient",
783
+ spanAttributes: { "mcp.server_id": serverId },
784
+ }).pipe(Effect.provideService(RpcClient.Protocol, protocol));
785
+
786
+ const initialized = yield* client
787
+ .initialize({
788
+ protocolVersion: OFFERED_PROTOCOL_VERSION,
789
+ capabilities: McpSchema.ClientCapabilities.make({}),
790
+ clientInfo,
791
+ })
792
+ .pipe(failClosed(serverId, `MCP initialize with ${serverId} failed`));
793
+
794
+ const negotiated = yield* Schema.decodeUnknownEffect(McpClientProtocolVersion)(
795
+ initialized.protocolVersion,
796
+ ).pipe(
797
+ Effect.mapError(
798
+ connectionError(
799
+ serverId,
800
+ `MCP server ${serverId} negotiated unsupported protocol version '${initialized.protocolVersion}'`,
801
+ ),
802
+ ),
803
+ );
804
+
805
+ yield* Effect.annotateCurrentSpan({ "mcp.protocol_version": negotiated });
806
+ yield* client["notifications/initialized"](undefined, { discard: true }).pipe(
807
+ failClosed(serverId, `Could not acknowledge MCP initialization with ${serverId}`),
808
+ );
809
+
810
+ const tools: Array<McpSchema.Tool> = [];
811
+ let cursor: string | undefined;
812
+ let pages = 0;
813
+
814
+ do {
815
+ const page = yield* client["tools/list"](
816
+ cursor === undefined ? undefined : McpSchema.PaginatedRequestMeta.make({ cursor }),
817
+ ).pipe(failClosed(serverId, `MCP tools/list with ${serverId} failed`));
818
+
819
+ tools.push(...page.tools);
820
+ cursor = page.nextCursor;
821
+ pages += 1;
822
+ // `validateMcpDiscovery` rejects the count; stop paying for more pages.
823
+ if (tools.length > request.maxToolCount) break;
824
+ if (cursor !== undefined && pages >= MAX_TOOL_LIST_PAGES) {
825
+ return yield* McpConnectionError.make({
826
+ serverId,
827
+ message: `MCP server ${serverId} paginated tools/list beyond ${MAX_TOOL_LIST_PAGES} pages`,
828
+ });
829
+ }
830
+ } while (cursor !== undefined);
831
+
832
+ const callTool = Effect.fn("McpClient.callTool")(function* (name: string, params: unknown) {
833
+ const args = yield* decodeToolArguments(params ?? {}).pipe(
834
+ Effect.mapError((cause) =>
835
+ McpToolCallFailed.make({
836
+ serverId,
837
+ tool: name,
838
+ reason: "invalid-arguments",
839
+ message: `MCP tool arguments must be a JSON object: ${cause.message}`,
840
+ }),
841
+ ),
842
+ );
843
+
844
+ const result = yield* client["tools/call"]({ name, arguments: args }).pipe(
845
+ Effect.mapError((error) =>
846
+ McpToolCallFailed.make({
847
+ serverId,
848
+ tool: name,
849
+ reason: isRpcClientError(error) ? "transport" : "protocol-error",
850
+ message: error.message,
851
+ }),
852
+ ),
853
+ // A JSON-RPC error the MCP error union cannot decode (or any other
854
+ // malformed reply) surfaces as a defect from the RPC client. It is still
855
+ // the server's answer, so it reaches the model as a failed tool result
856
+ // rather than aborting the batch.
857
+ Effect.catchDefect((defect) =>
858
+ Effect.fail(
859
+ McpToolCallFailed.make({
860
+ serverId,
861
+ tool: name,
862
+ reason: "protocol-error",
863
+ message: describeDefect(defect),
864
+ }),
865
+ ),
866
+ ),
867
+ );
868
+
869
+ if (result.isError === true) {
870
+ return yield* McpToolCallFailed.make({
871
+ serverId,
872
+ tool: name,
873
+ reason: "tool-error",
874
+ message: errorText(result.content),
875
+ content: result.content,
876
+ });
877
+ }
878
+
879
+ return McpToolResult.make({
880
+ content: result.content,
881
+ ...(result.structuredContent === undefined
882
+ ? {}
883
+ : { structuredContent: result.structuredContent }),
884
+ });
885
+ });
886
+
887
+ const toolkit: McpToolkit = yield* Effect.try({
888
+ try: () =>
889
+ Toolkit.make(...tools.map((tool) => makeMcpTool(tool, transport.trustToolAnnotations))),
890
+ catch: connectionError(
891
+ serverId,
892
+ `MCP server ${serverId} advertised tools that cannot form a Toolkit`,
893
+ ),
894
+ });
895
+
896
+ const handlers = toolkit.toLayer(
897
+ Object.fromEntries(
898
+ tools.map((tool) => [tool.name, (params: unknown) => callTool(tool.name, params)] as const),
899
+ ),
900
+ );
901
+
902
+ return {
903
+ identity: McpServerIdentity.make({ serverId, implementation: initialized.serverInfo }),
904
+ capabilities: initialized.capabilities,
905
+ tools,
906
+ toolkit,
907
+ handlers,
908
+ } satisfies McpConnectedServer;
909
+ });
910
+
911
+ /** Platform services one transport needs, as declared by `McpServerTransport<R>`. */
912
+ export type McpTransportRequirements<Transport> =
913
+ Transport extends McpServerTransport<infer R> ? R : never;
914
+
915
+ const makeConnectorLayer = <R>(
916
+ transports: ReadonlyArray<McpServerTransport<R>>,
917
+ options: { readonly clientInfo?: McpSchema.Implementation | undefined } | undefined,
918
+ ): Layer.Layer<McpConnector, never, R> =>
919
+ Layer.effect(McpConnector)(
920
+ Effect.gen(function* () {
921
+ const services = yield* Effect.context<R>();
922
+ const byServerId = new Map(transports.map((transport) => [transport.serverId, transport]));
923
+ const clientInfo = options?.clientInfo ?? defaultMcpClientInfo;
924
+
925
+ return McpConnector.of({
926
+ connect: (request) => {
927
+ const transport = byServerId.get(request.serverId);
928
+
929
+ if (transport === undefined) {
930
+ return Effect.fail(
931
+ McpConnectionError.make({
932
+ serverId: request.serverId,
933
+ message: `No MCP transport is configured for server '${request.serverId}'`,
934
+ }),
935
+ );
936
+ }
937
+
938
+ // The Layer supplies the transport's platform services, but the
939
+ // connection must live and die with the caller's Scope, never the
940
+ // Layer's.
941
+ return connectServer(transport, request, clientInfo).pipe(
942
+ Effect.updateContext((caller: Context.Context<Scope.Scope>) =>
943
+ Context.merge(Context.merge(caller, services), Context.pick(Scope.Scope)(caller)),
944
+ ),
945
+ );
946
+ },
947
+ });
948
+ }),
949
+ );
950
+
951
+ /**
952
+ * `McpConnector` over real transports. Each `connect` acquires the transport
953
+ * in the caller's Scope, negotiates a protocol revision, lists tools within the
954
+ * request bounds, and returns dynamic Effect AI Tools plus the handler Layer
955
+ * that forwards their calls. The Layer requires the union of every
956
+ * transport's platform services.
957
+ */
958
+ export const layer = <const Transports extends ReadonlyArray<McpServerTransport<unknown>>>(
959
+ transports: Transports,
960
+ options?: { readonly clientInfo?: McpSchema.Implementation | undefined },
961
+ ): Layer.Layer<McpConnector, never, McpTransportRequirements<Transports[number]>> =>
962
+ makeConnectorLayer(
963
+ // Type-level only: each element declares its own `R`, and the Layer
964
+ // requires their union. Nothing about the values changes.
965
+ transports as ReadonlyArray<McpServerTransport<McpTransportRequirements<Transports[number]>>>,
966
+ options,
967
+ );