Skip to content

Commit 1aad768

Browse files
committed
Merge branch 'main' into ihrpr/response-returns-json
2 parents 5b99e94 + df87019 commit 1aad768

File tree

3 files changed

+1189
-87
lines changed

3 files changed

+1189
-87
lines changed

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,68 @@ server.tool(
380380

381381
## Advanced Usage
382382

383+
### Dynamic Servers
384+
385+
If you want to offer an initial set of tools/prompts/resources, but later add additional ones based on user action or external state change, you can add/update/remove them _after_ the Server is connected. This will automatically emit the corresponding `listChanged` notificaions:
386+
387+
```ts
388+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
389+
import { z } from "zod";
390+
391+
const server = new McpServer({
392+
name: "Dynamic Example",
393+
version: "1.0.0"
394+
});
395+
396+
const listMessageTool = server.tool(
397+
"listMessages",
398+
{ channel: z.string() },
399+
async ({ channel }) => ({
400+
content: [{ type: "text", text: await listMessages(channel) }]
401+
})
402+
);
403+
404+
const putMessageTool = server.tool(
405+
"putMessage",
406+
{ channel: z.string(), message: z.string() },
407+
async ({ channel, message }) => ({
408+
content: [{ type: "text", text: await putMessage(channel, string) }]
409+
})
410+
);
411+
// Until we upgrade auth, `putMessage` is disabled (won't show up in listTools)
412+
putMessageTool.disable()
413+
414+
const upgradeAuthTool = server.tool(
415+
"upgradeAuth",
416+
{ permission: z.enum(["write', vadmin"])},
417+
// Any mutations here will automatically emit `listChanged` notifications
418+
async ({ permission }) => {
419+
const { ok, err, previous } = await upgradeAuthAndStoreToken(permission)
420+
if (!ok) return {content: [{ type: "text", text: `Error: ${err}` }]}
421+
422+
// If we previously had read-only access, 'putMessage' is now available
423+
if (previous === "read") {
424+
putMessageTool.enable()
425+
}
426+
427+
if (permission === 'write') {
428+
// If we've just upgraded to 'write' permissions, we can still call 'upgradeAuth'
429+
// but can only upgrade to 'admin'.
430+
upgradeAuthTool.update({
431+
paramSchema: { permission: z.enum(["admin"]) }, // change validation rules
432+
})
433+
} else {
434+
// If we're now an admin, we no longer have anywhere to upgrade to, so fully remove that tool
435+
upgradeAuthTool.remove()
436+
}
437+
}
438+
)
439+
440+
// Connect as normal
441+
const transport = new StdioServerTransport();
442+
await server.connect(transport);
443+
```
444+
383445
### Low-Level Server
384446

385447
For more control, you can use the low-level Server class directly:

0 commit comments

Comments
 (0)