Skip to content

MCP icm_memory_store ignores [memory] auto_consolidate_enabled/threshold — hardcoded threshold 10 caused data loss with consolidation explicitly disabled #318

Description

@jakobtfaber

Summary

The MCP server's icm_memory_store path auto-consolidates a topic when it exceeds 10 entries, unconditionally — it never reads [memory] auto_consolidate_enabled / auto_consolidate_threshold from config. The constant's own doc comment says "can be overridden by config", but no config read exists anywhere in the icm-mcp crate. Setting auto_consolidate_enabled = false in config.toml therefore does nothing for MCP-driven stores, while the CLI path honors it.

Observed on icm 0.10.57 (macOS, arm64); source refs below are main as of 2026-07-02 and match the observed behavior.

Source references

  • crates/icm-mcp/src/tools.rs:15-16/// Default threshold for auto-consolidation (can be overridden by config). const AUTO_CONSOLIDATE_THRESHOLD: usize = 10; — the "overridden by config" claim is not implemented.
  • crates/icm-mcp/src/tools.rs:1083 and :1091 — both branches (compact / non-compact) of the icm_memory_store handler call try_auto_consolidate(store, embedder, topic, AUTO_CONSOLIDATE_THRESHOLD) with the hardcoded const.
  • For contrast, the CLI path is properly gated: crates/icm-cli/src/config.rs:45-48 defines auto_consolidate_enabled / auto_consolidate_threshold, default enabled = false (config.rs:253), and crates/icm-cli/src/main.rs:2072 early-returns unless enabled.
  • Scope notes (so the fix is precisely targeted): explicit icm_memory_updatetool_update (tools.rs:1467) never consolidates, and the store handler's dedup-update branch (tools.rs:997) returns before the consolidation call — the trigger is MCP new-store only.

Impact (real data loss event)

With auto_consolidate_enabled = false in config, an MCP icm_memory_store that pushed a topic to 11 entries deleted the 10 existing memories in that topic and replaced them with a single lexically concatenated summary row (|-joined), including one segment that was extraction meta-noise. The verbatim originals were unrecoverable from the store (we happened to have an external backup). This is the same lexical-concatenation quality problem described in #186, but triggered automatically and against an explicit opt-out.

Suggested fix

Thread the loaded config into the MCP tool layer and gate try_auto_consolidate on auto_consolidate_enabled, using the configured threshold.

One migration caveat worth deciding deliberately: MemoryConfig::default() has auto_consolidate_enabled = false, so naively reusing the config default would silently flip MCP behavior from always-on to off-by-default for users with no config file. Either default the MCP path to enabled-with-threshold-10 when the key is absent (preserves current behavior), or treat the flip as an intentional breaking change and changelog it.

Suggested test coverage: MCP new-store at/over threshold with enabled=false (no consolidation), enabled=true custom threshold, dedup-update branch (never consolidates), explicit icm_memory_update (never consolidates).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions