Tool names easily exceed Claude Code's 64-character limit due to MD5 hash appending
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3528937. -->
Reported by: [askibinski](https://www.drupal.org/user/248999)
>>>
<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>Not exactly a bug per se, but still annoying developement experience. But also I'm questioning the way that security is implemented here, however I parked those remarks in a comment here: <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/mcp/-/work_items/3526963" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/mcp/-/work_items/3526963</a></span>.</p>
<p>Claude Code enforces a 64-character limit for MCP tool names, but the current MCP module's tool naming scheme can easily exceed this limit when combined with Claude Code's prefixing system.</p>
<p>The issue occurs because:<br>
1. The MCP module appends a 32-character MD5 hash to tool names in `src/Plugin/McpJsonRpc/ToolsList.php` at line 38:<br>
```php<br>
name: $instance->getPluginId() . '_' . md5($tool->name),<br>
```<br>
2. Claude Code adds its own prefix: `mcp__<server-name>__<tool-name>`<br>
3. The combined length often exceeds Claude Code's 64-character limit</tool-name></server-name></p>
<p>This results in API errors like:</p>
<pre>API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"tools.15.custom.name: String should have at most 64 characters"}}</pre><p>The docs currently state about the tool id:</p>
<blockquote><p>Tool IDs<br>
When the MCP module exposes tools to clients, it prefixes the tool name with the plugin ID and uses MD5 hash for security. In your executeTool() method, compare the incoming ID with the MD5 hash of your tool name.</p></blockquote>
<p>The MD5 hash generation happens in the `ToolsList::execute()` method where all available plugins are processed and their tool names are transformed using:</p>
<div class="codeblock">
<pre><span style="color: #000000"><span style="color: #0000BB"><?php<br>$prefixizedTools </span><span style="color: #007700">= </span><span style="color: #0000BB">array_map</span><span style="color: #007700">(<br> </span><span style="color: #0000BB">fn</span><span style="color: #007700">(</span><span style="color: #0000BB">$tool</span><span style="color: #007700">) => new </span><span style="color: #0000BB">Tool</span><span style="color: #007700">(<br> </span><span style="color: #0000BB">name</span><span style="color: #007700">: </span><span style="color: #0000BB">$instance</span><span style="color: #007700">-></span><span style="color: #0000BB">getPluginId</span><span style="color: #007700">() . </span><span style="color: #DD0000">'_' </span><span style="color: #007700">. </span><span style="color: #0000BB">md5</span><span style="color: #007700">(</span><span style="color: #0000BB">$tool</span><span style="color: #007700">-></span><span style="color: #0000BB">name</span><span style="color: #007700">),<br> </span><span style="color: #0000BB">description</span><span style="color: #007700">: </span><span style="color: #DD0000">"Original name: </span><span style="color: #0000BB">$tool</span><span style="color: #007700">-></span><span style="color: #0000BB">name</span><span style="color: #DD0000">, Description: </span><span style="color: #0000BB">$tool</span><span style="color: #007700">-></span><span style="color: #0000BB">description</span><span style="color: #DD0000">"</span><span style="color: #007700">,<br> </span><span style="color: #0000BB">inputSchema</span><span style="color: #007700">: </span><span style="color: #0000BB">$tool</span><span style="color: #007700">-></span><span style="color: #0000BB">inputSchema</span><span style="color: #007700">,<br> ),<br> </span><span style="color: #0000BB">$instanceTools<br></span><span style="color: #007700">);<br></span><span style="color: #0000BB">?></span></span></pre></div>
<p>The tool->name should already be unique but is set in code and can also be long.</p>
<h3 id="summary-steps-reproduce">Steps to reproduce</h3>
<p>1. Create an MCP plugin with a plugin ID longer than ~20 characters<br>
2. Add the MCP server to Claude Code CLI: `claude mcp add myserver -- /path/to/mcp-server-drupal --drupal-url=<a href="http://example.com">http://example.com</a>`<br>
3. Try to use Claude Code<br>
4. Observe the 64-character limit error</p>
<p>The character budget breakdown:<br>
- `mcp__` = 5 characters (Claude Code prefix)<br>
- `<server-name>__` = variable (typically 7-15 characters)<br>
- `<br>
<plugin-id>_` = variable (plugin ID + underscore)<br>
- `<md5-hash>` = 32 characters (always)</md5-hash></plugin-id></server-name></p>
<p>This leaves very little room for meaningful plugin IDs when using Claude Code.</p>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>**Option 1: Shorten the hash**<br>
Replace the full 32-character MD5 hash with a shorter hash to provide more room for plugin IDs:</p>
<div class="codeblock">
<pre><span style="color: #000000"><span style="color: #0000BB"><?php<br>name</span><span style="color: #007700">: </span><span style="color: #0000BB">$instance</span><span style="color: #007700">-></span><span style="color: #0000BB">getPluginId</span><span style="color: #007700">() . </span><span style="color: #DD0000">'_' </span><span style="color: #007700">. </span><span style="color: #0000BB">substr</span><span style="color: #007700">(</span><span style="color: #0000BB">md5</span><span style="color: #007700">(</span><span style="color: #0000BB">$tool</span><span style="color: #007700">-></span><span style="color: #0000BB">name</span><span style="color: #007700">), </span><span style="color: #0000BB">0</span><span style="color: #007700">, </span><span style="color: #0000BB">8</span><span style="color: #007700">),<br></span><span style="color: #0000BB">?></span></span></pre></div>
<p>This reduces the hash from 32 to 8 characters, providing 24 more characters for plugin IDs while maintaining reasonable collision resistance.</p>
<p>**Option 2: Documentation improvement**<br>
At minimum, documenting the character limit constraint in the module documentation and provide guidelines for plugin ID naming.</p>
<h3 id="summary-remaining-tasks">Remaining tasks</h3>
<p>- [ ] Decide on the preferred solution approach<br>
- [ ] Implement the chosen solution<br>
- [ ] Update documentation with character limit guidance<br>
- [ ] Add tests to verify tool name length constraints<br>
- [ ] Consider backward compatibility if changing hash length</p>
<h3 id="summary-ui-changes">User interface changes</h3>
<p>None required.</p>
<h3 id="summary-api-changes">API changes</h3>
<p>If implementing Option 1: Tool names will have shorter hashes, but this should be backward compatible as tool names are internal identifiers which do not change.</p>
<h3 id="summary-data-model-changes">Data model changes</h3>
<p>None required.</p>
> Related issue: [Issue #3539318](https://www.drupal.org/node/3539318)
issue