apps 0.0.1-beta.9 → 0.0.1-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 (191) hide show
  1. package/README.md +56 -38
  2. package/framework-reference.json +1 -1
  3. package/js/chunk-3LEVTFD4.js +712 -0
  4. package/js/chunk-5FHWNLCI.js +88 -0
  5. package/js/{chunk-FL2QR3XW.js → chunk-5MDA7MKL.js} +338 -73
  6. package/js/chunk-6XQLA5NC.js +5047 -0
  7. package/js/{chunk-M3B3DE4K.js → chunk-74YVXBKY.js} +463 -218
  8. package/js/chunk-7PHHWYV4.js +335 -0
  9. package/js/chunk-DADXWWRZ.js +449 -0
  10. package/js/{chunk-27F7W2LG.js → chunk-DDHBUKXX.js} +18 -2
  11. package/js/{chunk-UK573G7W.js → chunk-EOPQ727L.js} +87 -51
  12. package/js/{chunk-5T57N25Q.js → chunk-GQ33QSNB.js} +583 -69
  13. package/js/{chunk-JU7VHODU.js → chunk-H72MEDMN.js} +65 -10
  14. package/js/chunk-I5C7FD5Z.js +171 -0
  15. package/js/{chunk-CDL5PM2Q.js → chunk-IFJU5SYQ.js} +19082 -18402
  16. package/js/{chunk-VFZKSM3T.js → chunk-JPEUKEV4.js} +3 -3
  17. package/js/{chunk-KUMBKVJD.js → chunk-KLYSEHUD.js} +2 -2
  18. package/js/{chunk-RFVIONFX.js → chunk-KUCCHNVY.js} +123 -44
  19. package/js/chunk-OD3KFKZD.js +1617 -0
  20. package/js/{chunk-57RKNWL2.js → chunk-PD6I2SDG.js} +4 -4
  21. package/js/{chunk-72JNVHPK.js → chunk-PYQLOLOC.js} +4 -3
  22. package/js/{chunk-ODEIDRGW.js → chunk-QWQM3CLH.js} +795 -176
  23. package/js/{chunk-IJX4CYZO.js → chunk-TUMGL2OC.js} +228 -264
  24. package/js/{chunk-IPI4MFSN.js → chunk-XBG7HHXC.js} +2 -2
  25. package/js/chunk-XPRZTLHD.js +1915 -0
  26. package/js/chunk-YNJ5CZMJ.js +93 -0
  27. package/js/chunk-YRGL4QEF.js +49 -0
  28. package/js/{chunk-Z5M2LQOZ.js → chunk-YWFUWTUJ.js} +113 -58
  29. package/js/client.js +142 -78
  30. package/js/contracts.js +142 -21
  31. package/js/effect.js +18 -19
  32. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  33. package/js/graphql.js +49 -40
  34. package/js/host.js +85 -62
  35. package/js/index.js +165 -70
  36. package/js/mcp/effect.js +21 -21
  37. package/js/mcp.js +76 -56
  38. package/js/openapi.js +4189 -1411
  39. package/js/react.js +2 -3
  40. package/js/skills/effect.js +6 -3
  41. package/js/skills.js +208 -81
  42. package/js/storage/facet.js +1 -540
  43. package/js/ui/auth/contracts.js +2 -2
  44. package/js/ui/auth.js +5 -5
  45. package/js/ui/contracts.js +5 -4
  46. package/js/ui/serving.js +8605 -225
  47. package/package.json +3 -8
  48. package/runtime.json +1 -1
  49. package/types/app-cache/src/contracts/cache.d.ts +18 -0
  50. package/types/app-cache/src/index.d.ts +34 -2
  51. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  52. package/types/apps/src/contracts/app.d.ts +60 -11
  53. package/types/apps/src/contracts/cache.d.ts +20 -0
  54. package/types/apps/src/contracts/context.d.ts +60 -17
  55. package/types/apps/src/contracts/elicitation.d.ts +23 -7
  56. package/types/apps/src/contracts/events.d.ts +94 -0
  57. package/types/apps/src/contracts/failure.d.ts +30 -1
  58. package/types/apps/src/contracts/graphql.d.ts +2 -1
  59. package/types/apps/src/contracts/host.d.ts +1446 -17
  60. package/types/apps/src/contracts/icons.d.ts +28 -0
  61. package/types/apps/src/contracts/live.d.ts +2 -0
  62. package/types/apps/src/contracts/mcp.d.ts +81 -20
  63. package/types/apps/src/contracts/network.d.ts +120 -0
  64. package/types/apps/src/contracts/openapi-compile.d.ts +82 -3
  65. package/types/apps/src/contracts/openapi.d.ts +41 -9
  66. package/types/apps/src/contracts/operations.d.ts +14 -7
  67. package/types/apps/src/contracts/placement.d.ts +102 -0
  68. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  69. package/types/apps/src/contracts/protocols/1.d.ts +733 -81
  70. package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
  71. package/types/apps/src/contracts/protocols/11.d.ts +1149 -0
  72. package/types/apps/src/contracts/protocols/12.d.ts +3310 -0
  73. package/types/apps/src/contracts/protocols/2.d.ts +69 -26
  74. package/types/apps/src/contracts/protocols/3.d.ts +133 -33
  75. package/types/apps/src/contracts/protocols/4.d.ts +122 -45
  76. package/types/apps/src/contracts/protocols/5.d.ts +157 -47
  77. package/types/apps/src/contracts/protocols/6.d.ts +1629 -0
  78. package/types/apps/src/contracts/protocols/7.d.ts +1785 -0
  79. package/types/apps/src/contracts/protocols/8.d.ts +1182 -0
  80. package/types/apps/src/contracts/protocols/9.d.ts +1104 -0
  81. package/types/apps/src/contracts/protocols/current.d.ts +6669 -0
  82. package/types/apps/src/contracts/protocols/oauth-6.d.ts +74 -0
  83. package/types/apps/src/contracts/protocols/oauth.d.ts +134 -0
  84. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  85. package/types/apps/src/contracts/provider.d.ts +90 -6
  86. package/types/apps/src/contracts/schedules.d.ts +7 -1
  87. package/types/apps/src/contracts/schema.d.ts +21 -0
  88. package/types/apps/src/contracts/skills.d.ts +50 -13
  89. package/types/apps/src/contracts/sql.d.ts +63 -0
  90. package/types/apps/src/contracts/ui.d.ts +44 -14
  91. package/types/apps/src/contracts/webhooks.d.ts +24 -7
  92. package/types/apps/src/contracts/workflows.d.ts +19 -17
  93. package/types/apps/src/facet.d.ts +4 -5
  94. package/types/apps/src/host.d.ts +5 -0
  95. package/types/apps/src/implementation/account-router.d.ts +4 -3
  96. package/types/apps/src/implementation/app.d.ts +41 -14
  97. package/types/apps/src/implementation/authoring.d.ts +25 -5
  98. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  99. package/types/apps/src/implementation/cache.d.ts +29 -2
  100. package/types/apps/src/implementation/catalog-cache.d.ts +35 -4
  101. package/types/apps/src/implementation/elicitation.d.ts +18 -15
  102. package/types/apps/src/implementation/events.d.ts +64 -0
  103. package/types/apps/src/implementation/failure-detail.d.ts +28 -5
  104. package/types/apps/src/implementation/graphql-catalog.d.ts +3 -3
  105. package/types/apps/src/implementation/graphql.d.ts +4 -3
  106. package/types/apps/src/implementation/input-problems.d.ts +6 -2
  107. package/types/apps/src/implementation/invocation-timing.d.ts +18 -0
  108. package/types/apps/src/implementation/live.d.ts +2 -2
  109. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  110. package/types/apps/src/implementation/mcp-catalog.d.ts +6 -4
  111. package/types/apps/src/implementation/mcp-client.d.ts +17 -9
  112. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  113. package/types/apps/src/implementation/mcp.d.ts +20 -9
  114. package/types/apps/src/implementation/network.d.ts +16 -0
  115. package/types/apps/src/implementation/openapi-compile.d.ts +28 -7
  116. package/types/apps/src/implementation/openapi-document.d.ts +46 -19
  117. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  118. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  119. package/types/apps/src/implementation/openapi-source.d.ts +23 -1
  120. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  121. package/types/apps/src/implementation/operations.d.ts +57 -7
  122. package/types/apps/src/implementation/optimistic.d.ts +1 -1
  123. package/types/apps/src/implementation/placement.d.ts +60 -0
  124. package/types/apps/src/implementation/protocol-operations.d.ts +3 -0
  125. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  126. package/types/apps/src/implementation/provider.d.ts +19 -4
  127. package/types/apps/src/implementation/query-commit.d.ts +1 -1
  128. package/types/apps/src/implementation/router-catalog.d.ts +20 -18
  129. package/types/apps/src/implementation/router.d.ts +24 -5
  130. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  131. package/types/apps/src/implementation/schedules.d.ts +39 -8
  132. package/types/apps/src/implementation/schema.d.ts +98 -11
  133. package/types/apps/src/implementation/skills.d.ts +18 -24
  134. package/types/apps/src/implementation/sql.d.ts +71 -0
  135. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  136. package/types/apps/src/implementation/ui-auth.d.ts +1 -1
  137. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  138. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  139. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  140. package/types/apps/src/implementation/ui-serving.d.ts +26 -9
  141. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  142. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  143. package/types/apps/src/implementation/webhooks.d.ts +15 -6
  144. package/types/apps/src/implementation/workflow-context.d.ts +6 -2
  145. package/types/apps/src/implementation/workflows.d.ts +11 -4
  146. package/types/apps/src/index.d.ts +68 -19
  147. package/types/apps/src/mcp.d.ts +20 -1
  148. package/types/apps/src/openapi.d.ts +6 -1
  149. package/types/apps/src/react.d.ts +1 -1
  150. package/types/apps/src/skills.d.ts +10 -8
  151. package/types/apps/src/ui-serving.d.ts +1 -1
  152. package/types/telemetry/src/app-records.d.ts +42 -0
  153. package/types/telemetry/src/browser-operations.d.ts +2 -2
  154. package/types/telemetry/src/browser.d.ts +8 -3
  155. package/types/telemetry/src/config.d.ts +2 -2
  156. package/types/telemetry/src/index.d.ts +2 -1
  157. package/types/telemetry/src/layer.d.ts +10 -4
  158. package/types/telemetry/src/measurements.d.ts +1 -1
  159. package/types/telemetry/src/ownership.d.ts +60 -0
  160. package/types/telemetry/src/recorded-failure.d.ts +29 -0
  161. package/types/telemetry/src/relay.d.ts +16 -6
  162. package/types/telemetry/src/span-attributes.d.ts +17 -1
  163. package/types/telemetry/src/transport.d.ts +8 -1
  164. package/types/utils/src/api-error.d.ts +55 -0
  165. package/types/utils/src/connection-failure.d.ts +33 -0
  166. package/types/utils/src/recorded-message.d.ts +18 -0
  167. package/types/utils/src/user-facing-error.d.ts +83 -0
  168. package/js/chunk-7EK2JDX4.js +0 -299
  169. package/js/chunk-IKS2C5MQ.js +0 -224
  170. package/js/chunk-MKWZPDR6.js +0 -63
  171. package/js/chunk-N7YDVXYJ.js +0 -186
  172. package/js/chunk-NKLWZJLE.js +0 -172
  173. package/js/chunk-PJJ24GU7.js +0 -877
  174. package/js/chunk-PZB6T6KU.js +0 -19
  175. package/js/chunk-R3EV5FTO.js +0 -97
  176. package/js/chunk-SJFZCGXG.js +0 -1243
  177. package/js/chunk-WLE7WX2U.js +0 -2645
  178. package/js/chunk-YXQHV65J.js +0 -242
  179. package/js/chunk-ZQINWV4W.js +0 -630
  180. package/js/mcp/stdio.js +0 -128
  181. package/types/app-data/src/implementation/cursor.d.ts +0 -10
  182. package/types/app-data/src/implementation/index-key.d.ts +0 -7
  183. package/types/app-data/src/implementation/promise.d.ts +0 -68
  184. package/types/app-data/src/implementation/range.d.ts +0 -8
  185. package/types/app-data/src/implementation/schema.d.ts +0 -18
  186. package/types/app-data/src/implementation/sqlite.d.ts +0 -11
  187. package/types/app-data/src/index.d.ts +0 -4
  188. package/types/apps/src/contracts/storage.d.ts +0 -68
  189. package/types/apps/src/implementation/mcp-stdio.d.ts +0 -4
  190. package/types/apps/src/implementation/storage.d.ts +0 -15
  191. package/types/apps/src/mcp-stdio.d.ts +0 -5
@@ -0,0 +1,712 @@
1
+ import {
2
+ prepareElicitation
3
+ } from "./chunk-XPRZTLHD.js";
4
+ import {
5
+ failOnNetworkRefusal
6
+ } from "./chunk-YRGL4QEF.js";
7
+ import {
8
+ accountProviderError,
9
+ bodyUpstreamError,
10
+ fromPromise,
11
+ httpProviderError,
12
+ providerErrorDetail
13
+ } from "./chunk-I5C7FD5Z.js";
14
+ import {
15
+ ElicitationFailed,
16
+ McpCredentialsUnverified,
17
+ McpError,
18
+ McpHealthInput,
19
+ McpServerHeader,
20
+ McpToolMetadata,
21
+ McpToolResult,
22
+ McpToolsOptions,
23
+ NetworkRefused,
24
+ ProviderError,
25
+ RouterIcon,
26
+ ToolResultObservation,
27
+ defaultElicitationLimits,
28
+ defaultMcpClientLimits,
29
+ mcpHealthReserveMs,
30
+ mcpSdkTimerCeilingMs
31
+ } from "./chunk-6XQLA5NC.js";
32
+ import {
33
+ jsonSchemaDecoder,
34
+ nestJsonSchema,
35
+ preparedJsonSchemaDecoder
36
+ } from "./chunk-GQ33QSNB.js";
37
+ import {
38
+ captureTelemetry,
39
+ owned
40
+ } from "./chunk-QWQM3CLH.js";
41
+ import {
42
+ FetchHttpClient_exports
43
+ } from "./chunk-PD6I2SDG.js";
44
+ import {
45
+ JsonObject
46
+ } from "./chunk-DDHBUKXX.js";
47
+ import {
48
+ HttpClientRequest_exports,
49
+ HttpClient_exports
50
+ } from "./chunk-EOPQ727L.js";
51
+ import {
52
+ Clock_exports,
53
+ Deferred_exports,
54
+ Effect_exports,
55
+ Exit_exports,
56
+ Match_exports,
57
+ Option_exports,
58
+ Predicate_exports,
59
+ Queue_exports,
60
+ Redacted_exports,
61
+ Ref_exports,
62
+ Schema_exports,
63
+ Stream_exports
64
+ } from "./chunk-IFJU5SYQ.js";
65
+
66
+ // src/implementation/mcp.ts
67
+ import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
68
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
69
+ import {
70
+ ErrorCode as ErrorCode3,
71
+ McpError as ProtocolError3,
72
+ ToolListChangedNotificationSchema
73
+ } from "@modelcontextprotocol/sdk/types.js";
74
+ import { SSEClientTransport, SseError } from "@modelcontextprotocol/sdk/client/sse.js";
75
+ import {
76
+ StreamableHTTPClientTransport,
77
+ StreamableHTTPError
78
+ } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
79
+
80
+ // src/implementation/mcp-tools.ts
81
+ var resultFields = {
82
+ content: { type: "array", items: { type: "object" } },
83
+ structuredContent: { type: "object" },
84
+ isError: { type: "boolean" },
85
+ _meta: { type: "object" }
86
+ };
87
+ var definitionReference = /^#\/(?:\$defs|definitions)\/[^/]+$/;
88
+ var locating = /* @__PURE__ */ new Set(["$id", "$anchor", "$dynamicAnchor", "$recursiveAnchor"]);
89
+ var onlyDefinitionReferences = (value) => Array.isArray(value) ? value.every(onlyDefinitionReferences) : value === null || typeof value !== "object" ? true : Object.entries(value).every(
90
+ ([key, item]) => locating.has(key) || key === "$dynamicRef" || key === "$recursiveRef" ? false : key === "$ref" ? typeof item === "string" && definitionReference.test(item) : onlyDefinitionReferences(item)
91
+ );
92
+ var placed = (structuredContent, pointer) => {
93
+ if (onlyDefinitionReferences(structuredContent)) {
94
+ const { $defs, definitions, $schema: _draft, ...schema } = structuredContent;
95
+ return {
96
+ schema,
97
+ root: {
98
+ ...$defs === void 0 ? {} : { $defs },
99
+ ...definitions === void 0 ? {} : { definitions }
100
+ }
101
+ };
102
+ }
103
+ try {
104
+ return { schema: nestJsonSchema(structuredContent, pointer), root: {} };
105
+ } catch {
106
+ return { schema: structuredContent, root: {} };
107
+ }
108
+ };
109
+ var resultSchema = (structuredContent) => {
110
+ if (structuredContent === void 0)
111
+ return { type: "object", properties: resultFields, required: ["content"] };
112
+ const { schema, root } = placed(structuredContent, "#/anyOf/0/properties/structuredContent");
113
+ return {
114
+ // The envelope's keywords mean the same in every draft, so the server's draft applies.
115
+ ...structuredContent.$schema === void 0 ? {} : { $schema: structuredContent.$schema },
116
+ ...root,
117
+ anyOf: [
118
+ {
119
+ type: "object",
120
+ properties: { ...resultFields, structuredContent: schema, isError: { const: false } },
121
+ required: ["content", "structuredContent"]
122
+ },
123
+ {
124
+ type: "object",
125
+ properties: { ...resultFields, isError: { const: true } },
126
+ required: ["content", "isError"]
127
+ }
128
+ ]
129
+ };
130
+ };
131
+ var adaptMcpTool = (client, tool) => Effect_exports.gen(function* () {
132
+ const decoder = yield* jsonSchemaDecoder(tool.inputSchema).pipe(
133
+ Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
134
+ );
135
+ const output = preparedJsonSchemaDecoder(resultSchema(tool.outputSchema));
136
+ const { outputSchema: _upstream, ...metadata } = tool;
137
+ const adapted = {
138
+ ...metadata,
139
+ description: tool.description ?? tool.title ?? tool.name,
140
+ input: decoder,
141
+ output: output.decoder,
142
+ ...tool.annotations?.readOnlyHint === void 0 ? {} : { readOnly: tool.annotations.readOnlyHint },
143
+ run: (context, input) => Effect_exports.gen(function* () {
144
+ const arguments_ = yield* Schema_exports.decodeUnknownEffect(decoder)(input).pipe(
145
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonObject)),
146
+ Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_input" }))
147
+ );
148
+ yield* output.compile.pipe(
149
+ Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
150
+ );
151
+ const result = yield* client.call(tool.name, arguments_, context);
152
+ if (result.isError === true) {
153
+ (yield* ToolResultObservation).failed();
154
+ yield* Effect_exports.annotateCurrentSpan({
155
+ "executor.outcome": "failed",
156
+ "error.type": "McpToolError"
157
+ });
158
+ }
159
+ return result;
160
+ })
161
+ };
162
+ return adapted;
163
+ });
164
+ var adaptMcpTools = (client) => Effect_exports.gen(function* () {
165
+ const { tools: metadata } = yield* client.list;
166
+ const entries = yield* Effect_exports.forEach(
167
+ metadata,
168
+ (tool) => adaptMcpTool(client, tool).pipe(Effect_exports.map((adapted) => [tool.name, adapted]))
169
+ );
170
+ return Object.fromEntries(entries);
171
+ });
172
+
173
+ // src/implementation/mcp-client.ts
174
+ import {
175
+ ErrorCode as ErrorCode2,
176
+ ListToolsResultSchema,
177
+ McpError as ProtocolError2
178
+ } from "@modelcontextprotocol/sdk/types.js";
179
+
180
+ // src/implementation/mcp-call.ts
181
+ import {
182
+ ElicitRequestSchema,
183
+ ElicitResultSchema,
184
+ ErrorCode,
185
+ McpError as ProtocolError
186
+ } from "@modelcontextprotocol/sdk/types.js";
187
+ function callBudget(timeoutMs) {
188
+ return Effect_exports.gen(function* () {
189
+ const clock = yield* Clock_exports.Clock;
190
+ const changes = yield* Queue_exports.unbounded();
191
+ let remaining = timeoutMs, updated = clock.currentTimeMillisUnsafe(), waiting = 0;
192
+ const account = () => {
193
+ const now = clock.currentTimeMillisUnsafe();
194
+ if (waiting === 0) remaining -= Math.max(0, now - updated);
195
+ updated = now;
196
+ return remaining;
197
+ };
198
+ return {
199
+ waitForInput: (input) => Effect_exports.acquireUseRelease(
200
+ Effect_exports.sync(() => {
201
+ account();
202
+ waiting++;
203
+ }).pipe(Effect_exports.andThen(Queue_exports.offer(changes, void 0))),
204
+ () => input,
205
+ () => Effect_exports.sync(() => {
206
+ account();
207
+ waiting--;
208
+ }).pipe(Effect_exports.andThen(Queue_exports.offer(changes, void 0)))
209
+ ),
210
+ expired: Effect_exports.gen(function* () {
211
+ while (true) {
212
+ const left = account();
213
+ if (waiting === 0 && left <= 0)
214
+ return yield* new McpError({ phase: "call", reason: "timeout" });
215
+ if (waiting > 0) yield* Queue_exports.take(changes);
216
+ else yield* Queue_exports.take(changes).pipe(Effect_exports.raceFirst(Effect_exports.sleep(Math.max(1, left))));
217
+ }
218
+ })
219
+ };
220
+ });
221
+ }
222
+ var mcpCall = (client, name, input, context, timeoutMs, failure2) => Effect_exports.scoped(
223
+ Effect_exports.gen(function* () {
224
+ const budget = yield* callBudget(timeoutMs);
225
+ const failed = yield* Deferred_exports.make();
226
+ const runtime = yield* Effect_exports.context();
227
+ const callbacks = /* @__PURE__ */ new Set();
228
+ const lifetime = yield* Effect_exports.acquireRelease(
229
+ Effect_exports.sync(() => new AbortController()),
230
+ (controller) => (
231
+ // oxlint-disable-next-line executor/authored-code-through-adapter -- the MCP SDK's elicitation callbacks
232
+ Effect_exports.promise(async () => {
233
+ controller.abort();
234
+ client.removeRequestHandler("elicitation/create");
235
+ await Promise.allSettled(callbacks);
236
+ })
237
+ )
238
+ );
239
+ client.setRequestHandler(ElicitRequestSchema, (request, extra) => {
240
+ const signal = AbortSignal.any([lifetime.signal, extra.signal]);
241
+ const interaction = Effect_exports.gen(function* () {
242
+ const form = yield* prepareElicitation({
243
+ ...request.params,
244
+ mode: request.params.mode ?? "form"
245
+ });
246
+ const deliver = context.elicit;
247
+ if (deliver === void 0) return yield* new ElicitationFailed({ reason: "unavailable" });
248
+ const answer = yield* budget.waitForInput(
249
+ fromPromise(
250
+ deliver,
251
+ "elicitation"
252
+ )(form.request).pipe(
253
+ Effect_exports.mapError(
254
+ (error) => Option_exports.getOrElse(
255
+ Schema_exports.decodeUnknownOption(ElicitationFailed)(error),
256
+ () => new ElicitationFailed({ reason: "transport" })
257
+ )
258
+ ),
259
+ Effect_exports.timeoutOrElse({
260
+ duration: defaultElicitationLimits.timeoutMs,
261
+ orElse: () => Effect_exports.fail(new ElicitationFailed({ reason: "expired" }))
262
+ })
263
+ )
264
+ ).pipe(Effect_exports.withSpan("provider.mcp.elicitation"));
265
+ return yield* form.respond(answer).pipe(
266
+ Effect_exports.flatMap(
267
+ (response) => Effect_exports.try({
268
+ try: () => ElicitResultSchema.parse(response),
269
+ catch: () => new ElicitationFailed({ reason: "invalid-response" })
270
+ })
271
+ )
272
+ );
273
+ }).pipe(Effect_exports.tapError((error) => Deferred_exports.fail(failed, error)));
274
+ const callback = Effect_exports.runPromiseWith(runtime)(interaction, { signal }).catch(() => {
275
+ if (!lifetime.signal.aborted)
276
+ Effect_exports.runSync(Deferred_exports.fail(failed, new ElicitationFailed({ reason: "transport" })));
277
+ throw new ProtocolError(ErrorCode.InternalError, "User input could not be delivered");
278
+ });
279
+ callbacks.add(callback);
280
+ return callback.finally(() => callbacks.delete(callback));
281
+ });
282
+ return yield* Effect_exports.tryPromise({
283
+ try: (signal) => client.callTool({ name, arguments: input }, void 0, {
284
+ signal: AbortSignal.any([signal, lifetime.signal]),
285
+ timeout: mcpSdkTimerCeilingMs
286
+ }),
287
+ catch: (error) => failure2("call", error)
288
+ }).pipe(
289
+ Effect_exports.raceFirst(Deferred_exports.await(failed)),
290
+ Effect_exports.raceFirst(budget.expired),
291
+ Effect_exports.flatMap(
292
+ (result) => Schema_exports.decodeUnknownEffect(McpToolResult)(result).pipe(
293
+ Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_response" }))
294
+ )
295
+ ),
296
+ Effect_exports.tap(
297
+ (result) => Effect_exports.annotateCurrentSpan("mcp.tool.is_error", result.isError === true)
298
+ )
299
+ );
300
+ })
301
+ ).pipe(
302
+ owned("upstream", "provider.mcp.request", {
303
+ kind: "client",
304
+ attributes: {
305
+ "rpc.system.name": "jsonrpc",
306
+ "rpc.method": "tools/call",
307
+ "mcp.tool.name": name
308
+ }
309
+ })
310
+ );
311
+
312
+ // src/implementation/mcp-client.ts
313
+ var clientCodes = /* @__PURE__ */ new Set([
314
+ ErrorCode2.RequestTimeout,
315
+ ErrorCode2.ConnectionClosed
316
+ ]);
317
+ var answeredError = (error) => {
318
+ if (!(error instanceof ProtocolError2) || clientCodes.has(error.code)) return void 0;
319
+ const prefix = `MCP error ${error.code}: `;
320
+ return bodyUpstreamError({
321
+ error: {
322
+ code: error.code,
323
+ message: error.message.startsWith(prefix) ? error.message.slice(prefix.length) : error.message
324
+ }
325
+ });
326
+ };
327
+ var mcpJsonSchemaValidator = {
328
+ getValidator(document) {
329
+ const decoder = Effect_exports.runSync(jsonSchemaDecoder(document));
330
+ return (input) => {
331
+ const result = Effect_exports.runSyncExit(Schema_exports.decodeUnknownEffect(decoder)(input));
332
+ if (Exit_exports.isFailure(result))
333
+ return {
334
+ valid: false,
335
+ data: void 0,
336
+ errorMessage: "Value does not match the supported JSON Schema"
337
+ };
338
+ return { valid: true, data: result.value, errorMessage: void 0 };
339
+ };
340
+ }
341
+ };
342
+ function mcpClient(withClient2, timeoutMs, failure2) {
343
+ const list = withClient2(
344
+ "discover",
345
+ (client) => Effect_exports.gen(function* () {
346
+ const tools = /* @__PURE__ */ new Map();
347
+ const cursors = /* @__PURE__ */ new Set();
348
+ let cursor;
349
+ do {
350
+ const page = yield* Effect_exports.tryPromise({
351
+ // This session only reads metadata. listTools() also eagerly compiles
352
+ // every output validator; mcpRouter validates the selected tool on call.
353
+ try: (signal) => client.request(
354
+ { method: "tools/list", params: cursor === void 0 ? {} : { cursor } },
355
+ ListToolsResultSchema,
356
+ { signal, timeout: timeoutMs }
357
+ ),
358
+ catch: (error) => failure2("discover", error)
359
+ }).pipe(
360
+ owned("upstream", "provider.mcp.request", {
361
+ kind: "client",
362
+ attributes: { "rpc.system.name": "jsonrpc", "rpc.method": "tools/list" }
363
+ })
364
+ );
365
+ const metadata = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(McpToolMetadata))(
366
+ page.tools
367
+ ).pipe(
368
+ Effect_exports.mapError(() => new McpError({ phase: "discover", reason: "invalid_response" }))
369
+ );
370
+ for (const tool of metadata) {
371
+ if (!tool.name || tools.has(tool.name) || tools.size >= defaultMcpClientLimits.maxTools)
372
+ return yield* new McpError({ phase: "discover", reason: "invalid_response" });
373
+ tools.set(tool.name, tool);
374
+ }
375
+ cursor = page.nextCursor;
376
+ if (cursor !== void 0) {
377
+ if (cursors.has(cursor) || cursors.size >= defaultMcpClientLimits.maxPaginationCursors)
378
+ return yield* new McpError({ phase: "discover", reason: "invalid_response" });
379
+ cursors.add(cursor);
380
+ }
381
+ } while (cursor !== void 0);
382
+ const info = client.getServerVersion();
383
+ const instructions = client.getInstructions();
384
+ const icons = info?.icons?.flatMap(
385
+ (icon) => Option_exports.toArray(Schema_exports.decodeUnknownOption(RouterIcon)(icon))
386
+ );
387
+ const server = Schema_exports.decodeUnknownOption(McpServerHeader)({
388
+ ...info?.name === void 0 ? {} : { name: info.name },
389
+ ...info?.title === void 0 ? {} : { title: info.title },
390
+ ...info?.version === void 0 ? {} : { version: info.version },
391
+ ...info?.description === void 0 ? {} : { description: info.description },
392
+ ...info?.websiteUrl === void 0 ? {} : { websiteUrl: info.websiteUrl },
393
+ ...icons === void 0 ? {} : { icons },
394
+ ...instructions === void 0 ? {} : { instructions }
395
+ });
396
+ return {
397
+ tools: [...tools.values()],
398
+ server: Option_exports.getOrElse(server, () => ({}))
399
+ };
400
+ })
401
+ ).pipe(owned("upstream", "provider.mcp.discover"));
402
+ const check = withClient2(
403
+ "discover",
404
+ (client) => (
405
+ // oxlint-disable-next-line executor/authored-code-through-adapter -- MCP SDK
406
+ Effect_exports.tryPromise({
407
+ try: (signal) => client.request({ method: "tools/list", params: {} }, ListToolsResultSchema, {
408
+ signal,
409
+ timeout: timeoutMs
410
+ }),
411
+ catch: (error) => failure2("discover", error)
412
+ }).pipe(
413
+ Effect_exports.asVoid,
414
+ owned("upstream", "provider.mcp.request", {
415
+ kind: "client",
416
+ attributes: { "rpc.system.name": "jsonrpc", "rpc.method": "tools/list" }
417
+ })
418
+ )
419
+ )
420
+ ).pipe(owned("upstream", "provider.mcp.check"));
421
+ const call = (name, input, context) => withClient2("call", (client) => mcpCall(client, name, input, context, timeoutMs, failure2)).pipe(
422
+ owned("upstream", "provider.mcp.call", { attributes: { "mcp.tool.name": name } })
423
+ );
424
+ return { list, check, call };
425
+ }
426
+
427
+ // src/implementation/mcp.ts
428
+ var unreadable = (error) => error instanceof SyntaxError || error instanceof Error && Predicate_exports.hasProperty(error, "issues") && Array.isArray(error.issues);
429
+ var failure = (phase, error) => {
430
+ if (Schema_exports.is(ProviderError)(error) || Schema_exports.is(McpError)(error) || Schema_exports.is(NetworkRefused)(error))
431
+ return error;
432
+ const code = error instanceof UnauthorizedError ? 401 : error instanceof StreamableHTTPError || error instanceof SseError ? error.code : void 0;
433
+ if (code !== void 0 && code >= 300 && code <= 599)
434
+ return httpProviderError(code) ?? new McpError({ phase, reason: "request", status: code });
435
+ const upstream = answeredError(error);
436
+ return new McpError({
437
+ phase,
438
+ reason: code !== void 0 || unreadable(error) ? "invalid_response" : error instanceof ProtocolError3 && error.code === ErrorCode3.RequestTimeout ? "timeout" : "request",
439
+ ...upstream === void 0 ? {} : { upstream }
440
+ });
441
+ };
442
+ var errorBodyLimits = { maxBytes: 65536, readTimeoutMs: 2e3 };
443
+ var errorBody = (response) => Effect_exports.gen(function* () {
444
+ const json = /^application\/(?:[\w.-]+\+)?json$/i.test(
445
+ response.headers["content-type"]?.split(";")[0]?.trim() ?? ""
446
+ );
447
+ const length = response.headers["content-length"];
448
+ if (!json || length !== void 0 && Number(length) > errorBodyLimits.maxBytes)
449
+ return { body: Stream_exports.toReadableStream(response.stream), upstream: void 0 };
450
+ const unreadable2 = new McpError({ phase: "transport", reason: "invalid_response" });
451
+ const read = yield* response.stream.pipe(
452
+ Stream_exports.mapError(() => unreadable2),
453
+ Stream_exports.limitBytes(errorBodyLimits.maxBytes, () => Stream_exports.fail(unreadable2)),
454
+ Stream_exports.decodeText,
455
+ Stream_exports.mkString,
456
+ Effect_exports.timeout(errorBodyLimits.readTimeoutMs),
457
+ Effect_exports.option
458
+ );
459
+ if (Option_exports.isNone(read)) return { body: null, upstream: void 0 };
460
+ const parsed = Schema_exports.decodeUnknownOption(Schema_exports.fromJsonString(Schema_exports.Json))(read.value);
461
+ return {
462
+ body: read.value,
463
+ upstream: Option_exports.isSome(parsed) ? bodyUpstreamError(parsed.value) : void 0
464
+ };
465
+ });
466
+ var transportFetch = (connection, telemetry, rejected, answered) => (url, init) => Effect_exports.runPromiseWith(telemetry.context)(
467
+ Effect_exports.gen(function* () {
468
+ const target = yield* Effect_exports.try({
469
+ try: () => new URL(url),
470
+ catch: () => new McpError({ phase: "transport", reason: "invalid_response" })
471
+ });
472
+ if (connection.url.username || connection.url.password)
473
+ return yield* new McpError({ phase: "transport", reason: "invalid_input" });
474
+ if (target.origin !== connection.url.origin || target.username || target.password)
475
+ return yield* new McpError({ phase: "transport", reason: "invalid_response" });
476
+ const request = yield* Effect_exports.try({
477
+ try: () => {
478
+ const headers = new Headers(Redacted_exports.value(connection.headers));
479
+ new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
480
+ if (!headers.has("user-agent")) headers.set("user-agent", "Executor");
481
+ return HttpClientRequest_exports.fromWeb(new Request(target, { ...init, headers }));
482
+ },
483
+ // The provider's headers cannot form an HTTP request, such as a name with a space.
484
+ catch: () => new McpError({ phase: "transport", reason: "invalid_input" })
485
+ });
486
+ const client = yield* HttpClient_exports.HttpClient;
487
+ const response = yield* client.execute(request);
488
+ yield* failOnNetworkRefusal(response).pipe(
489
+ Effect_exports.tapError((refused) => Deferred_exports.fail(rejected, refused))
490
+ );
491
+ if (response.status < 400)
492
+ return new Response(
493
+ [204, 205, 304].includes(response.status) ? null : Stream_exports.toReadableStream(response.stream),
494
+ {
495
+ status: response.status,
496
+ headers: response.headers
497
+ }
498
+ );
499
+ const { body, upstream } = yield* errorBody(response);
500
+ const provider = httpProviderError(response.status, response.headers);
501
+ if (provider !== void 0) {
502
+ const refused = providerErrorDetail(provider, { upstream });
503
+ yield* Deferred_exports.fail(rejected, refused);
504
+ return yield* refused;
505
+ }
506
+ const session = new Headers(init?.headers).has("mcp-session-id");
507
+ yield* Ref_exports.update(
508
+ answered,
509
+ (responses) => new Map(responses).set(response.status, { upstream, session })
510
+ );
511
+ return new Response(body, { status: response.status, headers: response.headers });
512
+ }).pipe(
513
+ Effect_exports.provide(FetchHttpClient_exports.layer),
514
+ Effect_exports.provideService(FetchHttpClient_exports.RequestInit, { redirect: "manual" }),
515
+ Effect_exports.provideService(
516
+ FetchHttpClient_exports.Fetch,
517
+ (url2, options) => globalThis.fetch(url2, {
518
+ ...options,
519
+ signal: AbortSignal.any([
520
+ ...options?.signal ? [options.signal] : [],
521
+ ...init?.signal ? [init.signal] : []
522
+ ])
523
+ })
524
+ ),
525
+ Effect_exports.mapError((error) => failure("transport", error))
526
+ ),
527
+ init?.signal ? { signal: init.signal } : {}
528
+ );
529
+ var explain = (error, phase, responses) => {
530
+ if (Schema_exports.is(ProviderError)(error)) return providerErrorDetail(error, { phase });
531
+ if (phase === "call" && Schema_exports.is(McpError)(error) && error.phase === "transport" && error.reason === "request")
532
+ return new McpError({
533
+ phase,
534
+ reason: error.reason,
535
+ ...error.status === void 0 ? {} : { status: error.status },
536
+ ...error.upstream === void 0 ? {} : { upstream: error.upstream }
537
+ });
538
+ if (!Schema_exports.is(McpError)(error) || error.status === void 0) return error;
539
+ const response = responses.get(error.status);
540
+ if (response === void 0 || (error.upstream !== void 0 || response.upstream === void 0) && !response.session)
541
+ return error;
542
+ const upstream = error.upstream ?? response.upstream;
543
+ return new McpError({
544
+ phase: error.phase,
545
+ reason: error.reason,
546
+ status: error.status,
547
+ ...upstream === void 0 ? {} : { upstream },
548
+ ...response.session ? { session: true } : {}
549
+ });
550
+ };
551
+ var explained = (phase, answered) => (error) => Ref_exports.get(answered).pipe(
552
+ Effect_exports.flatMap((responses) => Effect_exports.fail(explain(error, phase, responses)))
553
+ );
554
+ function withClient(connection, mode, use, changed) {
555
+ const attempt = (kind) => Effect_exports.scoped(
556
+ Effect_exports.gen(function* () {
557
+ const telemetry = yield* captureTelemetry;
558
+ const rejected = yield* Deferred_exports.make();
559
+ const answered = yield* Ref_exports.make(/* @__PURE__ */ new Map());
560
+ const pending = /* @__PURE__ */ new Set();
561
+ const { client, transport } = yield* Effect_exports.acquireRelease(
562
+ Effect_exports.sync(() => {
563
+ const fetch = transportFetch(connection, telemetry, rejected, answered);
564
+ const client2 = new Client(
565
+ { name: "executor-apps", version: "0.1.0" },
566
+ {
567
+ jsonSchemaValidator: mcpJsonSchemaValidator,
568
+ capabilities: mode === "call" ? { elicitation: { form: {} } } : {}
569
+ }
570
+ );
571
+ if (changed !== void 0) {
572
+ client2.setNotificationHandler(ToolListChangedNotificationSchema, () => {
573
+ const task = Effect_exports.runPromiseWith(telemetry.context)(
574
+ changed.pipe(
575
+ Effect_exports.timeout("5 seconds"),
576
+ Effect_exports.catchCause(() => Effect_exports.logWarning("MCP catalog invalidation failed"))
577
+ )
578
+ );
579
+ pending.add(task);
580
+ return task.finally(() => pending.delete(task));
581
+ });
582
+ }
583
+ return {
584
+ client: client2,
585
+ transport: kind === "http" ? new StreamableHTTPClientTransport(connection.url, {
586
+ fetch,
587
+ reconnectionOptions: {
588
+ maxRetries: 0,
589
+ initialReconnectionDelay: 1e3,
590
+ maxReconnectionDelay: 1e3,
591
+ reconnectionDelayGrowFactor: 1
592
+ }
593
+ }) : new SSEClientTransport(connection.url, { fetch })
594
+ };
595
+ }),
596
+ ({ client: client2, transport: transport2 }) => Effect_exports.gen(function* () {
597
+ client2.removeNotificationHandler("notifications/tools/list_changed");
598
+ yield* Effect_exports.promise(async () => {
599
+ await Promise.allSettled(pending);
600
+ });
601
+ if (transport2 instanceof StreamableHTTPClientTransport && transport2.sessionId !== void 0) {
602
+ yield* Effect_exports.tryPromise(() => transport2.terminateSession()).pipe(
603
+ Effect_exports.timeout(defaultMcpClientLimits.cleanupTimeoutMs),
604
+ Effect_exports.ignore
605
+ );
606
+ }
607
+ yield* Effect_exports.tryPromise(() => client2.close()).pipe(
608
+ Effect_exports.timeout(defaultMcpClientLimits.cleanupTimeoutMs),
609
+ Effect_exports.ignore
610
+ );
611
+ }).pipe(owned("upstream", "provider.mcp.close"))
612
+ );
613
+ const wire = transport;
614
+ yield* Effect_exports.tryPromise({
615
+ try: (signal) => client.connect(wire, { signal, timeout: connection.timeoutMs }),
616
+ catch: (error) => failure("connect", error)
617
+ }).pipe(
618
+ Effect_exports.raceFirst(Deferred_exports.await(rejected)),
619
+ Effect_exports.catch(explained("connect", answered)),
620
+ Effect_exports.timeout(connection.timeoutMs),
621
+ owned("upstream", "provider.mcp.connect")
622
+ );
623
+ return yield* use(client).pipe(
624
+ Effect_exports.raceFirst(Deferred_exports.await(rejected)),
625
+ Effect_exports.catch(explained(mode, answered))
626
+ );
627
+ })
628
+ ).pipe(
629
+ owned("upstream", "provider.mcp.session", {
630
+ attributes: {
631
+ "mcp.transport": kind,
632
+ "mcp.operation": mode,
633
+ "server.address": connection.url.hostname
634
+ }
635
+ })
636
+ );
637
+ return attempt("http").pipe(
638
+ // Fallback is only for negotiation. Tool calls are never automatically replayed.
639
+ Effect_exports.catch(
640
+ (error) => Schema_exports.is(McpError)(error) && error.phase === "connect" && (error.status === 404 || error.status === 405) ? attempt("sse") : Effect_exports.fail(error)
641
+ ),
642
+ (operation) => mode === "discover" ? operation.pipe(Effect_exports.timeout(connection.timeoutMs)) : operation,
643
+ Effect_exports.catchTag(
644
+ "TimeoutError",
645
+ () => Effect_exports.fail(new McpError({ phase: "transport", reason: "timeout" }))
646
+ )
647
+ );
648
+ }
649
+ var mcpClientEffect = (input, changed) => Effect_exports.gen(function* () {
650
+ const options = yield* Schema_exports.decodeUnknownEffect(McpToolsOptions)(input).pipe(
651
+ Effect_exports.mapError(() => new McpError({ phase: "connect", reason: "invalid_input" }))
652
+ );
653
+ const url = new URL(options.url);
654
+ if (url.username || url.password || url.hash)
655
+ return yield* new McpError({ phase: "connect", reason: "invalid_input" });
656
+ const connection = {
657
+ url,
658
+ headers: Redacted_exports.make({ ...options.headers }),
659
+ timeoutMs: options.timeoutMs ?? defaultMcpClientLimits.timeoutMs
660
+ };
661
+ return mcpClient(
662
+ (mode, use) => withClient(connection, mode, use, changed).pipe(
663
+ Effect_exports.mapError(
664
+ (error) => options.accountId === void 0 ? error : accountProviderError(error, options.accountId)
665
+ )
666
+ ),
667
+ connection.timeoutMs,
668
+ failure
669
+ );
670
+ });
671
+ var refusesCredentials = (error) => Schema_exports.is(ProviderError)(error) && Match_exports.value(error.reason).pipe(
672
+ Match_exports.whenOr("unauthorized", "forbidden", "rejected", () => true),
673
+ Match_exports.whenOr("rate_limited", "unavailable", () => false),
674
+ Match_exports.exhaustive
675
+ );
676
+ var mcpHealthEffect = (check, options) => Effect_exports.gen(function* () {
677
+ const { deadline, timeoutMs, ...parsed } = yield* Schema_exports.decodeUnknownEffect(McpHealthInput)({
678
+ ...options,
679
+ accountId: check.account.id,
680
+ signal: check.signal,
681
+ deadline: check.deadline
682
+ }).pipe(Effect_exports.mapError(() => new McpError({ phase: "connect", reason: "invalid_input" })));
683
+ const end = Math.min(
684
+ (yield* Clock_exports.currentTimeMillis) + (timeoutMs ?? defaultMcpClientLimits.timeoutMs),
685
+ deadline === void 0 ? Number.POSITIVE_INFINITY : deadline - mcpHealthReserveMs
686
+ );
687
+ const remaining = Effect_exports.flatMap(
688
+ Clock_exports.currentTimeMillis,
689
+ (now) => end - now >= 1 ? Effect_exports.succeed(Math.floor(end - now)) : Effect_exports.fail(new McpError({ phase: "transport", reason: "timeout" }))
690
+ );
691
+ yield* (yield* mcpClientEffect({ ...parsed, timeoutMs: yield* remaining })).check;
692
+ return yield* remaining.pipe(
693
+ Effect_exports.flatMap(
694
+ (timeoutMs2) => mcpClientEffect({ url: parsed.url, signal: parsed.signal, timeoutMs: timeoutMs2 })
695
+ ),
696
+ Effect_exports.flatMap((anonymous) => anonymous.check),
697
+ Effect_exports.matchEffect({
698
+ onSuccess: () => Effect_exports.fail(new McpCredentialsUnverified({ anonymous: "answered" })),
699
+ // Executor's network refused the attempt, so the server never answered it.
700
+ onFailure: (error) => Schema_exports.is(NetworkRefused)(error) ? Effect_exports.fail(error) : refusesCredentials(error) ? Effect_exports.void : Effect_exports.fail(new McpCredentialsUnverified({ anonymous: error }))
701
+ }),
702
+ owned("upstream", "provider.mcp.anonymous")
703
+ );
704
+ }).pipe(owned("upstream", "provider.mcp.health"));
705
+ var mcpToolsEffect = (input) => mcpClientEffect(input).pipe(Effect_exports.flatMap(adaptMcpTools));
706
+
707
+ export {
708
+ adaptMcpTool,
709
+ mcpClientEffect,
710
+ mcpHealthEffect,
711
+ mcpToolsEffect
712
+ };