rohitg00/agentmemory · error · Error
Unknown tool: ${toolName}
Error message
Unknown tool: ${toolName} What it means
The standalone MCP server validates incoming tool calls against the IMPLEMENTED_TOOLS set before argument parsing. A tool name outside that set throws this error, distinguishing unimplemented/typo'd tool names from per-tool argument errors.
Source
Thrown at src/mcp/standalone.ts:120
interface Validated {
tool: string;
content?: string;
type?: string;
concepts?: string[];
files?: string[];
project?: string;
agentId?: string;
query?: string;
limit?: number;
format?: string;
tokenBudget?: number;
memoryIds?: string[];
reason?: string;
}
function validate(toolName: string, args: Record<string, unknown>): Validated {
if (!IMPLEMENTED_TOOLS.has(toolName)) {
throw new Error(`Unknown tool: ${toolName}`);
}
const v: Validated = { tool: toolName };
switch (toolName) {
case "memory_save": {
const content = args["content"];
if (typeof content !== "string" || !content.trim()) {
throw new Error("content is required");
}
v.content = content;
v.type = (args["type"] as string) || "fact";
v.concepts = normalizeList(args["concepts"]);
v.files = normalizeList(args["files"]);
// The tool schema exposes project (and now agentId); dropping them
// here silently broke project/agent scoping through the stdio
// package specifically.
if (typeof args["project"] === "string" && args["project"].trim()) {
v.project = args["project"].trim();
}View on GitHub (pinned to e04ba88819)
Solutions
- Check the exact tool name against the tools advertised by the server (list tools via the MCP client).
- Set AGENTMEMORY_TOOLS=all on the server if the tool exists but is hidden by the default subset.
- Upgrade the standalone server / plugin to matching versions.
- Fix typos in hand-written calls; use snake_case names like memory_save.
Example fix
// before
await callTool("memory_search_all", { query: "x" }); // unknown
// after
await callTool("memory_smart_search", { query: "x" }); Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = new Set(["memory_save", "memory_search", "memory_recall", "memory_smart_search", "memory_sessions", "memory_governance_delete", "memory_export", "memory_audit"]);
if (!KNOWN.has(toolName)) throw new Error(`refusing to call unknown tool: ${toolName}`); Type guard
function isKnownTool(name: string): name is KnownTool {
return KNOWN_TOOLS.includes(name as KnownTool);
} Try / catch
try {
return await callTool(toolName, args);
} catch (e) {
if (String(e.message).startsWith("Unknown tool:")) {
const tools = await listServerTools(); // resync client list
throw new Error(`${toolName} not available; server offers: ${tools.join(", ")}`);
}
throw e;
} Prevention
- Discover tools dynamically via the MCP list-tools endpoint instead of hardcoding names.
- Keep plugin and standalone server versions in lockstep.
- Set AGENTMEMORY_TOOLS=all if your workflow needs non-default tools.
When it happens
Trigger: An MCP client invoking a tool whose name is not in IMPLEMENTED_TOOLS — a typo (e.g. memory_serch), a tool from a newer/older plugin version than the running standalone server, or AGENTMEMORY_TOOLS visibility filtering excluding the tool the client believes exists.
Common situations: Plugin config listing tools the standalone build doesn't implement, stale cached tool lists in the MCP client after an upgrade, hand-written tool-call scripts with wrong names, default visible-tool subset (8 tools) hiding tools behind AGENTMEMORY_TOOLS=all.
Related errors
- mem::search: token_budget must be a positive integer
- content is required
- query is required
- memoryIds is required
- Invalid dateFrom: ${filter.dateFrom}
AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30).
Data as JSON: /api/errors/54e30e865f35dfd5.
Report an issue: GitHub.