Skip to content

Commit 1550326

Browse files
committed
Reworking mutation API
1 parent 693fdc3 commit 1550326

File tree

3 files changed

+1255
-66
lines changed

3 files changed

+1255
-66
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+
server.tool(
397+
"listMessages",
398+
{ channel: z.string() },
399+
async ({ channel }) => ({
400+
content: [{ type: "text", text: await listMessages(channel) }]
401+
})
402+
);
403+
404+
server.tool(
405+
"upgradeAuth",
406+
{ permission: z.enum(["write', vadmin"])},
407+
upgradeAuth
408+
)
409+
410+
// Connect with the existing set of tools
411+
const transport = new StdioServerTransport();
412+
await server.connect(transport);
413+
414+
// Any mutations after connection result in `listChanged` notifications so the client knows to refresh
415+
async function upgradeAuth({permission}) {
416+
const { ok, err, previous } = await upgradeAuthAndStoreToken(permission)
417+
418+
if (!ok) return {content: [{ type: "text", text: `Error: ${err}` }]}
419+
420+
// If we previously had read-only access, we need to add 'putMessage' now we can use it
421+
if (previous === "read") {
422+
server.tool(
423+
"putMessage",
424+
{ channel: z.string(), message: z.string() },
425+
async ({ channel, message }) => ({
426+
content: [{ type: "text", text: await putMessage(channel, string) }]
427+
})
428+
);
429+
}
430+
431+
// If we've just upgraded to 'write' permissions, we can still call 'upgradeAuth' but can only upgrade to 'admin'
432+
if (permission === 'write') {
433+
server.updateTool(
434+
"upgradeAuth",
435+
{ permission: z.enum(["admin"])}, // change param validation
436+
upgradeAuth
437+
)
438+
} else {
439+
// If we're on admin, we no longer have anywhere to upgrade to
440+
server.removeTool("upgradeAuth")
441+
}
442+
}
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)