Commit be69a25
Dynamic tool registration based on MCP client capabilities (#61)
* Implement dynamic tool registration based on MCP client capabilities
This commit introduces capability-aware tool registration that adapts to
client features, ensuring users only see tools that work with their client.
Key changes:
1. Tool Categorization (src/tools/toolRegistry.ts):
- Split tools into three categories by capability requirements:
* CORE_TOOLS (23 tools): Work in all MCP clients
* ELICITATION_TOOLS (2 tools): Require elicitation capability
- PreviewStyleTool
- StyleComparisonTool
* RESOURCE_FALLBACK_TOOLS (1 tool): Bridge for missing resource support
- GetReferenceTool
- Added new getter functions:
* getCoreTools()
* getElicitationTools()
* getResourceFallbackTools()
- Deprecated getAllTools() in favor of capability-aware functions
- Maintained ALL_TOOLS for backward compatibility and testing
2. Dynamic Registration (src/index.ts):
- Register CORE tools before connection (always available)
- After connection, check client capabilities via getClientCapabilities()
- Conditionally register ELICITATION_TOOLS if client supports elicitation
- Conditionally register RESOURCE_FALLBACK_TOOLS if client lacks resource support
- Send notifications/tools/list_changed notification after dynamic registration
- Added comprehensive logging for registration decisions
- Advertise listChanged: true capability to inform clients that tool list
can change dynamically
Benefits:
- Users only see tools that actually work with their client
- No confusing runtime capability errors
- Cleaner UX for capability-limited clients
- Backward compatible with existing tool configuration system
- Zero breaking changes (all tools still work, just registered conditionally)
All 520 tests pass.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Tests: Add unit tests for tool categorization
Add comprehensive unit tests to verify:
- Tool categorization correctness
- Getter functions return expected tools
- No overlap between categories
- Tool counts are correct
15 tests covering:
- getCoreTools() - 4 tests
- getElicitationTools() - 3 tests
- getResourceFallbackTools() - 2 tests
- getAllTools() - 3 tests
- Tool categorization consistency - 3 tests
All tests pass.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Fix: Move preview/comparison tools to CORE_TOOLS (elicitation not merged yet)
The elicitation support for preview_style_tool and style_comparison_tool
exists only in the add-preview-token-elicitation branch, which hasn't been
merged to main yet. Moving these tools to ELICITATION_TOOLS made them
unavailable to all clients.
Changes:
- Move preview_style_tool back to CORE_TOOLS
- Move style_comparison_tool back to CORE_TOOLS
- Keep ELICITATION_TOOLS as empty array (ready for future use)
- Update tests to reflect empty ELICITATION_TOOLS
- Add comments explaining this is temporary until elicitation support merges
When elicitation support is merged in the future, these tools can be moved
to ELICITATION_TOOLS in a follow-up PR.
All 535 tests pass.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Move GetMapboxDocSourceTool to RESOURCE_FALLBACK_TOOLS
The get_latest_mapbox_docs_tool duplicates functionality of the
resource://mapbox-documentation resource. It should only be available
to clients that don't properly support resources.
Changes:
- Move GetMapboxDocSourceTool from CORE_TOOLS to RESOURCE_FALLBACK_TOOLS
- CORE_TOOLS now has 24 tools (down from 25)
- RESOURCE_FALLBACK_TOOLS now has 2 tools (up from 1):
* get_reference_tool (reference resources)
* get_latest_mapbox_docs_tool (documentation resource)
- Update tests to reflect new categorization
- Add test for get_latest_mapbox_docs_tool in resource fallback tools
Clients that properly support resources will no longer see this tool,
reducing clutter in their tool list.
All 536 tests pass.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Fix: Correct resource fallback tool detection logic
The previous logic incorrectly checked clientCapabilities.resources which
doesn't exist (resources is a SERVER capability, not a CLIENT capability).
Now correctly detects clients by name using getClientVersion() and only
registers fallback tools for clients with known resource support issues
(e.g., Claude Desktop).
Result: MCP Inspector and other proper clients now see 23 tools instead
of 26, with resource fallback tools only appearing for Claude clients.
MCP Inspector Output After Fix:
Tools (23):
[
"bounding_box_tool",
"check_color_contrast_tool",
"compare_styles_tool",
"coordinate_conversion_tool",
"country_bounding_box_tool",
"create_style_tool",
"create_token_tool",
"delete_style_tool",
"geojson_preview_tool",
"get_feedback_tool",
"list_feedback_tool",
"list_styles_tool",
"list_tokens_tool",
"optimize_style_tool",
"preview_style_tool",
"retrieve_style_tool",
"style_builder_tool",
"style_comparison_tool",
"tilequery_tool",
"update_style_tool",
"validate_expression_tool",
"validate_geojson_tool",
"validate_style_tool"
]
Resources (5):
[
"resource://mapbox-documentation",
"resource://mapbox-layer-type-mapping",
"resource://mapbox-streets-v8-fields",
"resource://mapbox-style-layers",
"resource://mapbox-token-scopes"
]
Fixes dynamic tool registration to work as intended.
* Address code review: Invert resource fallback logic for safer client compatibility
Per @Valiunia's review feedback, invert the resource fallback tool logic to use an allowlist approach instead of blocklist. This is safer for unknown clients.
Changes:
- OLD: Only provide fallback tools if client name includes 'claude' (blocklist)
- NEW: Provide fallback tools to ALL clients UNLESS we know they support resources (allowlist)
Known clients with proper resource support (skip fallback tools):
- inspector
- vscode
Benefits:
- Unknown/new clients get fallback tools by default (safer)
- No risk of missing clients that need resource fallback
- More defensive approach for ecosystem compatibility
Related: PR #61 review comments
All tests passing (536 tests).
* Clarify resource fallback logic: for clients without resource support (like smolagents)
Update comments and logic to reflect the real use case: resource fallback tools
are for clients that don't support resources at all (like smolagents), not for
buggy resource implementations.
Changes:
- Add 'claude' to allowlist (Claude Desktop now supports resources properly)
- Update comments to clarify this is for clients without resource support
- Change from "may not support properly" to "don't support resources"
- Document smolagents as the primary use case
Known clients WITH resource support (skip fallback tools):
- inspector
- vscode
- claude (Claude Desktop/Code)
Clients WITHOUT resource support (get fallback tools):
- smolagents
- unknown/new clients (safer default)
All tests passing (536 tests).
* Replace client detection with CLIENT_NEEDS_RESOURCE_FALLBACK env var (opt-in)
Remove fragile name-based client detection and replace with explicit
environment variable configuration. Use opt-in approach since most MCP
clients support resources.
Changes:
- Remove client name checking logic entirely
- Add CLIENT_NEEDS_RESOURCE_FALLBACK environment variable
- Default (unset): Assume client supports resources, skip fallback tools
- Set to "true": Client needs fallback tools (e.g., smolagents)
Benefits:
- No maintenance burden tracking client names/versions
- Better default (most clients support resources)
- Opt-in only for exceptions (smolagents, etc.)
- Explicit configuration by users who know their client
Configuration:
```bash
# smolagents or clients without resource support
export CLIENT_NEEDS_RESOURCE_FALLBACK=true
# Claude Desktop, VS Code, Inspector, etc. (default)
# Leave unset - assumes resource support
```
Documentation updated in README.md explaining when to set this variable.
All tests passing (536 tests).
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>1 parent 45fa1b3 commit be69a25
4 files changed
Lines changed: 352 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1304 | 1304 | | |
1305 | 1305 | | |
1306 | 1306 | | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
| 1316 | + | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
1307 | 1330 | | |
1308 | 1331 | | |
1309 | 1332 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
17 | 21 | | |
18 | 22 | | |
19 | 23 | | |
| |||
54 | 58 | | |
55 | 59 | | |
56 | 60 | | |
57 | | - | |
58 | | - | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
59 | 69 | | |
60 | 70 | | |
61 | 71 | | |
| |||
65 | 75 | | |
66 | 76 | | |
67 | 77 | | |
68 | | - | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
69 | 81 | | |
70 | 82 | | |
71 | 83 | | |
72 | 84 | | |
73 | 85 | | |
74 | 86 | | |
75 | | - | |
76 | | - | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
77 | 90 | | |
78 | 91 | | |
79 | 92 | | |
| |||
210 | 223 | | |
211 | 224 | | |
212 | 225 | | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
213 | 300 | | |
214 | 301 | | |
215 | 302 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
32 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
33 | 36 | | |
34 | 37 | | |
35 | 38 | | |
| |||
41 | 44 | | |
42 | 45 | | |
43 | 46 | | |
| 47 | + | |
44 | 48 | | |
45 | 49 | | |
46 | 50 | | |
47 | 51 | | |
48 | 52 | | |
49 | 53 | | |
50 | 54 | | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
60 | 101 | | |
61 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
62 | 107 | | |
63 | 108 | | |
64 | 109 | | |
65 | 110 | | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
66 | 132 | | |
67 | 133 | | |
68 | 134 | | |
0 commit comments