@modelcontextprotocol/sdk 1.12.3 → 1.13.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 +342 -24
- package/dist/cjs/client/auth.d.ts +15 -3
- package/dist/cjs/client/auth.d.ts.map +1 -1
- package/dist/cjs/client/auth.js +40 -10
- package/dist/cjs/client/auth.js.map +1 -1
- package/dist/cjs/client/index.d.ts +308 -26
- package/dist/cjs/client/index.d.ts.map +1 -1
- package/dist/cjs/client/index.js +11 -2
- package/dist/cjs/client/index.js.map +1 -1
- package/dist/cjs/client/sse.d.ts +2 -0
- package/dist/cjs/client/sse.d.ts.map +1 -1
- package/dist/cjs/client/sse.js +30 -13
- package/dist/cjs/client/sse.js.map +1 -1
- package/dist/cjs/client/streamableHttp.d.ts +3 -0
- package/dist/cjs/client/streamableHttp.d.ts.map +1 -1
- package/dist/cjs/client/streamableHttp.js +9 -0
- package/dist/cjs/client/streamableHttp.js.map +1 -1
- package/dist/cjs/examples/client/simpleStreamableHttp.js +261 -5
- package/dist/cjs/examples/client/simpleStreamableHttp.js.map +1 -1
- package/dist/cjs/examples/server/demoInMemoryOAuthProvider.d.ts +10 -4
- package/dist/cjs/examples/server/demoInMemoryOAuthProvider.d.ts.map +1 -1
- package/dist/cjs/examples/server/demoInMemoryOAuthProvider.js +21 -7
- package/dist/cjs/examples/server/demoInMemoryOAuthProvider.js.map +1 -1
- package/dist/cjs/examples/server/simpleStreamableHttp.js +246 -10
- package/dist/cjs/examples/server/simpleStreamableHttp.js.map +1 -1
- package/dist/cjs/server/auth/handlers/authorize.d.ts.map +1 -1
- package/dist/cjs/server/auth/handlers/authorize.js +3 -3
- package/dist/cjs/server/auth/handlers/authorize.js.map +1 -1
- package/dist/cjs/server/auth/handlers/register.d.ts.map +1 -1
- package/dist/cjs/server/auth/handlers/register.js +0 -1
- package/dist/cjs/server/auth/handlers/register.js.map +1 -1
- package/dist/cjs/server/auth/handlers/revoke.d.ts +1 -1
- package/dist/cjs/server/auth/handlers/revoke.d.ts.map +1 -1
- package/dist/cjs/server/auth/handlers/revoke.js +4 -6
- package/dist/cjs/server/auth/handlers/revoke.js.map +1 -1
- package/dist/cjs/server/auth/handlers/token.d.ts.map +1 -1
- package/dist/cjs/server/auth/handlers/token.js +6 -6
- package/dist/cjs/server/auth/handlers/token.js.map +1 -1
- package/dist/cjs/server/auth/middleware/bearerAuth.d.ts.map +1 -1
- package/dist/cjs/server/auth/middleware/bearerAuth.js +0 -1
- package/dist/cjs/server/auth/middleware/bearerAuth.js.map +1 -1
- package/dist/cjs/server/auth/middleware/clientAuth.d.ts.map +1 -1
- package/dist/cjs/server/auth/middleware/clientAuth.js +0 -1
- package/dist/cjs/server/auth/middleware/clientAuth.js.map +1 -1
- package/dist/cjs/server/auth/provider.d.ts +3 -2
- package/dist/cjs/server/auth/provider.d.ts.map +1 -1
- package/dist/cjs/server/auth/providers/proxyProvider.d.ts +2 -2
- package/dist/cjs/server/auth/providers/proxyProvider.d.ts.map +1 -1
- package/dist/cjs/server/auth/providers/proxyProvider.js +10 -2
- package/dist/cjs/server/auth/providers/proxyProvider.js.map +1 -1
- package/dist/cjs/server/auth/types.d.ts +5 -0
- package/dist/cjs/server/auth/types.d.ts.map +1 -1
- package/dist/cjs/server/completable.d.ts +3 -1
- package/dist/cjs/server/completable.d.ts.map +1 -1
- package/dist/cjs/server/completable.js.map +1 -1
- package/dist/cjs/server/index.d.ts +14 -1
- package/dist/cjs/server/index.d.ts.map +1 -1
- package/dist/cjs/server/index.js +36 -5
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/server/mcp.d.ts +28 -1
- package/dist/cjs/server/mcp.d.ts.map +1 -1
- package/dist/cjs/server/mcp.js +147 -84
- package/dist/cjs/server/mcp.js.map +1 -1
- package/dist/cjs/server/sse.d.ts.map +1 -1
- package/dist/cjs/server/sse.js.map +1 -1
- package/dist/cjs/server/streamableHttp.d.ts +2 -1
- package/dist/cjs/server/streamableHttp.d.ts.map +1 -1
- package/dist/cjs/server/streamableHttp.js +36 -5
- package/dist/cjs/server/streamableHttp.js.map +1 -1
- package/dist/cjs/shared/auth-utils.d.ts +23 -0
- package/dist/cjs/shared/auth-utils.d.ts.map +1 -0
- package/dist/cjs/shared/auth-utils.js +48 -0
- package/dist/cjs/shared/auth-utils.js.map +1 -0
- package/dist/cjs/shared/metadataUtils.d.ts +12 -0
- package/dist/cjs/shared/metadataUtils.d.ts.map +1 -0
- package/dist/cjs/shared/metadataUtils.js +29 -0
- package/dist/cjs/shared/metadataUtils.js.map +1 -0
- package/dist/cjs/shared/transport.d.ts +4 -0
- package/dist/cjs/shared/transport.d.ts.map +1 -1
- package/dist/cjs/types.d.ts +16263 -2158
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +220 -59
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/client/auth.d.ts +15 -3
- package/dist/esm/client/auth.d.ts.map +1 -1
- package/dist/esm/client/auth.js +39 -10
- package/dist/esm/client/auth.js.map +1 -1
- package/dist/esm/client/index.d.ts +308 -26
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +11 -2
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/sse.d.ts +2 -0
- package/dist/esm/client/sse.d.ts.map +1 -1
- package/dist/esm/client/sse.js +30 -13
- package/dist/esm/client/sse.js.map +1 -1
- package/dist/esm/client/streamableHttp.d.ts +3 -0
- package/dist/esm/client/streamableHttp.d.ts.map +1 -1
- package/dist/esm/client/streamableHttp.js +9 -0
- package/dist/esm/client/streamableHttp.js.map +1 -1
- package/dist/esm/examples/client/simpleStreamableHttp.js +259 -6
- package/dist/esm/examples/client/simpleStreamableHttp.js.map +1 -1
- package/dist/esm/examples/server/demoInMemoryOAuthProvider.d.ts +10 -4
- package/dist/esm/examples/server/demoInMemoryOAuthProvider.d.ts.map +1 -1
- package/dist/esm/examples/server/demoInMemoryOAuthProvider.js +21 -7
- package/dist/esm/examples/server/demoInMemoryOAuthProvider.js.map +1 -1
- package/dist/esm/examples/server/simpleStreamableHttp.js +246 -10
- package/dist/esm/examples/server/simpleStreamableHttp.js.map +1 -1
- package/dist/esm/server/auth/handlers/authorize.d.ts.map +1 -1
- package/dist/esm/server/auth/handlers/authorize.js +3 -3
- package/dist/esm/server/auth/handlers/authorize.js.map +1 -1
- package/dist/esm/server/auth/handlers/register.d.ts.map +1 -1
- package/dist/esm/server/auth/handlers/register.js +0 -1
- package/dist/esm/server/auth/handlers/register.js.map +1 -1
- package/dist/esm/server/auth/handlers/revoke.d.ts +1 -1
- package/dist/esm/server/auth/handlers/revoke.d.ts.map +1 -1
- package/dist/esm/server/auth/handlers/revoke.js +5 -7
- package/dist/esm/server/auth/handlers/revoke.js.map +1 -1
- package/dist/esm/server/auth/handlers/token.d.ts.map +1 -1
- package/dist/esm/server/auth/handlers/token.js +6 -6
- package/dist/esm/server/auth/handlers/token.js.map +1 -1
- package/dist/esm/server/auth/middleware/bearerAuth.d.ts.map +1 -1
- package/dist/esm/server/auth/middleware/bearerAuth.js +0 -1
- package/dist/esm/server/auth/middleware/bearerAuth.js.map +1 -1
- package/dist/esm/server/auth/middleware/clientAuth.d.ts.map +1 -1
- package/dist/esm/server/auth/middleware/clientAuth.js +0 -1
- package/dist/esm/server/auth/middleware/clientAuth.js.map +1 -1
- package/dist/esm/server/auth/provider.d.ts +3 -2
- package/dist/esm/server/auth/provider.d.ts.map +1 -1
- package/dist/esm/server/auth/providers/proxyProvider.d.ts +2 -2
- package/dist/esm/server/auth/providers/proxyProvider.d.ts.map +1 -1
- package/dist/esm/server/auth/providers/proxyProvider.js +10 -2
- package/dist/esm/server/auth/providers/proxyProvider.js.map +1 -1
- package/dist/esm/server/auth/types.d.ts +5 -0
- package/dist/esm/server/auth/types.d.ts.map +1 -1
- package/dist/esm/server/completable.d.ts +3 -1
- package/dist/esm/server/completable.d.ts.map +1 -1
- package/dist/esm/server/completable.js.map +1 -1
- package/dist/esm/server/index.d.ts +14 -1
- package/dist/esm/server/index.d.ts.map +1 -1
- package/dist/esm/server/index.js +34 -6
- package/dist/esm/server/index.js.map +1 -1
- package/dist/esm/server/mcp.d.ts +28 -1
- package/dist/esm/server/mcp.d.ts.map +1 -1
- package/dist/esm/server/mcp.js +147 -84
- package/dist/esm/server/mcp.js.map +1 -1
- package/dist/esm/server/sse.d.ts.map +1 -1
- package/dist/esm/server/sse.js.map +1 -1
- package/dist/esm/server/streamableHttp.d.ts +2 -1
- package/dist/esm/server/streamableHttp.d.ts.map +1 -1
- package/dist/esm/server/streamableHttp.js +37 -6
- package/dist/esm/server/streamableHttp.js.map +1 -1
- package/dist/esm/shared/auth-utils.d.ts +23 -0
- package/dist/esm/shared/auth-utils.d.ts.map +1 -0
- package/dist/esm/shared/auth-utils.js +44 -0
- package/dist/esm/shared/auth-utils.js.map +1 -0
- package/dist/esm/shared/metadataUtils.d.ts +12 -0
- package/dist/esm/shared/metadataUtils.d.ts.map +1 -0
- package/dist/esm/shared/metadataUtils.js +26 -0
- package/dist/esm/shared/metadataUtils.js.map +1 -0
- package/dist/esm/shared/transport.d.ts +4 -0
- package/dist/esm/shared/transport.d.ts.map +1 -1
- package/dist/esm/types.d.ts +16263 -2158
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +217 -57
- package/dist/esm/types.js.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- [Resources](#resources)
|
|
12
12
|
- [Tools](#tools)
|
|
13
13
|
- [Prompts](#prompts)
|
|
14
|
+
- [Completions](#completions)
|
|
14
15
|
- [Running Your Server](#running-your-server)
|
|
15
16
|
- [stdio](#stdio)
|
|
16
17
|
- [Streamable HTTP](#streamable-http)
|
|
@@ -54,22 +55,30 @@ import { z } from "zod";
|
|
|
54
55
|
|
|
55
56
|
// Create an MCP server
|
|
56
57
|
const server = new McpServer({
|
|
57
|
-
name: "
|
|
58
|
+
name: "demo-server",
|
|
58
59
|
version: "1.0.0"
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
// Add an addition tool
|
|
62
|
-
server.
|
|
63
|
-
{
|
|
63
|
+
server.registerTool("add",
|
|
64
|
+
{
|
|
65
|
+
title: "Addition Tool",
|
|
66
|
+
description: "Add two numbers",
|
|
67
|
+
inputSchema: { a: z.number(), b: z.number() }
|
|
68
|
+
},
|
|
64
69
|
async ({ a, b }) => ({
|
|
65
70
|
content: [{ type: "text", text: String(a + b) }]
|
|
66
71
|
})
|
|
67
72
|
);
|
|
68
73
|
|
|
69
74
|
// Add a dynamic greeting resource
|
|
70
|
-
server.
|
|
75
|
+
server.registerResource(
|
|
71
76
|
"greeting",
|
|
72
77
|
new ResourceTemplate("greeting://{name}", { list: undefined }),
|
|
78
|
+
{
|
|
79
|
+
title: "Greeting Resource", // Display name for UI
|
|
80
|
+
description: "Dynamic greeting generator"
|
|
81
|
+
},
|
|
73
82
|
async (uri, { name }) => ({
|
|
74
83
|
contents: [{
|
|
75
84
|
uri: uri.href,
|
|
@@ -100,7 +109,7 @@ The McpServer is your core interface to the MCP protocol. It handles connection
|
|
|
100
109
|
|
|
101
110
|
```typescript
|
|
102
111
|
const server = new McpServer({
|
|
103
|
-
name: "
|
|
112
|
+
name: "my-app",
|
|
104
113
|
version: "1.0.0"
|
|
105
114
|
});
|
|
106
115
|
```
|
|
@@ -111,9 +120,14 @@ Resources are how you expose data to LLMs. They're similar to GET endpoints in a
|
|
|
111
120
|
|
|
112
121
|
```typescript
|
|
113
122
|
// Static resource
|
|
114
|
-
server.
|
|
123
|
+
server.registerResource(
|
|
115
124
|
"config",
|
|
116
125
|
"config://app",
|
|
126
|
+
{
|
|
127
|
+
title: "Application Config",
|
|
128
|
+
description: "Application configuration data",
|
|
129
|
+
mimeType: "text/plain"
|
|
130
|
+
},
|
|
117
131
|
async (uri) => ({
|
|
118
132
|
contents: [{
|
|
119
133
|
uri: uri.href,
|
|
@@ -123,9 +137,13 @@ server.resource(
|
|
|
123
137
|
);
|
|
124
138
|
|
|
125
139
|
// Dynamic resource with parameters
|
|
126
|
-
server.
|
|
140
|
+
server.registerResource(
|
|
127
141
|
"user-profile",
|
|
128
142
|
new ResourceTemplate("users://{userId}/profile", { list: undefined }),
|
|
143
|
+
{
|
|
144
|
+
title: "User Profile",
|
|
145
|
+
description: "User profile information"
|
|
146
|
+
},
|
|
129
147
|
async (uri, { userId }) => ({
|
|
130
148
|
contents: [{
|
|
131
149
|
uri: uri.href,
|
|
@@ -133,6 +151,33 @@ server.resource(
|
|
|
133
151
|
}]
|
|
134
152
|
})
|
|
135
153
|
);
|
|
154
|
+
|
|
155
|
+
// Resource with context-aware completion
|
|
156
|
+
server.registerResource(
|
|
157
|
+
"repository",
|
|
158
|
+
new ResourceTemplate("github://repos/{owner}/{repo}", {
|
|
159
|
+
list: undefined,
|
|
160
|
+
complete: {
|
|
161
|
+
// Provide intelligent completions based on previously resolved parameters
|
|
162
|
+
repo: (value, context) => {
|
|
163
|
+
if (context?.arguments?.["owner"] === "org1") {
|
|
164
|
+
return ["project1", "project2", "project3"].filter(r => r.startsWith(value));
|
|
165
|
+
}
|
|
166
|
+
return ["default-repo"].filter(r => r.startsWith(value));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}),
|
|
170
|
+
{
|
|
171
|
+
title: "GitHub Repository",
|
|
172
|
+
description: "Repository information"
|
|
173
|
+
},
|
|
174
|
+
async (uri, { owner, repo }) => ({
|
|
175
|
+
contents: [{
|
|
176
|
+
uri: uri.href,
|
|
177
|
+
text: `Repository: ${owner}/${repo}`
|
|
178
|
+
}]
|
|
179
|
+
})
|
|
180
|
+
);
|
|
136
181
|
```
|
|
137
182
|
|
|
138
183
|
### Tools
|
|
@@ -141,11 +186,15 @@ Tools let LLMs take actions through your server. Unlike resources, tools are exp
|
|
|
141
186
|
|
|
142
187
|
```typescript
|
|
143
188
|
// Simple tool with parameters
|
|
144
|
-
server.
|
|
189
|
+
server.registerTool(
|
|
145
190
|
"calculate-bmi",
|
|
146
191
|
{
|
|
147
|
-
|
|
148
|
-
|
|
192
|
+
title: "BMI Calculator",
|
|
193
|
+
description: "Calculate Body Mass Index",
|
|
194
|
+
inputSchema: {
|
|
195
|
+
weightKg: z.number(),
|
|
196
|
+
heightM: z.number()
|
|
197
|
+
}
|
|
149
198
|
},
|
|
150
199
|
async ({ weightKg, heightM }) => ({
|
|
151
200
|
content: [{
|
|
@@ -156,9 +205,13 @@ server.tool(
|
|
|
156
205
|
);
|
|
157
206
|
|
|
158
207
|
// Async tool with external API call
|
|
159
|
-
server.
|
|
208
|
+
server.registerTool(
|
|
160
209
|
"fetch-weather",
|
|
161
|
-
{
|
|
210
|
+
{
|
|
211
|
+
title: "Weather Fetcher",
|
|
212
|
+
description: "Get weather data for a city",
|
|
213
|
+
inputSchema: { city: z.string() }
|
|
214
|
+
},
|
|
162
215
|
async ({ city }) => {
|
|
163
216
|
const response = await fetch(`https://api.weather.com/${city}`);
|
|
164
217
|
const data = await response.text();
|
|
@@ -167,16 +220,56 @@ server.tool(
|
|
|
167
220
|
};
|
|
168
221
|
}
|
|
169
222
|
);
|
|
223
|
+
|
|
224
|
+
// Tool that returns ResourceLinks
|
|
225
|
+
server.registerTool(
|
|
226
|
+
"list-files",
|
|
227
|
+
{
|
|
228
|
+
title: "List Files",
|
|
229
|
+
description: "List project files",
|
|
230
|
+
inputSchema: { pattern: z.string() }
|
|
231
|
+
},
|
|
232
|
+
async ({ pattern }) => ({
|
|
233
|
+
content: [
|
|
234
|
+
{ type: "text", text: `Found files matching "${pattern}":` },
|
|
235
|
+
// ResourceLinks let tools return references without file content
|
|
236
|
+
{
|
|
237
|
+
type: "resource_link",
|
|
238
|
+
uri: "file:///project/README.md",
|
|
239
|
+
name: "README.md",
|
|
240
|
+
mimeType: "text/markdown",
|
|
241
|
+
description: 'A README file'
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
type: "resource_link",
|
|
245
|
+
uri: "file:///project/src/index.ts",
|
|
246
|
+
name: "index.ts",
|
|
247
|
+
mimeType: "text/typescript",
|
|
248
|
+
description: 'An index file'
|
|
249
|
+
}
|
|
250
|
+
]
|
|
251
|
+
})
|
|
252
|
+
);
|
|
170
253
|
```
|
|
171
254
|
|
|
255
|
+
#### ResourceLinks
|
|
256
|
+
|
|
257
|
+
Tools can return `ResourceLink` objects to reference resources without embedding their full content. This is essential for performance when dealing with large files or many resources - clients can then selectively read only the resources they need using the provided URIs.
|
|
258
|
+
|
|
172
259
|
### Prompts
|
|
173
260
|
|
|
174
261
|
Prompts are reusable templates that help LLMs interact with your server effectively:
|
|
175
262
|
|
|
176
263
|
```typescript
|
|
177
|
-
server.
|
|
264
|
+
import { completable } from "@modelcontextprotocol/sdk/server/completable.js";
|
|
265
|
+
|
|
266
|
+
server.registerPrompt(
|
|
178
267
|
"review-code",
|
|
179
|
-
{
|
|
268
|
+
{
|
|
269
|
+
title: "Code Review",
|
|
270
|
+
description: "Review code for best practices and potential issues",
|
|
271
|
+
argsSchema: { code: z.string() }
|
|
272
|
+
},
|
|
180
273
|
({ code }) => ({
|
|
181
274
|
messages: [{
|
|
182
275
|
role: "user",
|
|
@@ -187,6 +280,106 @@ server.prompt(
|
|
|
187
280
|
}]
|
|
188
281
|
})
|
|
189
282
|
);
|
|
283
|
+
|
|
284
|
+
// Prompt with context-aware completion
|
|
285
|
+
server.registerPrompt(
|
|
286
|
+
"team-greeting",
|
|
287
|
+
{
|
|
288
|
+
title: "Team Greeting",
|
|
289
|
+
description: "Generate a greeting for team members",
|
|
290
|
+
argsSchema: {
|
|
291
|
+
department: completable(z.string(), (value) => {
|
|
292
|
+
// Department suggestions
|
|
293
|
+
return ["engineering", "sales", "marketing", "support"].filter(d => d.startsWith(value));
|
|
294
|
+
}),
|
|
295
|
+
name: completable(z.string(), (value, context) => {
|
|
296
|
+
// Name suggestions based on selected department
|
|
297
|
+
const department = context?.arguments?.["department"];
|
|
298
|
+
if (department === "engineering") {
|
|
299
|
+
return ["Alice", "Bob", "Charlie"].filter(n => n.startsWith(value));
|
|
300
|
+
} else if (department === "sales") {
|
|
301
|
+
return ["David", "Eve", "Frank"].filter(n => n.startsWith(value));
|
|
302
|
+
} else if (department === "marketing") {
|
|
303
|
+
return ["Grace", "Henry", "Iris"].filter(n => n.startsWith(value));
|
|
304
|
+
}
|
|
305
|
+
return ["Guest"].filter(n => n.startsWith(value));
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
({ department, name }) => ({
|
|
310
|
+
messages: [{
|
|
311
|
+
role: "assistant",
|
|
312
|
+
content: {
|
|
313
|
+
type: "text",
|
|
314
|
+
text: `Hello ${name}, welcome to the ${department} team!`
|
|
315
|
+
}
|
|
316
|
+
}]
|
|
317
|
+
})
|
|
318
|
+
);
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Completions
|
|
322
|
+
|
|
323
|
+
MCP supports argument completions to help users fill in prompt arguments and resource template parameters. See the examples above for [resource completions](#resources) and [prompt completions](#prompts).
|
|
324
|
+
|
|
325
|
+
#### Client Usage
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
// Request completions for any argument
|
|
329
|
+
const result = await client.complete({
|
|
330
|
+
ref: {
|
|
331
|
+
type: "ref/prompt", // or "ref/resource"
|
|
332
|
+
name: "example" // or uri: "template://..."
|
|
333
|
+
},
|
|
334
|
+
argument: {
|
|
335
|
+
name: "argumentName",
|
|
336
|
+
value: "partial" // What the user has typed so far
|
|
337
|
+
},
|
|
338
|
+
context: { // Optional: Include previously resolved arguments
|
|
339
|
+
arguments: {
|
|
340
|
+
previousArg: "value"
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Display Names and Metadata
|
|
348
|
+
|
|
349
|
+
All resources, tools, and prompts support an optional `title` field for better UI presentation. The `title` is used as a display name, while `name` remains the unique identifier.
|
|
350
|
+
|
|
351
|
+
**Note:** The `register*` methods (`registerTool`, `registerPrompt`, `registerResource`) are the recommended approach for new code. The older methods (`tool`, `prompt`, `resource`) remain available for backwards compatibility.
|
|
352
|
+
|
|
353
|
+
#### Title Precedence for Tools
|
|
354
|
+
|
|
355
|
+
For tools specifically, there are two ways to specify a title:
|
|
356
|
+
- `title` field in the tool configuration
|
|
357
|
+
- `annotations.title` field (when using the older `tool()` method with annotations)
|
|
358
|
+
|
|
359
|
+
The precedence order is: `title` → `annotations.title` → `name`
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
// Using registerTool (recommended)
|
|
363
|
+
server.registerTool("my_tool", {
|
|
364
|
+
title: "My Tool", // This title takes precedence
|
|
365
|
+
annotations: {
|
|
366
|
+
title: "Annotation Title" // This is ignored if title is set
|
|
367
|
+
}
|
|
368
|
+
}, handler);
|
|
369
|
+
|
|
370
|
+
// Using tool with annotations (older API)
|
|
371
|
+
server.tool("my_tool", "description", {
|
|
372
|
+
title: "Annotation Title" // This is used as title
|
|
373
|
+
}, handler);
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
When building clients, use the provided utility to get the appropriate display name:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
import { getDisplayName } from "@modelcontextprotocol/sdk/shared/metadataUtils.js";
|
|
380
|
+
|
|
381
|
+
// Automatically handles the precedence: title → annotations.title → name
|
|
382
|
+
const displayName = getDisplayName(tool);
|
|
190
383
|
```
|
|
191
384
|
|
|
192
385
|
## Running Your Server
|
|
@@ -401,13 +594,17 @@ import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mc
|
|
|
401
594
|
import { z } from "zod";
|
|
402
595
|
|
|
403
596
|
const server = new McpServer({
|
|
404
|
-
name: "
|
|
597
|
+
name: "echo-server",
|
|
405
598
|
version: "1.0.0"
|
|
406
599
|
});
|
|
407
600
|
|
|
408
|
-
server.
|
|
601
|
+
server.registerResource(
|
|
409
602
|
"echo",
|
|
410
603
|
new ResourceTemplate("echo://{message}", { list: undefined }),
|
|
604
|
+
{
|
|
605
|
+
title: "Echo Resource",
|
|
606
|
+
description: "Echoes back messages as resources"
|
|
607
|
+
},
|
|
411
608
|
async (uri, { message }) => ({
|
|
412
609
|
contents: [{
|
|
413
610
|
uri: uri.href,
|
|
@@ -416,17 +613,25 @@ server.resource(
|
|
|
416
613
|
})
|
|
417
614
|
);
|
|
418
615
|
|
|
419
|
-
server.
|
|
616
|
+
server.registerTool(
|
|
420
617
|
"echo",
|
|
421
|
-
{
|
|
618
|
+
{
|
|
619
|
+
title: "Echo Tool",
|
|
620
|
+
description: "Echoes back the provided message",
|
|
621
|
+
inputSchema: { message: z.string() }
|
|
622
|
+
},
|
|
422
623
|
async ({ message }) => ({
|
|
423
624
|
content: [{ type: "text", text: `Tool echo: ${message}` }]
|
|
424
625
|
})
|
|
425
626
|
);
|
|
426
627
|
|
|
427
|
-
server.
|
|
628
|
+
server.registerPrompt(
|
|
428
629
|
"echo",
|
|
429
|
-
{
|
|
630
|
+
{
|
|
631
|
+
title: "Echo Prompt",
|
|
632
|
+
description: "Creates a prompt to process a message",
|
|
633
|
+
argsSchema: { message: z.string() }
|
|
634
|
+
},
|
|
430
635
|
({ message }) => ({
|
|
431
636
|
messages: [{
|
|
432
637
|
role: "user",
|
|
@@ -450,7 +655,7 @@ import { promisify } from "util";
|
|
|
450
655
|
import { z } from "zod";
|
|
451
656
|
|
|
452
657
|
const server = new McpServer({
|
|
453
|
-
name: "
|
|
658
|
+
name: "sqlite-explorer",
|
|
454
659
|
version: "1.0.0"
|
|
455
660
|
});
|
|
456
661
|
|
|
@@ -463,9 +668,14 @@ const getDb = () => {
|
|
|
463
668
|
};
|
|
464
669
|
};
|
|
465
670
|
|
|
466
|
-
server.
|
|
671
|
+
server.registerResource(
|
|
467
672
|
"schema",
|
|
468
673
|
"schema://main",
|
|
674
|
+
{
|
|
675
|
+
title: "Database Schema",
|
|
676
|
+
description: "SQLite database schema",
|
|
677
|
+
mimeType: "text/plain"
|
|
678
|
+
},
|
|
469
679
|
async (uri) => {
|
|
470
680
|
const db = getDb();
|
|
471
681
|
try {
|
|
@@ -484,9 +694,13 @@ server.resource(
|
|
|
484
694
|
}
|
|
485
695
|
);
|
|
486
696
|
|
|
487
|
-
server.
|
|
697
|
+
server.registerTool(
|
|
488
698
|
"query",
|
|
489
|
-
{
|
|
699
|
+
{
|
|
700
|
+
title: "SQL Query",
|
|
701
|
+
description: "Execute SQL queries on the database",
|
|
702
|
+
inputSchema: { sql: z.string() }
|
|
703
|
+
},
|
|
490
704
|
async ({ sql }) => {
|
|
491
705
|
const db = getDb();
|
|
492
706
|
try {
|
|
@@ -635,6 +849,109 @@ const transport = new StdioServerTransport();
|
|
|
635
849
|
await server.connect(transport);
|
|
636
850
|
```
|
|
637
851
|
|
|
852
|
+
### Eliciting User Input
|
|
853
|
+
|
|
854
|
+
MCP servers can request additional information from users through the elicitation feature. This is useful for interactive workflows where the server needs user input or confirmation:
|
|
855
|
+
|
|
856
|
+
```typescript
|
|
857
|
+
// Server-side: Restaurant booking tool that asks for alternatives
|
|
858
|
+
server.tool(
|
|
859
|
+
"book-restaurant",
|
|
860
|
+
{
|
|
861
|
+
restaurant: z.string(),
|
|
862
|
+
date: z.string(),
|
|
863
|
+
partySize: z.number()
|
|
864
|
+
},
|
|
865
|
+
async ({ restaurant, date, partySize }) => {
|
|
866
|
+
// Check availability
|
|
867
|
+
const available = await checkAvailability(restaurant, date, partySize);
|
|
868
|
+
|
|
869
|
+
if (!available) {
|
|
870
|
+
// Ask user if they want to try alternative dates
|
|
871
|
+
const result = await server.server.elicitInput({
|
|
872
|
+
message: `No tables available at ${restaurant} on ${date}. Would you like to check alternative dates?`,
|
|
873
|
+
requestedSchema: {
|
|
874
|
+
type: "object",
|
|
875
|
+
properties: {
|
|
876
|
+
checkAlternatives: {
|
|
877
|
+
type: "boolean",
|
|
878
|
+
title: "Check alternative dates",
|
|
879
|
+
description: "Would you like me to check other dates?"
|
|
880
|
+
},
|
|
881
|
+
flexibleDates: {
|
|
882
|
+
type: "string",
|
|
883
|
+
title: "Date flexibility",
|
|
884
|
+
description: "How flexible are your dates?",
|
|
885
|
+
enum: ["next_day", "same_week", "next_week"],
|
|
886
|
+
enumNames: ["Next day", "Same week", "Next week"]
|
|
887
|
+
}
|
|
888
|
+
},
|
|
889
|
+
required: ["checkAlternatives"]
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
if (result.action === "accept" && result.content?.checkAlternatives) {
|
|
894
|
+
const alternatives = await findAlternatives(
|
|
895
|
+
restaurant,
|
|
896
|
+
date,
|
|
897
|
+
partySize,
|
|
898
|
+
result.content.flexibleDates as string
|
|
899
|
+
);
|
|
900
|
+
return {
|
|
901
|
+
content: [{
|
|
902
|
+
type: "text",
|
|
903
|
+
text: `Found these alternatives: ${alternatives.join(", ")}`
|
|
904
|
+
}]
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
return {
|
|
909
|
+
content: [{
|
|
910
|
+
type: "text",
|
|
911
|
+
text: "No booking made. Original date not available."
|
|
912
|
+
}]
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// Book the table
|
|
917
|
+
await makeBooking(restaurant, date, partySize);
|
|
918
|
+
return {
|
|
919
|
+
content: [{
|
|
920
|
+
type: "text",
|
|
921
|
+
text: `Booked table for ${partySize} at ${restaurant} on ${date}`
|
|
922
|
+
}]
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
);
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
Client-side: Handle elicitation requests
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
// This is a placeholder - implement based on your UI framework
|
|
932
|
+
async function getInputFromUser(message: string, schema: any): Promise<{
|
|
933
|
+
action: "accept" | "reject" | "cancel";
|
|
934
|
+
data?: Record<string, any>;
|
|
935
|
+
}> {
|
|
936
|
+
// This should be implemented depending on the app
|
|
937
|
+
throw new Error("getInputFromUser must be implemented for your platform");
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
client.setRequestHandler(ElicitRequestSchema, async (request) => {
|
|
941
|
+
const userResponse = await getInputFromUser(
|
|
942
|
+
request.params.message,
|
|
943
|
+
request.params.requestedSchema
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
return {
|
|
947
|
+
action: userResponse.action,
|
|
948
|
+
content: userResponse.action === "accept" ? userResponse.data : undefined
|
|
949
|
+
};
|
|
950
|
+
});
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
**Note**: Elicitation requires client support. Clients must declare the `elicitation` capability during initialization.
|
|
954
|
+
|
|
638
955
|
### Writing MCP Clients
|
|
639
956
|
|
|
640
957
|
The SDK provides a high-level client interface:
|
|
@@ -683,6 +1000,7 @@ const result = await client.callTool({
|
|
|
683
1000
|
arg1: "value"
|
|
684
1001
|
}
|
|
685
1002
|
});
|
|
1003
|
+
|
|
686
1004
|
```
|
|
687
1005
|
|
|
688
1006
|
### Proxy Authorization Requests Upstream
|
|
@@ -58,6 +58,14 @@ export interface OAuthClientProvider {
|
|
|
58
58
|
* the authorization result.
|
|
59
59
|
*/
|
|
60
60
|
codeVerifier(): string | Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* If defined, overrides the selection and validation of the
|
|
63
|
+
* RFC 8707 Resource Indicator. If left undefined, default
|
|
64
|
+
* validation behavior will be used.
|
|
65
|
+
*
|
|
66
|
+
* Implementations must verify the returned resource matches the MCP server.
|
|
67
|
+
*/
|
|
68
|
+
validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;
|
|
61
69
|
}
|
|
62
70
|
export type AuthResult = "AUTHORIZED" | "REDIRECT";
|
|
63
71
|
export declare class UnauthorizedError extends Error {
|
|
@@ -75,6 +83,7 @@ export declare function auth(provider: OAuthClientProvider, { serverUrl, authori
|
|
|
75
83
|
scope?: string;
|
|
76
84
|
resourceMetadataUrl?: URL;
|
|
77
85
|
}): Promise<AuthResult>;
|
|
86
|
+
export declare function selectResourceURL(serverUrl: string | URL, provider: OAuthClientProvider, resourceMetadata?: OAuthProtectedResourceMetadata): Promise<URL | undefined>;
|
|
78
87
|
/**
|
|
79
88
|
* Extract resource_metadata from response header.
|
|
80
89
|
*/
|
|
@@ -101,12 +110,13 @@ export declare function discoverOAuthMetadata(authorizationServerUrl: string | U
|
|
|
101
110
|
/**
|
|
102
111
|
* Begins the authorization flow with the given server, by generating a PKCE challenge and constructing the authorization URL.
|
|
103
112
|
*/
|
|
104
|
-
export declare function startAuthorization(authorizationServerUrl: string | URL, { metadata, clientInformation, redirectUrl, scope, state, }: {
|
|
113
|
+
export declare function startAuthorization(authorizationServerUrl: string | URL, { metadata, clientInformation, redirectUrl, scope, state, resource, }: {
|
|
105
114
|
metadata?: OAuthMetadata;
|
|
106
115
|
clientInformation: OAuthClientInformation;
|
|
107
116
|
redirectUrl: string | URL;
|
|
108
117
|
scope?: string;
|
|
109
118
|
state?: string;
|
|
119
|
+
resource?: URL;
|
|
110
120
|
}): Promise<{
|
|
111
121
|
authorizationUrl: URL;
|
|
112
122
|
codeVerifier: string;
|
|
@@ -114,20 +124,22 @@ export declare function startAuthorization(authorizationServerUrl: string | URL,
|
|
|
114
124
|
/**
|
|
115
125
|
* Exchanges an authorization code for an access token with the given server.
|
|
116
126
|
*/
|
|
117
|
-
export declare function exchangeAuthorization(authorizationServerUrl: string | URL, { metadata, clientInformation, authorizationCode, codeVerifier, redirectUri, }: {
|
|
127
|
+
export declare function exchangeAuthorization(authorizationServerUrl: string | URL, { metadata, clientInformation, authorizationCode, codeVerifier, redirectUri, resource, }: {
|
|
118
128
|
metadata?: OAuthMetadata;
|
|
119
129
|
clientInformation: OAuthClientInformation;
|
|
120
130
|
authorizationCode: string;
|
|
121
131
|
codeVerifier: string;
|
|
122
132
|
redirectUri: string | URL;
|
|
133
|
+
resource?: URL;
|
|
123
134
|
}): Promise<OAuthTokens>;
|
|
124
135
|
/**
|
|
125
136
|
* Exchange a refresh token for an updated access token.
|
|
126
137
|
*/
|
|
127
|
-
export declare function refreshAuthorization(authorizationServerUrl: string | URL, { metadata, clientInformation, refreshToken, }: {
|
|
138
|
+
export declare function refreshAuthorization(authorizationServerUrl: string | URL, { metadata, clientInformation, refreshToken, resource, }: {
|
|
128
139
|
metadata?: OAuthMetadata;
|
|
129
140
|
clientInformation: OAuthClientInformation;
|
|
130
141
|
refreshToken: string;
|
|
142
|
+
resource?: URL;
|
|
131
143
|
}): Promise<OAuthTokens>;
|
|
132
144
|
/**
|
|
133
145
|
* Performs OAuth 2.0 Dynamic Client Registration according to RFC 7591.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/client/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,WAAW,EAAE,aAAa,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/client/auth.ts"],"names":[],"mappings":"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"}
|