apps 0.0.1-beta.3 → 0.0.1-beta.30

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 (139) hide show
  1. package/README.md +68 -44
  2. package/framework-reference.json +1 -1
  3. package/js/{chunk-G7ZIRKMK.js → chunk-2D2PKLGQ.js} +118 -197
  4. package/js/chunk-3SPRHIEE.js +42 -0
  5. package/js/{chunk-FDNTX5QJ.js → chunk-4N26L465.js} +2 -2
  6. package/js/chunk-5ZHHO4OM.js +92 -0
  7. package/js/{chunk-EVJUVWN2.js → chunk-65SZ23BK.js} +2 -2
  8. package/js/{chunk-M6ZRRIBI.js → chunk-6JBTHTI5.js} +1 -1
  9. package/js/{chunk-J7O55ZV7.js → chunk-6NK26ONC.js} +332 -187
  10. package/js/chunk-6VWYEQ4X.js +254 -0
  11. package/js/{chunk-RN2MXB4R.js → chunk-AE4FWJQU.js} +128 -24
  12. package/js/{chunk-HDJH3RPR.js → chunk-BBTELEAN.js} +2 -2
  13. package/js/{chunk-LGIYBDWA.js → chunk-BRGF7VFN.js} +65 -1
  14. package/js/{chunk-MYYEW3RA.js → chunk-BSRU52RU.js} +984 -61
  15. package/js/{chunk-FZJOYIZO.js → chunk-BTJMXW4I.js} +1 -1
  16. package/js/{chunk-HDTGZWP2.js → chunk-IMCEF6KE.js} +139 -32
  17. package/js/chunk-KQCMHI3K.js +118 -0
  18. package/js/{chunk-BMOIAIVR.js → chunk-M2KEEOIQ.js} +49 -1
  19. package/js/{chunk-YEJOQEII.js → chunk-MYCVMDWI.js} +45 -7
  20. package/js/{chunk-FW5HBOIK.js → chunk-NXTXZ635.js} +1841 -1701
  21. package/js/chunk-OD3KFKZD.js +1617 -0
  22. package/js/{chunk-JN55AYQH.js → chunk-OI5CKSBU.js} +61 -32
  23. package/js/{chunk-NQ3OMCA5.js → chunk-P46HIAX6.js} +2 -2
  24. package/js/chunk-PUC24GZP.js +801 -0
  25. package/js/{chunk-SATWJKN6.js → chunk-PWF2DRJ3.js} +1 -1
  26. package/js/{chunk-D47C7KG5.js → chunk-VUVBMNKC.js} +2 -2
  27. package/js/{chunk-ZCAMUXSG.js → chunk-WGBI5MVX.js} +3 -4
  28. package/js/{chunk-T2LAZCAD.js → chunk-WQ5MVBTP.js} +1 -1
  29. package/js/{chunk-PLCMJREA.js → chunk-XBQTJP76.js} +60 -20
  30. package/js/{chunk-QKHR7BMF.js → chunk-XGN5IFOZ.js} +3 -3
  31. package/js/{chunk-WFSQXYUT.js → chunk-YML53Z7H.js} +42 -5
  32. package/js/{chunk-5MQZEB6Y.js → chunk-ZZOCEUTB.js} +37 -12
  33. package/js/client.js +120 -84
  34. package/js/contracts.js +110 -16
  35. package/js/effect.js +20 -20
  36. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  37. package/js/graphql.js +58 -54
  38. package/js/host.js +20 -20
  39. package/js/index.js +247 -204
  40. package/js/mcp/effect.js +24 -22
  41. package/js/mcp/stdio.js +35 -30
  42. package/js/mcp.js +105 -68
  43. package/js/openapi.js +4087 -1503
  44. package/js/react.js +3 -3
  45. package/js/skills/effect.js +5 -3
  46. package/js/skills.js +15 -15
  47. package/js/storage/facet.js +4 -4
  48. package/js/ui/auth/contracts.js +2 -2
  49. package/js/ui/auth.js +5 -5
  50. package/js/ui/contracts.js +5 -4
  51. package/js/ui/serving.js +8516 -214
  52. package/package.json +1 -1
  53. package/runtime.json +1 -1
  54. package/types/app-data/src/contracts/database.d.ts +33 -6
  55. package/types/app-data/src/implementation/schema.d.ts +2 -17
  56. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  57. package/types/apps/src/contracts/app.d.ts +7 -6
  58. package/types/apps/src/contracts/failure.d.ts +54 -0
  59. package/types/apps/src/contracts/graphql.d.ts +2 -1
  60. package/types/apps/src/contracts/host.d.ts +34 -11
  61. package/types/apps/src/contracts/mcp.d.ts +91 -10
  62. package/types/apps/src/contracts/network.d.ts +84 -0
  63. package/types/apps/src/contracts/openapi-compile.d.ts +31 -3
  64. package/types/apps/src/contracts/openapi.d.ts +45 -9
  65. package/types/apps/src/contracts/operations.d.ts +5 -6
  66. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  67. package/types/apps/src/contracts/protocols/1.d.ts +251 -69
  68. package/types/apps/src/contracts/protocols/2.d.ts +710 -0
  69. package/types/apps/src/contracts/protocols/3.d.ts +716 -0
  70. package/types/apps/src/contracts/protocols/4.d.ts +1298 -0
  71. package/types/apps/src/contracts/protocols/5.d.ts +1174 -0
  72. package/types/apps/src/contracts/protocols/6.d.ts +1620 -0
  73. package/types/apps/src/contracts/protocols/7.d.ts +1784 -0
  74. package/types/apps/src/contracts/protocols/8.d.ts +1119 -0
  75. package/types/apps/src/contracts/protocols/oauth.d.ts +89 -0
  76. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  77. package/types/apps/src/contracts/provider.d.ts +115 -10
  78. package/types/apps/src/contracts/router.d.ts +59 -0
  79. package/types/apps/src/contracts/skills.d.ts +18 -5
  80. package/types/apps/src/contracts/storage.d.ts +3 -3
  81. package/types/apps/src/contracts/ui.d.ts +18 -0
  82. package/types/apps/src/contracts/workflows.d.ts +34 -3
  83. package/types/apps/src/graphql.d.ts +1 -3
  84. package/types/apps/src/implementation/account-router.d.ts +12 -0
  85. package/types/apps/src/implementation/app.d.ts +5 -4
  86. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  87. package/types/apps/src/implementation/catalog-cache.d.ts +34 -4
  88. package/types/apps/src/implementation/elicitation.d.ts +9 -9
  89. package/types/apps/src/implementation/failure-detail.d.ts +46 -0
  90. package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
  91. package/types/apps/src/implementation/graphql.d.ts +4 -3
  92. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  93. package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
  94. package/types/apps/src/implementation/mcp-client.d.ts +49 -25
  95. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  96. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  97. package/types/apps/src/implementation/mcp.d.ts +52 -25
  98. package/types/apps/src/implementation/network.d.ts +16 -0
  99. package/types/apps/src/implementation/openapi-compile.d.ts +27 -6
  100. package/types/apps/src/implementation/openapi-document.d.ts +35 -8
  101. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  102. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  103. package/types/apps/src/implementation/openapi-source.d.ts +8 -6
  104. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  105. package/types/apps/src/implementation/operations.d.ts +36 -3
  106. package/types/apps/src/implementation/protocol-operations.d.ts +6 -4
  107. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  108. package/types/apps/src/implementation/provider.d.ts +19 -5
  109. package/types/apps/src/implementation/router-catalog.d.ts +224 -0
  110. package/types/apps/src/implementation/router.d.ts +68 -0
  111. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  112. package/types/apps/src/implementation/schema.d.ts +52 -1
  113. package/types/apps/src/implementation/skills.d.ts +2 -2
  114. package/types/apps/src/implementation/storage.d.ts +5 -3
  115. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  116. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  117. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  118. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  119. package/types/apps/src/implementation/ui-serving.d.ts +10 -4
  120. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  121. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  122. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  123. package/types/apps/src/implementation/workflow-context.d.ts +11 -3
  124. package/types/apps/src/index.d.ts +29 -11
  125. package/types/apps/src/mcp-stdio.d.ts +2 -5
  126. package/types/apps/src/mcp.d.ts +25 -5
  127. package/types/apps/src/openapi.d.ts +6 -6
  128. package/types/apps/src/skills.d.ts +4 -4
  129. package/types/telemetry/src/browser-operations.d.ts +5 -2
  130. package/types/telemetry/src/config.d.ts +2 -2
  131. package/types/utils/src/api-error.d.ts +48 -0
  132. package/js/chunk-PYUYJRSK.js +0 -93
  133. package/js/chunk-SWPD52J7.js +0 -35
  134. package/js/chunk-W7D7WVSY.js +0 -18
  135. package/js/chunk-Z5NMEGJN.js +0 -29
  136. package/js/chunk-ZJWDMTE3.js +0 -63
  137. package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
  138. package/types/apps/src/implementation/account-operations.d.ts +0 -151
  139. package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
@@ -0,0 +1,254 @@
1
+ import {
2
+ HostedTool,
3
+ RouterKey,
4
+ RouterMeta,
5
+ reservedRouterKeys
6
+ } from "./chunk-BSRU52RU.js";
7
+ import {
8
+ decoderOf
9
+ } from "./chunk-YML53Z7H.js";
10
+ import {
11
+ Effect_exports,
12
+ Schema_exports
13
+ } from "./chunk-NXTXZ635.js";
14
+
15
+ // src/implementation/authoring.ts
16
+ var NativeCallback = /* @__PURE__ */ Symbol("apps.NativeCallback");
17
+ var fromPromise = (callback) => (...args) => {
18
+ if (NativeCallback in callback) {
19
+ const native = callback[NativeCallback];
20
+ return native(...args);
21
+ }
22
+ return Effect_exports.tryPromise({ try: () => callback(...args), catch: (error) => error });
23
+ };
24
+ var toPromise = (operation, signal) => {
25
+ const native = (...args) => Effect_exports.suspend(() => {
26
+ if (signal === void 0) return operation(...args);
27
+ if (signal.aborted) return Effect_exports.interrupt;
28
+ const cancelled = Effect_exports.callback((resume) => {
29
+ if (signal.aborted) {
30
+ resume(Effect_exports.interrupt);
31
+ return;
32
+ }
33
+ const abort = () => resume(Effect_exports.interrupt);
34
+ signal.addEventListener("abort", abort, { once: true });
35
+ return Effect_exports.sync(() => signal.removeEventListener("abort", abort));
36
+ });
37
+ return Effect_exports.raceFirst(
38
+ cancelled,
39
+ Effect_exports.suspend(() => operation(...args))
40
+ );
41
+ });
42
+ return Object.assign((...args) => Effect_exports.runPromise(native(...args)), {
43
+ [NativeCallback]: native
44
+ });
45
+ };
46
+
47
+ // src/implementation/operations.ts
48
+ var NativeOperation = /* @__PURE__ */ Symbol("apps.Operation");
49
+ var NativeRouterKey = /* @__PURE__ */ Symbol("apps.Router");
50
+ var operationDeclaration = (operation) => ({
51
+ kind: operation.kind,
52
+ [NativeOperation]: operation
53
+ });
54
+ var nativeOperation = (value) => {
55
+ if (typeof value !== "object" || value === null || !(NativeOperation in value)) return void 0;
56
+ return value[NativeOperation];
57
+ };
58
+ var operationOptions = (options) => {
59
+ const approval = options.approval;
60
+ return {
61
+ ...options.description === void 0 ? {} : { description: options.description },
62
+ ...options.title === void 0 ? {} : { title: options.title },
63
+ ...options.annotations === void 0 ? {} : { annotations: options.annotations },
64
+ ...options._meta === void 0 ? {} : { _meta: options._meta },
65
+ input: decoderOf(options.input),
66
+ ...approval === void 0 ? {} : {
67
+ approval: (context) => Effect_exports.tryPromise({ try: async () => approval(context), catch: (error) => error })
68
+ }
69
+ };
70
+ };
71
+ var approvedOperation = (operation, approval) => {
72
+ const copy = Object.defineProperties({}, Object.getOwnPropertyDescriptors(operation));
73
+ return Object.defineProperty(copy, "approval", {
74
+ enumerable: true,
75
+ value: (context) => Effect_exports.tryPromise({ try: async () => approval(context), catch: (error) => error })
76
+ });
77
+ };
78
+ var withApproval = (operation, approval) => ({
79
+ ...operation,
80
+ [NativeOperation]: approvedOperation(operation[NativeOperation], approval)
81
+ });
82
+ var toolAnnotations = (operation) => nativeOperation(operation)?.annotations;
83
+ var make = (kind, options, run) => operationDeclaration({
84
+ ...operationOptions(options),
85
+ kind,
86
+ // The host always validates JSON serialization, even without a stronger output declaration.
87
+ ...options.output === void 0 ? {} : { output: decoderOf(options.output) },
88
+ run: (context, input) => Effect_exports.tryPromise({
89
+ // SAFETY: defineApp checks the handler context against its requirements.
90
+ // The host validates account bindings and creates the matching storage facade.
91
+ try: () => run(context, input),
92
+ catch: (error) => error
93
+ })
94
+ });
95
+ var query = (options, run) => make("query", options, run);
96
+ var mutation = (options, run) => make("mutation", options, run);
97
+
98
+ // src/implementation/router.ts
99
+ var routerDeclaration = (node) => ({
100
+ [NativeRouterKey]: node
101
+ });
102
+ var nativeRouter = (value) => {
103
+ if (typeof value !== "object" || value === null || !(NativeRouterKey in value)) return void 0;
104
+ return value[NativeRouterKey];
105
+ };
106
+ var nativeNode = (value) => nativeOperation(value) ?? nativeRouter(value);
107
+ var metaOf = (options) => {
108
+ if (options === void 0) return void 0;
109
+ const defined = Object.fromEntries(
110
+ Object.entries(options).filter(([, value]) => value !== void 0)
111
+ );
112
+ return Object.keys(defined).length === 0 ? void 0 : Schema_exports.decodeUnknownSync(RouterMeta)(defined);
113
+ };
114
+ var mergeMeta = (base, override) => base === void 0 ? override : override === void 0 ? base : { ...base, ...override };
115
+ function router(children, options) {
116
+ const meta = metaOf(options);
117
+ const existing = nativeRouter(children);
118
+ if (existing !== void 0)
119
+ return routerDeclaration(
120
+ existing.kind === "router" ? { ...existing, ...withMeta(mergeMeta(existing.meta, meta)) } : { ...existing, ...withOverrides(mergeMeta(existing.overrides, meta)) }
121
+ );
122
+ const nodes = {};
123
+ for (const [key, value] of Object.entries(children)) {
124
+ if (reservedRouterKeys.has(key)) throw new Error(`Router key "${key}" is reserved`);
125
+ if (!Schema_exports.is(RouterKey)(key))
126
+ throw new Error(`Router key "${key}" must start with a letter or _ and contain no dots`);
127
+ const node = nativeNode(value);
128
+ if (node === void 0)
129
+ throw new Error(`Router key "${key}" must be a query, mutation or router`);
130
+ nodes[key] = node;
131
+ }
132
+ return routerDeclaration({ kind: "router", ...withMeta(meta), children: nodes });
133
+ }
134
+ var withMeta = (meta) => meta === void 0 ? {} : { meta };
135
+ var withOverrides = (overrides) => overrides === void 0 ? {} : { overrides };
136
+ var dynamicRouter = (source) => {
137
+ const meta = source.meta;
138
+ return routerDeclaration({
139
+ kind: "dynamic",
140
+ ...meta === void 0 ? {} : {
141
+ meta: () => fromPromise(async () => meta())().pipe(
142
+ Effect_exports.flatMap((options) => Schema_exports.decodeUnknownEffect(RouterMeta)(options))
143
+ )
144
+ },
145
+ list: () => fromPromise(async () => source.list())().pipe(
146
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool)))
147
+ ),
148
+ resolve: (name) => fromPromise(async () => source.resolve(name))().pipe(
149
+ Effect_exports.map((value) => {
150
+ if (value === void 0) return void 0;
151
+ const operation = nativeOperation(value);
152
+ if (operation === void 0) throw new Error("Expected an operation declaration");
153
+ return operation;
154
+ })
155
+ )
156
+ });
157
+ };
158
+ var joinPath = (path, name) => path === "" ? name : `${path}.${name}`;
159
+ var locate = (root, name) => {
160
+ if (root?.kind === "dynamic") return { kind: "dynamic", source: root, router: "", name };
161
+ let current = root;
162
+ let path = "";
163
+ let rest = name;
164
+ while (current !== void 0) {
165
+ const dot = rest.indexOf(".");
166
+ const key = dot < 0 ? rest : rest.slice(0, dot);
167
+ const child = Object.hasOwn(current.children, key) ? current.children[key] : void 0;
168
+ if (child === void 0) return void 0;
169
+ const remaining = dot < 0 ? void 0 : rest.slice(dot + 1);
170
+ switch (child.kind) {
171
+ case "query":
172
+ case "mutation":
173
+ return remaining === void 0 ? { kind: "operation", operation: child, router: path } : void 0;
174
+ case "dynamic":
175
+ return remaining === void 0 || remaining === "" ? void 0 : { kind: "dynamic", source: child, router: joinPath(path, key), name: remaining };
176
+ case "router":
177
+ if (remaining === void 0) return void 0;
178
+ current = child;
179
+ path = joinPath(path, key);
180
+ rest = remaining;
181
+ }
182
+ }
183
+ return void 0;
184
+ };
185
+ var declaredOperations = (root, path = "") => Object.entries(root?.children ?? {}).flatMap(([key, child]) => {
186
+ const name = joinPath(path, key);
187
+ switch (child.kind) {
188
+ case "query":
189
+ case "mutation":
190
+ return [{ name, router: path, operation: child }];
191
+ case "router":
192
+ return declaredOperations(child, name);
193
+ case "dynamic":
194
+ return [];
195
+ }
196
+ });
197
+ var withApprovals = (source, policy) => {
198
+ const native = nativeRouter(source);
199
+ if (native === void 0) throw new Error("withApprovals expects a router");
200
+ const operation = (node, name) => {
201
+ const approval = policy(operationDeclaration(node), name);
202
+ return approval === void 0 ? node : approvedOperation(node, approval);
203
+ };
204
+ const child = (node, name) => {
205
+ switch (node.kind) {
206
+ case "query":
207
+ case "mutation":
208
+ return operation(node, name);
209
+ case "router":
210
+ case "dynamic":
211
+ return walk(node, name);
212
+ }
213
+ };
214
+ const walk = (node, path) => node.kind === "dynamic" ? {
215
+ ...node,
216
+ resolve: (name) => node.resolve(name).pipe(
217
+ Effect_exports.flatMap(
218
+ (resolved) => resolved === void 0 ? Effect_exports.succeed(void 0) : Effect_exports.try({
219
+ try: () => operation(resolved, joinPath(path, name)),
220
+ catch: (error) => error
221
+ })
222
+ )
223
+ )
224
+ } : {
225
+ ...node,
226
+ children: Object.fromEntries(
227
+ Object.entries(node.children).map(([key, value]) => [
228
+ key,
229
+ child(value, joinPath(path, key))
230
+ ])
231
+ )
232
+ };
233
+ return routerDeclaration(walk(native, ""));
234
+ };
235
+
236
+ export {
237
+ fromPromise,
238
+ toPromise,
239
+ operationDeclaration,
240
+ nativeOperation,
241
+ withApproval,
242
+ toolAnnotations,
243
+ query,
244
+ mutation,
245
+ routerDeclaration,
246
+ nativeRouter,
247
+ mergeMeta,
248
+ router,
249
+ dynamicRouter,
250
+ joinPath,
251
+ locate,
252
+ declaredOperations,
253
+ withApprovals
254
+ };
@@ -1,26 +1,32 @@
1
1
  import {
2
2
  prepareElicitation
3
- } from "./chunk-J7O55ZV7.js";
3
+ } from "./chunk-6NK26ONC.js";
4
4
  import {
5
5
  fromPromise
6
- } from "./chunk-PYUYJRSK.js";
6
+ } from "./chunk-6VWYEQ4X.js";
7
+ import {
8
+ bodyUpstreamError
9
+ } from "./chunk-KQCMHI3K.js";
7
10
  import {
8
11
  ElicitationFailed,
9
12
  McpError,
13
+ McpServerHeader,
10
14
  McpToolMetadata,
11
15
  McpToolResult,
16
+ RouterIcon,
12
17
  ToolResultObservation,
13
18
  defaultElicitationLimits,
14
19
  defaultMcpClientLimits,
15
20
  mcpSdkTimerCeilingMs
16
- } from "./chunk-MYYEW3RA.js";
21
+ } from "./chunk-BSRU52RU.js";
17
22
  import {
18
- compileJsonSchemaDecoder,
19
- jsonSchemaDecoder
20
- } from "./chunk-WFSQXYUT.js";
23
+ jsonSchemaDecoder,
24
+ nestJsonSchema,
25
+ preparedJsonSchemaDecoder
26
+ } from "./chunk-YML53Z7H.js";
21
27
  import {
22
28
  JsonObject
23
- } from "./chunk-SATWJKN6.js";
29
+ } from "./chunk-PWF2DRJ3.js";
24
30
  import {
25
31
  Clock_exports,
26
32
  Deferred_exports,
@@ -29,29 +35,79 @@ import {
29
35
  Option_exports,
30
36
  Queue_exports,
31
37
  Schema_exports
32
- } from "./chunk-FW5HBOIK.js";
38
+ } from "./chunk-NXTXZ635.js";
33
39
 
34
40
  // src/implementation/mcp-tools.ts
41
+ var resultFields = {
42
+ content: { type: "array", items: { type: "object" } },
43
+ structuredContent: { type: "object" },
44
+ isError: { type: "boolean" },
45
+ _meta: { type: "object" }
46
+ };
47
+ var definitionReference = /^#\/(?:\$defs|definitions)\/[^/]+$/;
48
+ var locating = /* @__PURE__ */ new Set(["$id", "$anchor", "$dynamicAnchor", "$recursiveAnchor"]);
49
+ var onlyDefinitionReferences = (value) => Array.isArray(value) ? value.every(onlyDefinitionReferences) : value === null || typeof value !== "object" ? true : Object.entries(value).every(
50
+ ([key, item]) => locating.has(key) || key === "$dynamicRef" || key === "$recursiveRef" ? false : key === "$ref" ? typeof item === "string" && definitionReference.test(item) : onlyDefinitionReferences(item)
51
+ );
52
+ var placed = (structuredContent, pointer) => {
53
+ if (onlyDefinitionReferences(structuredContent)) {
54
+ const { $defs, definitions, $schema: _draft, ...schema } = structuredContent;
55
+ return {
56
+ schema,
57
+ root: {
58
+ ...$defs === void 0 ? {} : { $defs },
59
+ ...definitions === void 0 ? {} : { definitions }
60
+ }
61
+ };
62
+ }
63
+ try {
64
+ return { schema: nestJsonSchema(structuredContent, pointer), root: {} };
65
+ } catch {
66
+ return { schema: structuredContent, root: {} };
67
+ }
68
+ };
69
+ var resultSchema = (structuredContent) => {
70
+ if (structuredContent === void 0)
71
+ return { type: "object", properties: resultFields, required: ["content"] };
72
+ const { schema, root } = placed(structuredContent, "#/anyOf/0/properties/structuredContent");
73
+ return {
74
+ // The envelope's keywords mean the same in every draft, so the server's draft applies.
75
+ ...structuredContent.$schema === void 0 ? {} : { $schema: structuredContent.$schema },
76
+ ...root,
77
+ anyOf: [
78
+ {
79
+ type: "object",
80
+ properties: { ...resultFields, structuredContent: schema, isError: { const: false } },
81
+ required: ["content", "structuredContent"]
82
+ },
83
+ {
84
+ type: "object",
85
+ properties: { ...resultFields, isError: { const: true } },
86
+ required: ["content", "isError"]
87
+ }
88
+ ]
89
+ };
90
+ };
35
91
  var adaptMcpTool = (client, tool) => Effect_exports.gen(function* () {
36
92
  const decoder = yield* jsonSchemaDecoder(tool.inputSchema).pipe(
37
93
  Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
38
94
  );
39
- const output = tool.outputSchema === void 0 ? void 0 : yield* Effect_exports.cached(
40
- compileJsonSchemaDecoder(tool.outputSchema).pipe(
41
- Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
42
- )
43
- );
95
+ const output = preparedJsonSchemaDecoder(resultSchema(tool.outputSchema));
96
+ const { outputSchema: _upstream, ...metadata } = tool;
44
97
  const adapted = {
45
- ...tool,
98
+ ...metadata,
46
99
  description: tool.description ?? tool.title ?? tool.name,
47
100
  input: decoder,
101
+ output: output.decoder,
48
102
  ...tool.annotations?.readOnlyHint === void 0 ? {} : { readOnly: tool.annotations.readOnlyHint },
49
103
  run: (context, input) => Effect_exports.gen(function* () {
50
104
  const arguments_ = yield* Schema_exports.decodeUnknownEffect(decoder)(input).pipe(
51
105
  Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonObject)),
52
106
  Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_input" }))
53
107
  );
54
- const outputDecoder = output === void 0 ? void 0 : yield* output;
108
+ yield* output.compile.pipe(
109
+ Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
110
+ );
55
111
  const result = yield* client.call(tool.name, arguments_, context);
56
112
  if (result.isError === true) {
57
113
  (yield* ToolResultObservation).failed();
@@ -60,17 +116,13 @@ var adaptMcpTool = (client, tool) => Effect_exports.gen(function* () {
60
116
  "error.type": "McpToolError"
61
117
  });
62
118
  }
63
- if (outputDecoder !== void 0 && !result.isError)
64
- yield* Schema_exports.decodeUnknownEffect(outputDecoder)(result.structuredContent).pipe(
65
- Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_response" }))
66
- );
67
119
  return result;
68
120
  })
69
121
  };
70
122
  return adapted;
71
123
  });
72
124
  var adaptMcpTools = (client) => Effect_exports.gen(function* () {
73
- const metadata = yield* client.list;
125
+ const { tools: metadata } = yield* client.list;
74
126
  const entries = yield* Effect_exports.forEach(
75
127
  metadata,
76
128
  (tool) => adaptMcpTool(client, tool).pipe(Effect_exports.map((adapted) => [tool.name, adapted]))
@@ -79,7 +131,11 @@ var adaptMcpTools = (client) => Effect_exports.gen(function* () {
79
131
  });
80
132
 
81
133
  // src/implementation/mcp-client.ts
82
- import { ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
134
+ import {
135
+ ErrorCode as ErrorCode2,
136
+ ListToolsResultSchema,
137
+ McpError as ProtocolError2
138
+ } from "@modelcontextprotocol/sdk/types.js";
83
139
 
84
140
  // src/implementation/mcp-call.ts
85
141
  import {
@@ -208,6 +264,20 @@ var mcpCall = (client, name, input, context, timeoutMs, failure) => Effect_expor
208
264
  );
209
265
 
210
266
  // src/implementation/mcp-client.ts
267
+ var clientCodes = /* @__PURE__ */ new Set([
268
+ ErrorCode2.RequestTimeout,
269
+ ErrorCode2.ConnectionClosed
270
+ ]);
271
+ var answeredError = (error) => {
272
+ if (!(error instanceof ProtocolError2) || clientCodes.has(error.code)) return void 0;
273
+ const prefix = `MCP error ${error.code}: `;
274
+ return bodyUpstreamError({
275
+ error: {
276
+ code: error.code,
277
+ message: error.message.startsWith(prefix) ? error.message.slice(prefix.length) : error.message
278
+ }
279
+ });
280
+ };
211
281
  var mcpJsonSchemaValidator = {
212
282
  getValidator(document) {
213
283
  const decoder = Effect_exports.runSync(jsonSchemaDecoder(document));
@@ -233,7 +303,7 @@ function mcpClient(withClient, timeoutMs, failure) {
233
303
  do {
234
304
  const page = yield* Effect_exports.tryPromise({
235
305
  // This session only reads metadata. listTools() also eagerly compiles
236
- // every output validator; mcpOperations validates the selected tool on call.
306
+ // every output validator; mcpRouter validates the selected tool on call.
237
307
  try: (signal) => client.request(
238
308
  { method: "tools/list", params: cursor === void 0 ? {} : { cursor } },
239
309
  ListToolsResultSchema,
@@ -263,18 +333,52 @@ function mcpClient(withClient, timeoutMs, failure) {
263
333
  cursors.add(cursor);
264
334
  }
265
335
  } while (cursor !== void 0);
266
- return [...tools.values()];
336
+ const info = client.getServerVersion();
337
+ const instructions = client.getInstructions();
338
+ const icons = info?.icons?.flatMap(
339
+ (icon) => Option_exports.toArray(Schema_exports.decodeUnknownOption(RouterIcon)(icon))
340
+ );
341
+ const server = Schema_exports.decodeUnknownOption(McpServerHeader)({
342
+ ...info?.name === void 0 ? {} : { name: info.name },
343
+ ...info?.title === void 0 ? {} : { title: info.title },
344
+ ...info?.version === void 0 ? {} : { version: info.version },
345
+ ...info?.description === void 0 ? {} : { description: info.description },
346
+ ...info?.websiteUrl === void 0 ? {} : { websiteUrl: info.websiteUrl },
347
+ ...icons === void 0 ? {} : { icons },
348
+ ...instructions === void 0 ? {} : { instructions }
349
+ });
350
+ return {
351
+ tools: [...tools.values()],
352
+ server: Option_exports.getOrElse(server, () => ({}))
353
+ };
267
354
  })
268
355
  ).pipe(Effect_exports.withSpan("provider.mcp.discover"));
356
+ const check = withClient(
357
+ "discover",
358
+ (client) => Effect_exports.tryPromise({
359
+ try: (signal) => client.request({ method: "tools/list", params: {} }, ListToolsResultSchema, {
360
+ signal,
361
+ timeout: timeoutMs
362
+ }),
363
+ catch: (error) => failure("discover", error)
364
+ }).pipe(
365
+ Effect_exports.asVoid,
366
+ Effect_exports.withSpan("provider.mcp.request", {
367
+ kind: "client",
368
+ attributes: { "rpc.system.name": "jsonrpc", "rpc.method": "tools/list" }
369
+ })
370
+ )
371
+ ).pipe(Effect_exports.withSpan("provider.mcp.check"));
269
372
  const call = (name, input, context) => withClient("call", (client) => mcpCall(client, name, input, context, timeoutMs, failure)).pipe(
270
373
  Effect_exports.withSpan("provider.mcp.call", { attributes: { "mcp.tool.name": name } })
271
374
  );
272
- return { list, call };
375
+ return { list, check, call };
273
376
  }
274
377
 
275
378
  export {
276
379
  adaptMcpTool,
277
380
  adaptMcpTools,
381
+ answeredError,
278
382
  mcpJsonSchemaValidator,
279
383
  mcpClient
280
384
  };
@@ -4,7 +4,7 @@ import {
4
4
  fromWeb,
5
5
  layerMergedContext,
6
6
  make2 as make
7
- } from "./chunk-QKHR7BMF.js";
7
+ } from "./chunk-XGN5IFOZ.js";
8
8
  import {
9
9
  Reference,
10
10
  Service,
@@ -17,7 +17,7 @@ import {
17
17
  succeed4 as succeed,
18
18
  toReadableStreamEffect,
19
19
  tryPromise
20
- } from "./chunk-FW5HBOIK.js";
20
+ } from "./chunk-NXTXZ635.js";
21
21
  import {
22
22
  __export
23
23
  } from "./chunk-CZ7CSFO4.js";
@@ -1,6 +1,55 @@
1
+ import {
2
+ AccountId
3
+ } from "./chunk-PWF2DRJ3.js";
1
4
  import {
2
5
  Schema_exports
3
- } from "./chunk-FW5HBOIK.js";
6
+ } from "./chunk-NXTXZ635.js";
7
+
8
+ // src/contracts/failure.ts
9
+ var maxFailureMessageLength = 2048;
10
+ var FailureSource = Schema_exports.Literals(["app", "storage", "service"]);
11
+ var FailureName = Schema_exports.String.check(Schema_exports.isMaxLength(128));
12
+ var FailureCode = Schema_exports.String.check(Schema_exports.isMaxLength(128));
13
+ var FailureMessage = Schema_exports.String.check(Schema_exports.isMaxLength(maxFailureMessageLength));
14
+ var maxFailureFields = 8;
15
+ var maxFailureFieldLength = 256;
16
+ var FailureFieldName = Schema_exports.String.check(
17
+ Schema_exports.isPattern(/^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/)
18
+ );
19
+ var FailureFieldValue = Schema_exports.Union([
20
+ Schema_exports.String.check(Schema_exports.isMaxLength(maxFailureFieldLength)),
21
+ Schema_exports.Finite,
22
+ Schema_exports.Boolean
23
+ ]);
24
+ var FailureFields = Schema_exports.Record(FailureFieldName, FailureFieldValue).check(
25
+ Schema_exports.isMaxProperties(maxFailureFields)
26
+ );
27
+ var FailureDetail = {
28
+ source: Schema_exports.optionalKey(FailureSource),
29
+ errorName: Schema_exports.optionalKey(FailureName),
30
+ code: Schema_exports.optionalKey(FailureCode),
31
+ message: Schema_exports.optionalKey(FailureMessage),
32
+ fields: Schema_exports.optionalKey(FailureFields)
33
+ };
34
+ var maxUpstreamMessageLength = 1024;
35
+ var UpstreamError = Schema_exports.Struct({
36
+ code: Schema_exports.Union([
37
+ Schema_exports.Int,
38
+ Schema_exports.String.check(Schema_exports.isMinLength(1), Schema_exports.isMaxLength(128))
39
+ ]),
40
+ message: Schema_exports.optionalKey(Schema_exports.String.check(Schema_exports.isMaxLength(maxUpstreamMessageLength)))
41
+ });
42
+ var FailurePhase = Schema_exports.Literals(["connect", "discover", "call"]);
43
+
44
+ // src/contracts/provider-error.ts
45
+ var ProviderError = class extends Schema_exports.TaggedError()("ProviderError", {
46
+ reason: Schema_exports.Literals(["unauthorized", "forbidden", "rate_limited", "unavailable", "rejected"]),
47
+ status: Schema_exports.optional(Schema_exports.Int.check(Schema_exports.isBetween({ minimum: 100, maximum: 599 }))),
48
+ accountId: Schema_exports.optional(AccountId),
49
+ phase: Schema_exports.optional(FailurePhase),
50
+ upstream: Schema_exports.optional(UpstreamError)
51
+ }) {
52
+ };
4
53
 
5
54
  // ../app-cache/src/contracts/cache.ts
6
55
  var CacheError = class extends Schema_exports.TaggedError()("CacheError", {
@@ -76,6 +125,21 @@ var CacheReply = Schema_exports.Union([
76
125
  ]);
77
126
 
78
127
  export {
128
+ maxFailureMessageLength,
129
+ FailureSource,
130
+ FailureName,
131
+ FailureCode,
132
+ FailureMessage,
133
+ maxFailureFields,
134
+ maxFailureFieldLength,
135
+ FailureFieldName,
136
+ FailureFieldValue,
137
+ FailureFields,
138
+ FailureDetail,
139
+ maxUpstreamMessageLength,
140
+ UpstreamError,
141
+ FailurePhase,
142
+ ProviderError,
79
143
  CacheError,
80
144
  cacheLimits,
81
145
  CacheEntry,