Summary
In @agentmemory/mcp v0.9.17 the standalone proxy makes full memory content unreachable through MCP. Three related defects in src/mcp/standalone.ts:
memory_recall and memory_smart_search are aliased to the same endpoint. Both hit /agentmemory/smart-search, which is compact-by-design (returns {obsId, sessionId, title, type, score, timestamp} only). memory_recall should hit /agentmemory/search, which honors the format parameter.
- The
format parameter is advertised but silently dropped. src/mcp/tools-registry.ts:27-30 declares memory_recall accepts format: full | compact | narrative defaulting to full. The validator in src/mcp/standalone.ts only extracts query and limit - format never reaches the daemon.
smart-search's expandIds parameter is unreachable via MCP. The validator doesn't extract it either, so the documented compact-then-expand pattern can only be used via direct REST.
Net effect: through MCP, callers only ever see titles + scores. The actual content IS in the database - calling /agentmemory/search directly with {"query":"...", "format":"full"} returns full observations including narrative, facts, rules, and concepts.
Reproduction
# Through MCP - compact only
{ "tool": "memory_recall", "arguments": { "query": "chatterbox", "format": "full" } }
# Returns: { mode: "compact", results: [{obsId, title, score, ...}] } - no content
# Through REST directly - full content
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"query":"chatterbox","limit":5,"format":"full"}' \
https://daemon/agentmemory/search
# Returns: { format: "full", results: [{observation: {title, concepts, facts: [full text], ...}}] }
Source locations
- Validator that drops
format: src/mcp/standalone.ts lines 113-120 (case memory_recall / memory_smart_search)
- Proxy handler that calls wrong endpoint:
src/mcp/standalone.ts lines 162-168
- Tool schema declaring
format: src/mcp/tools-registry.ts lines 13-50
- Working REST handler honoring
format: src/functions/search.ts line 178
Suggested fix
Split the two cases in both the validator and the proxy handler:
// validate()
case "memory_recall": {
const query = args["query"];
if (typeof query !== "string" || !query.trim()) throw new Error("query is required");
v.query = query.trim();
v.limit = parseLimit(args["limit"]);
v.format = (args["format"] as string) || "full";
v.tokenBudget = typeof args["token_budget"] === "number" ? args["token_budget"] : undefined;
return v;
}
case "memory_smart_search": {
// unchanged + add expandIds extraction
v.query = (args["query"] as string)?.trim();
v.limit = parseLimit(args["limit"]);
v.expandIds = normalizeList(args["expandIds"]);
return v;
}
// handleProxy()
case "memory_recall": {
const result = await handle.call("/agentmemory/search", {
method: "POST",
body: JSON.stringify({
query: v.query,
limit: v.limit,
format: v.format,
token_budget: v.tokenBudget,
}),
});
return textResponse(result, true);
}
case "memory_smart_search": {
const result = await handle.call("/agentmemory/smart-search", {
method: "POST",
body: JSON.stringify({ query: v.query, limit: v.limit, expandIds: v.expandIds }),
});
return textResponse(result, true);
}
The handleLocal() path should mirror the same split so the in-process fallback also returns content rather than just titles.
Workaround for users
Until this ships, hit the REST API directly. A small bash helper:
curl -sk -H "Authorization: Bearer $AGENTMEMORY_SECRET" -H "Content-Type: application/json" \
-d '{"query":"...","limit":5,"format":"full"}' \
"$AGENTMEMORY_URL/agentmemory/search"
This returns the full observation including facts[], narrative, concepts, etc. - which is what every caller of memory_recall actually wants.
Why this matters
The whole point of a memory system is to return the memories. Returning rankings without content forces every caller into a second tool call to retrieve bodies - except that second tool call doesn't exist in the MCP surface (expandIds is also dropped), so today the only working path is direct REST. That defeats MCP integration for every downstream agent.
Summary
In
@agentmemory/mcpv0.9.17 the standalone proxy makes full memory content unreachable through MCP. Three related defects insrc/mcp/standalone.ts:memory_recallandmemory_smart_searchare aliased to the same endpoint. Both hit/agentmemory/smart-search, which is compact-by-design (returns{obsId, sessionId, title, type, score, timestamp}only).memory_recallshould hit/agentmemory/search, which honors theformatparameter.formatparameter is advertised but silently dropped.src/mcp/tools-registry.ts:27-30declaresmemory_recallacceptsformat: full | compact | narrativedefaulting tofull. The validator insrc/mcp/standalone.tsonly extractsqueryandlimit-formatnever reaches the daemon.smart-search'sexpandIdsparameter is unreachable via MCP. The validator doesn't extract it either, so the documented compact-then-expand pattern can only be used via direct REST.Net effect: through MCP, callers only ever see titles + scores. The actual content IS in the database - calling
/agentmemory/searchdirectly with{"query":"...", "format":"full"}returns full observations including narrative, facts, rules, and concepts.Reproduction
Source locations
format:src/mcp/standalone.tslines 113-120 (casememory_recall/memory_smart_search)src/mcp/standalone.tslines 162-168format:src/mcp/tools-registry.tslines 13-50format:src/functions/search.tsline 178Suggested fix
Split the two cases in both the validator and the proxy handler:
The
handleLocal()path should mirror the same split so the in-process fallback also returns content rather than just titles.Workaround for users
Until this ships, hit the REST API directly. A small bash helper:
This returns the full observation including
facts[],narrative,concepts, etc. - which is what every caller ofmemory_recallactually wants.Why this matters
The whole point of a memory system is to return the memories. Returning rankings without content forces every caller into a second tool call to retrieve bodies - except that second tool call doesn't exist in the MCP surface (
expandIdsis also dropped), so today the only working path is direct REST. That defeats MCP integration for every downstream agent.