@nylorun/runtime 0.23.0-beta → 0.25.0-beta

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 (301) hide show
  1. package/CHANGELOG.md +252 -0
  2. package/README.md +87 -28
  3. package/dist/adapters/execution/restate.js +1 -1
  4. package/dist/adapters/replication/pgoutput.d.ts +2 -0
  5. package/dist/adapters/replication/pgoutput.js +6 -3
  6. package/dist/adapters/sandbox/local.d.ts +9 -1
  7. package/dist/adapters/sandbox/local.js +16 -4
  8. package/dist/adapters/sandbox/virtual.js +4 -1
  9. package/dist/api/a2a/card.d.ts +11 -1
  10. package/dist/api/a2a/card.js +26 -2
  11. package/dist/api/a2a/endpoint.js +9 -3
  12. package/dist/api/a2a/protocol.d.ts +25 -2
  13. package/dist/api/a2a/protocol.js +20 -3
  14. package/dist/api/a2a/routes.d.ts +6 -1
  15. package/dist/api/a2a/routes.js +67 -9
  16. package/dist/api/a2a/tasks.js +2 -1
  17. package/dist/api/ag-ui/endpoint.js +8 -3
  18. package/dist/api/ag-ui/history.d.ts +6 -1
  19. package/dist/api/ag-ui/history.js +39 -3
  20. package/dist/api/ag-ui/routes.d.ts +4 -1
  21. package/dist/api/ag-ui/routes.js +63 -20
  22. package/dist/api/ag-ui/translate.js +3 -2
  23. package/dist/api/components.d.ts +5327 -1091
  24. package/dist/api/components.js +40 -16
  25. package/dist/api/gate/keys.d.ts +2 -1
  26. package/dist/api/gate/keys.js +14 -1
  27. package/dist/api/gate/routes.d.ts +6 -0
  28. package/dist/api/gate/routes.js +52 -3
  29. package/dist/api/http/app.js +17 -6
  30. package/dist/api/http/body.d.ts +3 -3
  31. package/dist/api/http/body.js +7 -7
  32. package/dist/api/http/define.d.ts +6 -0
  33. package/dist/api/http/define.js +13 -1
  34. package/dist/api/http/respond.js +1 -1
  35. package/dist/api/http/routes/artifacts.js +35 -8
  36. package/dist/api/http/routes/coverage.d.ts +9 -0
  37. package/dist/api/http/routes/coverage.js +34 -0
  38. package/dist/api/http/routes/environment-manifests.d.ts +9 -0
  39. package/dist/api/http/routes/environment-manifests.js +118 -0
  40. package/dist/api/http/routes/environments.d.ts +11 -0
  41. package/dist/api/http/routes/environments.js +332 -0
  42. package/dist/api/http/routes/mcp.d.ts +1 -1
  43. package/dist/api/http/routes/mcp.js +2 -2
  44. package/dist/api/http/routes/me.js +1 -1
  45. package/dist/api/http/routes/reads.d.ts +94 -9
  46. package/dist/api/http/routes/reads.js +54 -5
  47. package/dist/api/http/routes/sessions.js +24 -9
  48. package/dist/api/http/routes/tenant.js +65 -15
  49. package/dist/api/inbound-files.d.ts +65 -0
  50. package/dist/api/inbound-files.js +115 -0
  51. package/dist/api/openapi.js +48 -28
  52. package/dist/artifacts/disk.d.ts +59 -0
  53. package/dist/artifacts/disk.js +569 -0
  54. package/dist/artifacts/export.d.ts +1 -1
  55. package/dist/artifacts/export.js +2 -3
  56. package/dist/artifacts/folders.d.ts +6 -3
  57. package/dist/artifacts/folders.js +17 -12
  58. package/dist/artifacts/media-types.d.ts +15 -0
  59. package/dist/artifacts/media-types.js +56 -4
  60. package/dist/artifacts/parts.d.ts +12 -3
  61. package/dist/artifacts/parts.js +15 -4
  62. package/dist/artifacts/service.d.ts +2 -1
  63. package/dist/artifacts/service.js +6 -1
  64. package/dist/artifacts/workspace.d.ts +5 -5
  65. package/dist/artifacts/workspace.js +7 -19
  66. package/dist/core/flow-host.d.ts +3 -4
  67. package/dist/core/flow-host.js +5 -2
  68. package/dist/core/provider.d.ts +3 -2
  69. package/dist/core/provider.js +5 -37
  70. package/dist/core/sandbox-routes.d.ts +2 -21
  71. package/dist/core/sandbox-routes.js +11 -44
  72. package/dist/core/turn-manifest.d.ts +3 -2
  73. package/dist/core/turn-manifest.js +29 -5
  74. package/dist/execution/types.d.ts +1 -1
  75. package/dist/gates/contract.d.ts +3 -24
  76. package/dist/gates/contract.js +1 -36
  77. package/dist/gates/egress-credentials.d.ts +9 -0
  78. package/dist/gates/egress-credentials.js +11 -4
  79. package/dist/gates/egress.d.ts +22 -1
  80. package/dist/gates/egress.js +116 -10
  81. package/dist/gates/fixture-model.d.ts +28 -0
  82. package/dist/gates/fixture-model.js +92 -0
  83. package/dist/gates/handler.js +4 -4
  84. package/dist/gates/http-tool.d.ts +9 -6
  85. package/dist/gates/http-tool.js +11 -17
  86. package/dist/gates/in-process.d.ts +5 -0
  87. package/dist/gates/in-process.js +12 -1
  88. package/dist/gates/journal.d.ts +30 -0
  89. package/dist/gates/journal.js +51 -0
  90. package/dist/gates/mcp-handler.d.ts +4 -0
  91. package/dist/gates/mcp-handler.js +7 -4
  92. package/dist/gates/meter.d.ts +10 -2
  93. package/dist/gates/meter.js +20 -5
  94. package/dist/gates/policy.d.ts +49 -0
  95. package/dist/gates/policy.js +132 -0
  96. package/dist/gates/tenant-vaults.d.ts +7 -7
  97. package/dist/gates/tenant-vaults.js +5 -5
  98. package/dist/gates/tool-calls.d.ts +10 -5
  99. package/dist/gates/tool-calls.js +28 -10
  100. package/dist/gates/tool-client.d.ts +8 -0
  101. package/dist/gates/tool-client.js +27 -11
  102. package/dist/gates/tool-contract.d.ts +11 -69
  103. package/dist/gates/tool-contract.js +1 -85
  104. package/dist/gates/tool-gate.d.ts +1 -1
  105. package/dist/harness/calls.d.ts +14 -7
  106. package/dist/harness/calls.js +30 -24
  107. package/dist/harness/executors.js +12 -9
  108. package/dist/harness/main.js +24 -5
  109. package/dist/harness/pod.d.ts +39 -0
  110. package/dist/harness/pod.js +46 -0
  111. package/dist/harness/service.d.ts +0 -1
  112. package/dist/harness/service.js +17 -9
  113. package/dist/harness/setup.d.ts +29 -0
  114. package/dist/harness/setup.js +174 -0
  115. package/dist/harness/ws-client.js +3 -2
  116. package/dist/harness/ws-port.d.ts +1 -5
  117. package/dist/harness/ws-port.js +1 -5
  118. package/dist/harness-api/in-process.js +3 -3
  119. package/dist/harness-api/record.d.ts +15 -1
  120. package/dist/harness-api/record.js +180 -50
  121. package/dist/harness-api/redact.d.ts +3 -0
  122. package/dist/harness-api/redact.js +45 -0
  123. package/dist/harness-api/server.d.ts +35 -4
  124. package/dist/harness-api/server.js +130 -17
  125. package/dist/harness-api/start.d.ts +10 -3
  126. package/dist/harness-api/start.js +40 -10
  127. package/dist/harness-api/tool-journal.d.ts +105 -0
  128. package/dist/harness-api/tool-journal.js +132 -0
  129. package/dist/harness-api/tool-status.d.ts +13 -0
  130. package/dist/harness-api/tool-status.js +26 -0
  131. package/dist/harness-api/workspace.d.ts +12 -7
  132. package/dist/harness-api/workspace.js +47 -25
  133. package/dist/harness-api/ws-server.d.ts +11 -3
  134. package/dist/harness-api/ws-server.js +94 -15
  135. package/dist/host/gates.d.ts +2 -1
  136. package/dist/host/gates.js +10 -2
  137. package/dist/host/main.js +54 -5
  138. package/dist/host/operate.js +67 -5
  139. package/dist/host/stack-config.d.ts +64 -0
  140. package/dist/host/stack-config.js +62 -2
  141. package/dist/keys/client.js +4 -1
  142. package/dist/keys/keys.d.ts +13 -6
  143. package/dist/keys/keys.js +9 -8
  144. package/dist/management-openapi.json +1264 -2171
  145. package/dist/mcp/connect.d.ts +26 -22
  146. package/dist/mcp/connect.js +30 -34
  147. package/dist/mcp/pool.d.ts +3 -6
  148. package/dist/mcp/pool.js +14 -28
  149. package/dist/mcp/preview.d.ts +3 -3
  150. package/dist/mcp/preview.js +10 -21
  151. package/dist/mcp/snapshot.d.ts +16 -24
  152. package/dist/mcp/snapshot.js +33 -45
  153. package/dist/model/capabilities.d.ts +26 -0
  154. package/dist/model/capabilities.js +44 -0
  155. package/dist/model/catalog.d.ts +34 -3
  156. package/dist/model/catalog.js +38 -2
  157. package/dist/model/models.d.ts +2 -0
  158. package/dist/model/models.js +1 -1
  159. package/dist/model/native-blocks.d.ts +35 -0
  160. package/dist/model/native-blocks.js +170 -0
  161. package/dist/model/pi-model.js +114 -94
  162. package/dist/openapi.json +12822 -3943
  163. package/dist/reads/types.d.ts +16 -3
  164. package/dist/record/append.d.ts +3 -1
  165. package/dist/record/append.js +1 -0
  166. package/dist/record/envelope.d.ts +5 -1
  167. package/dist/record/envelope.js +7 -3
  168. package/dist/record/environment.d.ts +25 -0
  169. package/dist/record/environment.js +44 -0
  170. package/dist/record/index.d.ts +1 -1
  171. package/dist/record/index.js +1 -1
  172. package/dist/sandbox/disk-fs.d.ts +95 -0
  173. package/dist/sandbox/disk-fs.js +206 -0
  174. package/dist/sandbox/join.d.ts +17 -18
  175. package/dist/sandbox/join.js +46 -15
  176. package/dist/sandbox/manager.d.ts +47 -21
  177. package/dist/sandbox/manager.js +162 -107
  178. package/dist/sandbox/placement.d.ts +14 -13
  179. package/dist/sandbox/placement.js +31 -14
  180. package/dist/sandbox/pods/client.d.ts +9 -2
  181. package/dist/sandbox/pods/lifecycle.d.ts +36 -27
  182. package/dist/sandbox/pods/lifecycle.js +29 -26
  183. package/dist/sandbox/pods/reconcile.js +18 -12
  184. package/dist/sandbox/pods/spec.d.ts +15 -13
  185. package/dist/sandbox/pods/spec.js +17 -20
  186. package/dist/sandbox/records.d.ts +2 -2
  187. package/dist/sandbox/records.js +3 -3
  188. package/dist/sandbox/resolve.d.ts +37 -27
  189. package/dist/sandbox/resolve.js +73 -41
  190. package/dist/sandbox/runtime-tools.d.ts +9 -0
  191. package/dist/sandbox/runtime-tools.js +16 -0
  192. package/dist/sandbox/session-sandbox.d.ts +4 -6
  193. package/dist/sandbox/session-sandbox.js +47 -94
  194. package/dist/sandbox/setup.d.ts +64 -0
  195. package/dist/sandbox/setup.js +160 -0
  196. package/dist/sandbox/share.d.ts +21 -26
  197. package/dist/sandbox/share.js +36 -63
  198. package/dist/sandbox/skills.d.ts +8 -6
  199. package/dist/sandbox/skills.js +24 -23
  200. package/dist/sandbox/tenant-config.d.ts +12 -14
  201. package/dist/sandbox/tenant-config.js +12 -17
  202. package/dist/sandbox/types.d.ts +6 -0
  203. package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
  204. package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
  205. package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
  206. package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
  207. package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
  208. package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
  209. package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
  210. package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
  211. package/dist/store/postgres/drizzle/meta/_journal.json +56 -0
  212. package/dist/store/postgres/reads.js +123 -17
  213. package/dist/store/postgres/record-writer.d.ts +4 -4
  214. package/dist/store/postgres/record-writer.js +9 -9
  215. package/dist/store/postgres/record.d.ts +7 -0
  216. package/dist/store/postgres/record.js +23 -2
  217. package/dist/store/postgres/schema.d.ts +1126 -736
  218. package/dist/store/postgres/schema.js +136 -73
  219. package/dist/store/postgres/store.js +195 -67
  220. package/dist/store/types.d.ts +165 -50
  221. package/dist/tenant/advance.d.ts +7 -6
  222. package/dist/tenant/advance.js +118 -42
  223. package/dist/tenant/artifact-tool.d.ts +1 -1
  224. package/dist/tenant/artifact-tool.js +46 -26
  225. package/dist/tenant/commands.d.ts +15 -2
  226. package/dist/tenant/commands.js +115 -14
  227. package/dist/tenant/context.d.ts +56 -24
  228. package/dist/tenant/context.js +4 -15
  229. package/dist/tenant/effects.d.ts +1 -1
  230. package/dist/tenant/effects.js +44 -29
  231. package/dist/tenant/environment-manifests.d.ts +57 -0
  232. package/dist/tenant/environment-manifests.js +200 -0
  233. package/dist/tenant/environments.d.ts +174 -0
  234. package/dist/tenant/environments.js +1044 -0
  235. package/dist/tenant/harness-tokens.d.ts +21 -0
  236. package/dist/tenant/harness-tokens.js +61 -0
  237. package/dist/tenant/host-token.d.ts +1 -1
  238. package/dist/tenant/host-token.js +2 -4
  239. package/dist/tenant/identity-file.d.ts +4 -4
  240. package/dist/tenant/identity-file.js +17 -8
  241. package/dist/tenant/issuers.js +3 -3
  242. package/dist/tenant/model-setting.d.ts +14 -0
  243. package/dist/tenant/model-setting.js +51 -0
  244. package/dist/tenant/principals.js +1 -1
  245. package/dist/tenant/reset.js +3 -3
  246. package/dist/tenant/runtime.d.ts +6 -1
  247. package/dist/tenant/runtime.js +7 -1
  248. package/dist/tenant/session.d.ts +3 -3
  249. package/dist/tenant/session.js +0 -14
  250. package/dist/tenant/sessions.d.ts +18 -14
  251. package/dist/tenant/sessions.js +99 -143
  252. package/dist/tenant/signing-keys.d.ts +5 -1
  253. package/dist/tenant/skill-tool.d.ts +3 -3
  254. package/dist/tenant/skill-tool.js +6 -11
  255. package/dist/tenant/status.js +3 -3
  256. package/dist/tenant/sweep.js +13 -7
  257. package/dist/tenant/tool-results.js +1 -1
  258. package/dist/tenant/tool-search.d.ts +7 -11
  259. package/dist/tenant/tool-search.js +8 -5
  260. package/dist/tenant/transcript.d.ts +245 -36
  261. package/dist/tenant/transcript.js +64 -12
  262. package/dist/tenant/turn-timing.d.ts +43 -0
  263. package/dist/tenant/turn-timing.js +39 -0
  264. package/dist/tenant/types.d.ts +2 -0
  265. package/dist/traces/ids.d.ts +41 -0
  266. package/dist/traces/ids.js +81 -0
  267. package/dist/traces/key.d.ts +6 -0
  268. package/dist/traces/key.js +37 -0
  269. package/dist/traces/map.d.ts +113 -0
  270. package/dist/traces/map.js +289 -0
  271. package/dist/traces/options.d.ts +7 -0
  272. package/dist/traces/options.js +1 -0
  273. package/dist/traces/otlp.d.ts +42 -0
  274. package/dist/traces/otlp.js +84 -0
  275. package/dist/traces/projector.d.ts +58 -0
  276. package/dist/traces/projector.js +200 -0
  277. package/dist/traces/read.d.ts +23 -0
  278. package/dist/traces/read.js +16 -0
  279. package/dist/vault/coverage.d.ts +26 -0
  280. package/dist/vault/coverage.js +62 -0
  281. package/dist/vault/error.d.ts +11 -1
  282. package/dist/vault/error.js +5 -1
  283. package/dist/vault/host-model.d.ts +4 -1
  284. package/dist/vault/host-model.js +10 -2
  285. package/dist/vault/service.d.ts +92 -48
  286. package/dist/vault/service.js +462 -376
  287. package/dist/vault/sources.d.ts +5 -16
  288. package/dist/vault/sources.js +6 -8
  289. package/dist/version.d.ts +1 -1
  290. package/dist/version.js +2 -2
  291. package/package.json +13 -13
  292. package/dist/api/http/routes/sandboxes.d.ts +0 -9
  293. package/dist/api/http/routes/sandboxes.js +0 -153
  294. package/dist/api/http/routes/vaults.d.ts +0 -10
  295. package/dist/api/http/routes/vaults.js +0 -139
  296. package/dist/record/sandbox.d.ts +0 -25
  297. package/dist/record/sandbox.js +0 -43
  298. package/dist/sandbox/capability.d.ts +0 -3
  299. package/dist/sandbox/capability.js +0 -10
  300. package/dist/tenant/sandboxes.d.ts +0 -123
  301. package/dist/tenant/sandboxes.js +0 -566
@@ -12,10 +12,16 @@ export interface McpRequestOptions {
12
12
  /** Options of one tool call. */
13
13
  export interface McpCallOptions extends McpRequestOptions {
14
14
  /**
15
- * The call's effect id. A gate runs a keyed call once and keeps its outcome, so a re-send
16
- * after a takeover joins it (F4.1). An in-process connection ignores it.
15
+ * The call's effect id. A gate keeps a keyed call's outcome, so a re-send after a takeover
16
+ * joins it (F4.1), and the server gets it in `_meta` (R5.5).
17
17
  */
18
18
  readonly key?: string;
19
+ /**
20
+ * The call's span context (R7.4), sent as the `traceparent` header on the call's requests where
21
+ * this process holds the connection. A client of the gates service leaves it out: the gate reads
22
+ * it from the call's journal row.
23
+ */
24
+ readonly traceparent?: string;
19
25
  }
20
26
  /** A page of `tools/list`, as the MCP SDK returns it. */
21
27
  export interface McpToolPage {
@@ -73,9 +79,8 @@ export type McpToolFailure = {
73
79
  readonly message: string;
74
80
  /** True when calling again may work (R2b C7). */
75
81
  readonly retryable?: boolean;
76
- /** With `credential_rejected`: the server, and the scope of the vault whose credential was sent. */
82
+ /** With `credential_rejected`: the server. */
77
83
  readonly server?: string;
78
- readonly vault?: "installation" | "user";
79
84
  /** How many credential values the message had in it, replaced (R2b C8). */
80
85
  readonly redacted?: number;
81
86
  };
@@ -93,8 +98,8 @@ export type McpToolOutcome = {
93
98
  * - `mcp.forbidden`: the server answered `403`.
94
99
  * - `mcp.error`: the server answered a JSON-RPC error; the message has its code.
95
100
  * - `mcp.status`: the server answered another HTTP error status, without a JSON-RPC error.
96
- * - `mcp.lost`: sent, and the answer was lost, so the tool may have run. The model sees it only
97
- * for a tool the server marks read-only or idempotent (Q15); any other call is `uncertain`.
101
+ * - `mcp.lost`: sent, and the answer was lost, so the tool may have run. The model sees it, and
102
+ * decides whether to call again (R5; it replaced R2b's read-only and idempotent exception).
98
103
  * - `mcp.too-large`: the answer passed `MCP_RESULT_MAX_BYTES` (R2b C11), as an HTTP tool's
99
104
  * answer is `http.too-large`. The tool ran; its answer was not kept.
100
105
  */
@@ -110,9 +115,8 @@ export interface McpCallFailure {
110
115
  /** The request reached the server, so it may have acted on it. */
111
116
  readonly sent: boolean;
112
117
  readonly retryable: boolean;
113
- /** With `credential_rejected`: the server, and the scope of the vault whose credential was sent. */
118
+ /** With `credential_rejected`: the server. */
114
119
  readonly server?: string;
115
- readonly vault?: "installation" | "user";
116
120
  /** How many credential values the message had in it, replaced (R2b C8). */
117
121
  readonly redacted?: number;
118
122
  }
@@ -134,16 +138,16 @@ export declare class McpCallFailed extends Error {
134
138
  */
135
139
  export declare class CredentialRejected extends McpCallFailed {
136
140
  readonly server: string;
137
- /** The scope of the vault whose credential was sent; absent when none was. */
138
- readonly vault?: "installation" | "user" | undefined;
141
+ /** Whether a credential of the session's Environment was sent. */
142
+ readonly sent: boolean;
139
143
  /**
140
144
  * The answer's `WWW-Authenticate`, which may name the server's protected-resource metadata
141
145
  * (RFC 9728 `resource_metadata`): a tool preview reads it (R2b C12). Never shown to the model.
142
146
  */
143
147
  readonly challenge?: string | undefined;
144
148
  constructor(server: string,
145
- /** The scope of the vault whose credential was sent; absent when none was. */
146
- vault?: "installation" | "user" | undefined,
149
+ /** Whether a credential of the session's Environment was sent. */
150
+ sent: boolean,
147
151
  /**
148
152
  * The answer's `WWW-Authenticate`, which may name the server's protected-resource metadata
149
153
  * (RFC 9728 `resource_metadata`): a tool preview reads it (R2b C12). Never shown to the model.
@@ -162,9 +166,16 @@ export declare class McpConnectionStale extends McpCallFailed {
162
166
  }
163
167
  /** A tool call that never reached its server: its connection could not be opened. */
164
168
  export declare function unreachable(server: string, error: unknown): McpCallFailed;
169
+ /**
170
+ * Where a `tools/call` carries its key (R5.5): MCP has no standard key field, and `_meta` is the
171
+ * spec's place for extra request data. The key is the call's effect id, the same on every send,
172
+ * so a server that reads it can run the call once.
173
+ */
174
+ export declare const IDEMPOTENCY_META_KEY = "nylorun/idempotency-key";
165
175
  /**
166
176
  * An SDK `Client` as an `McpClient`. Its answers and failures carry no credential value sent
167
- * with them (R2b C8), and a failed call is an `McpCallFailed` (C7).
177
+ * with them (R2b C8), and a failed call is an `McpCallFailed` (C7). A keyed call sends its key in
178
+ * `_meta` (R5.5).
168
179
  */
169
180
  export declare function sdkClient(client: Client, serverName: string): McpClient;
170
181
  export declare function openMcpServer(input: {
@@ -191,7 +202,6 @@ export declare function serverInstructions(text: unknown, secrets: readonly stri
191
202
  * collides gets the hash suffix first.
192
203
  */
193
204
  export declare function listMcpTools(client: McpClient, input: {
194
- capabilityId: string;
195
205
  serverName: string;
196
206
  taken: Set<string>;
197
207
  signal?: AbortSignal;
@@ -212,11 +222,5 @@ export declare function listMcpTools(client: McpClient, input: {
212
222
  * be opened again (the caller retries once), and with any error that leaves the call's fate
213
223
  * unknown.
214
224
  */
215
- export declare function callMcpTool(client: McpClient, serverToolName: string, args: unknown, options?: McpCallOptions & {
216
- /**
217
- * The tool is read-only or idempotent (`McpToolRecord.annotations`): a call whose answer was
218
- * lost after it was sent is `mcp.lost` to the model. Otherwise it is left uncertain (Q15).
219
- */
220
- readonly retrySafe?: boolean;
221
- }): Promise<McpToolOutcome>;
222
- export declare function diagnosticFromError(capabilityId: string, serverName: string, error: unknown): McpDiagnostic;
225
+ export declare function callMcpTool(client: McpClient, serverToolName: string, args: unknown, options?: McpCallOptions): Promise<McpToolOutcome>;
226
+ export declare function diagnosticFromError(serverName: string, error: unknown): McpDiagnostic;
@@ -29,7 +29,7 @@ export class McpCallFailed extends Error {
29
29
  /** The failure the gate answered, as the class the loop's own call would have thrown. */
30
30
  static from(failure) {
31
31
  return failure.code === "credential_rejected" && failure.server !== undefined
32
- ? new CredentialRejected(failure.server, failure.vault)
32
+ ? new CredentialRejected(failure.server, !failure.message.includes("holds none"))
33
33
  : new McpCallFailed(failure);
34
34
  }
35
35
  /** The failed tool outcome the model sees. */
@@ -41,7 +41,6 @@ export class McpCallFailed extends Error {
41
41
  message: failure.message,
42
42
  retryable: failure.retryable,
43
43
  ...(failure.server === undefined ? {} : { server: failure.server }),
44
- ...(failure.vault === undefined ? {} : { vault: failure.vault }),
45
44
  ...(failure.redacted ? { redacted: failure.redacted } : {}),
46
45
  };
47
46
  }
@@ -54,11 +53,11 @@ export class McpCallFailed extends Error {
54
53
  */
55
54
  export class CredentialRejected extends McpCallFailed {
56
55
  server;
57
- vault;
56
+ sent;
58
57
  challenge;
59
58
  constructor(server,
60
- /** The scope of the vault whose credential was sent; absent when none was. */
61
- vault,
59
+ /** Whether a credential of the session's Environment was sent. */
60
+ sent,
62
61
  /**
63
62
  * The answer's `WWW-Authenticate`, which may name the server's protected-resource metadata
64
63
  * (RFC 9728 `resource_metadata`): a tool preview reads it (R2b C12). Never shown to the model.
@@ -66,16 +65,15 @@ export class CredentialRejected extends McpCallFailed {
66
65
  challenge) {
67
66
  super({
68
67
  code: "credential_rejected",
69
- message: vault === undefined
70
- ? `The MCP server '${server}' answered HTTP 401: it needs a credential, and the session's vaults hold none for it`
71
- : `The MCP server '${server}' answered HTTP 401: it rejected the credential from the ${vault} vault`,
68
+ message: sent
69
+ ? `The MCP server '${server}' answered HTTP 401: it rejected the credential from the session's Environment`
70
+ : `The MCP server '${server}' answered HTTP 401: it needs a credential, and the session's Environment holds none for it`,
72
71
  sent: true,
73
72
  retryable: false,
74
73
  server,
75
- ...(vault === undefined ? {} : { vault }),
76
74
  });
77
75
  this.server = server;
78
- this.vault = vault;
76
+ this.sent = sent;
79
77
  this.challenge = challenge;
80
78
  this.name = "CredentialRejected";
81
79
  }
@@ -106,18 +104,26 @@ export function unreachable(server, error) {
106
104
  }
107
105
  /** The operation a request of the transport's fetch belongs to. */
108
106
  const tracking = new AsyncLocalStorage();
109
- function tracked(call, run) {
107
+ function tracked(call, run, traceparent) {
110
108
  const tracker = {
111
109
  secrets: new Set(),
112
110
  sent: false,
113
111
  settled: false,
114
112
  ...(call ? { calling: new AbortController() } : {}),
113
+ ...(traceparent ? { traceparent } : {}),
115
114
  };
116
115
  return tracking.run(tracker, () => run(tracker));
117
116
  }
117
+ /**
118
+ * Where a `tools/call` carries its key (R5.5): MCP has no standard key field, and `_meta` is the
119
+ * spec's place for extra request data. The key is the call's effect id, the same on every send,
120
+ * so a server that reads it can run the call once.
121
+ */
122
+ export const IDEMPOTENCY_META_KEY = "nylorun/idempotency-key";
118
123
  /**
119
124
  * An SDK `Client` as an `McpClient`. Its answers and failures carry no credential value sent
120
- * with them (R2b C8), and a failed call is an `McpCallFailed` (C7).
125
+ * with them (R2b C8), and a failed call is an `McpCallFailed` (C7). A keyed call sends its key in
126
+ * `_meta` (R5.5).
121
127
  */
122
128
  export function sdkClient(client, serverName) {
123
129
  return {
@@ -133,7 +139,10 @@ export function sdkClient(client, serverName) {
133
139
  callTool: (params, options) => tracked(true, async (tracker) => {
134
140
  const lost = tracker.calling.signal;
135
141
  try {
136
- const result = (await client.callTool(params, undefined, {
142
+ const keyed = options?.key === undefined
143
+ ? params
144
+ : { ...params, _meta: { [IDEMPOTENCY_META_KEY]: options.key } };
145
+ const result = (await client.callTool(keyed, undefined, {
137
146
  signal: options?.signal ? AbortSignal.any([options.signal, lost]) : lost,
138
147
  }));
139
148
  // An answer the stream did not count (an `sse` server answers on its event stream).
@@ -151,7 +160,7 @@ export function sdkClient(client, serverName) {
151
160
  finally {
152
161
  tracker.settled = true;
153
162
  }
154
- }),
163
+ }, options?.traceparent),
155
164
  };
156
165
  }
157
166
  export async function openMcpServer(input) {
@@ -275,9 +284,7 @@ export async function listMcpTools(client, input) {
275
284
  continue;
276
285
  const { tool, inputSchema } = candidate;
277
286
  const outputSchema = tool.outputSchema ? usableSchema(tool.outputSchema) : undefined;
278
- const annotations = retryHints(tool.annotations);
279
287
  tools.push({
280
- capabilityId: input.capabilityId,
281
288
  serverName: input.serverName,
282
289
  serverToolName: tool.name,
283
290
  name,
@@ -286,7 +293,6 @@ export async function listMcpTools(client, input) {
286
293
  : {}),
287
294
  inputSchema,
288
295
  ...(outputSchema === undefined ? {} : { outputSchema }),
289
- ...(annotations === undefined ? {} : { annotations }),
290
296
  });
291
297
  }
292
298
  return { tools, omitted, renamed, disabled, unknownTools };
@@ -307,6 +313,7 @@ export async function callMcpTool(client, serverToolName, args, options = {}) {
307
313
  }, {
308
314
  ...(options.key === undefined ? {} : { key: options.key }),
309
315
  ...(options.signal ? { signal: options.signal } : {}),
316
+ ...(options.traceparent === undefined ? {} : { traceparent: options.traceparent }),
310
317
  });
311
318
  }
312
319
  catch (error) {
@@ -315,11 +322,7 @@ export async function callMcpTool(client, serverToolName, args, options = {}) {
315
322
  // The connection's to handle: its holder opens it again and sends the call once more.
316
323
  if (error instanceof McpConnectionStale)
317
324
  throw error;
318
- // Sent, then lost: the tool may have run. Calling it again is the model's choice only for a
319
- // tool the server says is safe to repeat; any other waits for an operator.
320
- if (error.code === "mcp.lost" && !options.retrySafe)
321
- throw new Error(error.message);
322
- // Otherwise the outcome is known: the model sees it.
325
+ // The model sees it, `mcp.lost` included: sent, then lost, so the tool may have run (R5).
323
326
  return error.outcome();
324
327
  }
325
328
  const { result } = answer;
@@ -349,14 +352,13 @@ function onlyText(content) {
349
352
  return (Array.isArray(content) &&
350
353
  content.every((part) => !!part && typeof part === "object" && part.type === "text"));
351
354
  }
352
- export function diagnosticFromError(capabilityId, serverName, error) {
355
+ export function diagnosticFromError(serverName, error) {
353
356
  const credentialIds = error && typeof error === "object" && "credentialIds" in error
354
357
  ? error.credentialIds
355
358
  : undefined;
356
359
  const refused = error instanceof Error && error.message.startsWith("MCP authorization refused");
357
360
  if (refused) {
358
361
  return {
359
- capabilityId,
360
362
  serverName,
361
363
  outcome: "refused",
362
364
  message: error.message,
@@ -370,7 +372,6 @@ export function diagnosticFromError(capabilityId, serverName, error) {
370
372
  code === 401 ||
371
373
  (error instanceof Error && /\b401\b/.test(error.message));
372
374
  return {
373
- capabilityId,
374
375
  serverName,
375
376
  outcome: "failed",
376
377
  message: unauthorized
@@ -418,6 +419,9 @@ function authorizedFetch(server, endpoint, authorize, policy) {
418
419
  for (const [key, value] of Object.entries(result.headers))
419
420
  headers.set(key, value);
420
421
  const tracker = tracking.getStore();
422
+ // The tool call's span (R7.4): per request, so a pooled connection carries each call's own.
423
+ if (tracker?.traceparent)
424
+ headers.set("traceparent", tracker.traceparent);
421
425
  if (tracker && result.status === "authorized")
422
426
  for (const secret of credentialSecrets(result.headers, result.identity))
423
427
  tracker.secrets.add(secret);
@@ -436,7 +440,7 @@ function authorizedFetch(server, endpoint, authorize, policy) {
436
440
  tracker.sent = true;
437
441
  if (response.status === 401) {
438
442
  await response.body?.cancel().catch(() => undefined);
439
- throw new CredentialRejected(server.name, result.status === "authorized" ? result.vault : undefined, response.headers.get("www-authenticate") ?? undefined);
443
+ throw new CredentialRejected(server.name, result.status === "authorized", response.headers.get("www-authenticate") ?? undefined);
440
444
  }
441
445
  // The server ended the connection's session: the tool never saw the request.
442
446
  if (post && response.status === 404 && headers.has("mcp-session-id")) {
@@ -622,14 +626,6 @@ function rpcErrorOf(body) {
622
626
  }
623
627
  return undefined;
624
628
  }
625
- /** The hints that calling a tool again is safe, when the server gives any. */
626
- function retryHints(annotations) {
627
- const readOnly = annotations?.readOnlyHint === true;
628
- const idempotent = annotations?.idempotentHint === true;
629
- if (!readOnly && !idempotent)
630
- return undefined;
631
- return { ...(readOnly ? { readOnlyHint: true } : {}), ...(idempotent ? { idempotentHint: true } : {}) };
632
- }
633
629
  function sameOrigin(requestUrl, serverUrl) {
634
630
  try {
635
631
  return new URL(requestUrl).origin === new URL(serverUrl).origin;
@@ -51,15 +51,14 @@ export declare class McpPool {
51
51
  call(input: {
52
52
  sessionId: string;
53
53
  agentId?: string;
54
- capabilityId: string;
55
54
  serverName: string;
56
55
  serverToolName: string;
57
56
  args: unknown;
58
57
  manifest: AgentManifest;
59
58
  /** The effect id: a gate runs the call once under it (F4.1). */
60
59
  effectId?: string;
61
- /** The tool is read-only or idempotent: a lost answer is the model's to retry (R2b C7). */
62
- retrySafe?: boolean;
60
+ /** The call's span context (R7.4), sent as `traceparent` on a connection this process holds. */
61
+ traceparent?: string;
63
62
  signal?: AbortSignal;
64
63
  }): Promise<McpToolOutcome>;
65
64
  /** The session's connection to the server, opened when there is none, or why it cannot be. */
@@ -85,7 +84,6 @@ export interface McpServerRef {
85
84
  readonly sessionId: string;
86
85
  /** The agent used as a tool that declares the server; absent for the session's root agent. */
87
86
  readonly agentId?: string;
88
- readonly capabilityId: string;
89
87
  readonly serverName: string;
90
88
  }
91
89
  export interface DeclaredServer {
@@ -93,9 +91,8 @@ export interface DeclaredServer {
93
91
  readonly agentId?: string;
94
92
  /** The manifest of the agent that declares the server. */
95
93
  readonly manifest: AgentManifest;
96
- readonly capabilityId: string;
97
94
  readonly server: McpServerManifest;
98
95
  }
99
96
  /** Servers of the root agent, then of each agent it uses as a tool. */
100
97
  export declare function serversOf(manifest: AgentManifest): DeclaredServer[];
101
- export declare function findServer(manifest: AgentManifest, agentId: string | undefined, capabilityId: string, serverName: string): DeclaredServer | undefined;
98
+ export declare function findServer(manifest: AgentManifest, agentId: string | undefined, serverName: string): DeclaredServer | undefined;
package/dist/mcp/pool.js CHANGED
@@ -34,7 +34,6 @@ export class McpPool {
34
34
  if (!taken.has(declared.agentId))
35
35
  taken.set(declared.agentId, declaredToolNames(declared.manifest));
36
36
  const listed = await listMcpTools(opened.connection.client, {
37
- capabilityId: declared.capabilityId,
38
37
  serverName: declared.server.name,
39
38
  taken: taken.get(declared.agentId),
40
39
  server: declared.server,
@@ -43,13 +42,11 @@ export class McpPool {
43
42
  tools.push(...listed.tools.map((tool) => owned(declared, tool)));
44
43
  if (opened.connection.instructions)
45
44
  notes.push(owned(declared, {
46
- capabilityId: declared.capabilityId,
47
45
  serverName: declared.server.name,
48
46
  instructions: opened.connection.instructions,
49
47
  }));
50
48
  diagnostics.push({
51
49
  ...ownerOf(declared),
52
- capabilityId: declared.capabilityId,
53
50
  serverName: declared.server.name,
54
51
  outcome: "connected",
55
52
  message: [
@@ -67,7 +64,7 @@ export class McpPool {
67
64
  }
68
65
  catch (error) {
69
66
  await opened.connection.close().catch(() => { });
70
- diagnostics.push(owned(declared, diagnosticFromError(declared.capabilityId, declared.server.name, error)));
67
+ diagnostics.push(owned(declared, diagnosticFromError(declared.server.name, error)));
71
68
  }
72
69
  }
73
70
  return {
@@ -84,7 +81,7 @@ export class McpPool {
84
81
  const diagnostics = [];
85
82
  const seen = new Set();
86
83
  for (const tool of input.tools) {
87
- const key = this.liveKey(input.sessionId, tool.agentId, tool.capabilityId, tool.serverName);
84
+ const key = this.liveKey(input.sessionId, tool.agentId, tool.serverName);
88
85
  if (seen.has(key))
89
86
  continue;
90
87
  seen.add(key);
@@ -95,11 +92,10 @@ export class McpPool {
95
92
  continue;
96
93
  }
97
94
  input.signal?.throwIfAborted();
98
- const declared = findServer(input.manifest, tool.agentId, tool.capabilityId, tool.serverName);
95
+ const declared = findServer(input.manifest, tool.agentId, tool.serverName);
99
96
  if (!declared) {
100
97
  diagnostics.push({
101
98
  ...(tool.agentId === undefined ? {} : { agentId: tool.agentId }),
102
- capabilityId: tool.capabilityId,
103
99
  serverName: tool.serverName,
104
100
  outcome: "failed",
105
101
  message: "Declared MCP server is missing from the pinned manifest",
@@ -116,7 +112,7 @@ export class McpPool {
116
112
  return diagnostics;
117
113
  }
118
114
  async call(input) {
119
- const key = this.liveKey(input.sessionId, input.agentId, input.capabilityId, input.serverName);
115
+ const key = this.liveKey(input.sessionId, input.agentId, input.serverName);
120
116
  for (let attempt = 0;; attempt += 1) {
121
117
  const live = await this.liveFor(input, key);
122
118
  // No connection, so no call was sent: the model sees why, a 401 included (R2b C1, C7).
@@ -126,8 +122,8 @@ export class McpPool {
126
122
  try {
127
123
  return await callMcpTool(live.connection.client, input.serverToolName, input.args, {
128
124
  ...(input.effectId === undefined ? {} : { key: input.effectId }),
129
- ...(input.retrySafe ? { retrySafe: true } : {}),
130
125
  ...(input.signal ? { signal: input.signal } : {}),
126
+ ...(input.traceparent === undefined ? {} : { traceparent: input.traceparent }),
131
127
  });
132
128
  }
133
129
  catch (error) {
@@ -152,7 +148,7 @@ export class McpPool {
152
148
  const live = this.live.get(key);
153
149
  if (live)
154
150
  return live;
155
- const declared = findServer(input.manifest, input.agentId, input.capabilityId, input.serverName);
151
+ const declared = findServer(input.manifest, input.agentId, input.serverName);
156
152
  if (!declared)
157
153
  throw new Error(`MCP server '${input.serverName}' is not declared`);
158
154
  let opening = this.opening.get(key);
@@ -196,7 +192,7 @@ export class McpPool {
196
192
  }
197
193
  /** Keeps the connection, or closes it when the server is already connected for the session. */
198
194
  remember(sessionId, declared, connection) {
199
- const key = this.liveKey(sessionId, declared.agentId, declared.capabilityId, declared.server.name);
195
+ const key = this.liveKey(sessionId, declared.agentId, declared.server.name);
200
196
  const existing = this.live.get(key);
201
197
  if (existing) {
202
198
  if (existing.connection !== connection)
@@ -204,7 +200,6 @@ export class McpPool {
204
200
  return existing;
205
201
  }
206
202
  const live = {
207
- capabilityId: declared.capabilityId,
208
203
  serverName: declared.server.name,
209
204
  connection,
210
205
  lastUsedAt: this.now(),
@@ -213,8 +208,8 @@ export class McpPool {
213
208
  this.live.set(key, live);
214
209
  return live;
215
210
  }
216
- liveKey(sessionId, agentId, capabilityId, serverName) {
217
- return JSON.stringify([sessionId, agentId ?? null, capabilityId, serverName]);
211
+ liveKey(sessionId, agentId, serverName) {
212
+ return JSON.stringify([sessionId, agentId ?? null, serverName]);
218
213
  }
219
214
  async connectDeclared(input, declared) {
220
215
  try {
@@ -222,7 +217,6 @@ export class McpPool {
222
217
  const connection = await this.options.openRemote({
223
218
  sessionId: input.sessionId,
224
219
  ...ownerOf(declared),
225
- capabilityId: declared.capabilityId,
226
220
  serverName: declared.server.name,
227
221
  });
228
222
  return { ok: true, connection };
@@ -242,7 +236,7 @@ export class McpPool {
242
236
  return {
243
237
  ok: false,
244
238
  error,
245
- diagnostic: owned(declared, diagnosticFromError(declared.capabilityId, declared.server.name, error)),
239
+ diagnostic: owned(declared, diagnosticFromError(declared.server.name, error)),
246
240
  };
247
241
  }
248
242
  }
@@ -251,24 +245,16 @@ export class McpPool {
251
245
  export function serversOf(manifest) {
252
246
  const servers = [];
253
247
  const add = (agent, agentId) => {
254
- for (const capability of agent.capabilities)
255
- for (const server of Object.values(capability.mcpServers ?? {}))
256
- servers.push({
257
- ...(agentId === undefined ? {} : { agentId }),
258
- manifest: agent,
259
- capabilityId: capability.id,
260
- server,
261
- });
248
+ for (const server of Object.values(agent.mcpServers ?? {}))
249
+ servers.push({ ...(agentId === undefined ? {} : { agentId }), manifest: agent, server });
262
250
  };
263
251
  add(manifest);
264
252
  for (const child of delegatesOf(manifest))
265
253
  add(child.manifest, child.manifest.id);
266
254
  return servers;
267
255
  }
268
- export function findServer(manifest, agentId, capabilityId, serverName) {
269
- return serversOf(manifest).find((item) => item.agentId === agentId &&
270
- item.capabilityId === capabilityId &&
271
- item.server.name === serverName);
256
+ export function findServer(manifest, agentId, serverName) {
257
+ return serversOf(manifest).find((item) => item.agentId === agentId && item.server.name === serverName);
272
258
  }
273
259
  function ownerOf(declared) {
274
260
  return declared.agentId === undefined ? {} : { agentId: declared.agentId };
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * A remote MCP server's tools before an agent names it (R2b C12, `POST /v1/tenant/mcp/preview`,
3
- * `nylorun mcp inspect`, Studio's Credentials page). It runs where plaintext credentials live:
3
+ * `nylorun mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
4
4
  * the keys service (`keys/keys.ts`, `previewMcp`), in the gateway or in process.
5
5
  *
6
- * One connection: `initialize` and `tools/list` with the installation vault's credential for the
6
+ * One connection: `initialize` and `tools/list` with the Environment's credential for the
7
7
  * URL (its headers, and its `via`), under the Host's address policy, within 15 s; then it closes.
8
8
  * It never calls a tool, and sends no identity header: no person asked. A server that answers
9
9
  * `401` is `authRequired`, with its RFC 9728 protected-resource metadata when it publishes any,
@@ -16,7 +16,7 @@ import { openMcpServer } from "./connect.js";
16
16
  /** How long a preview may take, `initialize` and every `tools/list` page together. */
17
17
  export declare const MCP_PREVIEW_TIMEOUT_MS = 15000;
18
18
  export interface McpPreviewOptions {
19
- readonly vault: Pick<VaultService, "authorize" | "getVault" | "listVaults">;
19
+ readonly vault: Pick<VaultService, "authorize" | "listEnvironmentSecrets">;
20
20
  /** The Host's address policy for developer URLs (`TenantConfig.delivery`). */
21
21
  readonly policy: OutboundPolicy;
22
22
  /** Default `MCP_PREVIEW_TIMEOUT_MS`. */
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * A remote MCP server's tools before an agent names it (R2b C12, `POST /v1/tenant/mcp/preview`,
3
- * `nylorun mcp inspect`, Studio's Credentials page). It runs where plaintext credentials live:
3
+ * `nylorun mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
4
4
  * the keys service (`keys/keys.ts`, `previewMcp`), in the gateway or in process.
5
5
  *
6
- * One connection: `initialize` and `tools/list` with the installation vault's credential for the
6
+ * One connection: `initialize` and `tools/list` with the Environment's credential for the
7
7
  * URL (its headers, and its `via`), under the Host's address policy, within 15 s; then it closes.
8
8
  * It never calls a tool, and sends no identity header: no person asked. A server that answers
9
9
  * `401` is `authRequired`, with its RFC 9728 protected-resource metadata when it publishes any,
10
10
  * read under the same policy. No credential value sent is in the answer (`scrubValues`, C8).
11
11
  */
12
- import { INSTALLATION_OWNER, McpPreviewRequestSchema, } from "@nylorun/core/contracts";
12
+ import { McpPreviewRequestSchema, } from "@nylorun/core/contracts";
13
13
  import { scrubValues } from "../redact.js";
14
14
  import { HttpError } from "../tenant/http.js";
15
15
  import { guardedFetch, OutboundRefused } from "../tenant/outbound.js";
@@ -72,7 +72,6 @@ export async function previewMcpServer(body, options) {
72
72
  callTool: () => Promise.reject(new Error("A preview never calls a tool")),
73
73
  };
74
74
  const listed = await listMcpTools(listing, {
75
- capabilityId: "preview",
76
75
  serverName: name,
77
76
  taken: new Set(),
78
77
  signal,
@@ -119,28 +118,18 @@ export async function previewMcpServer(body, options) {
119
118
  }
120
119
  }
121
120
  /**
122
- * The installation vault credential for the URL: from `vaultId`, else from every installation
123
- * vault. None is a preview without one; two or more without `vaultId` is a refusal that names
124
- * them.
121
+ * The credential of Environment `environmentId`'s vault for the URL; none without an
122
+ * Environment (a preview without a credential). An Environment that does not exist is a 404.
125
123
  */
126
124
  async function credentialFor(vault, request) {
127
- let vaultIds;
128
- if (request.vaultId !== undefined) {
129
- const found = await vault.getVault(request.vaultId);
130
- if (found.ownerUserId !== INSTALLATION_OWNER)
131
- throw new VaultError(400, "A preview uses an installation vault's credential: no person asked for it");
132
- vaultIds = [found.id];
133
- }
134
- else
135
- vaultIds = (await vault.listVaults(undefined, { installation: true })).map((found) => found.id);
136
- if (vaultIds.length === 0)
125
+ if (request.environmentId === undefined)
137
126
  return { status: "unauthenticated", url: request.url, headers: {} };
138
- const result = await vault.authorize({ vaultIds, credentialSelections: [], url: request.url });
127
+ // The 404 of a missing Environment, before any request leaves.
128
+ await vault.listEnvironmentSecrets(request.environmentId);
129
+ const result = await vault.authorize({ environmentId: request.environmentId, url: request.url });
139
130
  if (result.status !== "refused")
140
131
  return result;
141
- throw new HttpError(409, result.reason === "ambiguous"
142
- ? "Several installation vaults hold a credential for this URL: name one with vaultId"
143
- : `The installation vault's credential for this URL cannot be used (${result.reason})`, { code: "request_rejected", details: { reason: result.reason, credentialIds: result.credentialIds } });
132
+ throw new HttpError(409, `Environment ${request.environmentId}'s credential for this URL cannot be used (${result.reason})`, { code: "request_rejected", details: { reason: result.reason, credentialIds: result.credentialIds } });
144
133
  }
145
134
  /** A preview that listed nothing: `mcp_preview_failed`, with the code a tool call would have had. */
146
135
  function failed(server, error, signal, secrets, timeoutMs) {