@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.
- package/Chat/package.json +6 -0
- package/EmbeddingModel/package.json +6 -0
- package/IdGenerator/package.json +6 -0
- package/LanguageModel/package.json +6 -0
- package/Model/package.json +6 -0
- package/Prompt/package.json +6 -0
- package/Response/package.json +6 -0
- package/Telemetry/package.json +6 -0
- package/Tool/package.json +6 -0
- package/Toolkit/package.json +6 -0
- package/dist/cjs/AiError.js +575 -11
- package/dist/cjs/AiError.js.map +1 -1
- package/dist/cjs/Chat.js +302 -0
- package/dist/cjs/Chat.js.map +1 -0
- package/dist/cjs/EmbeddingModel.js +184 -0
- package/dist/cjs/EmbeddingModel.js.map +1 -0
- package/dist/cjs/IdGenerator.js +255 -0
- package/dist/cjs/IdGenerator.js.map +1 -0
- package/dist/cjs/LanguageModel.js +584 -0
- package/dist/cjs/LanguageModel.js.map +1 -0
- package/dist/cjs/McpServer.js +12 -4
- package/dist/cjs/McpServer.js.map +1 -1
- package/dist/cjs/Model.js +118 -0
- package/dist/cjs/Model.js.map +1 -0
- package/dist/cjs/Prompt.js +649 -0
- package/dist/cjs/Prompt.js.map +1 -0
- package/dist/cjs/Response.js +635 -0
- package/dist/cjs/Response.js.map +1 -0
- package/dist/cjs/Telemetry.js +176 -0
- package/dist/cjs/Telemetry.js.map +1 -0
- package/dist/cjs/Tokenizer.js +87 -8
- package/dist/cjs/Tokenizer.js.map +1 -1
- package/dist/cjs/Tool.js +556 -0
- package/dist/cjs/Tool.js.map +1 -0
- package/dist/cjs/Toolkit.js +279 -0
- package/dist/cjs/Toolkit.js.map +1 -0
- package/dist/cjs/index.js +21 -19
- package/dist/dts/AiError.d.ts +577 -9
- package/dist/dts/AiError.d.ts.map +1 -1
- package/dist/dts/Chat.d.ts +356 -0
- package/dist/dts/Chat.d.ts.map +1 -0
- package/dist/dts/EmbeddingModel.d.ts +153 -0
- package/dist/dts/EmbeddingModel.d.ts.map +1 -0
- package/dist/dts/IdGenerator.d.ts +272 -0
- package/dist/dts/IdGenerator.d.ts.map +1 -0
- package/dist/dts/LanguageModel.d.ts +458 -0
- package/dist/dts/LanguageModel.d.ts.map +1 -0
- package/dist/dts/McpSchema.d.ts +25 -25
- package/dist/dts/McpServer.d.ts +6 -4
- package/dist/dts/McpServer.d.ts.map +1 -1
- package/dist/dts/Model.d.ts +124 -0
- package/dist/dts/Model.d.ts.map +1 -0
- package/dist/dts/Prompt.d.ts +1119 -0
- package/dist/dts/Prompt.d.ts.map +1 -0
- package/dist/dts/Response.d.ts +1519 -0
- package/dist/dts/Response.d.ts.map +1 -0
- package/dist/dts/Telemetry.d.ts +520 -0
- package/dist/dts/Telemetry.d.ts.map +1 -0
- package/dist/dts/Tokenizer.d.ts +131 -13
- package/dist/dts/Tokenizer.d.ts.map +1 -1
- package/dist/dts/Tool.d.ts +876 -0
- package/dist/dts/Tool.d.ts.map +1 -0
- package/dist/dts/Toolkit.d.ts +310 -0
- package/dist/dts/Toolkit.d.ts.map +1 -0
- package/dist/dts/index.d.ts +498 -13
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/esm/AiError.js +570 -10
- package/dist/esm/AiError.js.map +1 -1
- package/dist/esm/Chat.js +291 -0
- package/dist/esm/Chat.js.map +1 -0
- package/dist/esm/EmbeddingModel.js +173 -0
- package/dist/esm/EmbeddingModel.js.map +1 -0
- package/dist/esm/IdGenerator.js +245 -0
- package/dist/esm/IdGenerator.js.map +1 -0
- package/dist/esm/LanguageModel.js +572 -0
- package/dist/esm/LanguageModel.js.map +1 -0
- package/dist/esm/McpServer.js +12 -4
- package/dist/esm/McpServer.js.map +1 -1
- package/dist/esm/Model.js +108 -0
- package/dist/esm/Model.js.map +1 -0
- package/dist/esm/Prompt.js +633 -0
- package/dist/esm/Prompt.js.map +1 -0
- package/dist/esm/Response.js +619 -0
- package/dist/esm/Response.js.map +1 -0
- package/dist/esm/Telemetry.js +166 -0
- package/dist/esm/Telemetry.js.map +1 -0
- package/dist/esm/Tokenizer.js +87 -8
- package/dist/esm/Tokenizer.js.map +1 -1
- package/dist/esm/Tool.js +534 -0
- package/dist/esm/Tool.js.map +1 -0
- package/dist/esm/Toolkit.js +269 -0
- package/dist/esm/Toolkit.js.map +1 -0
- package/dist/esm/index.js +498 -13
- package/dist/esm/index.js.map +1 -1
- package/package.json +76 -68
- package/src/AiError.ts +739 -9
- package/src/Chat.ts +546 -0
- package/src/EmbeddingModel.ts +311 -0
- package/src/IdGenerator.ts +320 -0
- package/src/LanguageModel.ts +1074 -0
- package/src/McpServer.ts +337 -194
- package/src/Model.ts +155 -0
- package/src/Prompt.ts +1616 -0
- package/src/Response.ts +2131 -0
- package/src/Telemetry.ts +655 -0
- package/src/Tokenizer.ts +145 -24
- package/src/Tool.ts +1267 -0
- package/src/Toolkit.ts +516 -0
- package/src/index.ts +499 -13
- package/AiChat/package.json +0 -6
- package/AiEmbeddingModel/package.json +0 -6
- package/AiInput/package.json +0 -6
- package/AiLanguageModel/package.json +0 -6
- package/AiModel/package.json +0 -6
- package/AiResponse/package.json +0 -6
- package/AiTelemetry/package.json +0 -6
- package/AiTool/package.json +0 -6
- package/AiToolkit/package.json +0 -6
- package/dist/cjs/AiChat.js +0 -122
- package/dist/cjs/AiChat.js.map +0 -1
- package/dist/cjs/AiEmbeddingModel.js +0 -109
- package/dist/cjs/AiEmbeddingModel.js.map +0 -1
- package/dist/cjs/AiInput.js +0 -458
- package/dist/cjs/AiInput.js.map +0 -1
- package/dist/cjs/AiLanguageModel.js +0 -351
- package/dist/cjs/AiLanguageModel.js.map +0 -1
- package/dist/cjs/AiModel.js +0 -37
- package/dist/cjs/AiModel.js.map +0 -1
- package/dist/cjs/AiResponse.js +0 -681
- package/dist/cjs/AiResponse.js.map +0 -1
- package/dist/cjs/AiTelemetry.js +0 -58
- package/dist/cjs/AiTelemetry.js.map +0 -1
- package/dist/cjs/AiTool.js +0 -150
- package/dist/cjs/AiTool.js.map +0 -1
- package/dist/cjs/AiToolkit.js +0 -157
- package/dist/cjs/AiToolkit.js.map +0 -1
- package/dist/cjs/internal/common.js +0 -21
- package/dist/cjs/internal/common.js.map +0 -1
- package/dist/dts/AiChat.d.ts +0 -101
- package/dist/dts/AiChat.d.ts.map +0 -1
- package/dist/dts/AiEmbeddingModel.d.ts +0 -65
- package/dist/dts/AiEmbeddingModel.d.ts.map +0 -1
- package/dist/dts/AiInput.d.ts +0 -590
- package/dist/dts/AiInput.d.ts.map +0 -1
- package/dist/dts/AiLanguageModel.d.ts +0 -302
- package/dist/dts/AiLanguageModel.d.ts.map +0 -1
- package/dist/dts/AiModel.d.ts +0 -25
- package/dist/dts/AiModel.d.ts.map +0 -1
- package/dist/dts/AiResponse.d.ts +0 -863
- package/dist/dts/AiResponse.d.ts.map +0 -1
- package/dist/dts/AiTelemetry.d.ts +0 -242
- package/dist/dts/AiTelemetry.d.ts.map +0 -1
- package/dist/dts/AiTool.d.ts +0 -334
- package/dist/dts/AiTool.d.ts.map +0 -1
- package/dist/dts/AiToolkit.d.ts +0 -96
- package/dist/dts/AiToolkit.d.ts.map +0 -1
- package/dist/dts/internal/common.d.ts +0 -2
- package/dist/dts/internal/common.d.ts.map +0 -1
- package/dist/esm/AiChat.js +0 -111
- package/dist/esm/AiChat.js.map +0 -1
- package/dist/esm/AiEmbeddingModel.js +0 -98
- package/dist/esm/AiEmbeddingModel.js.map +0 -1
- package/dist/esm/AiInput.js +0 -433
- package/dist/esm/AiInput.js.map +0 -1
- package/dist/esm/AiLanguageModel.js +0 -340
- package/dist/esm/AiLanguageModel.js.map +0 -1
- package/dist/esm/AiModel.js +0 -29
- package/dist/esm/AiModel.js.map +0 -1
- package/dist/esm/AiResponse.js +0 -657
- package/dist/esm/AiResponse.js.map +0 -1
- package/dist/esm/AiTelemetry.js +0 -48
- package/dist/esm/AiTelemetry.js.map +0 -1
- package/dist/esm/AiTool.js +0 -134
- package/dist/esm/AiTool.js.map +0 -1
- package/dist/esm/AiToolkit.js +0 -147
- package/dist/esm/AiToolkit.js.map +0 -1
- package/dist/esm/internal/common.js +0 -14
- package/dist/esm/internal/common.js.map +0 -1
- package/src/AiChat.ts +0 -251
- package/src/AiEmbeddingModel.ts +0 -169
- package/src/AiInput.ts +0 -602
- package/src/AiLanguageModel.ts +0 -685
- package/src/AiModel.ts +0 -53
- package/src/AiResponse.ts +0 -986
- package/src/AiTelemetry.ts +0 -333
- package/src/AiTool.ts +0 -579
- package/src/AiToolkit.ts +0 -265
- 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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
110
|
-
|
|
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<
|
|
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(
|
|
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(
|
|
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(
|
|
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({
|
|
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
|
|
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
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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!: (
|
|
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(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
504
|
-
|
|
505
|
-
|
|
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<
|
|
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
|
|
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
|
-
|
|
610
|
-
|
|
611
|
-
|
|
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*
|
|
615
|
-
|
|
661
|
+
const built = yield* toolkit as any as Effect.Effect<
|
|
662
|
+
Toolkit.WithHandler<Tools>,
|
|
616
663
|
never,
|
|
617
|
-
Exclude<AiTool.
|
|
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
|
-
...
|
|
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
|
-
|
|
648
|
-
|
|
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"
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
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:
|
|
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
|
-
|
|
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<
|
|
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
|
|
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<
|
|
754
|
+
export type ResourceCompletions<
|
|
755
|
+
Schemas extends ReadonlyArray<Schema.Schema.Any>
|
|
756
|
+
> = {
|
|
697
757
|
readonly [
|
|
698
|
-
K in Extract<
|
|
699
|
-
|
|
700
|
-
|
|
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<
|
|
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?:
|
|
756
|
-
|
|
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
|
|
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
|
|
776
|
-
|
|
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
|
-
|
|
799
|
-
|
|
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?:
|
|
810
|
-
|
|
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<
|
|
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(
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
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(
|
|
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<
|
|
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?:
|
|
922
|
-
|
|
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
|
|
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]?: (
|
|
1054
|
+
readonly [K in keyof Params]?: (
|
|
1055
|
+
input: string
|
|
1056
|
+
) => Effect.Effect<Array<Params[K]>, any, any>
|
|
965
1057
|
} = {}
|
|
966
|
-
>(
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
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
|
|
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
|
|
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
|
-
(
|
|
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(
|
|
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
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
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]?: (
|
|
1170
|
+
readonly [K in keyof Params]?: (
|
|
1171
|
+
input: string
|
|
1172
|
+
) => Effect.Effect<Array<Params[K]>, any, any>
|
|
1060
1173
|
} = {}
|
|
1061
|
-
>(
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
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
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
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 = (
|
|
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<
|
|
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 (
|
|
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(
|
|
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": () =>
|
|
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(
|
|
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
|
-
|
|
1243
|
-
|
|
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
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1389
|
+
contents: [
|
|
1390
|
+
{
|
|
1391
|
+
uri,
|
|
1392
|
+
blob: content
|
|
1393
|
+
}
|
|
1394
|
+
]
|
|
1252
1395
|
}
|
|
1253
1396
|
}
|
|
1254
1397
|
return content
|