Skip to content

feat: handle tools/resources/prompts list_changed notifications#1132

Open
herakles-dev wants to merge 1 commit intomodelcontextprotocol:mainfrom
herakles-dev:feat/handle-list-changed-notifications
Open

feat: handle tools/resources/prompts list_changed notifications#1132
herakles-dev wants to merge 1 commit intomodelcontextprotocol:mainfrom
herakles-dev:feat/handle-list-changed-notifications

Conversation

@herakles-dev
Copy link

Summary

Add handling for notifications/tools/list_changed, notifications/resources/list_changed, and notifications/prompts/list_changed in the inspector's notification callback. When a server sends these notifications, the inspector now automatically refreshes the corresponding lists — matching the existing tasks/list_changed pattern.

This enables dynamic tool/resource/prompt registration use cases (e.g., gateway MCP servers that load/unload tools at runtime).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Refactoring (no functional changes)
  • Test updates
  • Build/CI improvements

Changes Made

client/src/App.tsx — Added 3 conditional blocks to the onNotification callback:

  • notifications/tools/list_changed → resets tool cursor, clears tools, re-fetches via listTools()
  • notifications/resources/list_changed → resets resource + template cursors, clears both lists, re-fetches via listResources() + listResourceTemplates()
  • notifications/prompts/list_changed → resets prompt cursor, clears prompts, re-fetches via listPrompts()

Each handler resets pagination cursors to undefined before re-fetching to ensure a clean refresh from page 1 (not a paginated continuation).

The notification schemas (ToolListChangedNotificationSchema, ResourceListChangedNotificationSchema, PromptListChangedNotificationSchema) are already imported and registered on the MCP client in useConnection.ts — this PR adds the missing response logic.

Related Issues

Fixes #832

Testing

  • Tested in UI mode
  • Tested in CLI mode
  • Tested with STDIO transport
  • Tested with SSE transport
  • Tested with Streamable HTTP transport
  • Added/updated automated tests
  • Manual testing performed

Test Results and/or Instructions

  1. Connect the inspector to an MCP server that supports dynamic tool registration
  2. Add/remove a tool on the server side
  3. The server sends a notifications/tools/list_changed notification
  4. Verify the Tools tab automatically refreshes to show the updated tool list
  5. Same flow applies for resources and prompts

The implementation follows the exact same pattern as the existing notifications/tasks/list_changed handler (line 424), which is already working in production.

Checklist

  • Code follows the style guidelines (ran npm run prettier-fix)
  • Self-review completed
  • Code is commented where necessary
  • Documentation updated (README, comments, etc.)

Breaking Changes

None. This is a purely additive change.

Additional Context

The infrastructure was already 95% complete:

  • SDK notification schemas are imported in useConnection.ts (lines 29-31)
  • Notification handlers are registered on the client (lines 753-755)
  • List fetching functions (listTools, listResources, listPrompts) already exist
  • State management is in place

The only missing piece was responding to the notifications in the onNotification callback, which this PR adds.

When a server sends list_changed notifications, the inspector now
automatically refreshes the corresponding lists. Pagination cursors
are reset to ensure a clean re-fetch from the first page.

Follows the existing pattern used for tasks/list_changed.

Closes modelcontextprotocol#832

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: support tools/list_changed notifications handling

1 participant