@effect/ai 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/Chat/package.json +6 -0
  2. package/EmbeddingModel/package.json +6 -0
  3. package/IdGenerator/package.json +6 -0
  4. package/LanguageModel/package.json +6 -0
  5. package/Model/package.json +6 -0
  6. package/Prompt/package.json +6 -0
  7. package/Response/package.json +6 -0
  8. package/Telemetry/package.json +6 -0
  9. package/Tool/package.json +6 -0
  10. package/Toolkit/package.json +6 -0
  11. package/dist/cjs/AiError.js +575 -11
  12. package/dist/cjs/AiError.js.map +1 -1
  13. package/dist/cjs/Chat.js +302 -0
  14. package/dist/cjs/Chat.js.map +1 -0
  15. package/dist/cjs/EmbeddingModel.js +184 -0
  16. package/dist/cjs/EmbeddingModel.js.map +1 -0
  17. package/dist/cjs/IdGenerator.js +255 -0
  18. package/dist/cjs/IdGenerator.js.map +1 -0
  19. package/dist/cjs/LanguageModel.js +584 -0
  20. package/dist/cjs/LanguageModel.js.map +1 -0
  21. package/dist/cjs/McpServer.js +12 -4
  22. package/dist/cjs/McpServer.js.map +1 -1
  23. package/dist/cjs/Model.js +118 -0
  24. package/dist/cjs/Model.js.map +1 -0
  25. package/dist/cjs/Prompt.js +649 -0
  26. package/dist/cjs/Prompt.js.map +1 -0
  27. package/dist/cjs/Response.js +635 -0
  28. package/dist/cjs/Response.js.map +1 -0
  29. package/dist/cjs/Telemetry.js +176 -0
  30. package/dist/cjs/Telemetry.js.map +1 -0
  31. package/dist/cjs/Tokenizer.js +87 -8
  32. package/dist/cjs/Tokenizer.js.map +1 -1
  33. package/dist/cjs/Tool.js +556 -0
  34. package/dist/cjs/Tool.js.map +1 -0
  35. package/dist/cjs/Toolkit.js +279 -0
  36. package/dist/cjs/Toolkit.js.map +1 -0
  37. package/dist/cjs/index.js +21 -19
  38. package/dist/dts/AiError.d.ts +577 -9
  39. package/dist/dts/AiError.d.ts.map +1 -1
  40. package/dist/dts/Chat.d.ts +356 -0
  41. package/dist/dts/Chat.d.ts.map +1 -0
  42. package/dist/dts/EmbeddingModel.d.ts +153 -0
  43. package/dist/dts/EmbeddingModel.d.ts.map +1 -0
  44. package/dist/dts/IdGenerator.d.ts +272 -0
  45. package/dist/dts/IdGenerator.d.ts.map +1 -0
  46. package/dist/dts/LanguageModel.d.ts +458 -0
  47. package/dist/dts/LanguageModel.d.ts.map +1 -0
  48. package/dist/dts/McpSchema.d.ts +25 -25
  49. package/dist/dts/McpServer.d.ts +6 -4
  50. package/dist/dts/McpServer.d.ts.map +1 -1
  51. package/dist/dts/Model.d.ts +124 -0
  52. package/dist/dts/Model.d.ts.map +1 -0
  53. package/dist/dts/Prompt.d.ts +1119 -0
  54. package/dist/dts/Prompt.d.ts.map +1 -0
  55. package/dist/dts/Response.d.ts +1519 -0
  56. package/dist/dts/Response.d.ts.map +1 -0
  57. package/dist/dts/Telemetry.d.ts +520 -0
  58. package/dist/dts/Telemetry.d.ts.map +1 -0
  59. package/dist/dts/Tokenizer.d.ts +131 -13
  60. package/dist/dts/Tokenizer.d.ts.map +1 -1
  61. package/dist/dts/Tool.d.ts +876 -0
  62. package/dist/dts/Tool.d.ts.map +1 -0
  63. package/dist/dts/Toolkit.d.ts +310 -0
  64. package/dist/dts/Toolkit.d.ts.map +1 -0
  65. package/dist/dts/index.d.ts +498 -13
  66. package/dist/dts/index.d.ts.map +1 -1
  67. package/dist/esm/AiError.js +570 -10
  68. package/dist/esm/AiError.js.map +1 -1
  69. package/dist/esm/Chat.js +291 -0
  70. package/dist/esm/Chat.js.map +1 -0
  71. package/dist/esm/EmbeddingModel.js +173 -0
  72. package/dist/esm/EmbeddingModel.js.map +1 -0
  73. package/dist/esm/IdGenerator.js +245 -0
  74. package/dist/esm/IdGenerator.js.map +1 -0
  75. package/dist/esm/LanguageModel.js +572 -0
  76. package/dist/esm/LanguageModel.js.map +1 -0
  77. package/dist/esm/McpServer.js +12 -4
  78. package/dist/esm/McpServer.js.map +1 -1
  79. package/dist/esm/Model.js +108 -0
  80. package/dist/esm/Model.js.map +1 -0
  81. package/dist/esm/Prompt.js +633 -0
  82. package/dist/esm/Prompt.js.map +1 -0
  83. package/dist/esm/Response.js +619 -0
  84. package/dist/esm/Response.js.map +1 -0
  85. package/dist/esm/Telemetry.js +166 -0
  86. package/dist/esm/Telemetry.js.map +1 -0
  87. package/dist/esm/Tokenizer.js +87 -8
  88. package/dist/esm/Tokenizer.js.map +1 -1
  89. package/dist/esm/Tool.js +534 -0
  90. package/dist/esm/Tool.js.map +1 -0
  91. package/dist/esm/Toolkit.js +269 -0
  92. package/dist/esm/Toolkit.js.map +1 -0
  93. package/dist/esm/index.js +498 -13
  94. package/dist/esm/index.js.map +1 -1
  95. package/package.json +76 -68
  96. package/src/AiError.ts +739 -9
  97. package/src/Chat.ts +546 -0
  98. package/src/EmbeddingModel.ts +311 -0
  99. package/src/IdGenerator.ts +320 -0
  100. package/src/LanguageModel.ts +1074 -0
  101. package/src/McpServer.ts +337 -194
  102. package/src/Model.ts +155 -0
  103. package/src/Prompt.ts +1616 -0
  104. package/src/Response.ts +2131 -0
  105. package/src/Telemetry.ts +655 -0
  106. package/src/Tokenizer.ts +145 -24
  107. package/src/Tool.ts +1267 -0
  108. package/src/Toolkit.ts +516 -0
  109. package/src/index.ts +499 -13
  110. package/AiChat/package.json +0 -6
  111. package/AiEmbeddingModel/package.json +0 -6
  112. package/AiInput/package.json +0 -6
  113. package/AiLanguageModel/package.json +0 -6
  114. package/AiModel/package.json +0 -6
  115. package/AiResponse/package.json +0 -6
  116. package/AiTelemetry/package.json +0 -6
  117. package/AiTool/package.json +0 -6
  118. package/AiToolkit/package.json +0 -6
  119. package/dist/cjs/AiChat.js +0 -122
  120. package/dist/cjs/AiChat.js.map +0 -1
  121. package/dist/cjs/AiEmbeddingModel.js +0 -109
  122. package/dist/cjs/AiEmbeddingModel.js.map +0 -1
  123. package/dist/cjs/AiInput.js +0 -458
  124. package/dist/cjs/AiInput.js.map +0 -1
  125. package/dist/cjs/AiLanguageModel.js +0 -351
  126. package/dist/cjs/AiLanguageModel.js.map +0 -1
  127. package/dist/cjs/AiModel.js +0 -37
  128. package/dist/cjs/AiModel.js.map +0 -1
  129. package/dist/cjs/AiResponse.js +0 -681
  130. package/dist/cjs/AiResponse.js.map +0 -1
  131. package/dist/cjs/AiTelemetry.js +0 -58
  132. package/dist/cjs/AiTelemetry.js.map +0 -1
  133. package/dist/cjs/AiTool.js +0 -150
  134. package/dist/cjs/AiTool.js.map +0 -1
  135. package/dist/cjs/AiToolkit.js +0 -157
  136. package/dist/cjs/AiToolkit.js.map +0 -1
  137. package/dist/cjs/internal/common.js +0 -21
  138. package/dist/cjs/internal/common.js.map +0 -1
  139. package/dist/dts/AiChat.d.ts +0 -101
  140. package/dist/dts/AiChat.d.ts.map +0 -1
  141. package/dist/dts/AiEmbeddingModel.d.ts +0 -65
  142. package/dist/dts/AiEmbeddingModel.d.ts.map +0 -1
  143. package/dist/dts/AiInput.d.ts +0 -590
  144. package/dist/dts/AiInput.d.ts.map +0 -1
  145. package/dist/dts/AiLanguageModel.d.ts +0 -302
  146. package/dist/dts/AiLanguageModel.d.ts.map +0 -1
  147. package/dist/dts/AiModel.d.ts +0 -25
  148. package/dist/dts/AiModel.d.ts.map +0 -1
  149. package/dist/dts/AiResponse.d.ts +0 -863
  150. package/dist/dts/AiResponse.d.ts.map +0 -1
  151. package/dist/dts/AiTelemetry.d.ts +0 -242
  152. package/dist/dts/AiTelemetry.d.ts.map +0 -1
  153. package/dist/dts/AiTool.d.ts +0 -334
  154. package/dist/dts/AiTool.d.ts.map +0 -1
  155. package/dist/dts/AiToolkit.d.ts +0 -96
  156. package/dist/dts/AiToolkit.d.ts.map +0 -1
  157. package/dist/dts/internal/common.d.ts +0 -2
  158. package/dist/dts/internal/common.d.ts.map +0 -1
  159. package/dist/esm/AiChat.js +0 -111
  160. package/dist/esm/AiChat.js.map +0 -1
  161. package/dist/esm/AiEmbeddingModel.js +0 -98
  162. package/dist/esm/AiEmbeddingModel.js.map +0 -1
  163. package/dist/esm/AiInput.js +0 -433
  164. package/dist/esm/AiInput.js.map +0 -1
  165. package/dist/esm/AiLanguageModel.js +0 -340
  166. package/dist/esm/AiLanguageModel.js.map +0 -1
  167. package/dist/esm/AiModel.js +0 -29
  168. package/dist/esm/AiModel.js.map +0 -1
  169. package/dist/esm/AiResponse.js +0 -657
  170. package/dist/esm/AiResponse.js.map +0 -1
  171. package/dist/esm/AiTelemetry.js +0 -48
  172. package/dist/esm/AiTelemetry.js.map +0 -1
  173. package/dist/esm/AiTool.js +0 -134
  174. package/dist/esm/AiTool.js.map +0 -1
  175. package/dist/esm/AiToolkit.js +0 -147
  176. package/dist/esm/AiToolkit.js.map +0 -1
  177. package/dist/esm/internal/common.js +0 -14
  178. package/dist/esm/internal/common.js.map +0 -1
  179. package/src/AiChat.ts +0 -251
  180. package/src/AiEmbeddingModel.ts +0 -169
  181. package/src/AiInput.ts +0 -602
  182. package/src/AiLanguageModel.ts +0 -685
  183. package/src/AiModel.ts +0 -53
  184. package/src/AiResponse.ts +0 -986
  185. package/src/AiTelemetry.ts +0 -333
  186. package/src/AiTool.ts +0 -579
  187. package/src/AiToolkit.ts +0 -265
  188. package/src/internal/common.ts +0 -12
package/src/McpServer.ts CHANGED
@@ -27,8 +27,6 @@ import type { Sink } from "effect/Sink"
27
27
  import type { Stream } from "effect/Stream"
28
28
  import type * as Types from "effect/Types"
29
29
  import * as FindMyWay from "find-my-way-ts"
30
- import * as AiTool from "./AiTool.js"
31
- import type * as AiToolkit from "./AiToolkit.js"
32
30
  import type {
33
31
  Annotations,
34
32
  CallTool,
@@ -66,6 +64,8 @@ import {
66
64
  Tool,
67
65
  ToolAnnotations
68
66
  } from "./McpSchema.js"
67
+ import * as AiTool from "./Tool.js"
68
+ import type * as Toolkit from "./Toolkit.js"
69
69
 
70
70
  /**
71
71
  * @since 1.0.0
@@ -76,6 +76,7 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
76
76
  {
77
77
  readonly notifications: RpcClient.RpcClient<RpcGroup.Rpcs<typeof ServerNotificationRpcs>>
78
78
  readonly notificationsMailbox: Mailbox.ReadonlyMailbox<RpcMessage.Request<any>>
79
+ readonly initializedClients: Set<number>
79
80
 
80
81
  readonly tools: ReadonlyArray<Tool>
81
82
  readonly addTool: (options: {
@@ -93,21 +94,22 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
93
94
  ) => Effect.Effect<void>
94
95
 
95
96
  readonly resourceTemplates: ReadonlyArray<ResourceTemplate>
96
- readonly addResourceTemplate: (
97
- options: {
98
- readonly template: ResourceTemplate
99
- readonly routerPath: string
100
- readonly completions: Record<string, (input: string) => Effect.Effect<CompleteResult, InternalError>>
101
- readonly handle: (
102
- uri: string,
103
- params: Array<string>
104
- ) => Effect.Effect<typeof ReadResourceResult.Type, InvalidParams | InternalError, McpServerClient>
105
- }
106
- ) => Effect.Effect<void>
97
+ readonly addResourceTemplate: (options: {
98
+ readonly template: ResourceTemplate
99
+ readonly routerPath: string
100
+ readonly completions: Record<string, (input: string) => Effect.Effect<CompleteResult, InternalError>>
101
+ readonly handle: (uri: string, params: Array<string>) => Effect.Effect<
102
+ typeof ReadResourceResult.Type,
103
+ InvalidParams | InternalError,
104
+ McpServerClient
105
+ >
106
+ }) => Effect.Effect<void>
107
107
 
108
- readonly findResource: (
109
- uri: string
110
- ) => Effect.Effect<typeof ReadResourceResult.Type, InvalidParams | InternalError, McpServerClient>
108
+ readonly findResource: (uri: string) => Effect.Effect<
109
+ typeof ReadResourceResult.Type,
110
+ InvalidParams | InternalError,
111
+ McpServerClient
112
+ >
111
113
 
112
114
  readonly prompts: ReadonlyArray<Prompt>
113
115
  readonly addPrompt: (options: {
@@ -134,19 +136,23 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
134
136
  */
135
137
  static readonly make = Effect.gen(function*() {
136
138
  const matcher = makeUriMatcher<
137
- {
139
+ | {
138
140
  readonly _tag: "ResourceTemplate"
139
141
  readonly handle: (
140
142
  uri: string,
141
143
  params: Array<string>
142
144
  ) => Effect.Effect<typeof ReadResourceResult.Type, InternalError | InvalidParams, McpServerClient>
143
- } | {
145
+ }
146
+ | {
144
147
  readonly _tag: "Resource"
145
148
  readonly effect: Effect.Effect<typeof ReadResourceResult.Type, InternalError, McpServerClient>
146
149
  }
147
150
  >()
148
151
  const tools = Arr.empty<Tool>()
149
- const toolMap = new Map<string, (payload: any) => Effect.Effect<CallToolResult, InternalError, McpServerClient>>()
152
+ const toolMap = new Map<
153
+ string,
154
+ (payload: any) => Effect.Effect<CallToolResult, InternalError, McpServerClient>
155
+ >()
150
156
  const resources: Array<Resource> = []
151
157
  const resourceTemplates: Array<ResourceTemplate> = []
152
158
  const prompts: Array<Prompt> = []
@@ -192,6 +198,7 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
192
198
  return McpServer.of({
193
199
  notifications: notifications.client,
194
200
  notificationsMailbox,
201
+ initializedClients: new Set<number>(),
195
202
  get tools() {
196
203
  return tools
197
204
  },
@@ -205,7 +212,11 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
205
212
  Effect.suspend((): Effect.Effect<CallToolResult, InternalError | InvalidParams, McpServerClient> => {
206
213
  const handle = toolMap.get(request.name)
207
214
  if (!handle) {
208
- return Effect.fail(new InvalidParams({ message: `Tool '${request.name}' not found` }))
215
+ return Effect.fail(
216
+ new InvalidParams({
217
+ message: `Tool '${request.name}' not found`
218
+ })
219
+ )
209
220
  }
210
221
  return handle(request.arguments)
211
222
  }),
@@ -219,16 +230,23 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
219
230
  Effect.suspend(() => {
220
231
  resources.push(resource)
221
232
  matcher.add(resource.uri, { _tag: "Resource", effect })
222
- return notifications.client["notifications/resources/list_changed"]({})
233
+ return notifications.client["notifications/resources/list_changed"](
234
+ {}
235
+ )
223
236
  }),
224
237
  addResourceTemplate: ({ completions, handle, routerPath, template }) =>
225
238
  Effect.suspend(() => {
226
239
  resourceTemplates.push(template)
227
240
  matcher.add(routerPath, { _tag: "ResourceTemplate", handle })
228
241
  for (const [param, handle] of Object.entries(completions)) {
229
- completionsMap.set(`ref/resource/${template.uriTemplate}/${param}`, handle)
242
+ completionsMap.set(
243
+ `ref/resource/${template.uriTemplate}/${param}`,
244
+ handle
245
+ )
230
246
  }
231
- return notifications.client["notifications/resources/list_changed"]({})
247
+ return notifications.client["notifications/resources/list_changed"](
248
+ {}
249
+ )
232
250
  }),
233
251
  findResource: (uri) =>
234
252
  Effect.suspend(() => {
@@ -252,14 +270,19 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
252
270
  prompts.push(options.prompt)
253
271
  promptMap.set(options.prompt.name, options.handle)
254
272
  for (const [param, handle] of Object.entries(options.completions)) {
255
- completionsMap.set(`ref/prompt/${options.prompt.name}/${param}`, handle)
273
+ completionsMap.set(
274
+ `ref/prompt/${options.prompt.name}/${param}`,
275
+ handle
276
+ )
256
277
  }
257
278
  return notifications.client["notifications/prompts/list_changed"]({})
258
279
  }),
259
280
  getPromptResult: Effect.fnUntraced(function*({ arguments: params, name }) {
260
281
  const handler = promptMap.get(name)
261
282
  if (!handler) {
262
- return yield* new InvalidParams({ message: `Prompt '${name}' not found` })
283
+ return yield* new InvalidParams({
284
+ message: `Prompt '${name}' not found`
285
+ })
263
286
  }
264
287
  return yield* handler(params ?? {})
265
288
  }),
@@ -269,7 +292,9 @@ export class McpServer extends Context.Tag("@effect/ai/McpServer")<
269
292
  ? `ref/resource/${ref.uri}/${complete.argument.name}`
270
293
  : `ref/prompt/${ref.name}/${complete.argument.name}`
271
294
  const handler = completionsMap.get(key)
272
- return handler ? yield* handler(complete.argument.value) : CompleteResult.empty
295
+ return handler
296
+ ? yield* handler(complete.argument.value)
297
+ : CompleteResult.empty
273
298
  })
274
299
  })
275
300
  })
@@ -292,13 +317,10 @@ const SUPPORTED_PROTOCOL_VERSIONS = [
292
317
  * @since 1.0.0
293
318
  * @category Constructors
294
319
  */
295
- export const run: (
296
- options: { readonly name: string; readonly version: string }
297
- ) => Effect.Effect<
298
- never,
299
- never,
300
- McpServer | RpcServer.Protocol
301
- > = Effect.fnUntraced(function*(options: {
320
+ export const run: (options: {
321
+ readonly name: string
322
+ readonly version: string
323
+ }) => Effect.Effect<never, never, McpServer | RpcServer.Protocol> = Effect.fnUntraced(function*(options: {
302
324
  readonly name: string
303
325
  readonly version: string
304
326
  }) {
@@ -308,28 +330,32 @@ export const run: (
308
330
 
309
331
  const clients = yield* RcMap.make({
310
332
  lookup: Effect.fnUntraced(function*(clientId: number) {
311
- let write!: (message: RpcMessage.FromServerEncoded) => Effect.Effect<void>
333
+ let write!: (
334
+ message: RpcMessage.FromServerEncoded
335
+ ) => Effect.Effect<void>
312
336
  const client = yield* RpcClient.make(ServerRequestRpcs, {
313
337
  spanPrefix: "McpServer/Client"
314
338
  }).pipe(
315
339
  Effect.provideServiceEffect(
316
340
  RpcClient.Protocol,
317
- RpcClient.Protocol.make(Effect.fnUntraced(function*(writeResponse) {
318
- write = writeResponse
319
- return {
320
- send(request, _transferables) {
321
- return protocol.send(clientId, {
322
- ...request,
323
- headers: undefined,
324
- traceId: undefined,
325
- spanId: undefined,
326
- sampled: undefined
327
- } as any)
328
- },
329
- supportsAck: true,
330
- supportsTransferables: false
331
- }
332
- }))
341
+ RpcClient.Protocol.make(
342
+ Effect.fnUntraced(function*(writeResponse) {
343
+ write = writeResponse
344
+ return {
345
+ send(request, _transferables) {
346
+ return protocol.send(clientId, {
347
+ ...request,
348
+ headers: undefined,
349
+ traceId: undefined,
350
+ spanId: undefined,
351
+ sampled: undefined
352
+ } as any)
353
+ },
354
+ supportsAck: true,
355
+ supportsTransferables: false
356
+ }
357
+ })
358
+ )
333
359
  )
334
360
  )
335
361
 
@@ -365,7 +391,9 @@ export const run: (
365
391
  requestId: String((request.payload as any).requestId)
366
392
  })
367
393
  }
368
- const handler = handlers.unsafeMap.get(request.tag) as Rpc.Handler<string>
394
+ const handler = handlers.unsafeMap.get(
395
+ request.tag
396
+ ) as Rpc.Handler<string>
369
397
  return handler
370
398
  ? handler.handler(request.payload, {
371
399
  clientId,
@@ -394,7 +422,12 @@ export const run: (
394
422
  })
395
423
 
396
424
  const encodeNotification = Schema.encode(
397
- Schema.Union(...Array.from(ServerNotificationRpcs.requests.values(), (rpc) => rpc.payloadSchema))
425
+ Schema.Union(
426
+ ...Array.from(
427
+ ServerNotificationRpcs.requests.values(),
428
+ (rpc) => rpc.payloadSchema
429
+ )
430
+ )
398
431
  )
399
432
  yield* server.notificationsMailbox.take.pipe(
400
433
  Effect.flatMap(Effect.fnUntraced(function*(request) {
@@ -405,7 +438,11 @@ export const run: (
405
438
  payload: encoded
406
439
  } as any
407
440
  const clientIds = yield* patchedProtocol.clientIds
408
- for (const clientId of clientIds) {
441
+ for (const clientId of server.initializedClients) {
442
+ if (!clientIds.has(clientId)) {
443
+ server.initializedClients.delete(clientId)
444
+ continue
445
+ }
409
446
  yield* patchedProtocol.send(clientId, message as any)
410
447
  }
411
448
  })),
@@ -500,10 +537,12 @@ export const layerStdio = <EIn, RIn, EOut, ROut>(options: {
500
537
  readonly stdout: Sink<unknown, Uint8Array | string, unknown, EOut, ROut>
501
538
  }): Layer.Layer<McpServer | McpServerClient, never, RIn | ROut> =>
502
539
  layer(options).pipe(
503
- Layer.provide(RpcServer.layerProtocolStdio({
504
- stdin: options.stdin,
505
- stdout: options.stdout
506
- })),
540
+ Layer.provide(
541
+ RpcServer.layerProtocolStdio({
542
+ stdin: options.stdin,
543
+ stdout: options.stdout
544
+ })
545
+ ),
507
546
  Layer.provide(RpcSerialization.layerNdJsonRpc()),
508
547
  // remove stdout loggers
509
548
  Layer.provideMerge(Logger.remove(Logger.defaultLogger)),
@@ -591,7 +630,11 @@ export const layerHttpRouter = (options: {
591
630
  readonly name: string
592
631
  readonly version: string
593
632
  readonly path: HttpRouter.PathInput
594
- }): Layer.Layer<McpServer | McpServerClient, never, HttpLayerRouter.HttpRouter> =>
633
+ }): Layer.Layer<
634
+ McpServer | McpServerClient,
635
+ never,
636
+ HttpLayerRouter.HttpRouter
637
+ > =>
595
638
  layer(options).pipe(
596
639
  Layer.provide(RpcServer.layerProtocolHttpRouter(options)),
597
640
  Layer.provide(RpcSerialization.layerJsonRpc())
@@ -603,30 +646,34 @@ export const layerHttpRouter = (options: {
603
646
  * @since 1.0.0
604
647
  * @category Tools
605
648
  */
606
- export const registerToolkit: <Tools extends AiTool.Any>(toolkit: AiToolkit.AiToolkit<Tools>) => Effect.Effect<
649
+ export const registerToolkit: <Tools extends Record<string, AiTool.Any>>(
650
+ toolkit: Toolkit.Toolkit<Tools>
651
+ ) => Effect.Effect<
607
652
  void,
608
653
  never,
609
- McpServer | AiTool.ToHandler<Tools> | Exclude<AiTool.Context<Tools>, McpServerClient>
610
- > = Effect.fnUntraced(function*<Tools extends AiTool.Any>(
611
- toolkit: AiToolkit.AiToolkit<Tools>
654
+ | McpServer
655
+ | AiTool.HandlersFor<Tools>
656
+ | Exclude<AiTool.Requirements<Tools>, McpServerClient>
657
+ > = Effect.fnUntraced(function*<Tools extends Record<string, AiTool.Any>>(
658
+ toolkit: Toolkit.Toolkit<Tools>
612
659
  ) {
613
660
  const registry = yield* McpServer
614
- const built = yield* (toolkit as any as Effect.Effect<
615
- AiToolkit.ToHandler<Tools>,
661
+ const built = yield* toolkit as any as Effect.Effect<
662
+ Toolkit.WithHandler<Tools>,
616
663
  never,
617
- Exclude<AiTool.ToHandler<Tools>, McpServerClient>
618
- >)
664
+ Exclude<AiTool.HandlersFor<Tools>, McpServerClient>
665
+ >
619
666
  const context = yield* Effect.context<never>()
620
- for (const tool of built.tools) {
667
+ for (const tool of Object.values(built.tools)) {
621
668
  const mcpTool = new Tool({
622
669
  name: tool.name,
623
670
  description: tool.description,
624
671
  inputSchema: makeJsonSchema(tool.parametersSchema.ast),
625
672
  annotations: new ToolAnnotations({
626
- ...(Context.getOption(tool.annotations, AiTool.Title).pipe(
673
+ ...Context.getOption(tool.annotations, AiTool.Title).pipe(
627
674
  Option.map((title) => ({ title })),
628
675
  Option.getOrUndefined
629
- )),
676
+ ),
630
677
  readOnlyHint: Context.get(tool.annotations, AiTool.Readonly),
631
678
  destructiveHint: Context.get(tool.annotations, AiTool.Destructive),
632
679
  idempotentHint: Context.get(tool.annotations, AiTool.Idempotent),
@@ -643,19 +690,25 @@ export const registerToolkit: <Tools extends AiTool.Any>(toolkit: AiToolkit.AiTo
643
690
  new CallToolResult({
644
691
  isError: true,
645
692
  structuredContent: typeof error === "object" ? error : undefined,
646
- content: [{
647
- type: "text",
648
- text: JSON.stringify(error)
649
- }]
693
+ content: [
694
+ {
695
+ type: "text",
696
+ text: JSON.stringify(error)
697
+ }
698
+ ]
650
699
  }),
651
700
  onSuccess: (result) =>
652
701
  new CallToolResult({
653
702
  isError: false,
654
- structuredContent: typeof result.encodedResult === "object" ? result.encodedResult : undefined,
655
- content: [{
656
- type: "text",
657
- text: JSON.stringify(result.encodedResult)
658
- }]
703
+ structuredContent: typeof result.encodedResult === "object"
704
+ ? result.encodedResult
705
+ : undefined,
706
+ content: [
707
+ {
708
+ type: "text",
709
+ text: JSON.stringify(result.encodedResult)
710
+ }
711
+ ]
659
712
  })
660
713
  })
661
714
  ) as any
@@ -670,12 +723,13 @@ export const registerToolkit: <Tools extends AiTool.Any>(toolkit: AiToolkit.AiTo
670
723
  * @since 1.0.0
671
724
  * @category Tools
672
725
  */
673
- export const toolkit = <Tools extends AiTool.Any>(
674
- toolkit: AiToolkit.AiToolkit<Tools>
726
+ export const toolkit = <Tools extends Record<string, AiTool.Any>>(
727
+ toolkit: Toolkit.Toolkit<Tools>
675
728
  ): Layer.Layer<
676
729
  never,
677
730
  never,
678
- AiTool.ToHandler<Tools> | Exclude<AiTool.Context<Tools>, McpServerClient>
731
+ | AiTool.HandlersFor<Tools>
732
+ | Exclude<AiTool.Requirements<Tools>, McpServerClient>
679
733
  > =>
680
734
  Layer.effectDiscard(registerToolkit(toolkit)).pipe(
681
735
  Layer.provide(McpServer.layer)
@@ -684,20 +738,30 @@ export const toolkit = <Tools extends AiTool.Any>(
684
738
  /**
685
739
  * @since 1.0.0
686
740
  */
687
- export type ValidateCompletions<Completions, Keys extends string> =
741
+ export type ValidateCompletions<
742
+ Completions,
743
+ Keys extends string
744
+ > =
688
745
  & Completions
689
746
  & {
690
- readonly [K in keyof Completions]: K extends Keys ? (input: string) => any : never
747
+ readonly [K in keyof Completions]: K extends Keys ? (input: string) => any
748
+ : never
691
749
  }
692
750
 
693
751
  /**
694
752
  * @since 1.0.0
695
753
  */
696
- export type ResourceCompletions<Schemas extends ReadonlyArray<Schema.Schema.Any>> = {
754
+ export type ResourceCompletions<
755
+ Schemas extends ReadonlyArray<Schema.Schema.Any>
756
+ > = {
697
757
  readonly [
698
- K in Extract<keyof Schemas, `${number}`> as Schemas[K] extends Param<infer Id, infer _S> ? Id
699
- : `param${K}`
700
- ]: (input: string) => Effect.Effect<Array<Schema.Schema.Type<Schemas[K]>>, any, any>
758
+ K in Extract<
759
+ keyof Schemas,
760
+ `${number}`
761
+ > as Schemas[K] extends Param<infer Id, infer _S> ? Id : `param${K}`
762
+ ]: (
763
+ input: string
764
+ ) => Effect.Effect<Array<Schema.Schema.Type<Schemas[K]>>, any, any>
701
765
  }
702
766
 
703
767
  /**
@@ -739,7 +803,9 @@ export const registerResource: {
739
803
  ...schemas:
740
804
  & Schemas
741
805
  & {
742
- readonly [K in keyof Schemas]: Schema.Schema.Encoded<Schemas[K]> extends string ? unknown
806
+ readonly [K in keyof Schemas]: Schema.Schema.Encoded<
807
+ Schemas[K]
808
+ > extends string ? unknown
743
809
  : "Schema must be encodable to a string"
744
810
  }
745
811
  ): <
@@ -752,8 +818,13 @@ export const registerResource: {
752
818
  readonly mimeType?: string | undefined
753
819
  readonly audience?: ReadonlyArray<"user" | "assistant"> | undefined
754
820
  readonly priority?: number | undefined
755
- readonly completion?: ValidateCompletions<Completions, keyof ResourceCompletions<Schemas>> | undefined
756
- readonly content: (uri: string, ...params: { readonly [K in keyof Schemas]: Schemas[K]["Type"] }) => Effect.Effect<
821
+ readonly completion?:
822
+ | ValidateCompletions<Completions, keyof ResourceCompletions<Schemas>>
823
+ | undefined
824
+ readonly content: (
825
+ uri: string,
826
+ ...params: { readonly [K in keyof Schemas]: Schemas[K]["Type"] }
827
+ ) => Effect.Effect<
757
828
  typeof ReadResourceResult.Type | string | Uint8Array,
758
829
  E,
759
830
  R
@@ -763,8 +834,9 @@ export const registerResource: {
763
834
  never,
764
835
  | Exclude<
765
836
  | R
766
- | (Completions[keyof Completions] extends (input: string) => infer Ret ?
767
- Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R : never
837
+ | (Completions[keyof Completions] extends (input: string) => infer Ret
838
+ ? Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R
839
+ : never
768
840
  : never),
769
841
  McpServerClient
770
842
  >
@@ -772,9 +844,14 @@ export const registerResource: {
772
844
  >
773
845
  } = function() {
774
846
  if (arguments.length === 1) {
775
- const options = arguments[0] as Resource & typeof Annotations.Type & {
776
- readonly content: Effect.Effect<typeof ReadResourceResult.Type | string | Uint8Array>
777
- }
847
+ const options = arguments[0] as
848
+ & Resource
849
+ & typeof Annotations.Type
850
+ & {
851
+ readonly content: Effect.Effect<
852
+ typeof ReadResourceResult.Type | string | Uint8Array
853
+ >
854
+ }
778
855
  return Effect.gen(function*() {
779
856
  const context = yield* Effect.context<any>()
780
857
  const registry = yield* McpServer
@@ -794,20 +871,22 @@ export const registerResource: {
794
871
  )
795
872
  })
796
873
  }
797
- const {
798
- params,
799
- routerPath,
800
- schema,
801
- uriPath
802
- } = compileUriTemplate(...(arguments as any as [any, any]))
874
+ const { params, routerPath, schema, uriPath } = compileUriTemplate(
875
+ ...(arguments as any as [any, any])
876
+ )
803
877
  return Effect.fnUntraced(function*<E, R>(options: {
804
878
  readonly name: string
805
879
  readonly description?: string | undefined
806
880
  readonly mimeType?: string | undefined
807
881
  readonly audience?: ReadonlyArray<"user" | "assistant"> | undefined
808
882
  readonly priority?: number | undefined
809
- readonly completion?: Record<string, (input: string) => Effect.Effect<any>> | undefined
810
- readonly content: (uri: string, ...params: Array<any>) => Effect.Effect<
883
+ readonly completion?:
884
+ | Record<string, (input: string) => Effect.Effect<any>>
885
+ | undefined
886
+ readonly content: (
887
+ uri: string,
888
+ ...params: Array<any>
889
+ ) => Effect.Effect<
811
890
  typeof ReadResourceResult.Type | string | Uint8Array,
812
891
  E,
813
892
  R
@@ -821,20 +900,24 @@ export const registerResource: {
821
900
  uriTemplate: uriPath,
822
901
  annotations: options
823
902
  })
824
- const completions: Record<string, (input: string) => Effect.Effect<CompleteResult, InternalError>> = {}
903
+ const completions: Record<
904
+ string,
905
+ (input: string) => Effect.Effect<CompleteResult, InternalError>
906
+ > = {}
825
907
  for (const [param, handle] of Object.entries(options.completion ?? {})) {
826
908
  const encodeArray = Schema.encodeUnknown(Schema.Array(params[param]))
827
909
  const handler = (input: string) =>
828
910
  handle(input).pipe(
829
911
  Effect.flatMap(encodeArray),
830
- Effect.map((values) =>
831
- new CompleteResult({
832
- completion: {
833
- values: values as Array<string>,
834
- total: values.length,
835
- hasMore: false
836
- }
837
- })
912
+ Effect.map(
913
+ (values) =>
914
+ new CompleteResult({
915
+ completion: {
916
+ values: values as Array<string>,
917
+ total: values.length,
918
+ hasMore: false
919
+ }
920
+ })
838
921
  ),
839
922
  Effect.catchAllCause((cause) => {
840
923
  const prettyError = Cause.prettyErrors(cause)[0]
@@ -850,7 +933,9 @@ export const registerResource: {
850
933
  completions,
851
934
  handle: (uri, params) =>
852
935
  decode(params).pipe(
853
- Effect.mapError((error) => new InvalidParams({ message: error.message })),
936
+ Effect.mapError(
937
+ (error) => new InvalidParams({ message: error.message })
938
+ ),
854
939
  Effect.flatMap((params) =>
855
940
  options.content(uri, ...params).pipe(
856
941
  Effect.map((content) => resolveResourceContent(uri, content)),
@@ -905,7 +990,9 @@ export const resource: {
905
990
  ...schemas:
906
991
  & Schemas
907
992
  & {
908
- readonly [K in keyof Schemas]: Schema.Schema.Encoded<Schemas[K]> extends string ? unknown
993
+ readonly [K in keyof Schemas]: Schema.Schema.Encoded<
994
+ Schemas[K]
995
+ > extends string ? unknown
909
996
  : "Schema must be encodable to a string"
910
997
  }
911
998
  ): <
@@ -918,8 +1005,13 @@ export const resource: {
918
1005
  readonly mimeType?: string | undefined
919
1006
  readonly audience?: ReadonlyArray<"user" | "assistant"> | undefined
920
1007
  readonly priority?: number | undefined
921
- readonly completion?: ValidateCompletions<Completions, keyof ResourceCompletions<Schemas>> | undefined
922
- readonly content: (uri: string, ...params: { readonly [K in keyof Schemas]: Schemas[K]["Type"] }) => Effect.Effect<
1008
+ readonly completion?:
1009
+ | ValidateCompletions<Completions, keyof ResourceCompletions<Schemas>>
1010
+ | undefined
1011
+ readonly content: (
1012
+ uri: string,
1013
+ ...params: { readonly [K in keyof Schemas]: Schemas[K]["Type"] }
1014
+ ) => Effect.Effect<
923
1015
  typeof ReadResourceResult.Type | string | Uint8Array,
924
1016
  E,
925
1017
  R
@@ -929,8 +1021,9 @@ export const resource: {
929
1021
  never,
930
1022
  Exclude<
931
1023
  | R
932
- | (Completions[keyof Completions] extends (input: string) => infer Ret ?
933
- Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R : never
1024
+ | (Completions[keyof Completions] extends (input: string) => infer Ret
1025
+ ? Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R
1026
+ : never
934
1027
  : never),
935
1028
  McpServerClient
936
1029
  >
@@ -942,10 +1035,7 @@ export const resource: {
942
1035
  )
943
1036
  }
944
1037
  const register = registerResource(...(arguments as any as [any, any]))
945
- return (options: any) =>
946
- Layer.effectDiscard(register(options)).pipe(
947
- Layer.provide(McpServer.layer)
948
- )
1038
+ return (options: any) => Layer.effectDiscard(register(options)).pipe(Layer.provide(McpServer.layer))
949
1039
  } as any
950
1040
 
951
1041
  /**
@@ -961,20 +1051,30 @@ export const registerPrompt = <
961
1051
  ParamsI extends Record<string, string> = {},
962
1052
  ParamsR = never,
963
1053
  const Completions extends {
964
- readonly [K in keyof Params]?: (input: string) => Effect.Effect<Array<Params[K]>, any, any>
1054
+ readonly [K in keyof Params]?: (
1055
+ input: string
1056
+ ) => Effect.Effect<Array<Params[K]>, any, any>
965
1057
  } = {}
966
- >(
967
- options: {
968
- readonly name: string
969
- readonly description?: string | undefined
970
- readonly parameters?: Schema.Schema<Params, ParamsI, ParamsR> | undefined
971
- readonly completion?: ValidateCompletions<Completions, Extract<keyof Params, string>> | undefined
972
- readonly content: (params: Params) => Effect.Effect<Array<typeof PromptMessage.Type> | string, E, R>
973
- }
974
- ): Effect.Effect<void, never, Exclude<ParamsR | R, McpServerClient> | McpServer> => {
1058
+ >(options: {
1059
+ readonly name: string
1060
+ readonly description?: string | undefined
1061
+ readonly parameters?: Schema.Schema<Params, ParamsI, ParamsR> | undefined
1062
+ readonly completion?:
1063
+ | ValidateCompletions<Completions, Extract<keyof Params, string>>
1064
+ | undefined
1065
+ readonly content: (
1066
+ params: Params
1067
+ ) => Effect.Effect<Array<typeof PromptMessage.Type> | string, E, R>
1068
+ }): Effect.Effect<
1069
+ void,
1070
+ never,
1071
+ Exclude<ParamsR | R, McpServerClient> | McpServer
1072
+ > => {
975
1073
  const args = Arr.empty<typeof PromptArgument.Type>()
976
1074
  const props: Record<string, Schema.Schema.Any> = {}
977
- const propSignatures = options.parameters ? AST.getPropertySignatures(options.parameters.ast) : []
1075
+ const propSignatures = options.parameters
1076
+ ? AST.getPropertySignatures(options.parameters.ast)
1077
+ : []
978
1078
  for (const prop of propSignatures) {
979
1079
  args.push({
980
1080
  name: prop.name as string,
@@ -988,14 +1088,18 @@ export const registerPrompt = <
988
1088
  description: options.description,
989
1089
  arguments: args
990
1090
  })
991
- const decode = options.parameters ? Schema.decodeUnknown(options.parameters) : () => Effect.succeed({} as Params)
1091
+ const decode = options.parameters
1092
+ ? Schema.decodeUnknown(options.parameters)
1093
+ : () => Effect.succeed({} as Params)
992
1094
  const completion: Record<string, (input: string) => Effect.Effect<any>> = options.completion ?? {}
993
1095
  return Effect.gen(function*() {
994
1096
  const registry = yield* McpServer
995
1097
  const context = yield* Effect.context<Exclude<R | ParamsR, McpServerClient>>()
996
1098
  const completions: Record<
997
1099
  string,
998
- (input: string) => Effect.Effect<CompleteResult, InternalError, McpServerClient>
1100
+ (
1101
+ input: string
1102
+ ) => Effect.Effect<CompleteResult, InternalError, McpServerClient>
999
1103
  > = {}
1000
1104
  for (const [param, handle] of Object.entries(completion)) {
1001
1105
  const encodeArray = Schema.encodeUnknown(Schema.Array(props[param]))
@@ -1022,16 +1126,23 @@ export const registerPrompt = <
1022
1126
  completions,
1023
1127
  handle: (params) =>
1024
1128
  decode(params).pipe(
1025
- Effect.mapError((error) => new InvalidParams({ message: error.message })),
1129
+ Effect.mapError(
1130
+ (error) => new InvalidParams({ message: error.message })
1131
+ ),
1026
1132
  Effect.flatMap((params) => options.content(params)),
1027
1133
  Effect.map((messages) => {
1028
- messages = typeof messages === "string" ?
1029
- [{
1030
- role: "user",
1031
- content: TextContent.make({ text: messages })
1032
- }] :
1033
- messages
1034
- return new GetPromptResult({ messages, description: prompt.description })
1134
+ messages = typeof messages === "string"
1135
+ ? [
1136
+ {
1137
+ role: "user",
1138
+ content: TextContent.make({ text: messages })
1139
+ }
1140
+ ]
1141
+ : messages
1142
+ return new GetPromptResult({
1143
+ messages,
1144
+ description: prompt.description
1145
+ })
1035
1146
  }),
1036
1147
  Effect.catchAllCause((cause) => {
1037
1148
  const prettyError = Cause.prettyErrors(cause)[0]
@@ -1056,17 +1167,21 @@ export const prompt = <
1056
1167
  ParamsI extends Record<string, string> = {},
1057
1168
  ParamsR = never,
1058
1169
  const Completions extends {
1059
- readonly [K in keyof Params]?: (input: string) => Effect.Effect<Array<Params[K]>, any, any>
1170
+ readonly [K in keyof Params]?: (
1171
+ input: string
1172
+ ) => Effect.Effect<Array<Params[K]>, any, any>
1060
1173
  } = {}
1061
- >(
1062
- options: {
1063
- readonly name: string
1064
- readonly description?: string | undefined
1065
- readonly parameters?: Schema.Schema<Params, ParamsI, ParamsR> | undefined
1066
- readonly completion?: ValidateCompletions<Completions, Extract<keyof Params, string>> | undefined
1067
- readonly content: (params: Params) => Effect.Effect<Array<typeof PromptMessage.Type> | string, E, R>
1068
- }
1069
- ): Layer.Layer<never, never, Exclude<ParamsR | R, McpServerClient>> =>
1174
+ >(options: {
1175
+ readonly name: string
1176
+ readonly description?: string | undefined
1177
+ readonly parameters?: Schema.Schema<Params, ParamsI, ParamsR> | undefined
1178
+ readonly completion?:
1179
+ | ValidateCompletions<Completions, Extract<keyof Params, string>>
1180
+ | undefined
1181
+ readonly content: (
1182
+ params: Params
1183
+ ) => Effect.Effect<Array<typeof PromptMessage.Type> | string, E, R>
1184
+ }): Layer.Layer<never, never, Exclude<ParamsR | R, McpServerClient>> =>
1070
1185
  Layer.effectDiscard(registerPrompt(options)).pipe(
1071
1186
  Layer.provide(McpServer.layer)
1072
1187
  )
@@ -1080,32 +1195,37 @@ export const prompt = <
1080
1195
  export const elicit: <A, I extends Record<string, any>, R>(options: {
1081
1196
  readonly message: string
1082
1197
  readonly schema: Schema.Schema<A, I, R>
1083
- }) => Effect.Effect<
1084
- A,
1085
- ElicitationDeclined,
1086
- McpServerClient | R
1087
- > = Effect.fnUntraced(function*<A, I extends Record<string, any>, R>(options: {
1088
- readonly message: string
1089
- readonly schema: Schema.Schema<A, I, R>
1090
- }) {
1091
- const { getClient } = yield* McpServerClient
1092
- const client = yield* getClient
1093
- const request = Elicit.payloadSchema.make({
1094
- message: options.message,
1095
- requestedSchema: makeJsonSchema(options.schema.ast)
1096
- })
1097
- const res = yield* client["elicitation/create"](request).pipe(
1098
- Effect.catchAllCause((cause) => Effect.fail(new ElicitationDeclined({ cause: Cause.squash(cause), request })))
1099
- )
1100
- switch (res.action) {
1101
- case "accept":
1102
- return yield* Effect.orDie(Schema.decodeUnknown(options.schema)(res.content))
1103
- case "cancel":
1104
- return yield* Effect.interrupt
1105
- case "decline":
1106
- return yield* Effect.fail(new ElicitationDeclined({ request }))
1107
- }
1108
- }, Effect.scoped)
1198
+ }) => Effect.Effect<A, ElicitationDeclined, McpServerClient | R> = Effect.fnUntraced(
1199
+ function*<A, I extends Record<string, any>, R>(options: {
1200
+ readonly message: string
1201
+ readonly schema: Schema.Schema<A, I, R>
1202
+ }) {
1203
+ const { getClient } = yield* McpServerClient
1204
+ const client = yield* getClient
1205
+ const request = Elicit.payloadSchema.make({
1206
+ message: options.message,
1207
+ requestedSchema: makeJsonSchema(options.schema.ast)
1208
+ })
1209
+ const res = yield* client["elicitation/create"](request).pipe(
1210
+ Effect.catchAllCause((cause) =>
1211
+ Effect.fail(
1212
+ new ElicitationDeclined({ cause: Cause.squash(cause), request })
1213
+ )
1214
+ )
1215
+ )
1216
+ switch (res.action) {
1217
+ case "accept":
1218
+ return yield* Effect.orDie(
1219
+ Schema.decodeUnknown(options.schema)(res.content)
1220
+ )
1221
+ case "cancel":
1222
+ return yield* Effect.interrupt
1223
+ case "decline":
1224
+ return yield* Effect.fail(new ElicitationDeclined({ request }))
1225
+ }
1226
+ },
1227
+ Effect.scoped
1228
+ )
1109
1229
 
1110
1230
  // -----------------------------------------------------------------------------
1111
1231
  // Internal
@@ -1125,7 +1245,10 @@ const makeUriMatcher = <A>() => {
1125
1245
  return { add, find } as const
1126
1246
  }
1127
1247
 
1128
- const compileUriTemplate = (segments: TemplateStringsArray, ...schemas: ReadonlyArray<Schema.Schema.Any>) => {
1248
+ const compileUriTemplate = (
1249
+ segments: TemplateStringsArray,
1250
+ ...schemas: ReadonlyArray<Schema.Schema.Any>
1251
+ ) => {
1129
1252
  let routerPath = segments[0].replace(":", "::")
1130
1253
  let uriPath = segments[0]
1131
1254
  const params: Record<string, Schema.Schema.Any> = {}
@@ -1165,15 +1288,20 @@ const layerHandlers = (serverInfo: {
1165
1288
  return {
1166
1289
  // Requests
1167
1290
  ping: () => Effect.succeed({}),
1168
- initialize(params) {
1291
+ initialize(params, { clientId }) {
1169
1292
  const requestedVersion = params.protocolVersion
1170
- const capabilities: Types.DeepMutable<typeof ServerCapabilities.Type> = {
1293
+ const capabilities: Types.DeepMutable<
1294
+ typeof ServerCapabilities.Type
1295
+ > = {
1171
1296
  completions: {}
1172
1297
  }
1173
1298
  if (server.tools.length > 0) {
1174
1299
  capabilities.tools = { listChanged: true }
1175
1300
  }
1176
- if (server.resources.length > 0 || server.resourceTemplates.length > 0) {
1301
+ if (
1302
+ server.resources.length > 0 ||
1303
+ server.resourceTemplates.length > 0
1304
+ ) {
1177
1305
  capabilities.resources = {
1178
1306
  listChanged: true,
1179
1307
  subscribe: false
@@ -1182,10 +1310,13 @@ const layerHandlers = (serverInfo: {
1182
1310
  if (server.prompts.length > 0) {
1183
1311
  capabilities.prompts = { listChanged: true }
1184
1312
  }
1313
+ server.initializedClients.add(clientId)
1185
1314
  return Effect.succeed({
1186
1315
  capabilities,
1187
1316
  serverInfo,
1188
- protocolVersion: SUPPORTED_PROTOCOL_VERSIONS.includes(requestedVersion)
1317
+ protocolVersion: SUPPORTED_PROTOCOL_VERSIONS.includes(
1318
+ requestedVersion
1319
+ )
1189
1320
  ? requestedVersion
1190
1321
  : LATEST_PROTOCOL_VERSION
1191
1322
  })
@@ -1194,12 +1325,20 @@ const layerHandlers = (serverInfo: {
1194
1325
  "logging/setLevel": () => InternalError.notImplemented,
1195
1326
  "prompts/get": server.getPromptResult,
1196
1327
  "prompts/list": () => Effect.sync(() => new ListPromptsResult({ prompts: server.prompts })),
1197
- "resources/list": () => Effect.sync(() => new ListResourcesResult({ resources: server.resources })),
1328
+ "resources/list": () =>
1329
+ Effect.sync(
1330
+ () => new ListResourcesResult({ resources: server.resources })
1331
+ ),
1198
1332
  "resources/read": ({ uri }) => server.findResource(uri),
1199
1333
  "resources/subscribe": () => InternalError.notImplemented,
1200
1334
  "resources/unsubscribe": () => InternalError.notImplemented,
1201
1335
  "resources/templates/list": () =>
1202
- Effect.sync(() => new ListResourceTemplatesResult({ resourceTemplates: server.resourceTemplates })),
1336
+ Effect.sync(
1337
+ () =>
1338
+ new ListResourceTemplatesResult({
1339
+ resourceTemplates: server.resourceTemplates
1340
+ })
1341
+ ),
1203
1342
  "tools/call": server.callTool,
1204
1343
  "tools/list": () => Effect.sync(() => new ListToolsResult({ tools: server.tools })),
1205
1344
 
@@ -1238,17 +1377,21 @@ const resolveResourceContent = (
1238
1377
  ): typeof ReadResourceResult.Type => {
1239
1378
  if (typeof content === "string") {
1240
1379
  return {
1241
- contents: [{
1242
- uri,
1243
- text: content
1244
- }]
1380
+ contents: [
1381
+ {
1382
+ uri,
1383
+ text: content
1384
+ }
1385
+ ]
1245
1386
  }
1246
1387
  } else if (content instanceof Uint8Array) {
1247
1388
  return {
1248
- contents: [{
1249
- uri,
1250
- blob: content
1251
- }]
1389
+ contents: [
1390
+ {
1391
+ uri,
1392
+ blob: content
1393
+ }
1394
+ ]
1252
1395
  }
1253
1396
  }
1254
1397
  return content