-
Notifications
You must be signed in to change notification settings - Fork 1.8k
docs: document tool list changed notifications #1857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -201,6 +201,25 @@ | |
|
|
||
| If a handler throws instead of returning `isError`, the SDK catches the exception and converts it to `{ isError: true }` automatically — so an explicit try/catch is optional but gives you control over the error message. When `isError` is true, output schema validation is skipped. | ||
|
|
||
| ### List changed notifications | ||
|
|
||
| When the set of available tools changes at runtime, the server should notify connected clients so they can refresh their tool list (see [List Changed Notification](https://spec.modelcontextprotocol.io/specification/2025-06-18/server/tools/#list-changed-notification) in the MCP specification). | ||
|
Check warning on line 206 in docs/server.md
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The new spec link at line 206 uses a different URL format than all other spec links in this file: it uses the Extended reasoning...What the bug is and how it manifests The newly added "List changed notifications" section links to the MCP specification using The specific code path that triggers it The inconsistency is on line 206 of Why existing code doesn't prevent it This is a documentation-only change with no automated consistency check on external URL format. There is no linter or CI rule enforcing that all spec links follow the same subdomain/path pattern, so the inconsistency slipped through. What the impact would be Two practical problems arise: (1) The pinned date How to fix it Replace the URL with: This matches the pattern used by lines 66 ( Step-by-step proof
Note on duplication: A refutation flagged this as a duplicate of bug_003. Both describe the same issue at the same location; however the inconsistency is real and the fix is unambiguous regardless of tracking ID. |
||
|
|
||
| {@linkcode @modelcontextprotocol/server!server/mcp.McpServer#registerTool | registerTool} sends this notification automatically when called after the client is already connected. To notify manually — for example, after removing a tool or toggling tool availability — call {@linkcode @modelcontextprotocol/server!server/mcp.McpServer#sendToolListChanged | sendToolListChanged}: | ||
|
|
||
| ```ts source="../examples/server/src/serverGuide.examples.ts#sendToolListChanged_basic" | ||
| // Automatic: registering a tool at runtime sends the notification | ||
| server.registerTool('new-tool', { description: 'A dynamically added tool' }, async () => ({ | ||
| content: [{ type: 'text', text: 'done' }] | ||
| })); | ||
|
|
||
| // Manual: notify clients explicitly (e.g. after removing a tool) | ||
| server.sendToolListChanged(); | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
|
Check warning on line 220 in docs/server.md
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The documentation's manual Extended reasoning...What the bug is: The new documentation section (docs/server.md lines 208-220) describes manual The specific code path: In Why the existing code doesn't prevent the issue: The documentation is simply describing the wrong scenario. Calling What the impact is: Developers reading this section will learn a subtly wrong model: that removing/disabling/enabling tools requires a manual follow-up call. More importantly, they will not learn the actual use case: external state changes the SDK has no visibility into, such as reading a feature flag and having a handler conditionally respond without ever calling How to fix it: Update the prose from "for example, after removing a tool or toggling tool availability" to describe the real use case — e.g., "for example, when an external condition such as a feature flag changes which tools are logically available, without calling Step-by-step proof: (1) Developer reads the new documentation and learns to write: |
||
| > On the client side, use the {@linkcode @modelcontextprotocol/client!client/client.ClientOptions | listChanged} option to automatically re-fetch tool lists when this notification arrives — see [Automatic list-change tracking](./client.md#automatic-list-change-tracking) in the client guide. | ||
|
|
||
| ## Resources | ||
|
|
||
| Resources expose read-only data — files, database schemas, configuration — that the host application can retrieve and attach as context for the model (see [Resources](https://modelcontextprotocol.io/docs/learn/server-concepts#resources) in the MCP overview). Unlike [tools](#tools), which the LLM invokes on its own, resources are application-controlled: the host decides which resources to fetch and how to present them. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -147,6 +147,19 @@ function registerTool_annotations(server: McpServer) { | |
| //#endregion registerTool_annotations | ||
| } | ||
|
|
||
| /** Example: Notifying clients when the tool list changes at runtime. */ | ||
| function sendToolListChanged_basic(server: McpServer) { | ||
| //#region sendToolListChanged_basic | ||
| // Automatic: registering a tool at runtime sends the notification | ||
| server.registerTool('new-tool', { description: 'A dynamically added tool' }, async () => ({ | ||
| content: [{ type: 'text', text: 'done' }] | ||
| })); | ||
|
|
||
| // Manual: notify clients explicitly (e.g. after removing a tool) | ||
| server.sendToolListChanged(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't need to do this "manually" -
Is that not working? If so we should probably fix that rather than have this manual workaround. |
||
| //#endregion sendToolListChanged_basic | ||
| } | ||
|
|
||
| /** Example: Registering a static resource at a fixed URI. */ | ||
| function registerResource_static(server: McpServer) { | ||
| //#region registerResource_static | ||
|
|
@@ -540,6 +553,7 @@ void registerTool_basic; | |
| void registerTool_resourceLink; | ||
| void registerTool_errorHandling; | ||
| void registerTool_annotations; | ||
| void sendToolListChanged_basic; | ||
| void registerTool_logging; | ||
| void registerTool_progress; | ||
| void registerTool_sampling; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outdated spec link - can we update to use
latestinstead of2025-06-18for consistency?