agentfootprint 12.1.0 → 12.2.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 (275) hide show
  1. package/AGENTS.md +1 -1
  2. package/CAPABILITIES.md +3 -1
  3. package/ai-instructions/claude-code/SKILL.md +1 -1
  4. package/dist/adapters/mcp/agentcoreRuntime/invoke.js +113 -7
  5. package/dist/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  6. package/dist/adapters/mcp/agentcoreRuntime/session.js +21 -21
  7. package/dist/adapters/mcp/agentcoreRuntime/session.js.map +1 -1
  8. package/dist/adapters/mcp/agentcoreRuntime/transport.js +79 -5
  9. package/dist/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  10. package/dist/core/Agent.js +6 -0
  11. package/dist/core/Agent.js.map +1 -1
  12. package/dist/core/agent/stages/toolCalls.js +4 -0
  13. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  14. package/dist/core/slots/buildToolsSlot.js +8 -0
  15. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  16. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.d.ts +23 -4
  17. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js +112 -6
  18. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  19. package/dist/esm/adapters/mcp/agentcoreRuntime/session.d.ts +20 -6
  20. package/dist/esm/adapters/mcp/agentcoreRuntime/session.js +21 -21
  21. package/dist/esm/adapters/mcp/agentcoreRuntime/session.js.map +1 -1
  22. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js +81 -7
  23. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  24. package/dist/esm/core/Agent.js +6 -0
  25. package/dist/esm/core/Agent.js.map +1 -1
  26. package/dist/esm/core/agent/stages/toolCalls.js +4 -0
  27. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  28. package/dist/esm/core/slots/buildToolsSlot.d.ts +12 -0
  29. package/dist/esm/core/slots/buildToolsSlot.js +8 -0
  30. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  31. package/dist/esm/events/payloads.d.ts +41 -0
  32. package/dist/esm/events/registry.d.ts +3 -1
  33. package/dist/esm/events/registry.js +2 -0
  34. package/dist/esm/events/registry.js.map +1 -1
  35. package/dist/esm/identity/types.d.ts +7 -3
  36. package/dist/esm/identity/types.js.map +1 -1
  37. package/dist/esm/index.d.ts +1 -1
  38. package/dist/esm/index.js +4 -1
  39. package/dist/esm/index.js.map +1 -1
  40. package/dist/esm/lib/boundedJson.d.ts +14 -7
  41. package/dist/esm/lib/boundedJson.js +14 -7
  42. package/dist/esm/lib/boundedJson.js.map +1 -1
  43. package/dist/esm/mcp/callLifetime.js +5 -2
  44. package/dist/esm/mcp/callLifetime.js.map +1 -1
  45. package/dist/esm/mcp/clientPort.d.ts +78 -0
  46. package/dist/esm/mcp/clientPort.js +33 -0
  47. package/dist/esm/mcp/clientPort.js.map +1 -0
  48. package/dist/esm/mcp/gatewayTransport.js +13 -3
  49. package/dist/esm/mcp/gatewayTransport.js.map +1 -1
  50. package/dist/esm/mcp/index.d.ts +9 -1
  51. package/dist/esm/mcp/index.js +8 -0
  52. package/dist/esm/mcp/index.js.map +1 -1
  53. package/dist/esm/mcp/mcpClient.d.ts +18 -1
  54. package/dist/esm/mcp/mcpClient.js +203 -43
  55. package/dist/esm/mcp/mcpClient.js.map +1 -1
  56. package/dist/esm/mcp/mockMcpClient.js +13 -0
  57. package/dist/esm/mcp/mockMcpClient.js.map +1 -1
  58. package/dist/esm/mcp/pool/boundTool.d.ts +58 -0
  59. package/dist/esm/mcp/pool/boundTool.js +218 -0
  60. package/dist/esm/mcp/pool/boundTool.js.map +1 -0
  61. package/dist/esm/mcp/pool/clientSet.d.ts +73 -0
  62. package/dist/esm/mcp/pool/clientSet.js +152 -0
  63. package/dist/esm/mcp/pool/clientSet.js.map +1 -0
  64. package/dist/esm/mcp/pool/definitions.d.ts +103 -0
  65. package/dist/esm/mcp/pool/definitions.js +168 -0
  66. package/dist/esm/mcp/pool/definitions.js.map +1 -0
  67. package/dist/esm/mcp/pool/errors.d.ts +76 -0
  68. package/dist/esm/mcp/pool/errors.js +91 -0
  69. package/dist/esm/mcp/pool/errors.js.map +1 -0
  70. package/dist/esm/mcp/pool/identityKey.d.ts +57 -0
  71. package/dist/esm/mcp/pool/identityKey.js +94 -0
  72. package/dist/esm/mcp/pool/identityKey.js.map +1 -0
  73. package/dist/esm/mcp/pool/lease.d.ts +36 -0
  74. package/dist/esm/mcp/pool/lease.js +51 -0
  75. package/dist/esm/mcp/pool/lease.js.map +1 -0
  76. package/dist/esm/mcp/pool/listTools.d.ts +33 -0
  77. package/dist/esm/mcp/pool/listTools.js +146 -0
  78. package/dist/esm/mcp/pool/listTools.js.map +1 -0
  79. package/dist/esm/mcp/pool/mcpClientPool.d.ts +121 -0
  80. package/dist/esm/mcp/pool/mcpClientPool.js +151 -0
  81. package/dist/esm/mcp/pool/mcpClientPool.js.map +1 -0
  82. package/dist/esm/mcp/pool/options.d.ts +183 -0
  83. package/dist/esm/mcp/pool/options.js +119 -0
  84. package/dist/esm/mcp/pool/options.js.map +1 -0
  85. package/dist/esm/mcp/pool/plan.d.ts +77 -0
  86. package/dist/esm/mcp/pool/plan.js +134 -0
  87. package/dist/esm/mcp/pool/plan.js.map +1 -0
  88. package/dist/esm/mcp/pool/pool.d.ts +307 -0
  89. package/dist/esm/mcp/pool/pool.js +1071 -0
  90. package/dist/esm/mcp/pool/pool.js.map +1 -0
  91. package/dist/esm/mcp/pool/pooledClient.d.ts +93 -0
  92. package/dist/esm/mcp/pool/pooledClient.js +90 -0
  93. package/dist/esm/mcp/pool/pooledClient.js.map +1 -0
  94. package/dist/esm/mcp/pool/record.d.ts +80 -0
  95. package/dist/esm/mcp/pool/record.js +75 -0
  96. package/dist/esm/mcp/pool/record.js.map +1 -0
  97. package/dist/esm/mcp/pool/sessionEnded.d.ts +24 -0
  98. package/dist/esm/mcp/pool/sessionEnded.js +31 -0
  99. package/dist/esm/mcp/pool/sessionEnded.js.map +1 -0
  100. package/dist/esm/mcp/pool/work.d.ts +116 -0
  101. package/dist/esm/mcp/pool/work.js +213 -0
  102. package/dist/esm/mcp/pool/work.js.map +1 -0
  103. package/dist/esm/mcp/requestGuard.d.ts +70 -0
  104. package/dist/esm/mcp/requestGuard.js +98 -0
  105. package/dist/esm/mcp/requestGuard.js.map +1 -0
  106. package/dist/esm/mcp/requestLedger.d.ts +35 -1
  107. package/dist/esm/mcp/requestLedger.js +76 -3
  108. package/dist/esm/mcp/requestLedger.js.map +1 -1
  109. package/dist/esm/mcp/seriesEvidence.d.ts +10 -6
  110. package/dist/esm/mcp/seriesEvidence.js +16 -7
  111. package/dist/esm/mcp/seriesEvidence.js.map +1 -1
  112. package/dist/esm/mcp/terminate.d.ts +94 -0
  113. package/dist/esm/mcp/terminate.js +184 -0
  114. package/dist/esm/mcp/terminate.js.map +1 -0
  115. package/dist/esm/mcp/throttleRetry.js +71 -7
  116. package/dist/esm/mcp/throttleRetry.js.map +1 -1
  117. package/dist/esm/mcp/types.d.ts +85 -7
  118. package/dist/esm/redaction/knownStrings.js +34 -0
  119. package/dist/esm/redaction/knownStrings.js.map +1 -1
  120. package/dist/esm/tool-providers/index.d.ts +2 -2
  121. package/dist/esm/tool-providers/index.js +7 -1
  122. package/dist/esm/tool-providers/index.js.map +1 -1
  123. package/dist/esm/tools/mcpClientUse.d.ts +59 -0
  124. package/dist/esm/tools/mcpClientUse.js +216 -0
  125. package/dist/esm/tools/mcpClientUse.js.map +1 -0
  126. package/dist/esm/tools/toolProvider.d.ts +16 -0
  127. package/dist/esm/tools/toolSessions.d.ts +41 -0
  128. package/dist/esm/tools/toolSessions.js +41 -1
  129. package/dist/esm/tools/toolSessions.js.map +1 -1
  130. package/dist/events/registry.js +2 -0
  131. package/dist/events/registry.js.map +1 -1
  132. package/dist/identity/types.js.map +1 -1
  133. package/dist/index.js +6 -3
  134. package/dist/index.js.map +1 -1
  135. package/dist/lib/boundedJson.js +14 -7
  136. package/dist/lib/boundedJson.js.map +1 -1
  137. package/dist/mcp/callLifetime.js +5 -2
  138. package/dist/mcp/callLifetime.js.map +1 -1
  139. package/dist/mcp/clientPort.js +38 -0
  140. package/dist/mcp/clientPort.js.map +1 -0
  141. package/dist/mcp/gatewayTransport.js +13 -3
  142. package/dist/mcp/gatewayTransport.js.map +1 -1
  143. package/dist/mcp/index.js +16 -1
  144. package/dist/mcp/index.js.map +1 -1
  145. package/dist/mcp/mcpClient.js +207 -45
  146. package/dist/mcp/mcpClient.js.map +1 -1
  147. package/dist/mcp/mockMcpClient.js +13 -0
  148. package/dist/mcp/mockMcpClient.js.map +1 -1
  149. package/dist/mcp/pool/boundTool.js +223 -0
  150. package/dist/mcp/pool/boundTool.js.map +1 -0
  151. package/dist/mcp/pool/clientSet.js +157 -0
  152. package/dist/mcp/pool/clientSet.js.map +1 -0
  153. package/dist/mcp/pool/definitions.js +174 -0
  154. package/dist/mcp/pool/definitions.js.map +1 -0
  155. package/dist/mcp/pool/errors.js +96 -0
  156. package/dist/mcp/pool/errors.js.map +1 -0
  157. package/dist/mcp/pool/identityKey.js +99 -0
  158. package/dist/mcp/pool/identityKey.js.map +1 -0
  159. package/dist/mcp/pool/lease.js +55 -0
  160. package/dist/mcp/pool/lease.js.map +1 -0
  161. package/dist/mcp/pool/listTools.js +150 -0
  162. package/dist/mcp/pool/listTools.js.map +1 -0
  163. package/dist/mcp/pool/mcpClientPool.js +155 -0
  164. package/dist/mcp/pool/mcpClientPool.js.map +1 -0
  165. package/dist/mcp/pool/options.js +123 -0
  166. package/dist/mcp/pool/options.js.map +1 -0
  167. package/dist/mcp/pool/plan.js +140 -0
  168. package/dist/mcp/pool/plan.js.map +1 -0
  169. package/dist/mcp/pool/pool.js +1075 -0
  170. package/dist/mcp/pool/pool.js.map +1 -0
  171. package/dist/mcp/pool/pooledClient.js +94 -0
  172. package/dist/mcp/pool/pooledClient.js.map +1 -0
  173. package/dist/mcp/pool/record.js +80 -0
  174. package/dist/mcp/pool/record.js.map +1 -0
  175. package/dist/mcp/pool/sessionEnded.js +35 -0
  176. package/dist/mcp/pool/sessionEnded.js.map +1 -0
  177. package/dist/mcp/pool/work.js +219 -0
  178. package/dist/mcp/pool/work.js.map +1 -0
  179. package/dist/mcp/requestGuard.js +106 -0
  180. package/dist/mcp/requestGuard.js.map +1 -0
  181. package/dist/mcp/requestLedger.js +76 -3
  182. package/dist/mcp/requestLedger.js.map +1 -1
  183. package/dist/mcp/seriesEvidence.js +16 -7
  184. package/dist/mcp/seriesEvidence.js.map +1 -1
  185. package/dist/mcp/terminate.js +193 -0
  186. package/dist/mcp/terminate.js.map +1 -0
  187. package/dist/mcp/throttleRetry.js +71 -7
  188. package/dist/mcp/throttleRetry.js.map +1 -1
  189. package/dist/redaction/knownStrings.js +34 -0
  190. package/dist/redaction/knownStrings.js.map +1 -1
  191. package/dist/tool-providers/index.js +12 -1
  192. package/dist/tool-providers/index.js.map +1 -1
  193. package/dist/tools/mcpClientUse.js +225 -0
  194. package/dist/tools/mcpClientUse.js.map +1 -0
  195. package/dist/tools/toolSessions.js +44 -1
  196. package/dist/tools/toolSessions.js.map +1 -1
  197. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts +23 -4
  198. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts.map +1 -1
  199. package/dist/types/adapters/mcp/agentcoreRuntime/session.d.ts +20 -6
  200. package/dist/types/adapters/mcp/agentcoreRuntime/session.d.ts.map +1 -1
  201. package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts.map +1 -1
  202. package/dist/types/core/Agent.d.ts.map +1 -1
  203. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  204. package/dist/types/core/slots/buildToolsSlot.d.ts +12 -0
  205. package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
  206. package/dist/types/events/payloads.d.ts +41 -0
  207. package/dist/types/events/payloads.d.ts.map +1 -1
  208. package/dist/types/events/registry.d.ts +3 -1
  209. package/dist/types/events/registry.d.ts.map +1 -1
  210. package/dist/types/identity/types.d.ts +7 -3
  211. package/dist/types/identity/types.d.ts.map +1 -1
  212. package/dist/types/index.d.ts +1 -1
  213. package/dist/types/index.d.ts.map +1 -1
  214. package/dist/types/lib/boundedJson.d.ts +14 -7
  215. package/dist/types/lib/boundedJson.d.ts.map +1 -1
  216. package/dist/types/mcp/callLifetime.d.ts.map +1 -1
  217. package/dist/types/mcp/clientPort.d.ts +79 -0
  218. package/dist/types/mcp/clientPort.d.ts.map +1 -0
  219. package/dist/types/mcp/gatewayTransport.d.ts.map +1 -1
  220. package/dist/types/mcp/index.d.ts +9 -1
  221. package/dist/types/mcp/index.d.ts.map +1 -1
  222. package/dist/types/mcp/mcpClient.d.ts +18 -1
  223. package/dist/types/mcp/mcpClient.d.ts.map +1 -1
  224. package/dist/types/mcp/mockMcpClient.d.ts.map +1 -1
  225. package/dist/types/mcp/pool/boundTool.d.ts +59 -0
  226. package/dist/types/mcp/pool/boundTool.d.ts.map +1 -0
  227. package/dist/types/mcp/pool/clientSet.d.ts +74 -0
  228. package/dist/types/mcp/pool/clientSet.d.ts.map +1 -0
  229. package/dist/types/mcp/pool/definitions.d.ts +104 -0
  230. package/dist/types/mcp/pool/definitions.d.ts.map +1 -0
  231. package/dist/types/mcp/pool/errors.d.ts +77 -0
  232. package/dist/types/mcp/pool/errors.d.ts.map +1 -0
  233. package/dist/types/mcp/pool/identityKey.d.ts +58 -0
  234. package/dist/types/mcp/pool/identityKey.d.ts.map +1 -0
  235. package/dist/types/mcp/pool/lease.d.ts +37 -0
  236. package/dist/types/mcp/pool/lease.d.ts.map +1 -0
  237. package/dist/types/mcp/pool/listTools.d.ts +34 -0
  238. package/dist/types/mcp/pool/listTools.d.ts.map +1 -0
  239. package/dist/types/mcp/pool/mcpClientPool.d.ts +122 -0
  240. package/dist/types/mcp/pool/mcpClientPool.d.ts.map +1 -0
  241. package/dist/types/mcp/pool/options.d.ts +184 -0
  242. package/dist/types/mcp/pool/options.d.ts.map +1 -0
  243. package/dist/types/mcp/pool/plan.d.ts +78 -0
  244. package/dist/types/mcp/pool/plan.d.ts.map +1 -0
  245. package/dist/types/mcp/pool/pool.d.ts +308 -0
  246. package/dist/types/mcp/pool/pool.d.ts.map +1 -0
  247. package/dist/types/mcp/pool/pooledClient.d.ts +94 -0
  248. package/dist/types/mcp/pool/pooledClient.d.ts.map +1 -0
  249. package/dist/types/mcp/pool/record.d.ts +81 -0
  250. package/dist/types/mcp/pool/record.d.ts.map +1 -0
  251. package/dist/types/mcp/pool/sessionEnded.d.ts +25 -0
  252. package/dist/types/mcp/pool/sessionEnded.d.ts.map +1 -0
  253. package/dist/types/mcp/pool/work.d.ts +117 -0
  254. package/dist/types/mcp/pool/work.d.ts.map +1 -0
  255. package/dist/types/mcp/requestGuard.d.ts +71 -0
  256. package/dist/types/mcp/requestGuard.d.ts.map +1 -0
  257. package/dist/types/mcp/requestLedger.d.ts +35 -1
  258. package/dist/types/mcp/requestLedger.d.ts.map +1 -1
  259. package/dist/types/mcp/seriesEvidence.d.ts +10 -6
  260. package/dist/types/mcp/seriesEvidence.d.ts.map +1 -1
  261. package/dist/types/mcp/terminate.d.ts +95 -0
  262. package/dist/types/mcp/terminate.d.ts.map +1 -0
  263. package/dist/types/mcp/throttleRetry.d.ts.map +1 -1
  264. package/dist/types/mcp/types.d.ts +85 -7
  265. package/dist/types/mcp/types.d.ts.map +1 -1
  266. package/dist/types/redaction/knownStrings.d.ts.map +1 -1
  267. package/dist/types/tool-providers/index.d.ts +2 -2
  268. package/dist/types/tool-providers/index.d.ts.map +1 -1
  269. package/dist/types/tools/mcpClientUse.d.ts +60 -0
  270. package/dist/types/tools/mcpClientUse.d.ts.map +1 -0
  271. package/dist/types/tools/toolProvider.d.ts +16 -0
  272. package/dist/types/tools/toolProvider.d.ts.map +1 -1
  273. package/dist/types/tools/toolSessions.d.ts +41 -0
  274. package/dist/types/tools/toolSessions.d.ts.map +1 -1
  275. package/package.json +3 -3
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ /**
3
+ * boundTool — a tool bound to its conversation, the list it came from and that
4
+ * list's generation, re-checked after every wait and at the send gate.
5
+ *
6
+ * Pattern: the shape every MCP tool takes (`mcpClient.ts` · `mcpToolShape`) +
7
+ * one `execute` that runs the five steps of § 6.3.
8
+ * Role: A bound tool carries its BINDING: the key it was listed for; the
9
+ * context it was listed in (per client, the configuration; shared, the
10
+ * entry's context); the list it came from (per client, the client
11
+ * incarnation; shared, the entry); and that list's generation. Its
12
+ * `execute`:
13
+ *
14
+ * 1. checks that the calling run's caller identity encodes to its key —
15
+ * otherwise `identity-mismatch`, nothing sent;
16
+ * 2. checks its binding is current — otherwise `stale-tools`, nothing sent;
17
+ * 3. is admitted against `maxOperations` and takes a lease on its key's
18
+ * client, opening one from a plan resolved now when the key has none. A
19
+ * client whose plan's context differs from the binding's refuses with
20
+ * `binding-changed` (the client stays for the next list). A client that is
21
+ * not the incarnation the tool was listed from is checked against its OWN
22
+ * fresh list — the call goes on only if that list holds the same
23
+ * definition, compared as canonical JSON; otherwise `stale-tools`. Under
24
+ * the app's sharing contract, a replacement whose context matches uses the
25
+ * shared entry as it stands;
26
+ * 4. after every wait, checks step 2 again — and asks the app's `share`
27
+ * again, so a changed authorization name refuses it (`binding-changed`);
28
+ * 5. sends through the send gate (`mcp/requestGuard.ts`), asked at every
29
+ * boundary the request crosses — before every attempt, after a credential
30
+ * arrives, after signing — classifies the outcome (a server's 404 for the
31
+ * session is `SessionExpiredError`; a handle this process lost is
32
+ * `LocalSessionHandleLostError`; neither is repeated), files its use, and
33
+ * releases its lease once the request's own work has settled.
34
+ *
35
+ * Never another conversation's connection: the binding is to the KEY, and a
36
+ * client of any other key never serves it.
37
+ */
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.noteRefusal = exports.boundTool = void 0;
40
+ const mcpClientUse_js_1 = require("../../tools/mcpClientUse.js");
41
+ const toolSessions_js_1 = require("../../tools/toolSessions.js");
42
+ const sessionEnded_js_1 = require("./sessionEnded.js");
43
+ const mcpClient_js_1 = require("../mcpClient.js");
44
+ const requestGuard_js_1 = require("../requestGuard.js");
45
+ const errors_js_1 = require("./errors.js");
46
+ const identityKey_js_1 = require("./identityKey.js");
47
+ const record_js_1 = require("./record.js");
48
+ /** A callable tool for `binding`, shaped as every MCP tool is. */
49
+ function boundTool(pool, binding) {
50
+ return {
51
+ ...(0, mcpClient_js_1.mcpToolShape)(pool.settings.name, binding.definition.listed),
52
+ execute: (args, ctx) => executeBound(pool, binding, args, ctx),
53
+ };
54
+ }
55
+ exports.boundTool = boundTool;
56
+ /** The five steps. */
57
+ async function executeBound(pool, binding, args, ctx) {
58
+ const facts = new record_js_1.UseFacts(pool.settings.name, 'call');
59
+ facts.keyHash = binding.key.keyHash;
60
+ let operation;
61
+ try {
62
+ // 1 — the calling run's caller identity, encoded the one way.
63
+ const caller = (0, identityKey_js_1.poolKeyOf)(ctx?.identity, { requirePrincipal: false, requireTenant: false });
64
+ if (typeof caller === 'string' || caller.key !== binding.key.key) {
65
+ throw pool.refused('identity-mismatch');
66
+ }
67
+ pool.interact();
68
+ // 2 — the binding, before anything is admitted.
69
+ if (beforeLease(pool, binding) === 'stale')
70
+ throw pool.refused('stale-tools');
71
+ // 3 — admitted, leased, opened when the key has none; the app's names asked
72
+ // again, so a changed authorization refuses what was listed under the old.
73
+ operation = pool.admit('call', 'call', ctx?.signal);
74
+ const client = await pool.leaseClient(binding.key, operation, facts);
75
+ if (pool.refreshContext(client).context !== binding.context) {
76
+ throw pool.refused('binding-changed');
77
+ }
78
+ const { inner, effective } = await toolOn(pool, binding, client, operation, facts);
79
+ // 4 — after every wait, the binding again.
80
+ operation.check();
81
+ checkHolds(pool, client, effective);
82
+ // 5 — the send gate, asked at every boundary the request crosses.
83
+ operation.guardWith(() => checkHolds(pool, client, effective));
84
+ operation.phase = 'call';
85
+ const callCtx = (0, requestGuard_js_1.withCallGuard)({ ...(ctx ?? {}), signal: operation.signal }, operation);
86
+ try {
87
+ return await inner.execute(args, callCtx);
88
+ }
89
+ catch (error) {
90
+ throw classified(pool, client, operation, facts, error);
91
+ }
92
+ }
93
+ catch (error) {
94
+ noteRefusal(facts, error);
95
+ throw error;
96
+ }
97
+ finally {
98
+ operation?.finish();
99
+ (0, mcpClientUse_js_1.mcpClientUseOf)(ctx)?.file(facts.toUse());
100
+ }
101
+ }
102
+ /** The tool to run on `client`, and the binding the send gate checks it against. */
103
+ async function toolOn(pool, binding, client, operation, facts) {
104
+ const name = binding.definition.listed.name;
105
+ const port = client.port;
106
+ if (port === undefined)
107
+ throw pool.refused('init-failed');
108
+ if (binding.shared) {
109
+ // The shared entry as it stands: a definition this client may never have
110
+ // listed, so the tool carries its own checks (`ClientPort.bind`).
111
+ return { inner: port.bind(binding.definition.listed), effective: binding };
112
+ }
113
+ if (client.clientId === binding.clientId) {
114
+ const own = client.list.tool(name);
115
+ if (own === undefined)
116
+ throw pool.refused('stale-tools');
117
+ return { inner: own, effective: binding };
118
+ }
119
+ // A replacement: its own fresh list, under the context of now, then the
120
+ // same definition or nothing.
121
+ const listed = await pool.ensureListed(client, operation);
122
+ if (listed.context !== binding.context)
123
+ throw pool.refused('binding-changed');
124
+ const fresh = listed.list.definition(name);
125
+ const own = listed.list.tool(name);
126
+ if (fresh === undefined ||
127
+ own === undefined ||
128
+ fresh.canonical !== binding.definition.canonical) {
129
+ facts.revalidated = 'refused';
130
+ throw pool.refused('stale-tools');
131
+ }
132
+ facts.revalidated = 'kept';
133
+ return {
134
+ inner: own,
135
+ effective: {
136
+ ...binding,
137
+ clientId: client.clientId,
138
+ listId: listed.list.id,
139
+ generation: listed.list.generation,
140
+ },
141
+ };
142
+ }
143
+ /**
144
+ * Step 2, before a lease: a shared binding against its entry; a per-client
145
+ * binding against its incarnation when that incarnation is still the key's
146
+ * current client. An incarnation that is gone is not stale yet — step 3 checks
147
+ * the replacement's own list.
148
+ */
149
+ function beforeLease(pool, binding) {
150
+ if (binding.shared)
151
+ return sharedHolds(pool, binding) ? 'ok' : 'stale';
152
+ const current = pool.clients.currentFor(binding.key.key);
153
+ if (current === undefined || current.clientId !== binding.clientId)
154
+ return 'ok';
155
+ return listHolds(current, binding) ? 'ok' : 'stale';
156
+ }
157
+ /**
158
+ * The binding holds on `client` — the one the call runs on: the app's names
159
+ * still give its context, and its list has not moved. Otherwise the refusal:
160
+ * `binding-changed` for a changed context, `stale-tools` for a moved list.
161
+ */
162
+ function checkHolds(pool, client, binding) {
163
+ if (!pool.contextHolds(client, binding.context))
164
+ throw pool.refused('binding-changed');
165
+ const holds = binding.shared ? sharedHolds(pool, binding) : listHolds(client, binding);
166
+ if (!holds)
167
+ throw pool.refused('stale-tools');
168
+ }
169
+ function sharedHolds(pool, binding) {
170
+ const entry = pool.shared.peek(binding.context);
171
+ return (entry !== undefined &&
172
+ entry.list.id === binding.listId &&
173
+ entry.list.generation === binding.generation);
174
+ }
175
+ function listHolds(client, binding) {
176
+ return client.list.id === binding.listId && client.list.generation === binding.generation;
177
+ }
178
+ /**
179
+ * What the call failed with, as the pool read it: a server's 404 for the
180
+ * session it issued is `SessionExpiredError`; a handle this process lost is
181
+ * `LocalSessionHandleLostError` (the transport's own object). Either way the
182
+ * client leaves its key, and the call is not repeated. Anything else is the
183
+ * error as it came.
184
+ */
185
+ function classified(pool, client, operation, facts, error) {
186
+ const lost = pool.classifyFailure(client, operation, error);
187
+ if (lost === 'expired') {
188
+ facts.client = 'expired';
189
+ facts.evidence = 'server-404';
190
+ return new sessionEnded_js_1.ServerEndedSessionError(pool.settings.name, client.clientId, error);
191
+ }
192
+ if (lost === 'handle-lost') {
193
+ facts.client = 'handle-lost';
194
+ facts.evidence = 'transport-forgot-handle';
195
+ return error instanceof toolSessions_js_1.LocalSessionHandleLostError
196
+ ? error
197
+ : new toolSessions_js_1.LocalSessionHandleLostError({ cause: error });
198
+ }
199
+ return error;
200
+ }
201
+ /** A refusal's word on the record. */
202
+ function noteRefusal(facts, error) {
203
+ if (error instanceof errors_js_1.McpPoolRefusedError) {
204
+ facts.refusal = error.reason;
205
+ }
206
+ else if (error instanceof errors_js_1.PoolFullError) {
207
+ facts.refusal = LIMIT_WORDS[error.limit];
208
+ }
209
+ else {
210
+ return;
211
+ }
212
+ // No client was touched: the pool refused to give one.
213
+ if (facts.clientId === undefined)
214
+ facts.client = 'refused';
215
+ }
216
+ exports.noteRefusal = noteRefusal;
217
+ const LIMIT_WORDS = {
218
+ pool: 'pool-full',
219
+ principal: 'principal-full',
220
+ ending: 'ending-full',
221
+ operations: 'operations-full',
222
+ };
223
+ //# sourceMappingURL=boundTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundTool.js","sourceRoot":"","sources":["../../../src/mcp/pool/boundTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * clientSet — which clients the pool holds, and in which of its two sets.
4
+ *
5
+ * Pattern: two sets and their indexes, mutated only together.
6
+ * Role: § 5.3 of the design. The OPEN set holds every client that counts
7
+ * toward `maxClients` — opening, busy, idle, deferred, or an abandoned
8
+ * open that has not settled. The ENDING set holds every client from the
9
+ * decision to end it until that ending's work has settled, and counts
10
+ * toward `maxEnding`. A client leaves the open set only into the ending
11
+ * set — a lost handle too: its ending is its local close — or, when its
12
+ * open failed and left nothing to end, by being dropped. So the pool
13
+ * holds at most `maxClients + maxEnding` client objects.
14
+ *
15
+ * Each key has at most one CURRENT client — the one new leases go to. A client
16
+ * named by `terminate`, or whose session expired, stops being current at once
17
+ * while it stays in the open set, counted, until it can end.
18
+ *
19
+ * What the pool remembers of a key after its client left — the incarnation
20
+ * count and why the last one left — is bounded (`KEY_MEMORY`), least recently
21
+ * used forgotten first: after that a key's count starts again at 1. The record
22
+ * reads it; no binding depends on it.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.previousOf = exports.ClientSet = exports.KEY_MEMORY = void 0;
26
+ /** How many keys' incarnation counts the pool remembers. */
27
+ exports.KEY_MEMORY = 4096;
28
+ class ClientSet {
29
+ open = new Set();
30
+ ending = new Set();
31
+ current = new Map();
32
+ perPrincipal = new Map();
33
+ memory = new Map();
34
+ /** Clients in the open set. */
35
+ get openCount() {
36
+ return this.open.size;
37
+ }
38
+ /** Clients in the ending set. */
39
+ get endingCount() {
40
+ return this.ending.size;
41
+ }
42
+ /** Every client in the open set. */
43
+ openClients() {
44
+ return [...this.open];
45
+ }
46
+ /** Clients of the open set that count for `principal`. */
47
+ principalCount(principal) {
48
+ return this.perPrincipal.get(principal) ?? 0;
49
+ }
50
+ /** The key's current client — opening or open, taking new leases — if it has one. */
51
+ currentFor(key) {
52
+ return this.current.get(key);
53
+ }
54
+ /** The next incarnation number for `key`, and why its previous client left. */
55
+ nextIncarnation(key) {
56
+ const remembered = this.remember(key);
57
+ remembered.incarnations += 1;
58
+ const previous = remembered.previous;
59
+ remembered.previous = undefined;
60
+ return { generation: remembered.incarnations, ...(previous !== undefined && { previous }) };
61
+ }
62
+ /** A new client joins the open set as its key's current client. */
63
+ admit(client) {
64
+ this.open.add(client);
65
+ this.current.set(client.key.key, client);
66
+ this.perPrincipal.set(client.key.principal, this.principalCount(client.key.principal) + 1);
67
+ }
68
+ /**
69
+ * The client stops taking new leases: its key has no current client until the
70
+ * next open, and that open's record says `why`. A client that is no longer
71
+ * its key's current one has already left it, so nothing is recorded again —
72
+ * a later client of the key keeps its own reason.
73
+ */
74
+ retire(client, why) {
75
+ if (this.current.get(client.key.key) !== client)
76
+ return;
77
+ this.current.delete(client.key.key);
78
+ this.remember(client.key.key).previous = why;
79
+ }
80
+ /** The client moves from the open set into the ending set. */
81
+ moveToEnding(client, why) {
82
+ if (why !== undefined)
83
+ this.retire(client, why);
84
+ else if (this.current.get(client.key.key) === client)
85
+ this.current.delete(client.key.key);
86
+ this.leaveOpen(client);
87
+ this.ending.add(client);
88
+ }
89
+ /** The client's ending settled: it leaves the ending set. */
90
+ ended(client) {
91
+ this.ending.delete(client);
92
+ }
93
+ /** The client leaves the open set without ending — a failed open, a lost handle. */
94
+ drop(client, why) {
95
+ if (why !== undefined)
96
+ this.retire(client, why);
97
+ else if (this.current.get(client.key.key) === client)
98
+ this.current.delete(client.key.key);
99
+ this.leaveOpen(client);
100
+ }
101
+ /**
102
+ * The least recently used idle client of the open set — among those `pick`
103
+ * accepts — or `undefined` when every one is busy.
104
+ */
105
+ leastRecentlyUsedIdle(pick) {
106
+ let oldest;
107
+ for (const client of this.open) {
108
+ if (client.busy || client.state !== 'open' || !pick(client))
109
+ continue;
110
+ if (oldest === undefined || client.usedAt < oldest.usedAt)
111
+ oldest = client;
112
+ }
113
+ return oldest;
114
+ }
115
+ leaveOpen(client) {
116
+ if (!this.open.delete(client))
117
+ return;
118
+ const left = this.principalCount(client.key.principal) - 1;
119
+ if (left > 0)
120
+ this.perPrincipal.set(client.key.principal, left);
121
+ else
122
+ this.perPrincipal.delete(client.key.principal);
123
+ }
124
+ remember(key) {
125
+ let remembered = this.memory.get(key);
126
+ if (remembered !== undefined)
127
+ this.memory.delete(key);
128
+ else
129
+ remembered = { incarnations: 0, previous: undefined };
130
+ this.memory.set(key, remembered);
131
+ while (this.memory.size > exports.KEY_MEMORY) {
132
+ const oldest = this.memory.keys().next().value;
133
+ if (oldest === undefined)
134
+ break;
135
+ this.memory.delete(oldest);
136
+ }
137
+ return remembered;
138
+ }
139
+ }
140
+ exports.ClientSet = ClientSet;
141
+ /** The record's `previous` for an end reason, when it names one. */
142
+ function previousOf(reason) {
143
+ switch (reason) {
144
+ case 'idle':
145
+ case 'evicted':
146
+ case 'expired':
147
+ case 'handle-lost':
148
+ return reason;
149
+ case 'terminated':
150
+ case 'closed':
151
+ return 'terminated';
152
+ case 'abandoned-open':
153
+ return undefined;
154
+ }
155
+ }
156
+ exports.previousOf = previousOf;
157
+ //# sourceMappingURL=clientSet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientSet.js","sourceRoot":"","sources":["../../../src/mcp/pool/clientSet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ /**
3
+ * definitions — the tool lists a pool serves, and when each stops being served.
4
+ *
5
+ * Pattern: one list type, two owners — a client incarnation, or a shared entry.
6
+ * Role: § 6 of the design. A definition is what one `tools/list` entry says:
7
+ * name, description, input schema, and the declarations its `_meta`
8
+ * carries. The executable half (the connection) is never shared.
9
+ *
10
+ * - PER CLIENT (the default): a conversation's list is its own client's, and
11
+ * it belongs to that client INCARNATION alone — a replacement client, even
12
+ * one opened from the same plan, is a new session whose list may differ,
13
+ * so it lists again.
14
+ * - SHARED, only under the app's declared contract: one entry per context
15
+ * (`plan.ts`), listed on the client of whichever conversation needs it,
16
+ * bounded at `MAX_DEFINITION_ENTRIES` entries; a list longer than
17
+ * `MAX_SHARED_TOOLS` is used by its own client and not shared.
18
+ *
19
+ * A list stops being served in four ways, plus a time limit: the configuration
20
+ * (a new context is a new list), the server's tools-changed notice, the app's
21
+ * `permissionsChanged`, and `toolsChanged`. Invalidation moves the list's
22
+ * GENERATION at once — every tool bound to an older one is refused — and marks
23
+ * it to be listed again. A lapsed time limit lists again at the next list, and
24
+ * moves the generation only if the new list differs. A generation counts within
25
+ * one list: a replacement client and a new entry start counts of their own, and
26
+ * a binding names the list it came from, so no number of an old list can match
27
+ * a new one. A listing still in flight when its list's generation moved is
28
+ * discarded, never written.
29
+ *
30
+ * Every list is a frozen plain-data copy (`mcp/plainData.ts` · `copyJsonObject`),
31
+ * written once per generation, by one listing at a time.
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.SharedDefinitions = exports.DefinitionList = exports.definitionOf = void 0;
35
+ const canonicalJson_js_1 = require("../../lib/canonicalJson.js");
36
+ const plainData_js_1 = require("../plainData.js");
37
+ const options_js_1 = require("./options.js");
38
+ /** A frozen copy of `listed`, or `undefined` when it is not plain JSON data. */
39
+ function definitionOf(listed) {
40
+ const copy = (0, plainData_js_1.copyJsonObject)(listed);
41
+ if (copy === undefined || typeof copy['name'] !== 'string')
42
+ return undefined;
43
+ return { listed: deepFreeze(copy), canonical: (0, canonicalJson_js_1.canonicalJson)(copy) };
44
+ }
45
+ exports.definitionOf = definitionOf;
46
+ function deepFreeze(value) {
47
+ if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {
48
+ Object.freeze(value);
49
+ for (const child of Object.values(value))
50
+ deepFreeze(child);
51
+ }
52
+ return value;
53
+ }
54
+ /** Sequence for list ids: a binding names the list it came from. */
55
+ let lists = 0;
56
+ /**
57
+ * One list: an incarnation's own or a shared entry. Its `id` is stable for its
58
+ * life; its `generation` moves on invalidation, and on a time-limit relisting
59
+ * that changed it.
60
+ */
61
+ class DefinitionList {
62
+ id = `list-${++lists}`;
63
+ current = new Map();
64
+ tools = new Map();
65
+ /** Has any listing been written? */
66
+ written = false;
67
+ /** 0 until the first listing is written. */
68
+ generation = 0;
69
+ /** Invalidated: listed again before it is served. */
70
+ stale = false;
71
+ /** When it was last written, on the pool's clock. */
72
+ listedAt = 0;
73
+ /** The listing in flight, joined by anyone who needs the same list. */
74
+ listing;
75
+ /** Can it be served at `now`, as it stands? */
76
+ servable(now, ttlMs) {
77
+ return this.written && !this.stale && now - this.listedAt < ttlMs;
78
+ }
79
+ /**
80
+ * Invalidate: every older binding is refused, the next list lists again, and
81
+ * a listing in flight is discarded — even a first one, before anything was
82
+ * written. Generations only ever increase.
83
+ */
84
+ invalidate() {
85
+ this.generation += 1;
86
+ this.stale = true;
87
+ }
88
+ /** The definition named `name`, at the current generation. */
89
+ definition(name) {
90
+ return this.current.get(name);
91
+ }
92
+ /** The client's own wrapped tool named `name` (per-client lists only). */
93
+ tool(name) {
94
+ return this.tools.get(name);
95
+ }
96
+ /** Every definition, in listing order. */
97
+ all() {
98
+ return [...this.current.values()];
99
+ }
100
+ /**
101
+ * Write a listing that began at generation `began`. Refused — `false`, nothing
102
+ * written — when the generation moved while it ran. A first write moves the
103
+ * generation to a number no binding has seen; a write after invalidation keeps
104
+ * the moved one; a time-limit rewrite moves it only when the list differs.
105
+ */
106
+ write(began, definitions, tools, now) {
107
+ if (this.generation !== began)
108
+ return false;
109
+ const next = new Map(definitions.map((d) => [d.listed.name, d]));
110
+ if (!this.written)
111
+ this.generation += 1;
112
+ else if (!this.stale && differs(this.current, next))
113
+ this.generation += 1;
114
+ this.current = next;
115
+ this.tools = new Map((tools ?? []).map((t) => [t.schema.name, t]));
116
+ this.written = true;
117
+ this.stale = false;
118
+ this.listedAt = now;
119
+ return true;
120
+ }
121
+ }
122
+ exports.DefinitionList = DefinitionList;
123
+ function differs(a, b) {
124
+ if (a.size !== b.size)
125
+ return true;
126
+ for (const [name, definition] of a) {
127
+ if (b.get(name)?.canonical !== definition.canonical)
128
+ return true;
129
+ }
130
+ return false;
131
+ }
132
+ /**
133
+ * The shared definition entries, by context — bounded at
134
+ * `MAX_DEFINITION_ENTRIES`, the least recently used dropped first. A dropped
135
+ * entry's bindings are refused as stale: the entry they name is gone.
136
+ */
137
+ class SharedDefinitions {
138
+ maxEntries;
139
+ entries = new Map();
140
+ constructor(maxEntries = options_js_1.MAX_DEFINITION_ENTRIES) {
141
+ this.maxEntries = maxEntries;
142
+ }
143
+ get size() {
144
+ return this.entries.size;
145
+ }
146
+ /** The entry for `context`, created empty when there is none; most recently used. */
147
+ entryFor(context, tenant) {
148
+ let entry = this.entries.get(context);
149
+ if (entry !== undefined)
150
+ this.entries.delete(context);
151
+ else
152
+ entry = { list: new DefinitionList(), tenant };
153
+ this.entries.set(context, entry);
154
+ while (this.entries.size > this.maxEntries) {
155
+ const oldest = this.entries.keys().next().value;
156
+ if (oldest === undefined)
157
+ break;
158
+ this.entries.delete(oldest);
159
+ }
160
+ return entry;
161
+ }
162
+ /** The entry for `context` if it still exists — never created. */
163
+ peek(context) {
164
+ return this.entries.get(context);
165
+ }
166
+ /** Invalidate every entry `matches` selects. */
167
+ invalidate(matches) {
168
+ for (const entry of this.entries.values())
169
+ if (matches(entry))
170
+ entry.list.invalidate();
171
+ }
172
+ }
173
+ exports.SharedDefinitions = SharedDefinitions;
174
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../../src/mcp/pool/definitions.ts"],"names":[],"mappings":"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"}