Skip to content

Commit db9ec6d

Browse files
authored
fix the mcp server naming issue (#967)
I was trying to add an mcp server with package name `awslabs.terraform-mcp-server@latest` which resulted in invalid server name (the `.` was left in). Switched the implementation to use the createRFC1123ValidName func instead + added unit tests. Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
1 parent 5659d41 commit db9ec6d

2 files changed

Lines changed: 21 additions & 49 deletions

File tree

ui/src/components/AddServerDialog.tsx

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Terminal, Globe, Loader2, PlusCircle, Trash2, Code, InfoIcon, AlertCirc
88
import type { RemoteMCPServer, MCPServer, ToolServerCreateRequest } from "@/types";
99
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
1010
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
11-
import { isResourceNameValid } from "@/lib/utils";
11+
import { createRFC1123ValidName, isResourceNameValid } from "@/lib/utils";
1212
import { NamespaceCombobox } from "@/components/NamespaceCombobox";
1313
import { Checkbox } from "./ui/checkbox";
1414

@@ -51,52 +51,6 @@ export function AddServerDialog({ open, onOpenChange, onAddServer, onError }: Ad
5151
const [timeout, setTimeout] = useState("5s");
5252
const [sseReadTimeout, setSseReadTimeout] = useState("300s");
5353
const [terminateOnClose, setTerminateOnClose] = useState(true);
54-
55-
56-
// Clean up package name for server name
57-
const cleanPackageName = (pkgName: string): string => {
58-
let cleaned = pkgName.trim().replace(/^@[\w-]+\//, "");
59-
60-
if (cleaned.startsWith("mcp-") && cleaned.length > 4) {
61-
cleaned = cleaned.substring(4);
62-
}
63-
64-
// Convert to lowercase
65-
cleaned = cleaned.toLowerCase();
66-
// Replace spaces and invalid characters with hyphens
67-
cleaned = cleaned.replace(/[^a-z0-9.-]/g, "-");
68-
// Replace multiple consecutive hyphens with a single hyphen
69-
cleaned = cleaned.replace(/-+/g, "-");
70-
// Remove hyphens at the beginning and end
71-
cleaned = cleaned.replace(/^-+|-+$/g, "");
72-
// If the string starts with a dot, prepend an 'a'
73-
if (cleaned.startsWith(".")) {
74-
cleaned = "a" + cleaned;
75-
}
76-
77-
// If the string ends with a dot, append an 'a'
78-
if (cleaned.endsWith(".")) {
79-
cleaned = cleaned + "a";
80-
}
81-
82-
// Ensure the name starts and ends with an alphanumeric character
83-
// If it doesn't start with alphanumeric, prepend 'server-'
84-
if (!/^[a-z0-9]/.test(cleaned)) {
85-
cleaned = "server-" + cleaned;
86-
}
87-
88-
// If it doesn't end with alphanumeric, append '-server'
89-
if (!/[a-z0-9]$/.test(cleaned)) {
90-
cleaned = cleaned + "-server";
91-
}
92-
93-
// If the string is empty (could happen after all the replacements), use a default name
94-
if (!cleaned) {
95-
cleaned = "tool-server";
96-
}
97-
98-
return cleaned;
99-
};
10054

10155
// Handle server name input changes
10256
const handleServerNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -114,7 +68,7 @@ export function AddServerDialog({ open, onOpenChange, onAddServer, onError }: Ad
11468
let generatedName = "";
11569

11670
if (activeTab === "command" && packageName.trim()) {
117-
generatedName = cleanPackageName(packageName.trim());
71+
generatedName = createRFC1123ValidName([packageName.trim()]);
11872
} else if (activeTab === "url" && url.trim()) {
11973
try {
12074
const urlObj = new URL(url.trim());

ui/src/lib/__tests__/utils.test.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, it, jest, beforeEach, afterEach, afterAll } from '@jest/globals';
2-
import { getBackendUrl, getRelativeTimeString, isResourceNameValid, messageUtils } from '../utils';
2+
import { createRFC1123ValidName, getBackendUrl, getRelativeTimeString, isResourceNameValid, messageUtils } from '../utils';
33

44
describe('URL Generation Utilities', () => {
55
const originalEnv = process.env;
@@ -90,3 +90,21 @@ describe('Resource Name Validation', () => {
9090
});
9191
});
9292
});
93+
94+
95+
describe('RFC 1123 Valid Name', () => {
96+
describe('createRFC1123ValidName', () => {
97+
it('should create a valid RFC 1123 subdomain name with a single part', () => {
98+
expect(createRFC1123ValidName(['awslabs.terraform-mcp-server-latest'])).toBe('awslabs-terraform-mcp-server-latest');
99+
});
100+
101+
it('should sanitize and join multiple parts', () => {
102+
expect(createRFC1123ValidName(['My Service', 'v1.0', 'prod@us-east-1']))
103+
.toBe('my-service-v1-0-prod-us-east-1');
104+
});
105+
106+
it('should return empty string when all parts are invalid or empty', () => {
107+
expect(createRFC1123ValidName(['***', '___', ''])).toBe('');
108+
});
109+
});
110+
});

0 commit comments

Comments
 (0)