Skip to content

Conversation

@mattpodwysocki
Copy link
Contributor

@mattpodwysocki mattpodwysocki commented Jan 27, 2026

Summary

Implements capability-aware tool registration infrastructure that adapts to client features. Fixes incorrect resource capability detection and removes duplicate tools that conflict with MCP resources.

Key Changes

1. Fixed Resource Capability Detection (src/index.ts)

Problem: Checked clientCapabilities?.resources which doesn't exist (resources is a SERVER capability, not CLIENT capability)

Solution: Detect clients by name using getClientVersion() - only register fallback tools for clients with 'claude' in their name

2. Removed Duplicate Tools (src/tools/toolRegistry.ts)

Problem: Tools duplicated functionality already provided by MCP resources

Solution: Moved resource-duplicating tools to RESOURCE_FALLBACK_TOOLS:

  • resource_reader_tool - Generic fallback for reading any resource by URI
  • category_list_tool - Duplicated CategoryListResource (mapbox://categories)

Split tools into three capability-based categories:

  • CORE_TOOLS (19 tools): Work in all MCP clients, always available
  • ELICITATION_TOOLS (0 tools): Empty, ready for future elicitation support
  • RESOURCE_FALLBACK_TOOLS (2 tools): Only for clients with resource issues (Claude Desktop)

3. Dynamic Registration Infrastructure

  1. Register CORE tools before connection
  2. After connection, check client capabilities and version
  3. Conditionally register ELICITATION_TOOLS if client supports elicitation (none yet)
  4. Conditionally register RESOURCE_FALLBACK_TOOLS if client name includes 'claude'
  5. Send notifications/tools/list_changed after dynamic registration
  6. Advertise tools: { listChanged: true } capability

4. Tests (test/tools/toolRegistry.test.ts)

Added 15 comprehensive unit tests covering tool categorization, no overlap between categories, and proper counts.

MCP Inspector Output (After Fix)

Clients with proper resource support (Inspector, VS Code, etc.) now see:

Tools (19):

[
  "area_tool",
  "bbox_tool",
  "bearing_tool",
  "buffer_tool",
  "category_search_tool",
  "centroid_tool",
  "directions_tool",
  "distance_tool",
  "isochrone_tool",
  "map_matching_tool",
  "matrix_tool",
  "midpoint_tool",
  "optimization_tool",
  "point_in_polygon_tool",
  "reverse_geocode_tool",
  "search_and_geocode_tool",
  "simplify_tool",
  "static_map_image_tool",
  "version_tool"
]

Resources (1):

[
  "mapbox://categories"
]

Result: Inspector shows 19 tools (down from 21) - resource fallback tools only appear for Claude clients.

Benefits

No duplication: Resource fallback tools only for clients that need them
Correct behavior: Inspector and proper clients use resources instead of fallback tools
Better UX: Cleaner tool list for clients with proper resource support
Infrastructure ready: Framework in place for capability-dependent tools
Zero breaking changes: Claude Desktop still gets fallback tools

Testing

  • ✅ All 597 tests pass
  • ✅ Build successful
  • ✅ Verified in MCP Inspector
  • ✅ Comprehensive logging for debugging

MCP Specification Compliance

Follows MCP 1.0 specification for dynamic tool registration:

  • Uses notifications/tools/list_changed notification
  • Advertises listChanged capability
  • Registers tools after initialization handshake
  • Properly detects client capabilities

Related

Follows the same pattern as mcp-devkit-server PR #61.

mattpodwysocki and others added 7 commits January 12, 2026 16:18
Implements MCP server icons at the correct architectural level (server
initialization) instead of at the tool level. Adds both light and dark
theme variants of the Mapbox logo using base64-encoded SVG data URIs.

- Add mapbox-logo-black.svg for light theme backgrounds
- Add mapbox-logo-white.svg for dark theme backgrounds
- Update server initialization to include icons array with theme property
- Use 800x180 SVG logos embedded as base64 data URIs

This replaces the previous incorrect approach of adding icons to
individual tools, which was not aligned with the MCP specification.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updates the MCP SDK from 1.25.1 to 1.25.2 and recreates the output
validation patch for the new version. The patch continues to convert
strict output schema validation errors to warnings, allowing tools
to gracefully handle schema mismatches.

Changes:
- Update @modelcontextprotocol/sdk from ^1.25.1 to ^1.25.2
- Recreate SDK patch for version 1.25.2
- Remove obsolete 1.25.1 patch file
- All 397 tests pass with new SDK version

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit lays the groundwork for capability-aware tool registration,
enabling the server to adapt tool availability based on client features.

Key changes:

1. Tool Categorization (src/tools/toolRegistry.ts):
   - Introduced CORE_TOOLS constant containing all 21 tools
   - Note: ResourceReaderTool included in CORE_TOOLS since we cannot reliably
     detect whether a client needs it (resource support is not exposed in
     client capabilities for this MCP SDK version)
   - Added getCoreTools() function for capability-aware registration
   - Deprecated getAllTools() in favor of capability-aware functions
   - Maintained ALL_TOOLS for backward compatibility and testing

2. Infrastructure Setup (src/index.ts):
   - Updated imports to use getCoreTools() instead of getAllTools()
   - Advertise listChanged: true capability to support dynamic tool registration
   - Added comprehensive comments explaining how to implement dynamic registration
     when capability-dependent tools are added in the future

   - Pattern documented for future capability-dependent tools:
     * Categorize tools by capability requirements
     * Register core tools before connection
     * After connection, check client capabilities
     * Dynamically register capability-dependent tools
     * Send sendToolListChanged() notification

Benefits:
- Infrastructure ready for capability-dependent tools (like elicitation)
- No breaking changes (all tools still registered, just reorganized)
- Clear pattern established for future capability-aware features
- Follows same architecture as mcp-devkit-server

All 582 tests pass.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive unit tests to verify:
- Tool categorization correctness
- Getter functions return expected tools
- Tool counts are correct
- No duplicate tools

8 tests covering:
- getCoreTools() - 4 tests
- getAllTools() - 3 tests
- Tool categorization consistency - 1 test

All tests pass.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@mattpodwysocki mattpodwysocki requested a review from a team as a code owner January 27, 2026 17:22
- Fixed dynamic tool registration to detect clients by name using
  getClientVersion() instead of checking non-existent clientCapabilities.resources
- Moved ResourceReaderTool from CORE_TOOLS to RESOURCE_FALLBACK_TOOLS
  (generic fallback for all resources)
- Moved CategoryListTool from CORE_TOOLS to RESOURCE_FALLBACK_TOOLS
  (duplicates CategoryListResource)
- Created ELICITATION_TOOLS category (empty, ready for future use)
- Resource fallback tools only register for clients with 'claude' in name

Result: MCP Inspector and other proper clients now see 19 tools instead
of 21, with resource fallback tools only appearing for Claude clients.

MCP Inspector Output After Fix:

Tools (19):
[
  "area_tool",
  "bbox_tool",
  "bearing_tool",
  "buffer_tool",
  "category_search_tool",
  "centroid_tool",
  "directions_tool",
  "distance_tool",
  "isochrone_tool",
  "map_matching_tool",
  "matrix_tool",
  "midpoint_tool",
  "optimization_tool",
  "point_in_polygon_tool",
  "reverse_geocode_tool",
  "search_and_geocode_tool",
  "simplify_tool",
  "static_map_image_tool",
  "version_tool"
]

Resources (1):
[
  "mapbox://categories"
]

All tests passing (597 total).
@mattpodwysocki mattpodwysocki force-pushed the dynamic-tool-registration branch from 23d9dd2 to 639a3d4 Compare January 27, 2026 18:03
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.

1 participant