Improve tools naming

Created on 1 August 2025, 2 months ago

Idea is to improve the tools naming that MCP module exposes for LLMS. This issue is basically for discussion and planning at the moment.

Problem/Motivation

Right now, tool names are the combination of the plugin id and the md5 hash. The reason for that is that we need the names to be unique and also some clients limit name lengths, so its good to have predictable lengths for tool names.

Problem here is in two directions:
1. Understanding for humans - when listing the tools exposed by Drupal MCP, there is no way to easily find out and understand what they are expected to do. You simply see the plugin id followed by the hash.

2. Understanding for LLM clients - although there is a description there and it is the main thing that LLM uses to decide whether to use the tool or not (and to be honest, this works fine), having meaningful tool names could also help a lot, at least for some clients.

Steps to reproduce

Enable MCP module with couple of plugins and you check the list of tools with LLM clients.

Proposed resolution

We need to discuss how to solve this. One possible way could be to maintain a separate mapping with unique ids and descriptive names. That would also require to manage the caching. Also having a way to manage it with MCP module's configuration (a new, improved version will be released soon hopefully), would be nice.

✨ Feature request
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡¬πŸ‡ͺGeorgia jibla

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @jibla
  • πŸ‡¬πŸ‡ͺGeorgia gagosha
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    I'm not that the current tool name is the plugin ID followed by the hash. When I use Claude Code and get a list of tools, here is what I see:

    So, there is one called general_HASH followed by a long list, all of which aif_HASH. As plugin IDs already need to be unique in Drupal, I wonder how there could be many with the plugin ID aif.

    Is it fair to say that a 64-character limit is what we're aiming for?

    If so, we could just use the plugin ID as the tool name being exposed. Only if that is longer than 64 characters, we should truncate e.g. the first 57 characters, and append that by an underscore and a 6 character hash. Chances that this creates duplicates should be negligible.

  • πŸ‡¬πŸ‡ͺGeorgia jibla

    As of my knowledge, plugins can expose one or multiple tools, hence `aif_` prefixed many tools in the list.

    @gagosha - can you explain how exactly at the moment tool names are constructed and then we continue from there?

  • πŸ‡¬πŸ‡ͺGeorgia gagosha

    Hey @jibla @jurgenhaas,

    For now, tool IDs are generated using two distinct parts: the plugin ID and the tool name. The plugin ID comes from the custom Drupal plugin. So for @Jurgenhaas photo, `aif` is the plugin ID, which stands for "AI Function Calling".

    The second part is the MD5-hashed tool name, so there will be as many `aif_*` tools as the "AI Function Calling" plugin exposes.

    We use MD5 for two reasons:
    1. The Claude desktop application imposes a 64-character limit, and there might be other clients with similar restrictions.
    2. Tools need to be discoverable. During the discovery phase, we use the first part (`aif`) to locate the plugin, and the second part, the MD5 hash, to locate the plugin's specific tool. Truncation wouldn’t work in this case, as it could lead to hash collisions (i.e. different tools ending up with the same name).

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    The second part is the MD5-hashed tool name, so there will be as many `aif_*` tools as the "AI Function Calling" plugin exposes.

    "AI Function Calling" is not the plugin, it's the plugin manager.

    Instead, we should use the ID of each plugin, not aif. Maybe, it could remain in place as a prefix, but it should be followed by the real plugin ID, because that's not only telling to us humans but also to the LLM.

    Truncation wouldn’t work in this case, as it could lead to hash collisions (i.e. different tools ending up with the same name).

    I'm not worried about that at all. First, most plugin IDs are much shorter and we should not get into the position to even reach the 64-character limit. And if we did, it means we either have a huge difference in those 64 characters already, which avoids collisions. But if there are 2 similar plugins with almost identical IDs that are longer than that limit, their hashes will be entirely different and using just 48 bits of those hashes will not collide by any reasonable chance. It's more likely that every Drupal developer on the planet becomes a lottery millionaire ;-)

  • πŸ‡¬πŸ‡ͺGeorgia gagosha

    "AI Function Calling" is not the plugin, it's the plugin manager.

    For the MCP module, its plugin: https://git.drupalcode.org/project/mcp/-/blob/1.x/modules/mcp_extra/src/...

    The MCP module requires these plugins to wrap/proxy the actual plugins/plugin managers in its format and expose them. When exposing tools, the first part is the MCP plugin ID, and the second part is the tool name. For example, if there is no MD5, the tool name will be:
    `aif_action_plugin__entity__unpublish_action__menu_link_content`

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    aif_action_plugin__entity__unpublish_action__menu_link_content is an exceptionally long plugin ID, but it would still fit into the 64-character limit. It will be very rare if anything is longer than that.

    And as a user, I'd prefer that name instead of aif_6304ac6c6a22b421c72ce2719a9cd5ef.

  • πŸ‡¬πŸ‡ͺGeorgia gagosha

    Pushed the change. Updated the logic for ID generation, no longer using MD5 for everything.

    From now on, IDs are generated as: `[plugin name]_[tool name]`, and if the result exceeds the 64-character limit, it’s truncated and a 6-character MD5 hash suffix is added.

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    I wanted to test this, but I'm having strange issues. When I use version 1.1.0 of the MCP module, I can use mcp-server-drupal --drupal-url=https://mysite.dev and receive a success message. I can then use claude code and receive the list of tools with the "old" names.

    When I change to 1.x of the MCP module, I get the error message ERROR: No available instruments were found during the preflight check when using the mcp-server-drupal tool. Then, as expected, claude code can't receive tools either.

    I then checked the MR above, and that has the same effect as the 1.x branch.

    There are no errors in the logs, so I don't know what I should be doing. Do you have an idea what could be going wrong here?

  • πŸ‡¬πŸ‡ͺGeorgia gagosha

    Hey @jurgenhaas, I think this is due to the latest change that added granular access to the plugins.

    By default, they’re only accessible to the authenticated role. Could you try editing the plugin configuration and checking "Anonymous user"? I think the plugin tools should appear again after that.

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    OK, this is looking great. I only found one issue which is probably not related and if so, I'm happy to open a new issue for that:

    If there is a \Drupal\ai\Attribute\FunctionCall plugin with no context definition, which is allowed according to the attribute definition, then MCP tool collection fails with the error Adaptor Drupal\jsonrpc\Shaper\RpcResponseFactory returned invalid output data: [].

    This comes from \Drupal\mcp_extra\Plugin\Mcp\AiFunctionCalling::getTools where input schema receives NULL if no context is available. To resolve this, inputSchema: $converted['parameters'] needs to be adjusted like this:

            inputSchema: $converted['parameters'] ?? [
              'type' => 'object',
              'properties' => [],
              'required' => [],
            ],
    
  • πŸ‡¬πŸ‡ͺGeorgia gagosha

    Ah, you are right. Fix already pushed, thanks @jurgenhaas πŸ™Œ

  • πŸ‡¬πŸ‡ͺGeorgia jibla

    Changing status to `Fixed` as we already merged it into `1.x` and soon will release - `1.2.0-rc`.

    Thank you both.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024