@yolk-sdk/mcp 0.1.0-canary.13 → 0.1.0-canary.130

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 (164) hide show
  1. package/README.md +393 -40
  2. package/dist/client/client.d.mts +83 -19
  3. package/dist/client/client.d.mts.map +1 -1
  4. package/dist/client/client.mjs +599 -106
  5. package/dist/client/client.mjs.map +1 -1
  6. package/dist/client/config.d.mts +7 -10
  7. package/dist/client/config.d.mts.map +1 -1
  8. package/dist/client/config.mjs +1 -2
  9. package/dist/client/effect-fetch.d.mts +4 -0
  10. package/dist/client/effect-fetch.d.mts.map +1 -0
  11. package/dist/client/effect-fetch.mjs +35 -0
  12. package/dist/client/effect-fetch.mjs.map +1 -0
  13. package/dist/client/elicitation.d.mts +176 -0
  14. package/dist/client/elicitation.d.mts.map +1 -0
  15. package/dist/client/elicitation.mjs +508 -0
  16. package/dist/client/elicitation.mjs.map +1 -0
  17. package/dist/client/errors.d.mts +36 -7
  18. package/dist/client/errors.d.mts.map +1 -1
  19. package/dist/client/errors.mjs +39 -4
  20. package/dist/client/errors.mjs.map +1 -1
  21. package/dist/client/index.d.mts +6 -4
  22. package/dist/client/index.mjs +6 -4
  23. package/dist/client/node.d.mts +8 -11
  24. package/dist/client/node.d.mts.map +1 -1
  25. package/dist/client/node.mjs +2 -2
  26. package/dist/client/node.mjs.map +1 -1
  27. package/dist/client/protocol.d.mts +150 -56
  28. package/dist/client/protocol.d.mts.map +1 -1
  29. package/dist/client/protocol.mjs +268 -39
  30. package/dist/client/protocol.mjs.map +1 -1
  31. package/dist/conformance/auth-rejected.d.mts +4 -0
  32. package/dist/conformance/auth-rejected.d.mts.map +1 -0
  33. package/dist/conformance/auth-rejected.mjs +19 -0
  34. package/dist/conformance/auth-rejected.mjs.map +1 -0
  35. package/dist/conformance/call-gate.d.mts +14 -0
  36. package/dist/conformance/call-gate.d.mts.map +1 -0
  37. package/dist/conformance/call-gate.mjs +133 -0
  38. package/dist/conformance/call-gate.mjs.map +1 -0
  39. package/dist/conformance/call-read.d.mts +6 -0
  40. package/dist/conformance/call-read.d.mts.map +1 -0
  41. package/dist/conformance/call-read.mjs +24 -0
  42. package/dist/conformance/call-read.mjs.map +1 -0
  43. package/dist/conformance/call-tool-error.d.mts +5 -0
  44. package/dist/conformance/call-tool-error.d.mts.map +1 -0
  45. package/dist/conformance/call-tool-error.mjs +23 -0
  46. package/dist/conformance/call-tool-error.mjs.map +1 -0
  47. package/dist/conformance/cases.d.mts +25 -0
  48. package/dist/conformance/cases.d.mts.map +1 -0
  49. package/dist/conformance/cases.mjs +717 -0
  50. package/dist/conformance/cases.mjs.map +1 -0
  51. package/dist/conformance/elicitation-declaration.d.mts +6 -0
  52. package/dist/conformance/elicitation-declaration.d.mts.map +1 -0
  53. package/dist/conformance/elicitation-declaration.mjs +20 -0
  54. package/dist/conformance/elicitation-declaration.mjs.map +1 -0
  55. package/dist/conformance/index.d.mts +25 -0
  56. package/dist/conformance/index.d.mts.map +1 -0
  57. package/dist/conformance/index.mjs +42 -0
  58. package/dist/conformance/index.mjs.map +1 -0
  59. package/dist/conformance/json.d.mts +11 -0
  60. package/dist/conformance/json.d.mts.map +1 -0
  61. package/dist/conformance/json.mjs +30 -0
  62. package/dist/conformance/json.mjs.map +1 -0
  63. package/dist/conformance/legacy-session.d.mts +7 -0
  64. package/dist/conformance/legacy-session.d.mts.map +1 -0
  65. package/dist/conformance/legacy-session.mjs +15 -0
  66. package/dist/conformance/legacy-session.mjs.map +1 -0
  67. package/dist/conformance/modern-stateless.d.mts +7 -0
  68. package/dist/conformance/modern-stateless.d.mts.map +1 -0
  69. package/dist/conformance/modern-stateless.mjs +24 -0
  70. package/dist/conformance/modern-stateless.mjs.map +1 -0
  71. package/dist/conformance/negotiation-era.d.mts +6 -0
  72. package/dist/conformance/negotiation-era.d.mts.map +1 -0
  73. package/dist/conformance/negotiation-era.mjs +20 -0
  74. package/dist/conformance/negotiation-era.mjs.map +1 -0
  75. package/dist/conformance/observe.d.mts +78 -0
  76. package/dist/conformance/observe.d.mts.map +1 -0
  77. package/dist/conformance/observe.mjs +212 -0
  78. package/dist/conformance/observe.mjs.map +1 -0
  79. package/dist/conformance/param-value.d.mts +12 -0
  80. package/dist/conformance/param-value.d.mts.map +1 -0
  81. package/dist/conformance/param-value.mjs +22 -0
  82. package/dist/conformance/param-value.mjs.map +1 -0
  83. package/dist/conformance/response-encoding.d.mts +9 -0
  84. package/dist/conformance/response-encoding.d.mts.map +1 -0
  85. package/dist/conformance/response-encoding.mjs +23 -0
  86. package/dist/conformance/response-encoding.mjs.map +1 -0
  87. package/dist/conformance/sse.d.mts +14 -0
  88. package/dist/conformance/sse.d.mts.map +1 -0
  89. package/dist/conformance/sse.mjs +49 -0
  90. package/dist/conformance/sse.mjs.map +1 -0
  91. package/dist/conformance/synthetic.d.mts +127 -0
  92. package/dist/conformance/synthetic.d.mts.map +1 -0
  93. package/dist/conformance/synthetic.mjs +449 -0
  94. package/dist/conformance/synthetic.mjs.map +1 -0
  95. package/dist/conformance/target.d.mts +108 -0
  96. package/dist/conformance/target.d.mts.map +1 -0
  97. package/dist/conformance/target.mjs +77 -0
  98. package/dist/conformance/target.mjs.map +1 -0
  99. package/dist/conformance/tools-list.d.mts +6 -0
  100. package/dist/conformance/tools-list.d.mts.map +1 -0
  101. package/dist/conformance/tools-list.mjs +23 -0
  102. package/dist/conformance/tools-list.mjs.map +1 -0
  103. package/dist/conformance/unknown-tool.d.mts +9 -0
  104. package/dist/conformance/unknown-tool.d.mts.map +1 -0
  105. package/dist/conformance/unknown-tool.mjs +39 -0
  106. package/dist/conformance/unknown-tool.mjs.map +1 -0
  107. package/dist/core.d.mts +1 -0
  108. package/dist/core.mjs +2 -0
  109. package/dist/index.d.mts +1 -1
  110. package/dist/server/approval.d.mts +109 -0
  111. package/dist/server/approval.d.mts.map +1 -0
  112. package/dist/server/approval.mjs +155 -0
  113. package/dist/server/approval.mjs.map +1 -0
  114. package/dist/server/errors.d.mts +2 -5
  115. package/dist/server/errors.d.mts.map +1 -1
  116. package/dist/server/errors.mjs +2 -3
  117. package/dist/server/errors.mjs.map +1 -1
  118. package/dist/server/index.d.mts +4 -2
  119. package/dist/server/index.mjs +3 -1
  120. package/dist/server/node.d.mts +1 -0
  121. package/dist/server/node.mjs +2 -0
  122. package/dist/server/server.d.mts +35 -7
  123. package/dist/server/server.d.mts.map +1 -1
  124. package/dist/server/server.mjs +223 -73
  125. package/dist/server/server.mjs.map +1 -1
  126. package/dist/server/stdio.d.mts +1 -5
  127. package/dist/server/stdio.d.mts.map +1 -1
  128. package/dist/server/stdio.mjs +1 -2
  129. package/dist/server/stdio.mjs.map +1 -1
  130. package/package.json +26 -6
  131. package/src/client/README.md +19 -15
  132. package/src/client/client.ts +1108 -186
  133. package/src/client/effect-fetch.ts +64 -0
  134. package/src/client/elicitation.ts +936 -0
  135. package/src/client/errors.ts +49 -1
  136. package/src/client/index.ts +61 -4
  137. package/src/client/node.ts +2 -0
  138. package/src/client/protocol.ts +472 -50
  139. package/src/conformance/auth-rejected.ts +26 -0
  140. package/src/conformance/call-gate.ts +268 -0
  141. package/src/conformance/call-read.ts +37 -0
  142. package/src/conformance/call-tool-error.ts +39 -0
  143. package/src/conformance/cases.ts +1426 -0
  144. package/src/conformance/elicitation-declaration.ts +25 -0
  145. package/src/conformance/index.ts +166 -0
  146. package/src/conformance/json.ts +47 -0
  147. package/src/conformance/legacy-session.ts +13 -0
  148. package/src/conformance/modern-stateless.ts +25 -0
  149. package/src/conformance/negotiation-era.ts +20 -0
  150. package/src/conformance/observe.ts +375 -0
  151. package/src/conformance/param-value.ts +30 -0
  152. package/src/conformance/response-encoding.ts +23 -0
  153. package/src/conformance/sse.ts +66 -0
  154. package/src/conformance/synthetic.ts +511 -0
  155. package/src/conformance/target.ts +143 -0
  156. package/src/conformance/tools-list.ts +30 -0
  157. package/src/conformance/unknown-tool.ts +50 -0
  158. package/src/core.ts +1 -0
  159. package/src/server/README.md +11 -13
  160. package/src/server/approval.ts +292 -0
  161. package/src/server/errors.ts +1 -1
  162. package/src/server/index.ts +20 -1
  163. package/src/server/node.ts +1 -0
  164. package/src/server/server.ts +428 -65
package/README.md CHANGED
@@ -1,83 +1,436 @@
1
1
  # @yolk-sdk/mcp
2
2
 
3
- Domain-free Model Context Protocol client/server package.
3
+ MCP v2 (`2026-07-28`) client/server/protocol APIs, Effect/Yolk adapters, and legacy compatibility.
4
4
 
5
- Root export is intentionally tiny. Import client, protocol, and server APIs from explicit subpaths.
5
+ The root export is intentionally empty. Import APIs from explicit subpaths.
6
+
7
+ ## Tool schema admission
8
+
9
+ Yolk's `tools/list` adapter admits `inputSchema` as the object arm of
10
+ `@yolk-sdk/agent/protocol`'s `ToolJsonSchema`. This is plain finite JSON-data representation admission,
11
+ not JSON Schema meta-validation. Boolean roots fail in the typed `McpError` validation channel;
12
+ omitted schemas still default to `{ type: 'object', additionalProperties: true }`.
13
+ Tool arguments/results remain opaque until their execution/provider boundary.
6
14
 
7
15
  ## Install
8
16
 
9
17
  ```bash
10
- pnpm add @yolk-sdk/mcp@canary @yolk-sdk/agent@canary effect
18
+ pnpm add @yolk-sdk/mcp@canary @yolk-sdk/agent@canary effect@4.1.2
11
19
  ```
12
20
 
21
+ Running the experimental `@yolk-sdk/mcp/conformance` cases? Also add `@yolk-sdk/conformance@canary` (usually as a dev dependency); the examples import `@yolk-sdk/conformance/*` subpaths directly.
22
+
13
23
  Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
24
+ Use the SDK's matching Effect version (`4.1.2`) in host code.
25
+ Published package metadata requires Node.js 22+; `client/node` and `server/node` are Node-only.
14
26
 
15
27
  ## Subpaths
16
28
 
17
- | Subpath | Purpose |
18
- | --- | --- |
19
- | `@yolk-sdk/mcp/client` | Remote/local MCP config, tool listing/calling, protocol adapters |
20
- | `@yolk-sdk/mcp/client/node` | Node-only local stdio convenience helpers |
21
- | `@yolk-sdk/mcp/protocol` | JSON-RPC/MCP wire helpers |
22
- | `@yolk-sdk/mcp/server` | Tool-only MCP server primitives |
29
+ | Subpath | Purpose |
30
+ | --------------------------- | ---------------------------------------------------------------------- |
31
+ | `@yolk-sdk/mcp/client` | Official full-core client plus Effect/Yolk list and call helpers |
32
+ | `@yolk-sdk/mcp/client/node` | Official stdio client transport plus NodeServices convenience wrappers |
33
+ | `@yolk-sdk/mcp/conformance` | Experimental MCP conformance cases, target, seeds, and fixtures |
34
+ | `@yolk-sdk/mcp/core` | Official MCP v2 wire schemas |
35
+ | `@yolk-sdk/mcp/protocol` | Yolk JSON-RPC/MCP adapter helpers |
36
+ | `@yolk-sdk/mcp/server` | Official full-core server plus Yolk tool-only server primitives |
37
+ | `@yolk-sdk/mcp/server/node` | Official dual-era stdio server entrypoint |
38
+
39
+ Use `core` for the official full MCP wire-schema surface. Use `protocol` only for Yolk adapters and
40
+ legacy JSON-RPC helpers; it is not a replacement for the full-core APIs.
41
+
42
+ Yolk JSON-RPC initialize and tools/call construction uses Schema owners on both
43
+ `@yolk-sdk/mcp/client` and `@yolk-sdk/mcp/protocol` (same `protocol.ts`; no new export subpath):
44
+
45
+ | Symbol | Role |
46
+ | ------------------------- | ------------------------------------------------------------------------------ |
47
+ | `InitializeClientInfo` | `{ name, version }` |
48
+ | `InitializeParams` | `{ protocolVersion, capabilities, clientInfo }` |
49
+ | `InitializedNotification` | `{ jsonrpc: '2.0', method: 'notifications/initialized' }` (no `id` / `params`) |
50
+ | `ToolsCallParams` | `{ name, arguments? }` |
51
+
52
+ Prefer those Schema owners for new construction. Compatibility constructors
53
+ `makeJsonRpcRequest`, `makeInitializeParams`, and `makeInitializedNotification` remain and build
54
+ through the schemas. `makeJsonRpcRequest` still omits `params` when `undefined`.
23
55
 
24
56
  ## Imports
25
57
 
26
58
  ```ts
27
- import { listMcpTools } from '@yolk-sdk/mcp/client'
28
- import { listMcpToolsNode } from '@yolk-sdk/mcp/client/node'
29
- import { makeJsonRpcRequest } from '@yolk-sdk/mcp/protocol'
30
- import { makeMcpToolServer } from '@yolk-sdk/mcp/server'
59
+ import { Client } from '@yolk-sdk/mcp/client'
60
+ import { listLocalMcpServerToolsNode } from '@yolk-sdk/mcp/client/node'
61
+ import * as McpCore from '@yolk-sdk/mcp/core'
62
+ import { McpServer } from '@yolk-sdk/mcp/server'
63
+ import { serveStdio } from '@yolk-sdk/mcp/server/node'
31
64
  ```
32
65
 
33
- ## Remote client
66
+ ## Use the full MCP v2 client
67
+
68
+ The official client surface supports tools, resources, prompts, completions, MRTR, response caching, subscriptions, OAuth helpers, and legacy negotiation.
69
+
70
+ ```ts
71
+ import { Client, StreamableHTTPClientTransport } from '@yolk-sdk/mcp/client'
72
+
73
+ const client = new Client(
74
+ { name: 'my-app', version: '1.0.0' },
75
+ { versionNegotiation: { mode: 'auto' } }
76
+ )
77
+
78
+ await client.connect(new StreamableHTTPClientTransport(new URL('https://example.com/mcp')))
79
+
80
+ const { tools } = await client.listTools()
81
+ ```
82
+
83
+ `mode: 'auto'` prefers stateless MCP `2026-07-28` and falls back to an initialize-based server. Pin `{ pin: '2026-07-28' }` for modern-only behavior. The upstream `Client` default remains legacy for compatibility.
84
+
85
+ ## Use Effect/Yolk tool adapters
86
+
87
+ The high-level remote helpers use the official v2 client over an Effect `HttpClient` bridge. They negotiate modern MCP automatically, aggregate paginated tool lists, honor v2 routing headers and cache hints, and fall back to legacy servers. Discovered tools preserve provider `title`, `inputSchema`, `outputSchema`, and `annotations` metadata. Adapted tools are typed ([ADR 0013](https://github.com/magoz/yolk-sdk/blob/main/docs/adr/0013-typed-tool-results.md)): `ToolDef.outputSchema` is `{ value, files }` (`value` the server's `outputSchema`, unknown without one) and a successful call's `structuredContent` is `{ value, files }`: `value` is the server's `structuredContent` (checked against the listed `outputSchema`, remote and local), else the text of its text blocks and embedded text resources parsed once when it is one JSON object or array, else the text (`resource_link` blocks never enter it); blobs, images and audio become file fields (`FileRef`, or `FileUnavailable` without a file store). The model still sees the server's content, unchanged for results without file blocks. Registrations of adapted tools set `decodeOutput: mcpToolOutputDecoder` (`resolveTools` checks every result with it and fails `output_validation_required` without it). Files are stored when the call runs, through the `ToolFileCapture` `resolveTools` provides to its registrations; a call outside one (a HITL route calling `resumeRemoteMcpServerToolCall`, a direct `callLocalMcpServerTool`) passes `fileCapture: makeToolFileCapture({ store })` from `@yolk-sdk/agent/tools` on its input, or every file is `FileUnavailable` (`no file store`) and the blob is lost. Pass `exposure` in the options (a `ToolExposure` value or `(tool, serverName) => ToolExposure`) to set code mode `callableBy`/`discovery` on the adapted definitions; `mcpToolToToolDef` takes the same option.
34
88
 
35
89
  ```ts
36
90
  import { Effect } from 'effect'
91
+ import { FetchHttpClient } from 'effect/http'
37
92
  import { listRemoteMcpServerTools } from '@yolk-sdk/mcp/client'
38
93
 
39
- const tools = listRemoteMcpServerTools({
40
- id: 'docs',
41
- transport: { kind: 'http', url: 'https://example.com/mcp' },
42
- allowHttpLocalhost: false
94
+ const tools = await Effect.runPromise(
95
+ listRemoteMcpServerTools({
96
+ name: 'docs',
97
+ type: 'remote',
98
+ url: 'https://example.com/mcp'
99
+ }).pipe(Effect.provide(FetchHttpClient.layer))
100
+ )
101
+ ```
102
+
103
+ Use `McpClientOptions.sdk` for official client options such as capabilities, MRTR, and shared response caching. Set `McpClientOptions.configureClient` to register elicitation or sampling handlers before connection. Use a persistent official `Client` directly for long-lived subscriptions and progress streams.
104
+
105
+ ## Form elicitation for durable hosts (MRTR)
106
+
107
+ A server can pause a `tools/call` with an MCP `2026-07-28` `InputRequiredResult` (for example to
108
+ confirm a destructive tool with a form). A durable host cannot block on a person inside a tool
109
+ step, so Yolk returns the pause as data and resumes later, possibly in another process:
110
+
111
+ ```ts
112
+ import { Effect } from 'effect'
113
+ import { makeToolFileCapture } from '@yolk-sdk/agent/tools'
114
+ import {
115
+ callRemoteMcpServerToolResumable,
116
+ resumeRemoteMcpServerToolCall,
117
+ type McpClientOptions,
118
+ type McpElicitationResponse,
119
+ type McpElicitationResponses
120
+ } from '@yolk-sdk/mcp/client'
121
+
122
+ const options: McpClientOptions = { elicitation: { form: true } }
123
+
124
+ // A resume runs outside `resolveTools`: pass a capture (`makeToolFileCapture({ store })` from
125
+ // `@yolk-sdk/agent/tools`) or the resumed result's blobs are `FileUnavailable` and lost.
126
+ const call = {
127
+ config,
128
+ mcpToolName: 'delete-invoice',
129
+ toolCallId: 'call_1',
130
+ params,
131
+ options,
132
+ fileCapture: makeToolFileCapture({ store })
133
+ }
134
+
135
+ const step = Effect.gen(function* () {
136
+ const outcome = yield* callRemoteMcpServerToolResumable(call)
137
+
138
+ if (outcome._tag === 'Complete') return outcome.result
139
+
140
+ // Integration fragment: persist outcome.inputRequired (a Schema class) and show its forms to a
141
+ // person; resume later, possibly in another process, with their decisions, one per form keyed
142
+ // by its `key`. This sketch declines every form (the safe default when nobody decides); never
143
+ // auto-accept a confirmation.
144
+ const decline: McpElicitationResponse = { action: 'decline' }
145
+ const responses: McpElicitationResponses = Object.fromEntries(
146
+ outcome.inputRequired.elicitations.map(form => [form.key, decline])
147
+ )
148
+
149
+ return yield* resumeRemoteMcpServerToolCall({
150
+ ...call,
151
+ inputRequired: outcome.inputRequired,
152
+ responses
153
+ })
154
+ })
155
+ ```
156
+
157
+ - `elicitation: { form: true }` is the opt-in. Only then do the listing and the resumable call
158
+ functions declare `elicitation.form`, in the per-request `_meta` client capabilities of a modern
159
+ connection. Nothing declares it in a legacy `initialize`, and `callRemoteMcpServerTool` (which
160
+ cannot represent a pause) never declares it.
161
+ - The outcome is `Complete` (a `ToolResult`) or `InputRequired` (`McpInputRequired`: Schema-decoded
162
+ form elicitations with `key`, `message` and `requestedSchema`, the opaque `requestState`, the
163
+ binding `mcpToolName` and `argumentsDigest`, and the listed tool definition `tool`).
164
+ - The bound is 256 KiB of JSON by default (`elicitation.maxInputRequiredBytes`, a positive
165
+ integer, checked before connecting) plus 16 requests, applied to two parts separately. The
166
+ server-provided pause (the `InputRequiredResult` and the decoded pause without its tool
167
+ definition) is checked after the response body is buffered, so it bounds what is decoded and
168
+ persisted, not what is received. The listed tool definition is checked before the call: a tool
169
+ whose definition alone exceeds the bound fails `too_large` with nothing sent, so a pause the
170
+ server already made is never lost to the bound. A persisted pause is at most about twice the
171
+ bound.
172
+ - The resume is re-sent as a new request on a new connection with the same tool call (checked
173
+ against the pause's binding), the exact `requestState`, and the decisions (`accept` with
174
+ `content`, `decline`, `cancel`) as `inputResponses`. It lists nothing: it calls with the pause's
175
+ tool definition (for `x-mcp-header` mirroring) and checks the result against its `outputSchema`.
176
+ A carried definition that is not a valid MCP tool fails `malformed` before sending. Because the
177
+ definition is passed as `toolDefinition`, the official client does not re-list and retry after a
178
+ `HEADER_MISMATCH` (`-32020`): a server that changed the tool's `x-mcp-header` declarations since
179
+ the pause answers `McpError` (`cause: 'protocol'`). Decisions are checked before anything is sent
180
+ (type (integer vs number), `required`, `const`, `enum`, titled `oneOf`, `minLength`/`maxLength`, `format` (email, uri, date, date-time), `minimum`/`maximum`, `items.enum`, titled `items.anyOf`, `minItems`/`maxItems`); the server validates them again. The server may pause again.
181
+ - The carried definition is `name`, `inputSchema` and `outputSchema`: the only `toolDefinition`
182
+ fields the pinned official client reads. `annotations`, `_meta` and `execution` (task support,
183
+ which its `2026-07-28` codec removes from listings) are not carried.
184
+ - The pause is decoded from the raw `input_required` response as the server sent it: the response
185
+ the official client resolves the call with (the first whose id matches under the client's own
186
+ `Number(id)` coercion), captured at the transport before the client normalises it (it would drop
187
+ a non-string `requestState` and turn non-object `inputRequests` into `{}`). Such a response, or a
188
+ matched one whose id is not identical to the call's (`"1"` for `1`), fails `malformed`; other
189
+ ids, notifications and later duplicates are ignored.
190
+ - Formats are syntax checks, all linear: `date`/`date-time` per RFC 3339 on the proleptic
191
+ Gregorian calendar (years 0000-9999; second `60` only at `23:59:60` UTC after the offset); `uri`
192
+ an absolute RFC 3986 URI (scheme, then unreserved, sub-delims and the delimiters, other characters
193
+ percent-encoded; IP literals per the `IPv6address` grammar or `IPvFuture`; no WHATWG
194
+ normalisation);
195
+ `email` a pragmatic mailbox: a dot-atom local part (RFC 5322 `atext` runs joined by single dots,
196
+ at most 64 characters; no quoted strings), `@`, and a hostname of at least two LDH labels.
197
+ - Typed failures: `McpInputRequiredError` (`malformed`, `too_large`, `unsupported_request` for URL
198
+ mode, sampling, roots or input without the opt-in, `invalid_responses`, `mismatched_resume`,
199
+ `unsupported_era`) and `McpClientCapabilityRequiredError` for MCP `-32021`.
200
+ - Legacy-era elicitation (a server-initiated request answered while the call's stream is open) is
201
+ not supported; resuming against a legacy connection fails with `unsupported_era`.
202
+
203
+ ### Files in tool results
204
+
205
+ A successful call's `structuredContent` is `{ value, files }`
206
+ ([ADR 0013](https://github.com/magoz/yolk-sdk/blob/main/docs/adr/0013-typed-tool-results.md)):
207
+ embedded text resources go into `value` with the text blocks, and blobs, images and audio become
208
+ `files`, each a `FileRef` `{ fileId, name, mimeType, size }` (blob names come from the URI) or a
209
+ `FileUnavailable` `{ unavailable, name, mimeType }`. The model sees blob resources as file labels
210
+ (never base64) and images and audio as the server sent them, followed by their label once stored.
211
+
212
+ Files are stored while the call runs. Inside a `resolveTools` registration they go to the
213
+ resolution's `files` store. A call made anywhere else (a HITL route resuming
214
+ `resumeRemoteMcpServerToolCall`, a direct `callRemoteMcpServerTool` or `callLocalMcpServerTool`)
215
+ passes `fileCapture: makeToolFileCapture({ store })` (`@yolk-sdk/agent/tools`); without it every
216
+ file is `FileUnavailable` (`no file store`), and the blob cannot be fetched again later. See
217
+ [Move files between tools](https://github.com/magoz/yolk-sdk/blob/main/apps/docs/content/docs/integrations/files.mdx).
218
+
219
+ When adapting Yolk tools into an MCP server (`makeMcpToolServer`), an inline `FilePart` leaves as
220
+ an embedded resource blob and a stored (or omitted) one as its label.
221
+
222
+ ## Connect to a local stdio server
223
+
224
+ Node hosts can use the convenience wrappers from `client/node`:
225
+
226
+ ```ts
227
+ import { Effect } from 'effect'
228
+ import { listLocalMcpServerToolsNode } from '@yolk-sdk/mcp/client/node'
229
+
230
+ const tools = await Effect.runPromise(
231
+ listLocalMcpServerToolsNode(
232
+ {
233
+ name: 'local-tools',
234
+ type: 'local',
235
+ command: [process.execPath, './mcp-server.mjs'],
236
+ environment: {}
237
+ },
238
+ { securityPolicy: { allowLocalServers: true, allowDevHttpLocalhost: false } }
239
+ )
240
+ )
241
+ ```
242
+
243
+ Local servers are disabled by default. The host must explicitly allow them, choose a trusted
244
+ command, and provide the complete child environment; configured environment values do not extend
245
+ the host environment.
246
+
247
+ ## Build a full MCP server
248
+
249
+ Use the official server surface for tools, resources, prompts, completions, MRTR, and subscriptions:
250
+
251
+ ```ts
252
+ import { McpServer, createMcpHandler } from '@yolk-sdk/mcp/server'
253
+
254
+ const handler = createMcpHandler(() => {
255
+ const server = new McpServer({ name: 'my-server', version: '1.0.0' })
256
+ // Register tools, resources, and prompts here.
257
+ return server
43
258
  })
44
259
 
45
- // Host provides HttpClient layer and auth policy.
46
- Effect.runPromise(tools)
260
+ export default { fetch: handler.fetch }
47
261
  ```
48
262
 
49
- ## Local stdio client
263
+ `createMcpHandler` serves stateless `2026-07-28` and legacy initialize-based HTTP clients from one endpoint. Validate `Origin` and `Host` before calling `handler.fetch`.
264
+
265
+ For dual-era Node stdio, import `serveStdio` from `@yolk-sdk/mcp/server/node`. This subpath owns the
266
+ Node stdio transport only; the host owns authorization, process lifecycle, logging, and deployment
267
+ policy.
268
+
269
+ ## Adapt Yolk tools into MCP
50
270
 
51
271
  ```ts
52
- import { listMcpToolsNode } from '@yolk-sdk/mcp/client/node'
272
+ import { makeMcpToolServer, runStdioMcpServer } from '@yolk-sdk/mcp/server'
53
273
  ```
54
274
 
55
- `@yolk-sdk/mcp/client/node` may use Node process APIs. Keep Worker/browser imports on `@yolk-sdk/mcp/client`.
275
+ `makeMcpToolServer` exposes approved Yolk tools. Its HTTP handler accepts both stateless v2 and legacy requests, validates browser origins against the endpoint hostname by default, and preserves MCP content and structured results. No tool call outlives `handleHttpRequest` (an SSE answer is read to its end, and a read failure answers 500 with `-32603`; a call still running is interrupted and awaited), so its requirements may come from a scoped request layer; a cancelled request that carries `MCP-Protocol-Version` interrupts the tool. `subscriptions/listen` answers its acknowledgement plus a `complete` result: this tool-only server has no change notifications. `runStdioMcpServer` remains the Effect-native minimal stdio adapter; use `serveStdio` for the full modern stdio surface.
56
276
 
57
- ## Server
277
+ For legacy HTTP requests, an unreadable or already consumed body produces a JSON-RPC
278
+ invalid-request error (`-32600`) rather than an Effect defect. Malformed JSON remains a parse error
279
+ (`-32700`).
280
+
281
+ A tool may carry `annotations` (`title`, `readOnlyHint`, `destructiveHint`, `idempotentHint`,
282
+ `openWorldHint`), listed as the MCP tool annotations.
283
+
284
+ ### Ask the user before a tool runs
285
+
286
+ An approval tool (`McpServerApprovalTool`) runs only after the user accepts the call through MCP
287
+ form elicitation over multi round-trip requests (`2026-07-28`). Give the server `approvals`:
58
288
 
59
289
  ```ts
60
- import { makeMcpToolServer } from '@yolk-sdk/mcp/server'
290
+ import { Effect } from 'effect'
291
+ import { ToolDef, ToolResult } from '@yolk-sdk/agent/protocol'
292
+ import { makeMcpToolServer, type McpServerTool } from '@yolk-sdk/mcp/server'
293
+
294
+ declare const signingKey: string // at least 32 bytes, the same on every instance
295
+ declare const tokenId: string // the authenticated principal of this request
296
+
297
+ const send: McpServerTool = {
298
+ def: ToolDef.make({
299
+ name: 'send',
300
+ description: 'Send a message',
301
+ parameters: { type: 'object' }
302
+ }),
303
+ annotations: { destructiveHint: false },
304
+ approval: { message: call => Effect.succeed(`Send ${JSON.stringify(call.params)}?`) },
305
+ execute: (call, approved) =>
306
+ // Run the call at most once per `approved.approvalId`.
307
+ Effect.succeed(ToolResult.make({ toolCallId: call.id, content: 'sent' }))
308
+ }
309
+
310
+ const server = makeMcpToolServer({
311
+ name: 'my-server',
312
+ version: '1.0.0',
313
+ tools: [send],
314
+ approvals: { key: signingKey, principal: tokenId }
315
+ })
61
316
  ```
62
317
 
63
- The server is tool-only. Hosts own HTTP routes, auth, deployment, and tool policy.
64
- Protocol document parts are exposed as MCP resource blocks with encoded `file:///...` URIs.
318
+ - The first call answers an `input_required` result: one form elicitation under
319
+ `approvalInputKey` (`'approval'`, no fields: the client offers accept, decline and cancel) with
320
+ the policy's `message`, and a `requestState` signed by the SDK's `createRequestStateCodec`
321
+ (HMAC-SHA256, `ttlSeconds` default 600) and bound to `principal` and `tools/call`. Its payload
322
+ names the tool, the digest of the arguments (`mcpArgumentsDigest`) and a fresh `approvalId`.
323
+ - Only a retry that answers `accept` with a state that verifies for the same principal, tool and
324
+ arguments runs the tool, with `{ approvalId }`. A decline or a cancel answers an error result.
325
+ A state that fails verification, belongs to another call, or arrives without a decision asks
326
+ again with a new state.
327
+ - Build the server per request: `principal` is fixed when it is built. The state is also bound to
328
+ the server's `name`.
329
+ - The server keeps no state, so an accepted retry replays until the state expires: key once-only
330
+ execution on `approvalId`.
331
+ - A direct tool refuses a call that answers an approval prompt (a `requestState` or an answer under
332
+ `approvalInputKey`, `staleApprovalMessage`): when the host's policy turned an approval tool into a
333
+ direct one between the prompt and the answer, neither a decline nor a replayed accept becomes a
334
+ plain call.
335
+ - A request that does not declare form elicitation gets an error result and nothing runs.
336
+ Approval tools are not offered on 2025-era requests (stateless serving cannot route the
337
+ client's answer back to the open call) or on the header-less JSON path, and not at all without
338
+ `approvals`. Unusable `approvals` (a key under 32 bytes, an empty `principal`, a `ttlSeconds`
339
+ that is not a positive integer) leave them listed but answering an error result that names the
340
+ problem.
65
341
 
66
- ## Host responsibilities
342
+ ## Conformance cases (experimental)
67
343
 
68
- - Own persisted MCP server config, auth, and product tool policy.
69
- - Provide HTTP runtime layers and credentials for remote MCP.
70
- - Keep Node stdio usage behind Node-only hosts.
344
+ `@yolk-sdk/mcp/conformance` holds nine `read` conformance cases for `@yolk-sdk/conformance/runner`,
345
+ plus one opt-in `read` case, `mcpElicitationDeclarationCase` (fixtures:
346
+ `mcpConformanceElicitationFixtures`), for hosts that set `McpClientOptions.elicitation`; it only
347
+ lists, so it never triggers a confirmation.
348
+ They check the wire claims the remote client relies on: era negotiation, the modern stateless
349
+ headers, the legacy session, response encoding, the tool listing, a read call, a tool error, an
350
+ unknown tool, and a rejected credential. Every case runs the real `listRemoteMcpServerTools` and
351
+ `callRemoteMcpServerTool` through an observing `HttpClient`. The observer never sends a request of
352
+ its own (it may refuse to forward one, see below). It never keeps `authorization` or any other
353
+ credential-named header, never keeps the URL query, and never keeps a raw `mcp-session-id` value
354
+ (only evidence: an equality class such as `session#1`). It keeps request and response bodies
355
+ exactly as received; they may reflect anything a server echoes, credentials and session ids
356
+ included, so they are sensitive: in memory only, never logged or persisted. Persisted or printed
357
+ output is the live runner's job.
71
358
 
72
- ## Boundaries
359
+ A case that calls a tool (`mcp.modern.stateless`, `mcp.errors.unknown-tool`,
360
+ `mcp.tools.call-read`, `mcp.tools.call-tool-error`) is protected by the observer's fail-closed call
361
+ gate. The `tools/call` is forwarded only when every exchange of the call operation is fully
362
+ understood, that operation's own listing (made right before the call) is complete, and that
363
+ listing proves the call safe: the absent tool is not listed, or the read tool is marked
364
+ `readOnlyHint: true`. Anything else, including any uncertainty (a 202 answer to a request, a
365
+ message delivered on a GET, an unparseable body, an unterminated stream, two responses for one id,
366
+ an unknown shape), refuses to forward. A refusal before any forwarded call fails the precondition
367
+ with zero forwarded calls; a refused client retry after a forwarded call is reported as a retry.
368
+ Earlier preflight listings stay as friendly early failures. Answers are read as the SDK reads them:
369
+ JSON with `JSON.parse` semantics, and event streams with the SDK's own parser
370
+ (the same `eventsource-parser` the client resolves, verified in-repo by a parity test; a consumer
371
+ install whose package manager does not dedupe could still resolve two copies), fed the decoder
372
+ chunks the client's `TextDecoderStream` emits.
373
+
374
+ Mismatch messages carry only structural facts (methods, statuses, counts, positions, codes), never
375
+ body text or the target URL. A client failure a case re-raises is reported as the client words it
376
+ (it can quote a server body) and is sanitized by the runner. A host provides an `HttpClient`, an
377
+ `McpConformanceTarget` (server URL, headers, era, protocol version, timeout), and
378
+ `McpConformanceConfig` seeds. The cases name no product: provider targets and seeds live with the
379
+ provider. `selectMcpConformanceCases` leaves out the cases of the other era. The synthetic fixtures
380
+ replay on `https://mcp.example.test/modern/mcp` and `https://mcp.example.test/legacy/mcp`. See the
381
+ conformance API reference for every claim.
382
+
383
+ ```ts
384
+ import { Effect, Layer } from 'effect'
385
+ import { FetchHttpClient } from 'effect/http'
386
+ import { runConformance } from '@yolk-sdk/conformance/runner'
387
+ import {
388
+ McpConformanceConfig,
389
+ McpConformanceTarget,
390
+ mcpConformanceCases,
391
+ selectMcpConformanceCases
392
+ } from '@yolk-sdk/mcp/conformance'
73
393
 
74
- - App auth, persisted config, policy, and product tools stay outside this package.
75
- - Node convenience wrappers stay behind `@yolk-sdk/mcp/client/node`.
76
- - MCP may adapt to `@yolk-sdk/agent/protocol` tool types; agent loop/providers stay MCP-agnostic.
77
- - Remote MCP requires `https:` by default; localhost HTTP is explicit dev policy.
394
+ const target = {
395
+ name: 'docs',
396
+ url: 'https://example.com/mcp',
397
+ headers: {},
398
+ era: 'modern',
399
+ protocolVersion: '2026-07-28',
400
+ timeoutMs: 30_000
401
+ } as const
78
402
 
79
- ## Tree-shaking
403
+ const { applicable } = selectMcpConformanceCases(mcpConformanceCases, target.era)
404
+
405
+ const report = await Effect.runPromise(
406
+ runConformance(applicable, {
407
+ target: { kind: 'live', account: 'practice' },
408
+ layer: () =>
409
+ Layer.mergeAll(
410
+ FetchHttpClient.layer,
411
+ Layer.succeed(McpConformanceTarget, target),
412
+ Layer.succeed(McpConformanceConfig, {})
413
+ )
414
+ })
415
+ )
416
+ ```
417
+
418
+ No case is observed live yet. Only code under `src/conformance/` may import `@yolk-sdk/conformance`.
419
+
420
+ ## Host responsibilities
421
+
422
+ - Own persisted server config, credentials, authorization policy, and enabled capabilities.
423
+ - Partition private MCP caches by authorization context.
424
+ - Validate HTTP `Origin` and `Host` at deployment boundaries.
425
+ - Keep Node stdio usage behind trusted Node hosts and explicitly control child commands and environments.
426
+ - Treat tool annotations, server identity, icons, and request state as untrusted input.
427
+
428
+ Remote MCP requires HTTPS by default; localhost HTTP is an explicit development policy.
429
+
430
+ ## Boundaries
80
431
 
81
- - ESM package with `sideEffects: false`.
82
- - Explicit subpath exports only.
83
- - No wildcard exports or root feature barrel.
432
+ - MCP is external protocol infrastructure, not agent-loop or provider policy.
433
+ - `core`, `client`, and `server` expose protocol mechanics; Yolk adapters bridge generic tool and
434
+ content contracts only.
435
+ - App auth, credential storage, persisted server config, and product catalogs remain host-owned.
436
+ - Node process and stdio conveniences stay behind `client/node` and `server/node`.
@@ -1,40 +1,104 @@
1
1
  import { McpClientInfo, McpLocalServerConfig, McpRemoteServerConfig, McpSecurityPolicy, McpServerConfig } from "./config.mjs";
2
- import { McpError } from "./errors.mjs";
3
- import { mcpToolToToolDef } from "./protocol.mjs";
2
+ import { McpElicitationResponses, McpElicitationSupport, McpInputRequired, McpToolCallOutcome } from "./elicitation.mjs";
3
+ import { McpClientCapabilityRequiredError, McpError, McpInputRequiredError } from "./errors.mjs";
4
+ import { McpToolAnnotations, McpToolExposureResolver, mcpToolToToolDef } from "./protocol.mjs";
4
5
  import { Effect } from "effect";
5
- import { HttpClient } from "effect/unstable/http";
6
- import { ChildProcessSpawner } from "effect/unstable/process";
7
- import { ToolResult } from "@yolk-sdk/agent/protocol";
8
-
9
- //#region src/client/client.d.ts
10
- type McpClientOptions = {
6
+ import { Client, ClientOptions } from "@modelcontextprotocol/client";
7
+ import { HttpClient } from "effect/http";
8
+ import { ChildProcessSpawner } from "effect/process";
9
+ import { ToolFileCapture, ToolResult } from "@yolk-sdk/agent/protocol";
10
+ export type McpClientOptions = {
11
11
  readonly clientInfo?: McpClientInfo;
12
12
  readonly securityPolicy?: McpSecurityPolicy;
13
13
  readonly timeoutMs?: number;
14
+ readonly sdk?: ClientOptions;
15
+ readonly configureClient?: (client: Client) => void;
16
+ /** Code mode exposure of the listed tools' definitions (listing functions only). */
17
+ readonly exposure?: McpToolExposureResolver;
18
+ /**
19
+ * Opt-in MCP form elicitation (multi round-trip requests, protocol `2026-07-28`). When set, the
20
+ * remote listing and the resumable call functions declare `elicitation.form` in the per-request
21
+ * `_meta` client capabilities of a modern connection. It is never declared in a legacy
22
+ * `initialize` (legacy elicitation is a server-initiated request the host would have to answer
23
+ * synchronously), and `callRemoteMcpServerTool`, which cannot represent a paused call, never
24
+ * declares it.
25
+ */
26
+ readonly elicitation?: McpElicitationSupport;
14
27
  };
15
- type McpResolvedTool = {
28
+ export type McpResolvedTool = {
16
29
  readonly serverName: string;
17
30
  readonly mcpToolName: string;
31
+ readonly title?: string;
32
+ readonly outputSchema?: unknown;
33
+ readonly annotations?: McpToolAnnotations;
18
34
  readonly def: ReturnType<typeof mcpToolToToolDef>;
19
35
  };
20
- declare const listRemoteMcpServerTools: (config: McpRemoteServerConfig, options?: McpClientOptions) => Effect.Effect<ReadonlyArray<McpResolvedTool>, McpError, HttpClient.HttpClient>;
21
- declare const listLocalMcpServerTools: (config: McpLocalServerConfig, options?: McpClientOptions) => Effect.Effect<ReadonlyArray<McpResolvedTool>, McpError, ChildProcessSpawner.ChildProcessSpawner>;
22
- declare const listMcpServerTools: (config: McpServerConfig, options?: McpClientOptions) => Effect.Effect<readonly McpResolvedTool[], McpError, HttpClient.HttpClient | ChildProcessSpawner.ChildProcessSpawner>;
23
- type CallMcpServerToolInput = {
36
+ export declare const listRemoteMcpServerTools: (config: McpRemoteServerConfig, options?: McpClientOptions) => Effect.Effect<ReadonlyArray<McpResolvedTool>, McpError, HttpClient.HttpClient>;
37
+ export declare const listLocalMcpServerTools: (config: McpLocalServerConfig, options?: McpClientOptions) => Effect.Effect<ReadonlyArray<McpResolvedTool>, McpError, ChildProcessSpawner.ChildProcessSpawner>;
38
+ export declare const listMcpServerTools: (config: McpServerConfig, options?: McpClientOptions) => Effect.Effect<readonly McpResolvedTool[], McpError, ChildProcessSpawner.ChildProcessSpawner | HttpClient.HttpClient>;
39
+ export type CallMcpServerToolInput = {
24
40
  readonly config: McpServerConfig;
25
41
  readonly mcpToolName: string;
26
42
  readonly toolCallId: string;
27
43
  readonly params: unknown;
28
44
  readonly options?: McpClientOptions;
45
+ /**
46
+ * Stores the call's blobs, images and audio as file fields (ADR 0013), for example
47
+ * `makeToolFileCapture({ store })` from `@yolk-sdk/agent/tools`. Defaults to the ambient
48
+ * `ToolFileCapture`, which `resolveTools` provides around every registration; a call made
49
+ * outside one (a HITL route resuming a call, a host calling directly) needs this option, or
50
+ * every file is `FileUnavailable` (`no file store`).
51
+ */
52
+ readonly fileCapture?: ToolFileCapture['Service'];
29
53
  };
30
- declare const callRemoteMcpServerTool: (input: Omit<CallMcpServerToolInput, "config"> & {
54
+ export declare const callRemoteMcpServerTool: (input: Omit<CallMcpServerToolInput, 'config'> & {
31
55
  readonly config: McpRemoteServerConfig;
32
56
  }) => Effect.Effect<ToolResult, McpError, HttpClient.HttpClient>;
33
- declare const callLocalMcpServerTool: (input: Omit<CallMcpServerToolInput, "config"> & {
57
+ export type CallRemoteMcpServerToolInput = Omit<CallMcpServerToolInput, 'config'> & {
58
+ readonly config: McpRemoteServerConfig;
59
+ };
60
+ export type ResumeRemoteMcpServerToolCallInput = CallRemoteMcpServerToolInput & {
61
+ /** The paused call, exactly as the previous step answered it (persisted by the host). */
62
+ readonly inputRequired: McpInputRequired;
63
+ /** One decision per elicitation, keyed by `McpFormElicitation.key`. */
64
+ readonly responses: McpElicitationResponses;
65
+ };
66
+ export type McpResumableToolCallError = McpError | McpInputRequiredError | McpClientCapabilityRequiredError;
67
+ /**
68
+ * Calls a remote MCP tool and answers a typed outcome instead of blocking on input:
69
+ * `Complete` (the adapted result) or `InputRequired` (a serializable `McpInputRequired` the host
70
+ * persists, decides on, and passes to `resumeRemoteMcpServerToolCall`). Like
71
+ * `callRemoteMcpServerTool`, it lists tools on its own connection before calling; the pause
72
+ * carries the listed definition. Set `options.elicitation` to declare form elicitation; without
73
+ * it a server may refuse a tool that needs confirmation (`McpClientCapabilityRequiredError` for
74
+ * MCP `-32021`, or a tool error result).
75
+ */
76
+ export declare const callRemoteMcpServerToolResumable: (input: CallRemoteMcpServerToolInput) => Effect.Effect<McpToolCallOutcome, McpResumableToolCallError, HttpClient.HttpClient>;
77
+ /**
78
+ * Resumes a paused remote MCP tool call: the same tool call (same `mcpToolName` and `params`,
79
+ * checked against the pause's binding) is re-sent as a new request on a new connection, with the
80
+ * exact `requestState`, the host's decisions as `inputResponses`, and the pause's tool definition
81
+ * (no listing). The server may pause again (`InputRequired`). Fails with `McpInputRequiredError`
82
+ * before sending when the call does not match the pause (`mismatched_resume`) or `responses` do
83
+ * not match the elicitations (`invalid_responses`), and when the server now negotiates a legacy
84
+ * era (`unsupported_era`).
85
+ */
86
+ export declare const resumeRemoteMcpServerToolCall: (input: ResumeRemoteMcpServerToolCallInput) => Effect.Effect<McpToolCallOutcome, McpResumableToolCallError, HttpClient.HttpClient>;
87
+ /**
88
+ * Calls a local stdio MCP tool in one session, in order: `initialize`, then `tools/list`, awaited
89
+ * and decoded, then the output validator compiled, and only then `tools/call`. So anything that
90
+ * fails before the call (an `initialize` error, an `outputSchema` that is unusable or does not
91
+ * compile) sends no `tools/call`, nor does a broken session (a stdout line that is no JSON-RPC
92
+ * response, an early end before the listing's answer). A listing answered with an error or an
93
+ * undecodable result, or one that does not hold the tool (the first page only), does not fail
94
+ * the call: it runs without output validation (a value-free warning is logged;
95
+ * `mcpToolOutputDecoder` still checks the `{ value, files }` envelope). A successful result of a
96
+ * tool with a usable `outputSchema` must carry `structuredContent` that passes it, as on the
97
+ * remote calls (`assertStructuredOutput`).
98
+ */
99
+ export declare const callLocalMcpServerTool: (input: Omit<CallMcpServerToolInput, 'config'> & {
34
100
  readonly config: McpLocalServerConfig;
35
101
  }) => Effect.Effect<ToolResult, McpError, ChildProcessSpawner.ChildProcessSpawner>;
36
- declare const callMcpServerTool: (input: CallMcpServerToolInput) => Effect.Effect<ToolResult, McpError, ChildProcessSpawner.ChildProcessSpawner | HttpClient.HttpClient>;
37
- declare const listMcpTools: (configs: ReadonlyArray<McpServerConfig>, options?: McpClientOptions) => Effect.Effect<McpResolvedTool[], McpError, HttpClient.HttpClient | ChildProcessSpawner.ChildProcessSpawner>;
38
- //#endregion
39
- export { CallMcpServerToolInput, McpClientOptions, McpResolvedTool, callLocalMcpServerTool, callMcpServerTool, callRemoteMcpServerTool, listLocalMcpServerTools, listMcpServerTools, listMcpTools, listRemoteMcpServerTools };
102
+ export declare const callMcpServerTool: (input: CallMcpServerToolInput) => Effect.Effect<ToolResult, McpError, ChildProcessSpawner.ChildProcessSpawner | HttpClient.HttpClient>;
103
+ export declare const listMcpTools: (configs: ReadonlyArray<McpServerConfig>, options?: McpClientOptions) => Effect.Effect<McpResolvedTool[], McpError, ChildProcessSpawner.ChildProcessSpawner | HttpClient.HttpClient>;
40
104
  //# sourceMappingURL=client.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.mts","names":[],"sources":["../../src/client/client.ts"],"mappings":";;;;;;;;;KAgCY,gBAAA;EAAA,SACD,UAAA,GAAa,aAAA;EAAA,SACb,cAAA,GAAiB,iBAAiB;EAAA,SAClC,SAAA;AAAA;AAAA,KAGC,eAAA;EAAA,SACD,UAAA;EAAA,SACA,WAAA;EAAA,SACA,GAAA,EAAK,UAAU,QAAQ,gBAAA;AAAA;AAAA,cAqUrB,wBAAA,GACX,MAAA,EAAQ,qBAAA,EACR,OAAA,GAAU,gBAAA,KACT,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,eAAA,GAAkB,QAAA,EAAU,UAAA,CAAW,UAAA;AAAA,cAUzD,uBAAA,GACX,MAAA,EAAQ,oBAAA,EACR,OAAA,GAAU,gBAAA,KACT,MAAA,CAAO,MAAA,CACR,aAAA,CAAc,eAAA,GACd,QAAA,EACA,mBAAA,CAAoB,mBAAA;AAAA,cAYT,kBAAA,GAAsB,MAAA,EAAQ,eAAA,EAAiB,OAAA,GAAU,gBAAA,KAAgB,MAAA,CAAA,MAAA,UAAA,eAAA,IAAA,QAAA,EAAA,UAAA,CAAA,UAAA,GAAA,mBAAA,CAAA,mBAAA;AAAA,KAa1E,sBAAA;EAAA,SACD,MAAA,EAAQ,eAAA;EAAA,SACR,WAAA;EAAA,SACA,UAAA;EAAA,SACA,MAAA;EAAA,SACA,OAAA,GAAU,gBAAgB;AAAA;AAAA,cAmBxB,uBAAA,GACX,KAAA,EAAO,IAAA,CAAK,sBAAA;EAAA,SAA+C,MAAA,EAAQ,qBAAA;AAAA,MAClE,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,QAAA,EAAU,UAAA,CAAW,UAAA;AAAA,cAUrC,sBAAA,GACX,KAAA,EAAO,IAAA,CAAK,sBAAA;EAAA,SAA+C,MAAA,EAAQ,oBAAA;AAAA,MAClE,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,QAAA,EAAU,mBAAA,CAAoB,mBAAA;AAAA,cAU9C,iBAAA,GACX,KAAA,EAAO,sBAAA,KACN,MAAA,CAAO,MAAA,CACR,UAAA,EACA,QAAA,EACA,mBAAA,CAAoB,mBAAA,GAAsB,UAAA,CAAW,UAAA;AAAA,cAkB1C,YAAA,GAAgB,OAAA,EAAS,aAAA,CAAc,eAAA,GAAkB,OAAA,GAAU,gBAAA,KAAgB,MAAA,CAAA,MAAA,CAAA,eAAA,IAAA,QAAA,EAAA,UAAA,CAAA,UAAA,GAAA,mBAAA,CAAA,mBAAA"}
1
+ {"version":3,"file":"client.d.mts","names":["SdkClientOptions","SdkClient"],"sources":["../../src/client/client.ts"],"mappings":";;;;;;;;;YA8EY;WACD,aAAa;WACb,iBAAiB;WACjB;WACA,MAAMA;WACN,mBAAmB,QAAQC;;WAE3B,WAAW;;;;;;;;;WASX,cAAc;;YAGb;WACD;WACA;WACA;WACA;WACA,cAAc;WACd,KAAK,kBAAkB;;qBAoYrB,2BAAwB,QAC3B,uBAAqB,UACnB,qBACT,OAAO,OAAO,cAAc,kBAAkB,UAAU,WAAW;qBA6BzD,0BAAuB,QAC1B,sBAAoB,UAClB,qBACT,OAAO,OACR,cAAc,kBACd,UACA,oBAAoB;qBAwBT,qBAAkB,QAAY,iBAAe,UAAY,qBAAgB,OAAA,gBAAA,mBAAA,UAAA,oBAAA,sBAAA,WAAA;YAa1E;WACD,QAAQ;WACR;WACA;WACA;WACA,UAAU;;;;;;;;WAQV,cAAc;;qBAGZ,0BAAuB,OAC3B,KAAK;WAA+C,QAAQ;MAClE,OAAO,OAAO,YAAY,UAAU,WAAW;YAsBtC,+BAA+B,KAAK;WACrC,QAAQ;;YAGP,qCAAqC;;WAEtC,eAAe;;WAEf,WAAW;;YAGV,4BACR,WACA,wBACA;;;;;;;;;;qBAgeS,mCAAgC,OACpC,iCACN,OAAO,OAAO,oBAAoB,2BAA2B,WAAW;;;;;;;;;;qBAuB9D,gCAA6B,OACjC,uCACN,OAAO,OAAO,oBAAoB,2BAA2B,WAAW;;;;;;;;;;;;;qBA2L9D,yBAAsB,OAC1B,KAAK;WAA+C,QAAQ;MAClE,OAAO,OAAO,YAAY,UAAU,oBAAoB;qBA2E9C,oBAAiB,OACrB,2BACN,OAAO,OACR,YACA,UACA,oBAAoB,sBAAsB,WAAW;qBAM1C,eAAY,SAAa,cAAc,kBAAgB,UAAY,qBAAgB,OAAA,OAAA,mBAAA,UAAA,oBAAA,sBAAA,WAAA"}