tmcp 1.13.0 → 1.15.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmcp",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "description": "The main tmcp library",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * @import SqidsType from "sqids";
5
5
  * @import { JSONRPCRequest, JSONRPCParams } from "json-rpc-2.0";
6
6
  * @import { ExtractURITemplateVariables } from "./internal/uri-template.js";
7
- * @import { CallToolResult, ReadResourceResult, GetPromptResult, ClientCapabilities as ClientCapabilitiesType, JSONRPCRequest as JSONRPCRequestType, JSONRPCResponse, CreateMessageRequestParams, CreateMessageResult, Resource, LoggingLevel, ToolAnnotations, ClientInfo, ElicitResult } from "./validation/index.js";
8
- * @import { Tool, Completion, Prompt, StoredResource, ServerOptions, ServerInfo, SubscriptionsKeys, ChangedArgs, McpEvents } from "./internal/internal.js";
7
+ * @import { CallToolResult, ReadResourceResult, GetPromptResult, ServerInfo, ClientCapabilities as ClientCapabilitiesType, JSONRPCRequest as JSONRPCRequestType, JSONRPCResponse, CreateMessageRequestParams, CreateMessageResult, Resource, LoggingLevel, ToolAnnotations, ClientInfo, ElicitResult, Icons } from "./validation/index.js";
8
+ * @import { Tool, Completion, Prompt, StoredResource, ServerOptions, SubscriptionsKeys, ChangedArgs, McpEvents } from "./internal/internal.js";
9
9
  */
10
10
  import { JSONRPCClient, JSONRPCServer } from 'json-rpc-2.0';
11
11
  import { AsyncLocalStorage } from 'node:async_hooks';
@@ -24,6 +24,7 @@ import {
24
24
  McpError,
25
25
  ReadResourceResultSchema,
26
26
  ElicitResultSchema,
27
+ JSONRPCErrorSchema,
27
28
  } from './validation/index.js';
28
29
  import {
29
30
  get_supported_versions,
@@ -229,11 +230,6 @@ export class McpServer {
229
230
  }),
230
231
  );
231
232
 
232
- // Trigger initial roots request if client supports it
233
- if (validated_initialize.capabilities?.roots) {
234
- this.#refresh_roots();
235
- }
236
-
237
233
  // Return server response with negotiated version and capabilities
238
234
  return {
239
235
  protocolVersion: negotiated_version,
@@ -394,7 +390,7 @@ export class McpServer {
394
390
  name,
395
391
  title: tool.title || tool.description,
396
392
  description: tool.description,
397
-
393
+ icons: tool.icons,
398
394
  inputSchema: tool.schema
399
395
  ? await this.#options.adapter.toJsonSchema(
400
396
  tool.schema,
@@ -511,6 +507,7 @@ export class McpServer {
511
507
  return {
512
508
  name,
513
509
  title: prompt.title || prompt.description,
510
+ icons: prompt.icons,
514
511
  description: prompt.description,
515
512
  arguments: keys.map((key) => {
516
513
  const property =
@@ -602,8 +599,10 @@ export class McpServer {
602
599
  const all_resources = [];
603
600
 
604
601
  // Add static resources
605
- for (const [uri, { description, name, title, ...resource }] of this
606
- .#resources) {
602
+ for (const [
603
+ uri,
604
+ { description, name, title, icons, ...resource },
605
+ ] of this.#resources) {
607
606
  if (!resource.template) {
608
607
  if (
609
608
  resource.enabled != null &&
@@ -615,6 +614,7 @@ export class McpServer {
615
614
  title: title || description,
616
615
  description,
617
616
  uri,
617
+ icons,
618
618
  });
619
619
  } else if (resource.list_resources) {
620
620
  if (
@@ -655,7 +655,14 @@ export class McpServer {
655
655
  [...this.#resources].map(
656
656
  async ([
657
657
  uri,
658
- { description, name, title, template, enabled },
658
+ {
659
+ description,
660
+ name,
661
+ title,
662
+ template,
663
+ icons,
664
+ enabled,
665
+ },
659
666
  ]) => {
660
667
  if (!template) return null;
661
668
  if (
@@ -665,6 +672,7 @@ export class McpServer {
665
672
  return null;
666
673
  return {
667
674
  name,
675
+ icons,
668
676
  title: title || description,
669
677
  description,
670
678
  uriTemplate: uri,
@@ -789,7 +797,7 @@ export class McpServer {
789
797
  * Tools will be invoked by the LLM when it thinks it needs to use them, you can use the annotations to provide additional information about the tool, like what it does, how to use it, etc.
790
798
  * @template {StandardSchema | undefined} [TSchema=undefined]
791
799
  * @template {StandardSchema | undefined} [TOutputSchema=undefined]
792
- * @param {{ name: string; description: string; title?: string; enabled?: ()=>boolean | Promise<boolean>; 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
800
+ * @param {{ name: string; description: string; title?: string; enabled?: ()=>boolean | Promise<boolean>; 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 } & Icons} options
793
801
  * @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
794
802
  */
795
803
  tool(
@@ -801,6 +809,7 @@ export class McpServer {
801
809
  outputSchema,
802
810
  annotations,
803
811
  enabled,
812
+ icons,
804
813
  },
805
814
  execute,
806
815
  ) {
@@ -813,6 +822,7 @@ export class McpServer {
813
822
  outputSchema,
814
823
  execute,
815
824
  annotations,
825
+ icons,
816
826
  });
817
827
  }
818
828
  /**
@@ -822,10 +832,13 @@ export class McpServer {
822
832
  * A prompt can also have a schema that defines the input it expects, the user will be prompted to enter the inputs you request. It can also have a complete function
823
833
  * for each input that will be used to provide completions for the user.
824
834
  * @template {StandardSchema | undefined} [TSchema=undefined]
825
- * @param {{ name: string; description: string; title?: string; enabled?: ()=>boolean | Promise<boolean>; schema?: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema> extends Record<string, unknown> ? TSchema : never; complete?: NoInfer<TSchema extends undefined ? never : Partial<Record<keyof (StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>), Completion>>> }} options
835
+ * @param {{ name: string; description: string; title?: string; enabled?: ()=>boolean | Promise<boolean>; schema?: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema> extends Record<string, unknown> ? TSchema : never; complete?: NoInfer<TSchema extends undefined ? never : Partial<Record<keyof (StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>), Completion>>> } & Icons} options
826
836
  * @param {TSchema extends undefined ? (()=>Promise<GetPromptResult> | GetPromptResult) : (input: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>) => Promise<GetPromptResult> | GetPromptResult} execute
827
837
  */
828
- prompt({ name, description, title, schema, complete, enabled }, execute) {
838
+ prompt(
839
+ { name, description, title, schema, complete, enabled, icons },
840
+ execute,
841
+ ) {
829
842
  if (complete) {
830
843
  this.#completions['ref/prompt'].set(name, complete);
831
844
  }
@@ -836,6 +849,7 @@ export class McpServer {
836
849
  schema,
837
850
  execute,
838
851
  enabled,
852
+ icons,
839
853
  });
840
854
  }
841
855
  /**
@@ -855,10 +869,10 @@ export class McpServer {
855
869
  /**
856
870
  * Add a resource to the server. Resources are added manually to the context by the user to provide the LLM with additional context.
857
871
  * Use the description and title to help the user to understand what the resource is.
858
- * @param {{ name: string; description: string; title?: string; uri: string, enabled?: ()=>boolean | Promise<boolean>; }} options
872
+ * @param {{ name: string; description: string; title?: string; uri: string, enabled?: ()=>boolean | Promise<boolean>; } & Icons} options
859
873
  * @param {(uri: string) => Promise<ReadResourceResult> | ReadResourceResult} execute
860
874
  */
861
- resource({ name, description, title, uri, enabled }, execute) {
875
+ resource({ name, description, title, uri, enabled, icons }, execute) {
862
876
  this.#resource({
863
877
  name,
864
878
  description,
@@ -866,6 +880,7 @@ export class McpServer {
866
880
  uri,
867
881
  execute,
868
882
  enabled,
883
+ icons,
869
884
  template: false,
870
885
  });
871
886
  }
@@ -877,7 +892,7 @@ export class McpServer {
877
892
  * Use the description and title to help the user to understand what the resource is.
878
893
  * @template {string} TUri
879
894
  * @template {ExtractURITemplateVariables<TUri>} TVariables
880
- * @param {{ name: string; description: string; title?: string; enabled?: ()=>boolean | Promise<boolean>; uri: TUri; complete?: NoInfer<TVariables extends never ? never : Partial<Record<TVariables, Completion>>>; list?: () => Promise<Array<Resource>> | Array<Resource> }} options
895
+ * @param {{ name: string; description: string; title?: string; enabled?: ()=>boolean | Promise<boolean>; uri: TUri; complete?: NoInfer<TVariables extends never ? never : Partial<Record<TVariables, Completion>>>; list?: () => Promise<Array<Resource>> | Array<Resource> } & Icons} options
881
896
  * @param {(uri: string, params: Record<TVariables, string | string[]>) => Promise<ReadResourceResult> | ReadResourceResult} execute
882
897
  */
883
898
  template(
@@ -889,6 +904,7 @@ export class McpServer {
889
904
  complete,
890
905
  list: list_resources,
891
906
  enabled,
907
+ icons,
892
908
  },
893
909
  execute,
894
910
  ) {
@@ -900,6 +916,7 @@ export class McpServer {
900
916
  uri,
901
917
  execute,
902
918
  complete,
919
+ icons,
903
920
  list_resources,
904
921
  template: true,
905
922
  });
@@ -942,7 +959,10 @@ export class McpServer {
942
959
  );
943
960
  }
944
961
  // It's a response - handle with client
945
- const validated_response = v.parse(JSONRPCResponseSchema, message);
962
+ const validated_response = v.parse(
963
+ v.union([JSONRPCResponseSchema, JSONRPCErrorSchema]),
964
+ message,
965
+ );
946
966
  this.#lazyily_create_client();
947
967
  return this.#ctx_storage.run(ctx ?? {}, async () =>
948
968
  this.#client?.receive(validated_response),
@@ -10,7 +10,8 @@ import {
10
10
  Resource,
11
11
  ServerCapabilities,
12
12
  LoggingLevel,
13
- ToolAnnotations
13
+ ToolAnnotations,
14
+ Icons
14
15
  } from '../validation/index.js';
15
16
 
16
17
  export type Tool<TSchema extends StandardSchemaV1 = StandardSchemaV1<any>, TOutputSchema extends StandardSchemaV1 = StandardSchemaV1<any>> = {
@@ -23,7 +24,7 @@ export type Tool<TSchema extends StandardSchemaV1 = StandardSchemaV1<any>, TOutp
23
24
  execute: (
24
25
  input?: StandardSchemaV1.InferInput<TSchema>,
25
26
  ) => Promise<CallToolResult> | CallToolResult;
26
- };
27
+ } & Icons;
27
28
 
28
29
  export type Completion = (
29
30
  query: string,
@@ -38,7 +39,7 @@ export type Prompt<TSchema extends StandardSchemaV1 = StandardSchemaV1<any>> = {
38
39
  execute: (
39
40
  input?: StandardSchemaV1.InferInput<TSchema>,
40
41
  ) => Promise<GetPromptResult> | GetPromptResult;
41
- };
42
+ } & Icons;
42
43
 
43
44
  export type StoredResource =
44
45
  | {
@@ -54,7 +55,7 @@ export type StoredResource =
54
55
  uri: string,
55
56
  params: Record<string, string | string[]>,
56
57
  ) => Promise<ReadResourceResult> | ReadResourceResult;
57
- }
58
+ } & Icons
58
59
  | {
59
60
  description: string;
60
61
  name: string;
@@ -64,7 +65,7 @@ export type StoredResource =
64
65
  execute: (
65
66
  uri: string,
66
67
  ) => Promise<ReadResourceResult> | ReadResourceResult;
67
- };
68
+ } & Icons;
68
69
 
69
70
  export type ServerOptions<TSchema extends StandardSchemaV1 | undefined> = {
70
71
  capabilities?: ServerCapabilities;
@@ -79,12 +80,6 @@ export type ServerOptions<TSchema extends StandardSchemaV1 | undefined> = {
79
80
  }
80
81
  };
81
82
 
82
- export type ServerInfo = {
83
- name: string;
84
- version: string;
85
- description: string;
86
- };
87
-
88
83
  export type ChangedArgs = {
89
84
  'resource': [id: string];
90
85
  'tools': [];
@@ -25,7 +25,13 @@ declare module 'tmcp' {
25
25
  * Get the client information (name, version, etc.) of the client that initiated the current request...useful if you want to do something different based on the client.
26
26
  */
27
27
  currentClientInfo(): {
28
+ icons?: {
29
+ src: string;
30
+ mimeType?: string | undefined;
31
+ sizes?: string[] | undefined;
32
+ }[] | undefined;
28
33
  version: string;
34
+ websiteUrl?: string | undefined;
29
35
  name: string;
30
36
  title?: string | undefined;
31
37
  } | undefined;
@@ -48,7 +54,7 @@ declare module 'tmcp' {
48
54
  *
49
55
  * Tools will be invoked by the LLM when it thinks it needs to use them, you can use the annotations to provide additional information about the tool, like what it does, how to use it, etc.
50
56
  * */
51
- tool<TSchema extends StandardSchema | undefined = undefined, TOutputSchema extends StandardSchema | undefined = undefined>({ name, description, title, schema, outputSchema, annotations, enabled, }: {
57
+ tool<TSchema extends StandardSchema | undefined = undefined, TOutputSchema extends StandardSchema | undefined = undefined>({ name, description, title, schema, outputSchema, annotations, enabled, icons, }: {
52
58
  name: string;
53
59
  description: string;
54
60
  title?: string;
@@ -56,7 +62,7 @@ declare module 'tmcp' {
56
62
  schema?: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema> extends Record<string, unknown> ? TSchema : never;
57
63
  outputSchema?: StandardSchemaV1.InferOutput<TOutputSchema extends undefined ? never : TOutputSchema> extends Record<string, unknown> ? TOutputSchema : never;
58
64
  annotations?: ToolAnnotations;
59
- }, 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;
65
+ } & Icons, 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;
60
66
  /**
61
67
  * Add a prompt to the server. Prompts are used to provide the user with pre-defined messages that adds context to the LLM.
62
68
  * Use the description and title to help the user to understand what the prompt does and when to use it.
@@ -64,25 +70,25 @@ declare module 'tmcp' {
64
70
  * A prompt can also have a schema that defines the input it expects, the user will be prompted to enter the inputs you request. It can also have a complete function
65
71
  * for each input that will be used to provide completions for the user.
66
72
  * */
67
- prompt<TSchema extends StandardSchema | undefined = undefined>({ name, description, title, schema, complete, enabled }: {
73
+ prompt<TSchema extends StandardSchema | undefined = undefined>({ name, description, title, schema, complete, enabled, icons }: {
68
74
  name: string;
69
75
  description: string;
70
76
  title?: string;
71
77
  enabled?: () => boolean | Promise<boolean>;
72
78
  schema?: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema> extends Record<string, unknown> ? TSchema : never;
73
79
  complete?: NoInfer<TSchema extends undefined ? never : Partial<Record<keyof StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>, Completion>>>;
74
- }, execute: TSchema extends undefined ? (() => Promise<GetPromptResult> | GetPromptResult) : (input: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>) => Promise<GetPromptResult> | GetPromptResult): void;
80
+ } & Icons, execute: TSchema extends undefined ? (() => Promise<GetPromptResult> | GetPromptResult) : (input: StandardSchemaV1.InferInput<TSchema extends undefined ? never : TSchema>) => Promise<GetPromptResult> | GetPromptResult): void;
75
81
  /**
76
82
  * Add a resource to the server. Resources are added manually to the context by the user to provide the LLM with additional context.
77
83
  * Use the description and title to help the user to understand what the resource is.
78
84
  * */
79
- resource({ name, description, title, uri, enabled }: {
85
+ resource({ name, description, title, uri, enabled, icons }: {
80
86
  name: string;
81
87
  description: string;
82
88
  title?: string;
83
89
  uri: string;
84
90
  enabled?: () => boolean | Promise<boolean>;
85
- }, execute: (uri: string) => Promise<ReadResourceResult> | ReadResourceResult): void;
91
+ } & Icons, execute: (uri: string) => Promise<ReadResourceResult> | ReadResourceResult): void;
86
92
  /**
87
93
  * Add a resource template to the server. Resources are added manually to the context by the user to provide the LLM with additional context.
88
94
  * Resource templates are used to create resources dynamically based on a URI template. The URI template should be a valid URI template as defined in RFC 6570.
@@ -90,7 +96,7 @@ declare module 'tmcp' {
90
96
  * be invoked to provide completions for the template variables to the user.
91
97
  * Use the description and title to help the user to understand what the resource is.
92
98
  * */
93
- template<TUri extends string, TVariables extends ExtractURITemplateVariables<TUri>>({ name, description, title, uri, complete, list: list_resources, enabled, }: {
99
+ template<TUri extends string, TVariables extends ExtractURITemplateVariables<TUri>>({ name, description, title, uri, complete, list: list_resources, enabled, icons, }: {
94
100
  name: string;
95
101
  description: string;
96
102
  title?: string;
@@ -98,7 +104,7 @@ declare module 'tmcp' {
98
104
  uri: TUri;
99
105
  complete?: NoInfer<TVariables extends never ? never : Partial<Record<TVariables, Completion>>>;
100
106
  list?: () => Promise<Array<Resource>> | Array<Resource>;
101
- }, execute: (uri: string, params: Record<TVariables, string | string[]>) => Promise<ReadResourceResult> | ReadResourceResult): void;
107
+ } & Icons, execute: (uri: string, params: Record<TVariables, string | string[]>) => Promise<ReadResourceResult> | ReadResourceResult): void;
102
108
  /**
103
109
  * The main function that receive a JSONRpc message and either dispatch a `send` event or process the request.
104
110
  *
@@ -198,12 +204,6 @@ declare module 'tmcp' {
198
204
  }
199
205
  };
200
206
 
201
- type ServerInfo = {
202
- name: string;
203
- version: string;
204
- description: string;
205
- };
206
-
207
207
  type ChangedArgs = {
208
208
  'resource': [id: string];
209
209
  'tools': [];
@@ -234,6 +234,82 @@ declare module 'tmcp' {
234
234
  readonly _meta: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
235
235
  }, undefined>;
236
236
  }, undefined>;
237
+ const IconsSchema: v.ObjectSchema<{
238
+ /**
239
+ * Optional set of sized icons that the client can display in a user interface.
240
+ *
241
+ * Clients that support rendering icons MUST support at least the following MIME types:
242
+ * - `image/png` - PNG images (safe, universal compatibility)
243
+ * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)
244
+ *
245
+ * Clients that support rendering icons SHOULD also support:
246
+ * - `image/svg+xml` - SVG images (scalable but requires security precautions)
247
+ * - `image/webp` - WebP images (modern, efficient format)
248
+ */
249
+ readonly icons: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
250
+ /**
251
+ * URL or data URI for the icon.
252
+ */
253
+ readonly src: v.StringSchema<undefined>;
254
+ /**
255
+ * Optional MIME type for the icon.
256
+ */
257
+ readonly mimeType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
258
+ /**
259
+ * Optional array of strings that specify sizes at which the icon can be used.
260
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
261
+ *
262
+ * If not provided, the client should assume that the icon can be used at any size.
263
+ */
264
+ readonly sizes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
265
+ }, undefined>, undefined>, undefined>;
266
+ }, undefined>;
267
+ /**
268
+ * Describes the name and version of an MCP implementation.
269
+ */
270
+ const ImplementationSchema: v.ObjectSchema<{
271
+ /**
272
+ * Optional set of sized icons that the client can display in a user interface.
273
+ *
274
+ * Clients that support rendering icons MUST support at least the following MIME types:
275
+ * - `image/png` - PNG images (safe, universal compatibility)
276
+ * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)
277
+ *
278
+ * Clients that support rendering icons SHOULD also support:
279
+ * - `image/svg+xml` - SVG images (scalable but requires security precautions)
280
+ * - `image/webp` - WebP images (modern, efficient format)
281
+ */
282
+ readonly icons: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
283
+ /**
284
+ * URL or data URI for the icon.
285
+ */
286
+ readonly src: v.StringSchema<undefined>;
287
+ /**
288
+ * Optional MIME type for the icon.
289
+ */
290
+ readonly mimeType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
291
+ /**
292
+ * Optional array of strings that specify sizes at which the icon can be used.
293
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
294
+ *
295
+ * If not provided, the client should assume that the icon can be used at any size.
296
+ */
297
+ readonly sizes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
298
+ }, undefined>, undefined>, undefined>;
299
+ readonly version: v.StringSchema<undefined>;
300
+ readonly websiteUrl: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
301
+ /** Intended for programmatic or logical use, but used as a display name in past specs or fallback */
302
+ readonly name: v.StringSchema<undefined>;
303
+ /**
304
+ * Intended for UI and end-user contexts — optimized to be human-readable and easily understood,
305
+ * even by those unfamiliar with domain-specific terminology.
306
+ *
307
+ * If not provided, the name should be used for display (except for Tool,
308
+ * where `annotations.title` should be given precedence over using `name`,
309
+ * if present).
310
+ */
311
+ readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
312
+ }, undefined>;
237
313
  /**
238
314
  * Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
239
315
  */
@@ -289,7 +365,36 @@ declare module 'tmcp' {
289
365
  }, undefined>, undefined>;
290
366
  }, undefined>;
291
367
  readonly clientInfo: v.ObjectSchema<{
368
+ /**
369
+ * Optional set of sized icons that the client can display in a user interface.
370
+ *
371
+ * Clients that support rendering icons MUST support at least the following MIME types:
372
+ * - `image/png` - PNG images (safe, universal compatibility)
373
+ * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)
374
+ *
375
+ * Clients that support rendering icons SHOULD also support:
376
+ * - `image/svg+xml` - SVG images (scalable but requires security precautions)
377
+ * - `image/webp` - WebP images (modern, efficient format)
378
+ */
379
+ readonly icons: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
380
+ /**
381
+ * URL or data URI for the icon.
382
+ */
383
+ readonly src: v.StringSchema<undefined>;
384
+ /**
385
+ * Optional MIME type for the icon.
386
+ */
387
+ readonly mimeType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
388
+ /**
389
+ * Optional array of strings that specify sizes at which the icon can be used.
390
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
391
+ *
392
+ * If not provided, the client should assume that the icon can be used at any size.
393
+ */
394
+ readonly sizes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
395
+ }, undefined>, undefined>, undefined>;
292
396
  readonly version: v.StringSchema<undefined>;
397
+ readonly websiteUrl: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
293
398
  /** Intended for programmatic or logical use, but used as a display name in past specs or fallback */
294
399
  readonly name: v.StringSchema<undefined>;
295
400
  /**
@@ -361,6 +466,34 @@ declare module 'tmcp' {
361
466
  * A known resource that the server is capable of reading.
362
467
  */
363
468
  const ResourceSchema: v.ObjectSchema<{
469
+ /**
470
+ * Optional set of sized icons that the client can display in a user interface.
471
+ *
472
+ * Clients that support rendering icons MUST support at least the following MIME types:
473
+ * - `image/png` - PNG images (safe, universal compatibility)
474
+ * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)
475
+ *
476
+ * Clients that support rendering icons SHOULD also support:
477
+ * - `image/svg+xml` - SVG images (scalable but requires security precautions)
478
+ * - `image/webp` - WebP images (modern, efficient format)
479
+ */
480
+ readonly icons: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
481
+ /**
482
+ * URL or data URI for the icon.
483
+ */
484
+ readonly src: v.StringSchema<undefined>;
485
+ /**
486
+ * Optional MIME type for the icon.
487
+ */
488
+ readonly mimeType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
489
+ /**
490
+ * Optional array of strings that specify sizes at which the icon can be used.
491
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
492
+ *
493
+ * If not provided, the client should assume that the icon can be used at any size.
494
+ */
495
+ readonly sizes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
496
+ }, undefined>, undefined>, undefined>;
364
497
  /**
365
498
  * The URI of this resource.
366
499
  */
@@ -492,6 +625,34 @@ declare module 'tmcp' {
492
625
  readonly _meta: v.OptionalSchema<v.ObjectSchema<{}, undefined>, undefined>;
493
626
  }, undefined>, v.ObjectSchema<{
494
627
  readonly type: v.LiteralSchema<"resource_link", undefined>;
628
+ /**
629
+ * Optional set of sized icons that the client can display in a user interface.
630
+ *
631
+ * Clients that support rendering icons MUST support at least the following MIME types:
632
+ * - `image/png` - PNG images (safe, universal compatibility)
633
+ * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)
634
+ *
635
+ * Clients that support rendering icons SHOULD also support:
636
+ * - `image/svg+xml` - SVG images (scalable but requires security precautions)
637
+ * - `image/webp` - WebP images (modern, efficient format)
638
+ */
639
+ readonly icons: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
640
+ /**
641
+ * URL or data URI for the icon.
642
+ */
643
+ readonly src: v.StringSchema<undefined>;
644
+ /**
645
+ * Optional MIME type for the icon.
646
+ */
647
+ readonly mimeType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
648
+ /**
649
+ * Optional array of strings that specify sizes at which the icon can be used.
650
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
651
+ *
652
+ * If not provided, the client should assume that the icon can be used at any size.
653
+ */
654
+ readonly sizes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
655
+ }, undefined>, undefined>, undefined>;
495
656
  /**
496
657
  * The URI of this resource.
497
658
  */
@@ -676,6 +837,34 @@ declare module 'tmcp' {
676
837
  readonly _meta: v.OptionalSchema<v.ObjectSchema<{}, undefined>, undefined>;
677
838
  }, undefined>, v.ObjectSchema<{
678
839
  readonly type: v.LiteralSchema<"resource_link", undefined>;
840
+ /**
841
+ * Optional set of sized icons that the client can display in a user interface.
842
+ *
843
+ * Clients that support rendering icons MUST support at least the following MIME types:
844
+ * - `image/png` - PNG images (safe, universal compatibility)
845
+ * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)
846
+ *
847
+ * Clients that support rendering icons SHOULD also support:
848
+ * - `image/svg+xml` - SVG images (scalable but requires security precautions)
849
+ * - `image/webp` - WebP images (modern, efficient format)
850
+ */
851
+ readonly icons: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
852
+ /**
853
+ * URL or data URI for the icon.
854
+ */
855
+ readonly src: v.StringSchema<undefined>;
856
+ /**
857
+ * Optional MIME type for the icon.
858
+ */
859
+ readonly mimeType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
860
+ /**
861
+ * Optional array of strings that specify sizes at which the icon can be used.
862
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
863
+ *
864
+ * If not provided, the client should assume that the icon can be used at any size.
865
+ */
866
+ readonly sizes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
867
+ }, undefined>, undefined>, undefined>;
679
868
  /**
680
869
  * The URI of this resource.
681
870
  */
@@ -982,8 +1171,12 @@ declare module 'tmcp' {
982
1171
  */
983
1172
  readonly _meta: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
984
1173
  }, undefined>;
1174
+ type Icons = v.InferInput<typeof IconsSchema>;
985
1175
  type ClientCapabilities_1 = v.InferInput<typeof ClientCapabilitiesSchema>;
986
1176
  type ServerCapabilities = v.InferInput<typeof ServerCapabilitiesSchema>;
1177
+ type ServerInfo = v.InferInput<typeof ImplementationSchema> & {
1178
+ description?: string;
1179
+ };
987
1180
  type InitializeRequestParams = v.InferInput<typeof InitializeRequestParamsSchema>;
988
1181
  type CallToolResult<TStructuredContent extends Record<string, unknown> | undefined> = Omit<v.InferInput<typeof CallToolResultSchema>, "structuredContent" | "isError"> & (undefined extends TStructuredContent ? {
989
1182
  structuredContent?: undefined;
@@ -6,10 +6,11 @@
6
6
  "ClientCapabilities",
7
7
  "Completion",
8
8
  "ServerOptions",
9
- "ServerInfo",
10
9
  "ChangedArgs",
11
10
  "McpEvents",
12
11
  "JSONRPCResponseSchema",
12
+ "IconsSchema",
13
+ "ImplementationSchema",
13
14
  "ClientCapabilitiesSchema",
14
15
  "InitializeRequestParamsSchema",
15
16
  "ServerCapabilitiesSchema",
@@ -23,7 +24,9 @@
23
24
  "CreateMessageResultSchema",
24
25
  "ElicitResultSchema",
25
26
  "CompleteResultSchema",
27
+ "Icons",
26
28
  "ServerCapabilities",
29
+ "ServerInfo",
27
30
  "InitializeRequestParams",
28
31
  "ReadResourceResult",
29
32
  "GetPromptResult",
@@ -57,6 +60,6 @@
57
60
  null,
58
61
  null
59
62
  ],
60
- "mappings": ";;;;;cAsGaA,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCi2CsCC,kBAAkBA;MC56ClEC,UAAUA;;;;;MAyCVC,aAAaA;;;;;;;;;;;;;MAabC,UAAUA;;;;;;MAMVC,WAAWA;;;;;;;MAaXC,SAASA;;;;;;;;;;;;ODARC,qBAAqBA;;;;;;;;;;;;;;OAuGrBC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;OA6BxBC,6BAA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuB7BC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmMxBC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4GdC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8PxBC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BrBC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2GrBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEpBC,kBAAkBA;OAuGlBC,gCAAgCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8ChCC,yBAAyBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6GzBC,kBAAkBA;;;;;;;;;;;;;;;;;;OAkFlBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;MA8H2BC,kBAAkBA;MASbC,uBAAuBA;;;;;;;;;;;MAO5BC,kBAAkBA;MAGrBC,eAAeA;MAGhBC,cAAcA;MAGFC,0BAA0BA;MAGjCC,mBAAmBA;MAY9BC,QAAQA;MAMDC,eAAeA;MAGlBC,YAAYA;MAGTC,eAAeA;MAGlBC,YAAYA;;MEhgD7DC,IAAIA;;;;;;;MAOJC,cAAcA;;;;;;;MAOdC,cAAcA;;;;;MAKdC,qBAAqBA;;;;;;;;;;;;;;;;;MAiBrBC,4BAA4BA;;;;;;MAMrBC,2BAA2BA;;;;;;;OCjC1BC,iBAAiBA;;;;;;;;;;;;;;;;cAAjBA,iBAAiBA",
63
+ "mappings": ";;;;;cAuGaA,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aC84CsCC,kBAAkBA;MCz9ClEC,UAAUA;;;;;MAyCVC,aAAaA;;;;;;;;;;;;;MAabC,WAAWA;;;;;;;MAaXC,SAASA;;;;;;;;;;;;ODKRC,qBAAqBA;;;;;;;;;;;OAgHrBC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoBXC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAUpBC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;OA6BxBC,6BAA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuB7BC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmMxBC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8GdC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+PxBC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BrBC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4GrBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEpBC,kBAAkBA;OAuGlBC,gCAAgCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8ChCC,yBAAyBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6GzBC,kBAAkBA;;;;;;;;;;;;;;;;;;OAkFlBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;MA2HcC,KAAKA;;MAMQC,kBAAkBA;MAOKC,UAAUA;;;MAG5BC,uBAAuBA;;;;;;;;;;;MAO5BC,kBAAkBA;MAGrBC,eAAeA;MAGhBC,cAAcA;MAGFC,0BAA0BA;MAGjCC,mBAAmBA;MAY9BC,QAAQA;MAMDC,eAAeA;MAGlBC,YAAYA;MAGTC,eAAeA;MAGlBC,YAAYA;;ME/iD7DC,IAAIA;;;;;;;MAOJC,cAAcA;;;;;;;MAOdC,cAAcA;;;;;MAKdC,qBAAqBA;;;;;;;;;;;;;;;;;MAiBrBC,4BAA4BA;;;;;;MAMrBC,2BAA2BA;;;;;;;OCjC1BC,iBAAiBA;;;;;;;;;;;;;;;;cAAjBA,iBAAiBA",
61
64
  "ignoreList": []
62
65
  }
@@ -188,6 +188,43 @@ export const BaseMetadataSchema = v.object({
188
188
  */
189
189
  title: v.optional(v.string()),
190
190
  });
191
+
192
+ /**
193
+ * Icon schema for use in tools, prompts, resources, and implementations.
194
+ */
195
+ export const IconSchema = v.object({
196
+ /**
197
+ * URL or data URI for the icon.
198
+ */
199
+ src: v.string(),
200
+ /**
201
+ * Optional MIME type for the icon.
202
+ */
203
+ mimeType: v.optional(v.string()),
204
+ /**
205
+ * Optional array of strings that specify sizes at which the icon can be used.
206
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
207
+ *
208
+ * If not provided, the client should assume that the icon can be used at any size.
209
+ */
210
+ sizes: v.optional(v.array(v.string())),
211
+ });
212
+
213
+ export const IconsSchema = v.object({
214
+ /**
215
+ * Optional set of sized icons that the client can display in a user interface.
216
+ *
217
+ * Clients that support rendering icons MUST support at least the following MIME types:
218
+ * - `image/png` - PNG images (safe, universal compatibility)
219
+ * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)
220
+ *
221
+ * Clients that support rendering icons SHOULD also support:
222
+ * - `image/svg+xml` - SVG images (scalable but requires security precautions)
223
+ * - `image/webp` - WebP images (modern, efficient format)
224
+ */
225
+ icons: v.optional(v.array(IconSchema)),
226
+ });
227
+
191
228
  /* Initialization */
192
229
 
193
230
  /**
@@ -196,6 +233,8 @@ export const BaseMetadataSchema = v.object({
196
233
  export const ImplementationSchema = v.object({
197
234
  ...BaseMetadataSchema.entries,
198
235
  version: v.string(),
236
+ websiteUrl: v.optional(v.string()),
237
+ ...IconsSchema.entries,
199
238
  });
200
239
 
201
240
  /**
@@ -473,6 +512,7 @@ export const ResourceSchema = v.object({
473
512
  * for notes on _meta usage.
474
513
  */
475
514
  _meta: v.optional(v.object({})),
515
+ ...IconsSchema.entries,
476
516
  });
477
517
 
478
518
  /**
@@ -503,6 +543,7 @@ export const ResourceTemplateSchema = v.object({
503
543
  * for notes on _meta usage.
504
544
  */
505
545
  _meta: v.optional(v.object({})),
546
+ ...IconsSchema.entries,
506
547
  });
507
548
 
508
549
  /**
@@ -661,6 +702,7 @@ export const PromptSchema = v.object({
661
702
  * for notes on _meta usage.
662
703
  */
663
704
  _meta: v.optional(v.object({})),
705
+ ...IconsSchema.entries,
664
706
  });
665
707
 
666
708
  /**
@@ -925,6 +967,7 @@ export const ToolSchema = v.object({
925
967
  * for notes on _meta usage.
926
968
  */
927
969
  _meta: v.optional(v.object({})),
970
+ ...IconsSchema.entries,
928
971
  });
929
972
 
930
973
  /**
@@ -1476,6 +1519,9 @@ export const ServerResultSchema = v.union([
1476
1519
  ListToolsResultSchema,
1477
1520
  ]);
1478
1521
 
1522
+ /**
1523
+ * @typedef {v.InferInput<typeof IconsSchema>} Icons
1524
+ */
1479
1525
  /**
1480
1526
  * @typedef {v.InferInput<typeof ClientCapabilitiesSchema>} ClientCapabilities
1481
1527
  */
@@ -1485,8 +1531,9 @@ export const ServerResultSchema = v.union([
1485
1531
  /**
1486
1532
  * @typedef {v.InferInput<typeof ImplementationSchema>} ClientInfo
1487
1533
  */
1534
+ // TODO remove description from ServerInfo on next major...it was never in the protocol
1488
1535
  /**
1489
- * @typedef {v.InferInput<typeof ImplementationSchema>} ServerInfo
1536
+ * @typedef {v.InferInput<typeof ImplementationSchema> & { description?: string }} ServerInfo
1490
1537
  */
1491
1538
  /**
1492
1539
  * @typedef {v.InferInput<typeof InitializeRequestParamsSchema>} InitializeRequestParams