Skip to content

Add OpenAI-compatible tool name normalization for MCP tools#30

Merged
pardeike merged 2 commits intomainfrom
copilot/fix-50620edf-e7b5-43f4-8435-d50cb6bbefa3
Sep 14, 2025
Merged

Add OpenAI-compatible tool name normalization for MCP tools#30
pardeike merged 2 commits intomainfrom
copilot/fix-50620edf-e7b5-43f4-8435-d50cb6bbefa3

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Sep 14, 2025

Problem

The codex CLI registers MCP tools directly as OpenAI tools, but OpenAI's API validator rejects tool names containing dots (.) which are commonly used in MCP tool names like minecraft.inventory.get or games.list. This causes validation errors before the request even reaches the model, making it impossible to use GABS tools through OpenAI-compatible clients.

Solution

Added configurable tool name normalization that automatically converts MCP tool names to OpenAI-compatible format while preserving the original names for reference.

Key Features

Smart Normalization Algorithm:

  • Converts dots to underscores: minecraft.inventory.getminecraft_inventory_get
  • Handles special characters: game.player@stats#get!game_player_stats_get
  • Enforces 64-character limit with intelligent truncation
  • Ensures valid start characters (adds tool_ prefix if needed)
  • Removes consecutive underscores and trims boundaries

Configurable via GABS config:

{
  "toolNormalization": {
    "enableOpenAINormalization": true,
    "maxToolNameLength": 64,
    "preserveOriginalName": true
  }
}

Original Name Preservation:

  • Stores original MCP names in tool metadata (_meta.originalName)
  • Appends original names to descriptions when enabled
  • Allows clients to display meaningful names while using normalized names for API calls

Backward Compatibility:

  • Disabled by default - existing configurations continue working unchanged
  • New RegisterToolWithConfig() method supports normalization
  • Legacy RegisterTool() method preserved for compatibility

Example Transformations

Original MCP Name Normalized Name OpenAI Valid
games.list games_list
minecraft.inventory.get minecraft_inventory_get
rimworld.crafting.build_advanced_component rimworld_crafting_build_advanced_component
very.long.tool.name.that.exceeds.limit very_long_tool_name_that_exceeds

Implementation Details

  • Core normalization logic in internal/util/tool_normalization.go
  • Configuration structure extended in internal/config/games.go
  • MCP server integration updated in internal/mcp/stdio_server.go
  • Game-specific tools handled in internal/mirror/mirror.go
  • Comprehensive test coverage with 67 tests covering all scenarios
  • Debug logging shows transformations: normalized tool name for OpenAI compatibility original=games.list normalized=games_list

Usage

Enable in your GABS configuration:

{
  "version": "1.0",
  "toolNormalization": {
    "enableOpenAINormalization": true
  },
  "games": {
    // ... your games
  }
}

The codex CLI (and other OpenAI-compatible clients) will now receive tool names like games_list and minecraft_inventory_get that pass OpenAI's validation, while the original dotted names are preserved in metadata for display purposes.

Fixes the core issue where MCP tools were unusable with OpenAI API due to naming restrictions.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…e configuration and testing

Co-authored-by: pardeike <853584+pardeike@users.noreply.github.com>
Copilot AI changed the title [WIP] The codex CLI registers every MCP tool directly as an OpenAI tool. The dotted MCP name fails the API validator, and the request is rejected. The model choice is irrelevant; validation happens before sampling. Fix: normalize names before they reach Open... Add OpenAI-compatible tool name normalization for MCP tools Sep 14, 2025
Copilot AI requested a review from pardeike September 14, 2025 13:54
@pardeike pardeike marked this pull request as ready for review September 14, 2025 14:02
@pardeike pardeike merged commit 028ef48 into main Sep 14, 2025
3 checks passed
@pardeike pardeike deleted the copilot/fix-50620edf-e7b5-43f4-8435-d50cb6bbefa3 branch September 14, 2025 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants