tmcp 1.9.0 → 1.10.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/package.json +1 -1
- package/src/index.js +74 -21
- package/src/internal/internal.d.ts +3 -2
- package/src/types/index.d.ts +9 -4
- package/src/types/index.d.ts.map +1 -2
- package/src/validation/index.js +2 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @import { JSONRPCRequest, JSONRPCParams } from "json-rpc-2.0";
|
|
5
5
|
* @import { ExtractURITemplateVariables } from "./internal/uri-template.js";
|
|
6
6
|
* @import { CallToolResult, ReadResourceResult, GetPromptResult, ClientCapabilities as ClientCapabilitiesType, JSONRPCRequest as JSONRPCRequestType, JSONRPCResponse, CreateMessageRequestParams, CreateMessageResult, Resource, LoggingLevel, ToolAnnotations } from "./validation/index.js";
|
|
7
|
-
* @import { Tool, Completion, Prompt, StoredResource, ServerOptions, ServerInfo, SubscriptionsKeys, McpEvents
|
|
7
|
+
* @import { Tool, Completion, Prompt, StoredResource, ServerOptions, ServerInfo, SubscriptionsKeys, McpEvents } from "./internal/internal.js";
|
|
8
8
|
*/
|
|
9
9
|
import { JSONRPCClient, JSONRPCServer } from 'json-rpc-2.0';
|
|
10
10
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
@@ -92,7 +92,7 @@ export class McpServer {
|
|
|
92
92
|
#client;
|
|
93
93
|
#options;
|
|
94
94
|
/**
|
|
95
|
-
* @type {Map<string, Tool<any>>}
|
|
95
|
+
* @type {Map<string, Tool<any, any>>}
|
|
96
96
|
*/
|
|
97
97
|
#tools = new Map();
|
|
98
98
|
/**
|
|
@@ -328,12 +328,25 @@ export class McpServer {
|
|
|
328
328
|
name,
|
|
329
329
|
title: tool.title || tool.description,
|
|
330
330
|
description: tool.description,
|
|
331
|
-
|
|
331
|
+
|
|
332
332
|
inputSchema: tool.schema
|
|
333
333
|
? await this.#options.adapter.toJsonSchema(
|
|
334
334
|
tool.schema,
|
|
335
335
|
)
|
|
336
336
|
: { type: 'object', properties: {} },
|
|
337
|
+
...(tool.outputSchema
|
|
338
|
+
? {
|
|
339
|
+
outputSchema:
|
|
340
|
+
await this.#options.adapter.toJsonSchema(
|
|
341
|
+
tool.outputSchema,
|
|
342
|
+
),
|
|
343
|
+
}
|
|
344
|
+
: {}),
|
|
345
|
+
...(tool.annotations
|
|
346
|
+
? {
|
|
347
|
+
annotations: tool.annotations,
|
|
348
|
+
}
|
|
349
|
+
: {}),
|
|
337
350
|
};
|
|
338
351
|
}),
|
|
339
352
|
);
|
|
@@ -348,22 +361,57 @@ export class McpServer {
|
|
|
348
361
|
if (!tool) {
|
|
349
362
|
throw new McpError(-32601, `Tool ${name} not found`);
|
|
350
363
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
364
|
+
|
|
365
|
+
// Validate input arguments if schema is provided
|
|
366
|
+
let validated_args = args;
|
|
367
|
+
if (tool.schema) {
|
|
368
|
+
let validation_result =
|
|
369
|
+
tool.schema['~standard'].validate(args);
|
|
370
|
+
if (validation_result instanceof Promise)
|
|
371
|
+
validation_result = await validation_result;
|
|
372
|
+
if (validation_result.issues) {
|
|
373
|
+
throw new McpError(
|
|
374
|
+
-32602,
|
|
375
|
+
`Invalid arguments for tool ${name}: ${JSON.stringify(validation_result.issues)}`,
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
validated_args = validation_result.value;
|
|
362
379
|
}
|
|
363
|
-
|
|
380
|
+
|
|
381
|
+
// Execute the tool
|
|
382
|
+
const tool_result = tool.schema
|
|
383
|
+
? await tool.execute(validated_args)
|
|
384
|
+
: await tool.execute();
|
|
385
|
+
|
|
386
|
+
console.log({ tool_result });
|
|
387
|
+
|
|
388
|
+
// Parse the basic result structure
|
|
389
|
+
const parsed_result = v.parse(
|
|
364
390
|
CallToolResultSchema,
|
|
365
|
-
|
|
391
|
+
tool_result,
|
|
366
392
|
);
|
|
393
|
+
|
|
394
|
+
// If tool has outputSchema, validate and populate structuredContent
|
|
395
|
+
if (
|
|
396
|
+
tool.outputSchema &&
|
|
397
|
+
parsed_result.structuredContent !== undefined
|
|
398
|
+
) {
|
|
399
|
+
let output_validation = tool.outputSchema[
|
|
400
|
+
'~standard'
|
|
401
|
+
].validate(parsed_result.structuredContent);
|
|
402
|
+
if (output_validation instanceof Promise)
|
|
403
|
+
output_validation = await output_validation;
|
|
404
|
+
if (output_validation.issues) {
|
|
405
|
+
throw new McpError(
|
|
406
|
+
-32603,
|
|
407
|
+
`Tool ${name} returned invalid structured content: ${JSON.stringify(output_validation.issues)}`,
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
// Update with validated structured content
|
|
411
|
+
parsed_result.structuredContent = output_validation.value;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return parsed_result;
|
|
367
415
|
},
|
|
368
416
|
);
|
|
369
417
|
}
|
|
@@ -600,7 +648,7 @@ export class McpServer {
|
|
|
600
648
|
#init_completion() {
|
|
601
649
|
this.#server.addMethod(
|
|
602
650
|
'completion/complete',
|
|
603
|
-
({ argument, ref, context }) => {
|
|
651
|
+
async ({ argument, ref, context }) => {
|
|
604
652
|
const completions = this.#completions[ref.type];
|
|
605
653
|
if (!completions) return null;
|
|
606
654
|
const complete = completions.get(ref.uri ?? ref.name);
|
|
@@ -609,7 +657,7 @@ export class McpServer {
|
|
|
609
657
|
if (!actual_complete) return null;
|
|
610
658
|
return v.parse(
|
|
611
659
|
CompleteResultSchema,
|
|
612
|
-
actual_complete(argument.value, context),
|
|
660
|
+
await actual_complete(argument.value, context),
|
|
613
661
|
);
|
|
614
662
|
},
|
|
615
663
|
);
|
|
@@ -627,10 +675,14 @@ export class McpServer {
|
|
|
627
675
|
}
|
|
628
676
|
/**
|
|
629
677
|
* @template {StandardSchema | undefined} [TSchema=undefined]
|
|
630
|
-
* @
|
|
631
|
-
* @param {TSchema extends undefined ?
|
|
678
|
+
* @template {StandardSchema | undefined} [TOutputSchema=undefined]
|
|
679
|
+
* @param {{ name: string; description: string; title?: string; schema?: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema> extends Record<string, unknown> ? TSchema : never; outputSchema?: StandardSchemaV1.InferOutput<TOutputSchema extends undefined ? never : TOutputSchema> extends Record<string, unknown> ? TOutputSchema : never; annotations?: ToolAnnotations }} options
|
|
680
|
+
* @param {TSchema extends undefined ? (()=>Promise<CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>> | CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>) : ((input: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>) => Promise<CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>> | CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>)} execute
|
|
632
681
|
*/
|
|
633
|
-
tool(
|
|
682
|
+
tool(
|
|
683
|
+
{ name, description, title, schema, outputSchema, annotations },
|
|
684
|
+
execute,
|
|
685
|
+
) {
|
|
634
686
|
if (this.#options.capabilities?.tools?.listChanged) {
|
|
635
687
|
this.#notify('notifications/tools/list_changed', {});
|
|
636
688
|
}
|
|
@@ -638,6 +690,7 @@ export class McpServer {
|
|
|
638
690
|
description,
|
|
639
691
|
title,
|
|
640
692
|
schema,
|
|
693
|
+
outputSchema,
|
|
641
694
|
execute,
|
|
642
695
|
annotations,
|
|
643
696
|
});
|
|
@@ -13,9 +13,10 @@ import {
|
|
|
13
13
|
ToolAnnotations
|
|
14
14
|
} from '../validation/index.js';
|
|
15
15
|
|
|
16
|
-
export type Tool<TSchema extends StandardSchemaV1 = StandardSchemaV1<any>> = {
|
|
16
|
+
export type Tool<TSchema extends StandardSchemaV1 = StandardSchemaV1<any>, TOutputSchema extends StandardSchemaV1 = StandardSchemaV1<any>> = {
|
|
17
17
|
description: string;
|
|
18
18
|
schema: TSchema;
|
|
19
|
+
outputSchema?: TOutputSchema;
|
|
19
20
|
title?: string;
|
|
20
21
|
annotations?: ToolAnnotations;
|
|
21
22
|
execute: (
|
|
@@ -26,7 +27,7 @@ export type Tool<TSchema extends StandardSchemaV1 = StandardSchemaV1<any>> = {
|
|
|
26
27
|
export type Completion = (
|
|
27
28
|
query: string,
|
|
28
29
|
context: { arguments: Record<string, string> },
|
|
29
|
-
) => CompleteResult
|
|
30
|
+
) => CompleteResult | Promise<CompleteResult>;
|
|
30
31
|
|
|
31
32
|
export type Prompt<TSchema extends StandardSchemaV1 = StandardSchemaV1<any>> = {
|
|
32
33
|
description: string;
|
package/src/types/index.d.ts
CHANGED
|
@@ -23,13 +23,14 @@ declare module 'tmcp' {
|
|
|
23
23
|
|
|
24
24
|
on<TEvent extends keyof McpEvents>(event: TEvent, callback: McpEvents[TEvent], options?: AddEventListenerOptions): () => void;
|
|
25
25
|
|
|
26
|
-
tool<TSchema extends StandardSchema | undefined = undefined>({ name, description, title, schema, annotations }: {
|
|
26
|
+
tool<TSchema extends StandardSchema | undefined = undefined, TOutputSchema extends StandardSchema | undefined = undefined>({ name, description, title, schema, outputSchema, annotations }: {
|
|
27
27
|
name: string;
|
|
28
28
|
description: string;
|
|
29
29
|
title?: string;
|
|
30
30
|
schema?: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema> extends Record<string, unknown> ? TSchema : never;
|
|
31
|
+
outputSchema?: StandardSchemaV1.InferOutput<TOutputSchema extends undefined ? never : TOutputSchema> extends Record<string, unknown> ? TOutputSchema : never;
|
|
31
32
|
annotations?: ToolAnnotations;
|
|
32
|
-
}, execute: TSchema extends undefined ? (() => Promise<CallToolResult
|
|
33
|
+
}, execute: TSchema extends undefined ? (() => Promise<CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>> | CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>) : ((input: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>) => Promise<CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>> | CallToolResult<TOutputSchema extends undefined ? undefined : StandardSchemaV1.InferInput<TOutputSchema extends undefined ? never : TOutputSchema>>)): void;
|
|
33
34
|
|
|
34
35
|
prompt<TSchema extends StandardSchema | undefined = undefined>({ name, description, title, schema, complete }: {
|
|
35
36
|
name: string;
|
|
@@ -116,7 +117,7 @@ declare module 'tmcp' {
|
|
|
116
117
|
type Completion = (
|
|
117
118
|
query: string,
|
|
118
119
|
context: { arguments: Record<string, string> },
|
|
119
|
-
) => CompleteResult
|
|
120
|
+
) => CompleteResult | Promise<CompleteResult>;
|
|
120
121
|
|
|
121
122
|
type ServerOptions<TSchema extends StandardSchemaV1> = {
|
|
122
123
|
capabilities?: ServerCapabilities;
|
|
@@ -895,7 +896,11 @@ declare module 'tmcp' {
|
|
|
895
896
|
type ClientCapabilities_1 = v.InferInput<typeof ClientCapabilitiesSchema>;
|
|
896
897
|
type ServerCapabilities = v.InferInput<typeof ServerCapabilitiesSchema>;
|
|
897
898
|
type InitializeRequestParams = v.InferInput<typeof InitializeRequestParamsSchema>;
|
|
898
|
-
type CallToolResult = v.InferInput<typeof CallToolResultSchema
|
|
899
|
+
type CallToolResult<TStructuredContent extends Record<string, unknown> | undefined> = Omit<v.InferInput<typeof CallToolResultSchema>, "structuredContent"> & (undefined extends TStructuredContent ? {
|
|
900
|
+
structuredContent?: undefined;
|
|
901
|
+
} : {
|
|
902
|
+
structuredContent: TStructuredContent;
|
|
903
|
+
});
|
|
899
904
|
type ReadResourceResult = v.InferInput<typeof ReadResourceResultSchema>;
|
|
900
905
|
type GetPromptResult = v.InferInput<typeof GetPromptResultSchema>;
|
|
901
906
|
type CompleteResult = v.InferInput<typeof CompleteResultSchema>;
|
package/src/types/index.d.ts.map
CHANGED
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"CompleteResultSchema",
|
|
25
25
|
"ServerCapabilities",
|
|
26
26
|
"InitializeRequestParams",
|
|
27
|
-
"CallToolResult",
|
|
28
27
|
"ReadResourceResult",
|
|
29
28
|
"GetPromptResult",
|
|
30
29
|
"CompleteResult",
|
|
@@ -56,6 +55,6 @@
|
|
|
56
55
|
null,
|
|
57
56
|
null
|
|
58
57
|
],
|
|
59
|
-
"mappings": ";;;;;cAsFaA,SAASA
|
|
58
|
+
"mappings": ";;;;;cAsFaA,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCi3CsCC,kBAAkBA;MC76ClEC,UAAUA;;;;;MAsCVC,aAAaA;;;;;;;;;;;;;MAabC,UAAUA;;;;;;MAMVC,iBAAiBA;;MAEjBC,SAASA;;;;;;;;;;;;ODeRC,qBAAqBA;;;;;;;;;;;;;;OAuGrBC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;OA6BxBC,6BAA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuB7BC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmMxBC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4GdC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8PxBC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BrBC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2GrBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEpBC,kBAAkBA;OAuGlBC,gCAAgCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8ChCC,yBAAyBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+LzBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;MA8H2BC,kBAAkBA;MASbC,uBAAuBA;;;;;;MAO5BC,kBAAkBA;MAGrBC,eAAeA;MAGhBC,cAAcA;MAGFC,0BAA0BA;MAGjCC,mBAAmBA;MAY9BC,QAAQA;MAMDC,eAAeA;MAGlBC,YAAYA;MAGTC,eAAeA;;ME7/CnEC,IAAIA;;;;;;;MAOJC,cAAcA;;;;;;;MAOdC,cAAcA;;;;;MAKdC,qBAAqBA;;;;;;;;;;;;;;;;;MAiBrBC,4BAA4BA;;;;;;MAMrBC,2BAA2BA;;;;;;;OCjC1BC,iBAAiBA;;;;;;;;;;;;;;;;cAAjBA,iBAAiBA",
|
|
60
59
|
"ignoreList": []
|
|
61
60
|
}
|
package/src/validation/index.js
CHANGED
|
@@ -1492,7 +1492,8 @@ export const ServerResultSchema = v.union([
|
|
|
1492
1492
|
* @typedef {v.InferInput<typeof InitializeRequestParamsSchema>} InitializeRequestParams
|
|
1493
1493
|
*/
|
|
1494
1494
|
/**
|
|
1495
|
-
* @
|
|
1495
|
+
* @template {Record<string, unknown> | undefined} TStructuredContent
|
|
1496
|
+
* @typedef {Omit<v.InferInput<typeof CallToolResultSchema>, "structuredContent"> & (undefined extends TStructuredContent ? { structuredContent?: undefined } : { structuredContent: TStructuredContent })} CallToolResult
|
|
1496
1497
|
*/
|
|
1497
1498
|
/**
|
|
1498
1499
|
* @typedef {v.InferInput<typeof ReadResourceResultSchema>} ReadResourceResult
|