You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two commits: (1) Serialize MCP InitializeResult (issue #52 — bug, critical for strict MCP clients like Claude Code), and (2) Add batch memory support across the HTTP API, MCP add_memory tool, and CLI (issue #53). CI green.
crates/memayu-mcp/src/types.rs: derive/bump serde::Serialize (and keep Deserialize) on the MCP protocol types so the initialize response is emitted correctly:
(2) Batch memory support — commit 3ee6ec7 (issue #53)
Core:
crates/memayu-core/src/service.rs: new BatchMemory { content, metadata }, BatchItemResult::Stored/{ id } | Failed/{ error }, and MemoryService::add_memories_batch(user, &[BatchMemory]) -> Result<Vec<BatchItemResult>>. Ingestion loops each item through the existing add_memory (ADD/UPDATE + dedupe) pipeline; per-item failures are collected, only an empty batch raises CoreError::InvalidInput. New CoreError::InvalidInput(String) variant.
crates/memayu-api/src/transport/handlers/memory.rs: new POST /api/memories/batch → 400 on empty, else add_memories_batch + per-item result mapping into BatchMemoryError { index }. HTTP 200 even with per-item failures (graceful degradation).
Review of PR #59 at 3ee6ec7d591cf50aa65ee16f1bbcf2ab68257d29 (base main), spanning 2 commits: 92a6aad ("serialize MCP InitializeResult", #52) and 3ee6ec7 ("batch memory support", #53).
🔴 Blocking
None. CI green (cargo build, clippy, fmt, test, audit all pass).
🟡 Warning #1 — MCP batch duplicates core add_memories_batch rather than delegating
crates/memayu-mcp/src/tools/add_memory.rs batch path loops backend.add_memory(user_id, content) per item and rolls its own success/failure summary, while memayu-core::MemoryService::add_memories_batch already implements the same per-item ADD/UPDATE+dedupe pipeline with BatchItemResult. The MCP batch therefore does not go through the service batch (it uses its own per-call embedding/dedupe loop). Not a correctness bug (both paths are equivalent today), but it is duplicated logic that can drift — ideally the MCP layer calls add_memories_batch if/when its MemoryBackend gains a batch method. Low priority; flag for follow-up.
crates/memayu-mcp/src/types.rs: InitializeResult, ServerInfo, ServerCapabilities (and nested types) now #[derive(Serialize)] + #[serde(rename_all = "camelCase")]. protocol_version→protocolVersion, server_info→serverInfo, nested tools.listChanged all camelCase per MCP 2024-11-05 spec.
New #[cfg(test)] mod tests asserts the serialized JSON keys are camelCase including nested capabilities.tools.listChanged, and that server_info.name == "memayu-mcp" + version 0.1.0. Strict clients (Claude Code) that previously rejected the snake_case payload will now accept it.
BatchMemory { content, metadata } + BatchItemResult::Stored/{ memory_id } | Failed/{ error }, both re-exported from lib.rs.
MemoryService::add_memories_batch(user, &[BatchMemory]) -> Result<Vec<BatchItemResult>>: loops items through the existing add_memory (so ADD/UPDATE + dedupe still runs per item); per-item Err is caught into BatchItemResult::Failed, only an empty batch short-circuits with CoreError::InvalidInput("batch must contain at least one memory"). New CoreError::InvalidInput(String) variant.
Handler add_memories_batch → POST /api/memories/batch (registered in routes.rs): 400 on empty memories; per-item failure → BatchMemoryError { index } (zero-based request index); HTTP 200 even when some items fail (graceful degradation — caller inspects errors[]).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apiHTTP API transport/handlersbugSomething isn't workingcorememayu-core domain logicenhancementNew feature or requestmcpMCP server toolspriority-highHighest priority — must be done before next milestone
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two commits: (1)
Serialize MCP InitializeResult(issue #52 — bug, critical for strict MCP clients like Claude Code), and (2)Add batch memory supportacross the HTTP API, MCPadd_memorytool, and CLI (issue #53). CI green.Changes
(1) Serialize MCP
InitializeResult— commit92a6aad(issue #52)crates/memayu-mcp/src/types.rs: derive/bumpserde::Serialize(and keepDeserialize) on the MCP protocol types so theinitializeresponse is emitted correctly:InitializeResult→protocolVersion,serverInfo,capabilities(all#[serde(rename_all = "camelCase")]).ServerInfo { name, version },ServerCapabilities { instructions?, prompts?, resources?, tools?, auth? },ToolsCapability { listChanged }, etc. — serialized camelCase per the MCP 2024-11-05 spec.#[cfg(test)] mod tests(ser_deser+ camelCase assertions incl. nestedtools.listChanged) — verifies the serialized JSON usesprotocol_version→protocolVersion,listChanged(nested), andserver_info→serverInfo.(2) Batch memory support — commit
3ee6ec7(issue #53)Core:
crates/memayu-core/src/service.rs: newBatchMemory { content, metadata },BatchItemResult::Stored/{ id } | Failed/{ error }, andMemoryService::add_memories_batch(user, &[BatchMemory]) -> Result<Vec<BatchItemResult>>. Ingestion loops each item through the existingadd_memory(ADD/UPDATE + dedupe) pipeline; per-item failures are collected, only an empty batch raisesCoreError::InvalidInput. NewCoreError::InvalidInput(String)variant.crates/memayu-core/src/lib.rs: re-exportBatchMemory/BatchItemResult.HTTP API:
crates/memayu-api/src/modules/memory/dto.rs:AddMemoriesBatchRequest { memories: Vec<AddMemoryItem> },AddMemoryItem { content, metadata },BatchMemoryError { index, error },AddMemoriesBatchResponse { status, added, memory_ids, errors }.crates/memayu-api/src/transport/handlers/memory.rs: newPOST /api/memories/batch→ 400 on empty, elseadd_memories_batch+ per-item result mapping intoBatchMemoryError { index }. HTTP 200 even with per-item failures (graceful degradation).crates/memayu-api/src/transport/routes.rs: register/batch.MCP:
crates/memayu-mcp/src/tools/add_memory.rs:add_memorytool gains an optionalmemoriesarray input (items{ content, metadata }); per-item failures are summarized withitem {i}: <error>and successes collected. Single-contentpath unchanged (backward compatible).CLI:
bin/memayu/src/cli.rs: newmemayu add --batch/memayu batchstyle invocation accepting multiple memory payloads; per-item error summary to stderr.Tests
crates/memayu-api/tests/api.rs:add_memories_batch_stores_all(3 valid → added=3, errors []) andadd_memories_batch_reports_per_item_errors(3 with one empty-content → added=2, errors present, HTTP 200).bin/memayu/tests/cli.rs:add_batch_stores_all_items,add_batch_reports_partial_failures.crates/memayu-mcp/src/types.rs: ser/serde + camelCase test assertions.Migration / behavior
POST /api/memories/add(single) unchanged;/batchis new.add_memoryschema:memoriesarray is optional → existing single-contentcalls work unchanged.Checklist
Fixes #52 #53