Skip to content

Commit dff7b99

Browse files
corvid-agentclaude
andcommitted
fix: align tool name validation with SEP-986 spec (v1.x backport)
Fixes #1502 Backport of #1505 to v1.x branch: - Allow forward slash (/) in tool names per SEP-986 - Reduce max length from 128 to 64 per SEP-986 - Add warning for names starting/ending with / - Update tests to match new validation rules Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent fe9c07b commit dff7b99

2 files changed

Lines changed: 23 additions & 19 deletions

File tree

src/shared/toolNameValidation.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
/**
22
* Tool name validation utilities according to SEP: Specify Format for Tool Names
33
*
4-
* Tool names SHOULD be between 1 and 128 characters in length (inclusive).
4+
* Tool names SHOULD be between 1 and 64 characters in length (inclusive).
55
* Tool names are case-sensitive.
66
* Allowed characters: uppercase and lowercase ASCII letters (A-Z, a-z), digits
7-
* (0-9), underscore (_), dash (-), and dot (.).
7+
* (0-9), underscore (_), dash (-), dot (.), and forward slash (/).
88
* Tool names SHOULD NOT contain spaces, commas, or other special characters.
99
*/
1010

1111
/**
1212
* Regular expression for valid tool names according to SEP-986 specification
1313
*/
14-
const TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
14+
const TOOL_NAME_REGEX = /^[A-Za-z0-9._/-]{1,64}$/;
1515

1616
/**
1717
* Validates a tool name according to the SEP specification
@@ -32,10 +32,10 @@ export function validateToolName(name: string): {
3232
};
3333
}
3434

35-
if (name.length > 128) {
35+
if (name.length > 64) {
3636
return {
3737
isValid: false,
38-
warnings: [`Tool name exceeds maximum length of 128 characters (current: ${name.length})`]
38+
warnings: [`Tool name exceeds maximum length of 64 characters (current: ${name.length})`]
3939
};
4040
}
4141

@@ -57,16 +57,20 @@ export function validateToolName(name: string): {
5757
warnings.push('Tool name starts or ends with a dot, which may cause parsing issues in some contexts');
5858
}
5959

60+
if (name.startsWith('/') || name.endsWith('/')) {
61+
warnings.push('Tool name starts or ends with a forward slash, which may cause parsing issues in some contexts');
62+
}
63+
6064
// Check for invalid characters
6165
if (!TOOL_NAME_REGEX.test(name)) {
6266
const invalidChars = name
6367
.split('')
64-
.filter(char => !/[A-Za-z0-9._-]/.test(char))
68+
.filter(char => !/[A-Za-z0-9._/-]/.test(char))
6569
.filter((char, index, arr) => arr.indexOf(char) === index); // Remove duplicates
6670

6771
warnings.push(
6872
`Tool name contains invalid characters: ${invalidChars.map(c => `"${c}"`).join(', ')}`,
69-
'Allowed characters are: A-Z, a-z, 0-9, underscore (_), dash (-), and dot (.)'
73+
'Allowed characters are: A-Z, a-z, 0-9, underscore (_), dash (-), dot (.), and forward slash (/)'
7074
);
7175

7276
return {

test/shared/toolNameValidation.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ afterEach(() => {
1515
describe('validateToolName', () => {
1616
describe('valid tool names', () => {
1717
test.each`
18-
description | toolName
19-
${'simple alphanumeric names'} | ${'getUser'}
20-
${'names with underscores'} | ${'get_user_profile'}
21-
${'names with dashes'} | ${'user-profile-update'}
22-
${'names with dots'} | ${'admin.tools.list'}
23-
${'mixed character names'} | ${'DATA_EXPORT_v2.1'}
24-
${'single character names'} | ${'a'}
25-
${'128 character names'} | ${'a'.repeat(128)}
18+
description | toolName
19+
${'simple alphanumeric names'} | ${'getUser'}
20+
${'names with underscores'} | ${'get_user_profile'}
21+
${'names with dashes'} | ${'user-profile-update'}
22+
${'names with dots'} | ${'admin.tools.list'}
23+
${'mixed character names'} | ${'DATA_EXPORT_v2.1'}
24+
${'single character names'} | ${'a'}
25+
${'64 character names'} | ${'a'.repeat(64)}
26+
${'names with forward slashes'} | ${'user/profile/update'}
2627
`('should accept $description', ({ toolName }) => {
2728
const result = validateToolName(toolName);
2829
expect(result.isValid).toBe(true);
@@ -34,10 +35,9 @@ describe('validateToolName', () => {
3435
test.each`
3536
description | toolName | expectedWarning
3637
${'empty names'} | ${''} | ${'Tool name cannot be empty'}
37-
${'names longer than 128 characters'} | ${'a'.repeat(129)} | ${'Tool name exceeds maximum length of 128 characters (current: 129)'}
38+
${'names longer than 64 characters'} | ${'a'.repeat(65)} | ${'Tool name exceeds maximum length of 64 characters (current: 65)'}
3839
${'names with spaces'} | ${'get user profile'} | ${'Tool name contains invalid characters: " "'}
3940
${'names with commas'} | ${'get,user,profile'} | ${'Tool name contains invalid characters: ","'}
40-
${'names with forward slashes'} | ${'user/profile/update'} | ${'Tool name contains invalid characters: "/"'}
4141
${'names with other special chars'} | ${'user@domain.com'} | ${'Tool name contains invalid characters: "@"'}
4242
${'names with multiple invalid chars'} | ${'user name@domain,com'} | ${'Tool name contains invalid characters: " ", "@", ","'}
4343
${'names with unicode characters'} | ${'user-ñame'} | ${'Tool name contains invalid characters: "ñ"'}
@@ -94,7 +94,7 @@ describe('validateAndWarnToolName', () => {
9494
${'completely valid names'} | ${'get-user-profile'} | ${true} | ${false}
9595
${'invalid names with spaces'} | ${'get user profile'} | ${false} | ${true}
9696
${'empty names'} | ${''} | ${false} | ${true}
97-
${'names exceeding length limit'} | ${'a'.repeat(129)} | ${false} | ${true}
97+
${'names exceeding length limit'} | ${'a'.repeat(65)} | ${false} | ${true}
9898
`('should handle $description', ({ toolName, expectedResult, shouldWarn }) => {
9999
const result = validateAndWarnToolName(toolName);
100100
expect(result).toBe(expectedResult);
@@ -118,7 +118,7 @@ describe('edge cases and robustness', () => {
118118
description | toolName | shouldBeValid | expectedWarning
119119
${'names with only dots'} | ${'...'} | ${true} | ${'Tool name starts or ends with a dot, which may cause parsing issues in some contexts'}
120120
${'names with only dashes'} | ${'---'} | ${true} | ${'Tool name starts or ends with a dash, which may cause parsing issues in some contexts'}
121-
${'names with only forward slashes'} | ${'///'} | ${false} | ${'Tool name contains invalid characters: "/"'}
121+
${'names with only forward slashes'} | ${'///'} | ${true} | ${'Tool name starts or ends with a forward slash, which may cause parsing issues in some contexts'}
122122
${'names with mixed valid/invalid chars'} | ${'user@name123'} | ${false} | ${'Tool name contains invalid characters: "@"'}
123123
`('should handle $description', ({ toolName, shouldBeValid, expectedWarning }) => {
124124
const result = validateToolName(toolName);

0 commit comments

Comments
 (0)