mcp-data-platform-v1.99.0
mcp-data-platform v1.99.0
This release makes the platform's context-heavy paths budget-aware. Cross-enrichment payloads, the duplicate-review listing, and the knowledge search embedding each previously ran on a hardcoded limit or a single shared timeout; each is now individually bounded and observable, so a mature deployment's per-response overhead stays predictable and never crowds out the data being analyzed.
Highlights
- Memory cross-enrichment is now byte-budgeted, summary-first, and observable (#761)
review_duplicatesreturns a bounded, summary-first listing that cannot overrun an MCP client's output budget (#783)- The knowledge search embedding gets its own timeout, separate from the per-provider fan-out bound (#795)
Features
Budget the memory-enrichment payload (#761)
Memory cross-enrichment previously attached up to a hardcoded 5 records per tool call with no size budget and no summary tier, so a mature deployment's per-query memory_context + semantic_context could run to thousands of tokens and crowd out the data being analyzed. The payload is now bounded on three axes:
enrichment.memory_limit(default5) replaces the hardcoded constant.enrichment.memory_summary_bytes(default280) renders each record summary-first — first paragraph or first N bytes on a rune boundary — with atruncatedflag and anmcp:memory:<id>reference the agent can fetch when the excerpt is not enough.enrichment.memory_context_budget_bytes(default1500) bounds the rendered summaries. Records beyond the budget are listed as compactid+reference stubs inmemory_context_omittedso they stay fetchable; at least one record is always rendered.- Near-duplicate records are collapsed at render time, keyed on full content so records sharing only a prefix are not silently dropped.
New metric — mcp_enrichment_bytes_total (labels: tool, toolkit_kind, persona): the total bytes of cross-enrichment content appended per response, so operators can measure the overhead:
rate(mcp_enrichment_bytes_total[5m]) / rate(mcp_tool_calls_total[5m])
The enrichment middleware records the appended byte count on PlatformContext.EnrichmentBytes; the metrics middleware (outer to enrichment) reads it after the handler unwinds.
Summary-first, byte-bounded review_duplicates listing (#783)
review_duplicates previously returned two full records per pair (each up to the 4,000-char content cap plus metadata), so its default 20-pair listing produced a ~75 KB result that overran MCP clients' output budget and forced a spill-to-file before the agent could read it.
The listing is now summary-first and byte-bounded: each pair returns ids, score, status, timestamps, owner, and a bounded content_preview (≤200 runes per side) instead of the full records. A response never exceeds the pair budget, so it cannot overrun the output budget regardless of content length. The agent reads a record in full with fetch mcp:memory:<id> or memory_manage list before consolidating.
It is deliberately not offset-paginated. The candidate set is score-ordered and shrinks from the top as pairs are consolidated, so positional offset paging over that moving set would silently skip pairs. The pagination is the review loop itself — consolidate the surfaced pairs and re-run, which always re-presents the current highest-similarity pairs. A more_pairs flag signals when the byte budget or the page limit hid lower-scored pairs.
Give the search embedding its own timeout (#795)
The intent-embedding step in Router.Search and the per-provider fan-out arms shared one knob (knowledge.search_provider_timeout), but they have different failure semantics: a slow fan-out arm should drop out fast so it does not hold up the others, whereas cutting the embedding short silently downgrades ranking from hybrid to lexical and loses semantic relevance. Sharing one timeout meant an operator could not give a slow (cold or CPU-only) embedder headroom without also loosening the fan-out bound that v1.98.2 tightened.
- New config
knowledge.search_embed_timeout(default5s, byte-for-byte with v1.98.2 behavior). Non-positive values follow the existing keep-default / disable semantics. - The
Routergains an independent embed timeout and context alongside the existing provider trio; an embedder slower than the fan-out bound but faster than the embed bound still yields hybrid ranking, while a genuinely slow provider still drops at the fan-out bound. - Internal refactor: the persona storage layer was extracted into a new
pkg/platform/personastorepackage (de-stuttered:PersonaStore→Store,PersonaDefinition→Definition), keepingpkg/platformunder its package-size budget. No behavior change.
New configuration
enrichment:
memory_limit: 5 # max memory records attached per response
memory_summary_bytes: 280 # per-record summary size (rune-bounded)
memory_context_budget_bytes: 1500 # total rendered-summary budget
knowledge:
search_embed_timeout: 5s # intent-embedding timeout, separate from fan-outAll new knobs default to the values shown, preserving prior behavior on upgrade — no config changes are required.
Upgrade notes
- No breaking changes. All new limits and timeouts default to the platform's prior effective behavior, so an existing deployment behaves identically until an operator tunes them.
- Operators can now chart cross-enrichment overhead with the new
mcp_enrichment_bytes_totalmetric.
Full changelog: v1.98.2...v1.99.0
Installation
Homebrew (macOS)
brew install txn2/tap/mcp-data-platformClaude Code CLI
claude mcp add mcp-data-platform -- mcp-data-platform