MCP Tool Name Compatibility#1400
Open
kmeirlaen wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates LichtFeld Studio’s MCP tool surface to be compatible with strict MCP clients (e.g., Claude connectors) by (1) exposing underscore-separated tool names in tools/list while keeping dotted-name calls compatible, and (2) ensuring JSON Schema inputSchema.properties always serializes as an object (never null). It also relocates LichtFeld-specific tool metadata from non-standard annotations keys into _meta, and updates MCP documentation/examples accordingly.
Changes:
- Normalize MCP tool names by replacing
.with_for listing, while accepting both dotted/underscore names fortools/calllookups. - Harden MCP tool schema serialization so
inputSchema.propertiesis always{}when missing/invalid. - Move LichtFeld-specific tool metadata from
annotations(x-lfs-*) into_meta(app.lichtfeld/...) and update docs/examples to reference underscore tool names.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/test_mcp_protocol.cpp | Adds/updates protocol-level tests for underscore tool-name exposure, dotted/underscore call compatibility, _meta metadata, and null properties serialization. |
| src/mcp/mcp_training_context.cpp | Updates tool description text to reference normalized (underscore) tool names in user-facing guidance. |
| src/mcp/mcp_tools.cpp | Implements tool name normalization in the registry and fixes CommandCenter-generated tool schemas to use properties: {}. |
| src/mcp/mcp_protocol.cpp | Ensures inputSchema.properties serializes as an object and moves LichtFeld-specific metadata into _meta. |
| src/app/mcp_ui_registry_tools.cpp | Updates schema descriptions to reference normalized tool names (e.g., ui_menu_describe). |
| src/app/mcp_gui_tools.cpp | Updates user-facing messages/descriptions to reference normalized tool names. |
| docs/docs/development/mcp/recipes/selection-and-gaussians.md | Updates recipe examples to use underscore tool names. |
| docs/docs/development/mcp/recipes/operators-and-modal.md | Updates recipe examples to use underscore tool names (while keeping dotted non-tool ids like operator.modal). |
| docs/docs/development/mcp/recipes/load-dataset-and-train.md | Updates recipe examples to use underscore tool names for scene/training/runtime tools. |
| docs/docs/development/mcp/recipes/export-scene.md | Updates export recipe examples to use underscore tool names. |
| docs/docs/development/mcp/recipes/editor-and-runtime.md | Updates editor/runtime recipe examples to use underscore tool names. |
| docs/docs/development/mcp/index.md | Updates namespace overview and runtime tool references to underscore tool names. |
| docs/docs/development/mcp/bootstrap.md | Updates bootstrap guidance/examples to underscore tool names. |
| AGENTS.md | Updates agent guidance to use underscore tool names in recommended flows. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ted McpTool.name internally - copilot remark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This patch makes MCP tool names Claude-compatible by exposing underscore-separated names in
tools/listwhile preserving dotted-name compatibility for existing callers. It also fixes strict-client parsing by ensuring every MCP toolinputSchema.propertiesvalue is serialized as a JSON object, nevernull.Observed Symptoms And Replication
Claude-compatible MCP clients validate tool names with a restricted pattern similar to
^[a-zA-Z0-9_-]{1,64}$. LichtFeld Studio exposed tools such aseditor.run,scene.load_dataset, andruntime.job.wait, which contain dots. Clients that enforce this validation can silently drop those tools, leaving resources visible but no tools available.A second strict-client failure was observed in the live
tools/listpayload after the name and metadata fixes: the generated session toolssession_pause,session_request_stop, andsession_resumereturned{"type":"object","properties":null}. JSON Schema requirespropertiesto be an object. A strict client that parses the tools array as one payload can fail on that single invalid schema and drop the full tool list.Replication for the original issue:
http://127.0.0.1:45677/mcp.resources/listand observe resources are available.tools/listin a strict client and observe dotted tool names are rejected or omitted.tools/listJSON and observeinputSchema.propertiesisnullforsession_pause,session_request_stop, andsession_resume.Root Cause
The MCP server registered and returned tool names exactly as internal namespaces used them. Dotted names are convenient for internal grouping, but they are not accepted by clients that validate tool names as alphanumeric, underscore, or hyphen only. Runtime job IDs, operator IDs, event types, plugin capability names, and resource URIs are separate domain identifiers and should remain dotted.
The null-schema issue came from the CommandCenter-generated tool path.
ToolRegistry::operation_to_tooldefault-initialized the schemapropertiesJSON value, which leaves it asnullfor zero-argument operations. Other zero-argument tools used an explicitly empty object, so only tools generated through this path exposed the invalid shape. The protocol serializer also trusted stored schema values directly, so a bad registration could reach MCP clients unchanged.What This Patch Fixes
ToolRegistryboundaries by replacing.with_.tools/calland unregister paths working by normalizing incoming names before lookup.annotationslimited to standard MCP annotation hints and moves LichtFeld-specific metadata into tool_meta.properties: {}for zero-argument operations.inputSchema.propertiesas{}if a stored tool schema has null or non-object properties.training.main,editor.python,operator.modal,transform.translate, event types, andlichtfeld://resource URIs.tools/list, dotted and underscoretools/call, null schema property serialization, and unchanged structured response shape.Impact Notes
tools/listreturns Claude-compatible names;tools/callaccepts both old dotted names and new underscore names; custom metadata is exposed under_metawithapp.lichtfeld/...keys instead of non-standardx-lfs-*annotation keys.lichtfeld.mcp.call_tool(...)callers remain compatible.^[a-zA-Z0-9_-]{1,64}$,x-lfs-*keys no longer appear inannotations, and strict JSON Schema parsers no longer encounterinputSchema.properties: null.AGENTS.mdnow use underscore tool names while preserving dotted domain IDs.