From 75916b0b9bc13634605a146c9440f87835eddf9a Mon Sep 17 00:00:00 2001 From: aiirvizionz Date: Tue, 28 Jul 2026 11:08:40 -0600 Subject: [PATCH] fix mcp names for ip hosts --- src/mcp.mjs | 9 ++++++++- test/mcp.test.mjs | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/mcp.mjs b/src/mcp.mjs index 254c38f..456e79d 100644 --- a/src/mcp.mjs +++ b/src/mcp.mjs @@ -2,6 +2,7 @@ // supports them, from one canonical definition. MoshCode drives each engine's // own `mcp add` so the engine owns its config format. See prd/0003. import { ENGINES, isInstalled, ranOk, runCmd } from "./engines.mjs"; +import { isIP } from "node:net"; // Coding engines that can register MCP servers. Aider has no MCP support. export const MCP_ENGINES = ["claude", "gemini", "codex", "opencode"]; @@ -19,7 +20,13 @@ const SUFFIX_LABELS = ["co", "com", "net", "org", "gov", "edu", "ac"]; export function deriveName(target) { const sanitize = (s) => String(s).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, ""); try { - const labels = new URL(target).hostname.split(".").filter(Boolean); + const hostname = new URL(target).hostname; + const ipHost = hostname.replace(/^\[|\]$/g, ""); + if (isIP(ipHost)) { + const ipName = ipHost.replace(/[.:]+/g, "-").replace(/^-+|-+$/g, ""); + return sanitize(`ip-${ipName}`); + } + const labels = hostname.split(".").filter(Boolean); let withoutTld = labels.slice(0, -1); // drop the TLD // ...and the generic label of a multi-part suffix, as long as a real name // still precedes it (a bare "co.uk" host has nothing better to offer). diff --git a/test/mcp.test.mjs b/test/mcp.test.mjs index f2451e8..3667a64 100644 --- a/test/mcp.test.mjs +++ b/test/mcp.test.mjs @@ -20,6 +20,11 @@ test("deriveName pulls a sane name from a remote host", () => { assert.equal(deriveName("not a url"), "server"); }); +test("deriveName keeps IP literal hosts recognizable", () => { + assert.equal(deriveName("http://127.0.0.1:3000/sse"), "ip-127-0-0-1"); + assert.equal(deriveName("http://[::1]:3000/sse"), "ip-1"); +}); + test("deriveName skips the generic label of a multi-part suffix", () => { assert.equal(deriveName("https://mcp.acme.co.uk/sse"), "acme"); assert.equal(deriveName("https://api.example.com.au/mcp"), "example");