{"record":{"id":"ae50b25d094b32b2","repo":"github/copilot-sdk","slug":"invalid-mcp-tool-name-name-tool-names-must-ma","errorCode":null,"errorMessage":"Invalid mcp tool name '<name>': tool names must match /^[a-zA-Z0-9_-]+$/ or be the wildcard '*'. (template: Invalid <kind> tool name '<name>': tool names must match /^[a-zA-Z0-9_-]+$/ or be the wildcard '*'.)","messagePattern":"Invalid mcp tool name '<name>': tool names must match /\\^\\[a-zA-Z0-9_-\\]\\+\\$/ or be the wildcard '\\*'\\. \\(template: Invalid <kind> tool name '<name>': tool names must match /\\^\\[a-zA-Z0-9_-\\]\\+\\$/ or be the wildcard '\\*'\\.\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/rpc/ToolSet.java","lineNumber":118,"sourceCode":"     * @return this {@code ToolSet} for chaining\n     * @throws IllegalArgumentException\n     *             if toolName is null, empty, or contains invalid characters\n     */\n    public ToolSet addMcp(String toolName) {\n        validateName(\"mcp\", toolName);\n        add(\"mcp:\" + toolName);\n        return this;\n    }\n\n    private static void validateName(String kind, String name) {\n        if (name == null || name.isEmpty()) {\n            throw new IllegalArgumentException(\"Invalid \" + kind + \" tool name: must not be null or empty.\");\n        }\n        if (\"*\".equals(name)) {\n            return;\n        }\n        if (!VALID_TOOL_NAME.matcher(name).matches()) {\n            throw new IllegalArgumentException(\"Invalid \" + kind + \" tool name '\" + name\n                    + \"': tool names must match /^[a-zA-Z0-9_-]+$/ or be the wildcard '*'.\");\n        }\n    }\n}\n","sourceCodeStart":100,"sourceCodeEnd":123,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/rpc/ToolSet.java#L100-L123","documentation":"ToolSet names must match /^[a-zA-Z0-9_-]+$/ or be the wildcard \"*\". validateName throws this IllegalArgumentException when a name is non-empty but contains illegal characters (e.g. dots, colons, spaces, slashes), because such names cannot be matched against tool identifiers.","triggerScenarios":"Calling toolSet.addMcp(\"my.server.tool\"), addBuiltIn(\"search docs\"), addCustom(\"fs/read\"), or any name with characters outside [a-zA-Z0-9_-]. Passing a prefixed identifier like \"mcp:foo\" instead of the bare name \"foo\".","commonSituations":"Passing MCP server identifiers with dots/colons (FQDNs, URIs) instead of the registered tool name; including namespace prefixes like 'server:tool'; names with spaces copied from documentation; accidentally passing the wildcard with surrounding whitespace.","solutions":["Sanitize the name to allowed characters (letters, digits, underscore, hyphen) before adding.","Strip prefixes/qualifiers so only the bare tool name is passed (e.g. 'myserver_mytool' rather than 'my.server/mytool').","Use the exact string \"*\" (no whitespace) when you intend to allow all tools.","Validate names against /^[a-zA-Z0-9_-]+$/ in your config-loading code and fail with a clear message."],"exampleFix":"// before\nset.addMcp(\"github.com/tools/search\"); // illegal characters\n\n// after\nset.addMcp(\"github-com-tools-search\"); // sanitized, matches /^[a-zA-Z0-9_-]+$/","handlingStrategy":"validation","validationCode":"static final Pattern OK = Pattern.compile(\"^[a-zA-Z0-9_-]+$\");\nif (name == null || (!name.equals(\"*\") && !OK.matcher(name).matches()))\n  throw new IllegalArgumentException(\"illegal tool name: \" + name);","typeGuard":"static boolean isAllowedToolName(String n) {\n  return \"*\".equals(n) || (n != null && n.matches(\"^[a-zA-Z0-9_-]+$\"));\n}","tryCatchPattern":"try { set.addMcp(rawName); } catch (IllegalArgumentException e) {\n  set.addMcp(rawName.replaceAll(\"[^a-zA-Z0-9_-]\", \"-\")); // sanitized retry\n}","preventionTips":["Sanitize names (replace dots/colons/slashes with hyphens) at config-load time.","Never pass prefixed identifiers like 'server:tool' or 'a.b.c' into add* methods.","Use the exact wildcard \"*\" without whitespace when allowing all tools."],"tags":["java","validation","toolset","naming"],"backgroundTag":"invalid-identifier-format","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}