Skip to content

ADR-0011: Allow gateways to add tools with the same server side name to the MCP Gateway without conflict

Context

The current functionality only supports unique names for tools, making it hard for addition of tools from different gateways with similar common names.

This needs to be updated so that tool names are allowed with a combination of gateway name (slugified namespace) and tool name. This would allow servers to add their own versions of the tools.

The tool names would be stored along with their original name in the database so that the correct server side name is passed while invoking it.

Decision

We implemented this by making the following changes:

  1. Update IDs from integers to UUIDs:
  2. Modify the data type of id in Gateway, Tool and Server SQLAlchemy ORM classes from int to str
  3. Use a default value of uuid.uuid4().hex for the IDs
  4. Modify server_id and tool_id to String in server_tool_association table

  5. Separate server side and gateway side names for tools:

  6. Add a new field called original_name in Tool ORM class to store the MCP server side name used for invocation
  7. Define a hybrid operator name to capture how the gateway exposes the tool. Set it as f"{slugify(self.gateway.name)}{settings.gateway_tool_name_separator}{self.original_name}"
  8. Slugified self.gateway.name is used to remove spaces in new tool names
  9. Hybrid operator is used so it can be used in Python and SQL code for filtering and querying
  10. Add a new field called gateway_slug which is defined as the slug of the Gateway linked via self.gateway_id. This field is later used to extract the original name from name passed from APIs

  11. Addition of configurable environmental variable GATEWAY_TOOL_NAME_SEPARATOR to set how the tool name looks like:

  12. By default, this is set to - in config.py

  13. Updates Python object schemas, function data types to match database ORM changes**

  14. Change data type of gateway_id, tool_id and server_id from int to str in API functions
  15. When storing and updating tools, use original_name in DbTool objects to store the original name coming from _initiate_gateway.
  16. Remove check for only storing tools without matching original names
  17. Check if gateway.url exists instead of gateway.name exists before thowing GatewayNameConflictError.
  18. Check for existing tools on original_name and gateway_id instead of just name (as earlier) in update_gateway and toggle_gateway_status code.
  19. Set name and gateway_slug just before passing to ToolRead seprately since these don't come from the database as these are properties and not columns.
  20. To obtain tool from database for invocation, handle the case that name from the API is not stored as a column in the database, but is a property by making an appropriate comparison as DbTool.gateway_slug + settings.gateway_tool_name_separator + DbTool.original_name == name

  21. Handle tool changes from the gateway by adding and removing tools based on latest deactivate/activate or edit:

  22. Step 1: Add all tools not present in database based on original_name to gateway.tools
  23. Step 2: Remove any tools not sent in the latest call to _initialize_gateway from gateway.tools.

  24. Show row index in UI:

  25. Display the index of the row with loop.index in a new column called S. No. in Gateways, Tools and Servers screens.

Consequences

  • Two gateways can have the tools with the same native name on the gateway. e.g. gateway-1-get_system_time and gateway-2-get_system_time.
  • If the tools on a gateway change, they will reflect after Deactivate/Activate cycle or after Edit Gateway action.

Alternatives Considered

Option Why Not
Use qualified_name as display name and name as native MCP server name Requires changes at more places since most clients display and call with the field name

Status

PR created: