gethomepage/homepage · error · Error
Unknown tool '${name}'
Error message
Unknown tool '${name}' What it means
Thrown by the default branch of the switch in callTool() when the MCP tool dispatcher receives a name that does not match any of the registered tools (list_config_files, read_config_file, validate_config_file, write_config_file, add_service, add_info_widget, homepage_docs). Homepage's MCP server exposes a fixed tool list and rejects anything outside it, so this is an API contract violation by the MCP client, not a runtime failure of Homepage itself.
Source
Thrown at src/utils/mcp/homepage-mcp.js:439
JSON.stringify({ written: args.file, bytes: Buffer.byteLength(args.content, "utf8") }, null, 2),
);
}
case "add_service":
return addService(args);
case "add_info_widget":
return addInfoWidget(args);
case "homepage_docs": {
const topic = args.topic || "overview";
const links = {
overview: "https://gethomepage.dev/configs/",
troubleshooting: "https://gethomepage.dev/troubleshooting/",
widgets: "https://gethomepage.dev/widgets/",
...DOC_LINKS,
};
return textContent(JSON.stringify({ topic, url: links[topic] || links.overview }, null, 2));
}
default:
throw new Error(`Unknown tool '${name}'`);
}
}
export function mcpEnabled() {
return enabled();
}
export function mcpTokenConfigError() {
if (!enabled()) return null;
const token = requiredToken();
if (token && token.length < MIN_TOKEN_LENGTH) {
return `HOMEPAGE_MCP_TOKEN must be at least ${MIN_TOKEN_LENGTH} characters. Generate one with: openssl rand -base64 32`;
}
return null;
}
export function mcpTokenAuthorized(req) {
const token = requiredToken();View on GitHub (pinned to b6dca1ae03)
Solutions
- Call listTools / read the MCP server's tools/list response and verify the exact name; correct the client to use one of the registered tool names.
- If you expected a tool that no longer exists, check the Homepage changelog for a rename (e.g. an older 'add_widget' becoming 'add_info_widget').
- Ensure the client sends the tool name verbatim in lowercase with underscores, matching the name field returned by the server's tool schema.
- If you are extending Homepage, add a new case branch in callTool() (src/utils/mcp/homepage-mcp.js) and register the tool in getTools() so the name is both dispatched and advertised.
Example fix
// before
server.callTool('add_widget', { type: 'search' });
// after
server.callTool('add_info_widget', { type: 'search' }); Defensive patterns
Strategy: validation
Validate before calling
// Before dispatching, validate the name against the advertised tool list.
const allowed = new Set((await server.listTools()).map((t) => t.name));
if (!allowed.has(name)) {
return { isError: true, content: [{ type: "text", text: `Tool '${name}' not registered. Available: ${[...allowed].join(", ")}` }] };
}
return server.callTool(name, args); Type guard
// Narrow a tool name to the known Homepage tool union.
const HOMEPAGE_TOOLS = [
"list_config_files", "read_config_file", "validate_config_file",
"write_config_file", "add_service", "add_info_widget", "homepage_docs",
];
function isHomepageTool(name) {
return typeof name === "string" && HOMEPAGE_TOOLS.includes(name);
} Try / catch
try {
const result = await callTool(name, args);
res.json(result);
} catch (err) {
if (/^Unknown tool/.test(err.message)) {
res.status(400).json({ error: err.message, available: HOMEPAGE_TOOLS });
} else {
res.status(500).json({ error: err.message });
}
} Prevention
- Always drive tool selection from the live tools/list response, never from a hard-coded list in the client.
- Regenerate any cached tool catalog after upgrading Homepage.
- Write an integration test that asserts every tool your client calls appears in server.listTools().
When it happens
Trigger: An MCP client calls a tool name that is misspelled (e.g. 'add_widget' instead of 'add_info_widget'), uses a legacy/renamed tool name from an older Homepage version, sends a casing variant ('Homepage_Docs'), or calls a tool that exists in a different MCP server but not this one.
Common situations: Stale client cached against an older tool list after a Homepage upgrade that renamed/removed a tool; a client hard-coding tool names; LLM agent hallucinating a plausible-sounding tool name; copy/paste typos in a custom MCP client integration.
Related errors
- Unsupported config file '${file}'. Supported files: ${CONFIG
- ${name} must be an object
- group must be a non-empty string
- name must be a non-empty string
- services.yaml must contain a top-level array
AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13).
Data as JSON: /api/errors/89e73bec2a3fba18.
Report an issue: GitHub.