tmcp 1.11.0 → 1.12.1
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/README.md +69 -3
- package/package.json +1 -1
- package/src/index.js +61 -29
- package/src/internal/internal.d.ts +12 -1
- package/src/types/index.d.ts +8 -3
- package/src/types/index.d.ts.map +2 -2
package/README.md
CHANGED
|
@@ -201,12 +201,78 @@ server.template(
|
|
|
201
201
|
);
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
-
##### `
|
|
204
|
+
##### `withContext<T>()`
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
Specify the type of custom context for type-safe access to application-specific data.
|
|
207
207
|
|
|
208
208
|
```javascript
|
|
209
|
-
|
|
209
|
+
interface MyCustomContext {
|
|
210
|
+
userId: string;
|
|
211
|
+
permissions: string[];
|
|
212
|
+
database: DatabaseConnection;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const server = new McpServer(serverInfo, options).withContext<MyCustomContext>();
|
|
216
|
+
|
|
217
|
+
// Now you can access typed custom context in handlers
|
|
218
|
+
server.tool(
|
|
219
|
+
{
|
|
220
|
+
name: 'get-user-data',
|
|
221
|
+
description: 'Get current user data',
|
|
222
|
+
},
|
|
223
|
+
async () => {
|
|
224
|
+
const { userId, database } = server.ctx.custom!;
|
|
225
|
+
const userData = await database.users.findById(userId);
|
|
226
|
+
return {
|
|
227
|
+
content: [{ type: 'text', text: JSON.stringify(userData) }],
|
|
228
|
+
};
|
|
229
|
+
},
|
|
230
|
+
);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
##### `ctx`
|
|
234
|
+
|
|
235
|
+
Access the current request context, including session ID, auth info, and custom context.
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
server.tool(
|
|
239
|
+
{
|
|
240
|
+
name: 'context-aware-tool',
|
|
241
|
+
description: 'Tool that uses request context',
|
|
242
|
+
},
|
|
243
|
+
async () => {
|
|
244
|
+
const { sessionId, auth, custom } = server.ctx;
|
|
245
|
+
|
|
246
|
+
if (!custom?.userId) {
|
|
247
|
+
throw new Error('User authentication required');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
content: [
|
|
252
|
+
{
|
|
253
|
+
type: 'text',
|
|
254
|
+
text: `Hello user ${custom.userId} in session ${sessionId}`,
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
};
|
|
258
|
+
},
|
|
259
|
+
);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
##### `receive(request, context?)`
|
|
263
|
+
|
|
264
|
+
Process an incoming MCP request with optional context.
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
// Basic usage
|
|
268
|
+
const response = server.receive(jsonRpcRequest);
|
|
269
|
+
|
|
270
|
+
// With custom context (typically used by transports)
|
|
271
|
+
const response = server.receive(jsonRpcRequest, {
|
|
272
|
+
sessionId: 'session-123',
|
|
273
|
+
auth: authInfo,
|
|
274
|
+
custom: customContextData,
|
|
275
|
+
});
|
|
210
276
|
```
|
|
211
277
|
|
|
212
278
|
##### `elicitation(schema)`
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @import { JSONRPCRequest, JSONRPCParams } from "json-rpc-2.0";
|
|
6
6
|
* @import { ExtractURITemplateVariables } from "./internal/uri-template.js";
|
|
7
7
|
* @import { CallToolResult, ReadResourceResult, GetPromptResult, ClientCapabilities as ClientCapabilitiesType, JSONRPCRequest as JSONRPCRequestType, JSONRPCResponse, CreateMessageRequestParams, CreateMessageResult, Resource, LoggingLevel, ToolAnnotations, ClientInfo } from "./validation/index.js";
|
|
8
|
-
* @import { Tool, Completion, Prompt, StoredResource, ServerOptions, ServerInfo, SubscriptionsKeys, McpEvents } from "./internal/internal.js";
|
|
8
|
+
* @import { Tool, Completion, Prompt, StoredResource, ServerOptions, ServerInfo, 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';
|
|
@@ -762,6 +762,25 @@ export class McpServer {
|
|
|
762
762
|
return {};
|
|
763
763
|
});
|
|
764
764
|
}
|
|
765
|
+
|
|
766
|
+
#notify_tools_list_changed() {
|
|
767
|
+
if (this.#options.capabilities?.tools?.listChanged) {
|
|
768
|
+
this.#notify('notifications/tools/list_changed', {});
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
#notify_prompts_list_changed() {
|
|
773
|
+
if (this.#options.capabilities?.prompts?.listChanged) {
|
|
774
|
+
this.#notify('notifications/prompts/list_changed', {});
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
#notify_resources_list_changed() {
|
|
779
|
+
if (this.#options.capabilities?.resources?.listChanged) {
|
|
780
|
+
this.#notify('notifications/resources/list_changed', {});
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
765
784
|
/**
|
|
766
785
|
* Add a tool to the server. If you want to receive any input you need to provide a schema. The schema needs to be a valid Standard Schema V1 schema and needs to be an Object with the properties you need,
|
|
767
786
|
* Use the description and title to help the LLM to understand what the tool does and when to use it. If you provide an outputSchema, you need to return a structuredContent that matches the schema.
|
|
@@ -784,9 +803,7 @@ export class McpServer {
|
|
|
784
803
|
},
|
|
785
804
|
execute,
|
|
786
805
|
) {
|
|
787
|
-
|
|
788
|
-
this.#notify('notifications/tools/list_changed', {});
|
|
789
|
-
}
|
|
806
|
+
this.#notify_tools_list_changed();
|
|
790
807
|
this.#tools.set(name, {
|
|
791
808
|
description,
|
|
792
809
|
title,
|
|
@@ -811,9 +828,7 @@ export class McpServer {
|
|
|
811
828
|
if (complete) {
|
|
812
829
|
this.#completions['ref/prompt'].set(name, complete);
|
|
813
830
|
}
|
|
814
|
-
|
|
815
|
-
this.#notify('notifications/prompts/list_changed', {});
|
|
816
|
-
}
|
|
831
|
+
this.#notify_prompts_list_changed();
|
|
817
832
|
this.#prompts.set(name, {
|
|
818
833
|
description,
|
|
819
834
|
title,
|
|
@@ -832,9 +847,7 @@ export class McpServer {
|
|
|
832
847
|
if (resource.template) {
|
|
833
848
|
this.#templates.add(uri);
|
|
834
849
|
}
|
|
835
|
-
|
|
836
|
-
this.#notify('notifications/resources/list_changed', {});
|
|
837
|
-
}
|
|
850
|
+
this.#notify_resources_list_changed();
|
|
838
851
|
this.#resources.set(uri, resource);
|
|
839
852
|
}
|
|
840
853
|
|
|
@@ -937,24 +950,40 @@ export class McpServer {
|
|
|
937
950
|
|
|
938
951
|
/**
|
|
939
952
|
* Send a notification for subscriptions
|
|
940
|
-
* @
|
|
941
|
-
* @param {
|
|
953
|
+
* @template {keyof ChangedArgs} TWhat
|
|
954
|
+
* @param {[what: TWhat, ...ChangedArgs[TWhat]]} args
|
|
942
955
|
*/
|
|
943
|
-
changed(
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
this.#
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
956
|
+
changed(...args) {
|
|
957
|
+
const [what, id] = args;
|
|
958
|
+
if (what === 'prompts') {
|
|
959
|
+
this.#notify_prompts_list_changed();
|
|
960
|
+
} else if (what === 'tools') {
|
|
961
|
+
this.#notify_tools_list_changed();
|
|
962
|
+
} else if (what === 'resources') {
|
|
963
|
+
this.#notify_resources_list_changed();
|
|
964
|
+
} else {
|
|
965
|
+
if (
|
|
966
|
+
this.#subscriptions[
|
|
967
|
+
/** @type {SubscriptionsKeys} */ (what)
|
|
968
|
+
].has(id)
|
|
969
|
+
) {
|
|
970
|
+
const resource = this.#resources.get(id);
|
|
971
|
+
if (!resource) return;
|
|
972
|
+
const sessions =
|
|
973
|
+
this.#subscriptions[
|
|
974
|
+
/** @type {SubscriptionsKeys} */ (what)
|
|
975
|
+
].get(id);
|
|
976
|
+
this.#notify(
|
|
977
|
+
`notifications/resources/updated`,
|
|
978
|
+
{
|
|
979
|
+
uri: id,
|
|
980
|
+
title: resource.name,
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
sessions: sessions ? [...sessions] : undefined,
|
|
984
|
+
},
|
|
985
|
+
);
|
|
986
|
+
}
|
|
958
987
|
}
|
|
959
988
|
}
|
|
960
989
|
|
|
@@ -973,10 +1002,11 @@ export class McpServer {
|
|
|
973
1002
|
* If the client doesn't support elicitation, it will throw an error.
|
|
974
1003
|
*
|
|
975
1004
|
* @template {StandardSchema extends undefined ? never : StandardSchema} TSchema
|
|
1005
|
+
* @param {string} message
|
|
976
1006
|
* @param {TSchema} schema
|
|
977
1007
|
* @returns {Promise<StandardSchemaV1.InferOutput<TSchema>>}
|
|
978
1008
|
*/
|
|
979
|
-
async elicitation(schema) {
|
|
1009
|
+
async elicitation(message, schema) {
|
|
980
1010
|
if (!this.#client_capabilities?.elicitation)
|
|
981
1011
|
throw new McpError(-32601, "Client doesn't support elicitation");
|
|
982
1012
|
|
|
@@ -985,7 +1015,9 @@ export class McpServer {
|
|
|
985
1015
|
await this.#client?.request(
|
|
986
1016
|
'elicitation/create',
|
|
987
1017
|
{
|
|
988
|
-
|
|
1018
|
+
message,
|
|
1019
|
+
requestedSchema:
|
|
1020
|
+
await this.#options.adapter.toJsonSchema(schema),
|
|
989
1021
|
},
|
|
990
1022
|
{
|
|
991
1023
|
sessions: [this.#session_id],
|
|
@@ -85,7 +85,18 @@ export type ServerInfo = {
|
|
|
85
85
|
description: string;
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
export type
|
|
88
|
+
export type ChangedArgs = {
|
|
89
|
+
'resource': [id: string];
|
|
90
|
+
'tools': [];
|
|
91
|
+
'prompts': [];
|
|
92
|
+
'resources': [];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
type SubscriptionsKeysObj = {
|
|
96
|
+
[K in keyof ChangedArgs as ChangedArgs[K]["length"] extends 0 ? "without_args" : "with_args"]: K
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export type SubscriptionsKeys = SubscriptionsKeysObj["with_args"];
|
|
89
100
|
|
|
90
101
|
export type McpEvents = {
|
|
91
102
|
send: (message: {
|
package/src/types/index.d.ts
CHANGED
|
@@ -107,7 +107,7 @@ declare module 'tmcp' {
|
|
|
107
107
|
/**
|
|
108
108
|
* Send a notification for subscriptions
|
|
109
109
|
* */
|
|
110
|
-
changed(what:
|
|
110
|
+
changed<TWhat extends keyof ChangedArgs>(what: TWhat, ...args: ChangedArgs[TWhat]): void;
|
|
111
111
|
/**
|
|
112
112
|
* Refresh roots list from client
|
|
113
113
|
*/
|
|
@@ -120,7 +120,7 @@ declare module 'tmcp' {
|
|
|
120
120
|
* If the client doesn't support elicitation, it will throw an error.
|
|
121
121
|
*
|
|
122
122
|
* */
|
|
123
|
-
elicitation<TSchema extends StandardSchema extends undefined ? never : StandardSchema>(schema: TSchema): Promise<StandardSchemaV1.InferOutput<TSchema>>;
|
|
123
|
+
elicitation<TSchema extends StandardSchema extends undefined ? never : StandardSchema>(message: string, schema: TSchema): Promise<StandardSchemaV1.InferOutput<TSchema>>;
|
|
124
124
|
/**
|
|
125
125
|
* Request language model sampling from the client
|
|
126
126
|
* */
|
|
@@ -202,7 +202,12 @@ declare module 'tmcp' {
|
|
|
202
202
|
description: string;
|
|
203
203
|
};
|
|
204
204
|
|
|
205
|
-
type
|
|
205
|
+
type ChangedArgs = {
|
|
206
|
+
'resource': [id: string];
|
|
207
|
+
'tools': [];
|
|
208
|
+
'prompts': [];
|
|
209
|
+
'resources': [];
|
|
210
|
+
}
|
|
206
211
|
|
|
207
212
|
type McpEvents = {
|
|
208
213
|
send: (message: {
|
package/src/types/index.d.ts.map
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"Completion",
|
|
8
8
|
"ServerOptions",
|
|
9
9
|
"ServerInfo",
|
|
10
|
-
"
|
|
10
|
+
"ChangedArgs",
|
|
11
11
|
"McpEvents",
|
|
12
12
|
"JSONRPCResponseSchema",
|
|
13
13
|
"ClientCapabilitiesSchema",
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
null,
|
|
56
56
|
null
|
|
57
57
|
],
|
|
58
|
-
"mappings": ";;;;;cAqGaA,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCk2CsCC,kBAAkBA;MC56ClEC,UAAUA;;;;;MAyCVC,aAAaA;;;;;;;;;;;;;MAabC,UAAUA;;;;;;MAMVC,
|
|
58
|
+
"mappings": ";;;;;cAqGaA,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCk2CsCC,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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",
|
|
59
59
|
"ignoreList": []
|
|
60
60
|
}
|