Skip to content

fix(mcp): use POST /v4/memories + add test suite reproducing v3 bug#1040

Open
ZongrongLi wants to merge 3 commits into
supermemoryai:mainfrom
ZongrongLi:fix/mcp-memory-api-v4
Open

fix(mcp): use POST /v4/memories + add test suite reproducing v3 bug#1040
ZongrongLi wants to merge 3 commits into
supermemoryai:mainfrom
ZongrongLi:fix/mcp-memory-api-v4

Conversation

@ZongrongLi
Copy link
Copy Markdown

@ZongrongLi ZongrongLi commented Jun 3, 2026

Related Issue

Related to #792 (Claude Code plugin writes memories but recall/search returns empty — same write-path root cause for MCP users; issue #792 may also involve a separate read-path bug in the plugin)

Problem

The MCP createMemory() method calls the SDK’s client.memories.add(), which maps to POST /v3/documents. This endpoint routes through the document ingestion workflow (IngestContentWorkflow) that handles extraction, summarization, chunking, and embedding — designed for URLs, PDFs, images, and file uploads.

When plain text is sent through this pipeline:

  • The pipeline detects no real content to extract → status lands at "failed"
  • The document has 0 memory entries → invisible on the web UI and unsearchable

Real-world impact: 19/19 documents created by the MCP end up with status=failed. Users report "memories saved but search returns empty" (#792).

Original Design Decision

The original author used client.memories.add() because it was the only .add() method exposed by the SDK. However, the entire client.memories SDK class is misnamed — it operates on /v3/documents/* endpoints (list, update, delete, get documents). It is a document resource, not a memory resource.

The correct API for storing plain-text memories is POST /v4/memories, explicitly documented in apps/docs/memory-operations.mdx:

Create Memories: Memories are embedded and immediately searchable. This is useful for storing user preferences, traits, or any structured facts where you already know the exact memory content.
SDK support coming soon — use fetch or cURL for now.

(Source: apps/docs/memory-operations.mdx, lines 15-20)

Fix (2 commits)

Commit 1: Replace client.add() with direct fetch to POST /v4/memories

Before:

this.client.add({ content, containerTag, metadata })
→ POST /v3/documents
→ IngestContentWorkflow pipeline
→ status: "failed"

After:

fetch(POST /v4/memories, {
  containerTag, memories: [{ content, metadata: { sm_source: "mcp" } }]
})
→ Direct memory storage
→ Immediately active and searchable

Commit 2: Fix HTTP error dispatch

The !response.ok branch threw a raw Error without a .status property. The existing handleError() method dispatches status codes (401=reauth, 402=upgrade, 429=backoff, 500=retry) via "status" in error — without it every failure returned the same generic message.

Fix: Attach error.status = response.status before throwing.

Test Coverage (12 tests, all pass)

The test suite uses vitest to mock fetch() and verify every code path:

  • Endpoint validation: confirms POST /v4/memories, NOT /v3/documents
  • Payload format: verifies {containerTag, memories: [{content, metadata}]} shape
  • Response mapping: status, id fallback (memories[0] → documentId)
  • Auth header: Bearer token + Content-Type forwarded correctly
  • Error handling: 401/402/429/500/network → correct user-facing messages
  • Contract guard: v3 vs v4 payload shape differences

Run with:

cd apps/mcp && bun install && bun test

Verification

After the fix, 22/22 memories created via MCP are active and searchable (previously 19/19 failed). Verified on supermemory.ai web UI and through API search.

Files Changed

File Change
apps/mcp/src/client.ts +3 lines: attach .status to error object
apps/mcp/src/__tests__/supermemory-client.test.ts New: 12-test vitest suite
apps/mcp/vitest.config.ts New: vitest config
apps/mcp/package.json Add test script + vitest devDep
bun.lock Updated lockfile

…eation

The SDK's client.add() calls POST /v3/documents which uses the
document upload pipeline. This pipeline fails to process plain-text
memory content — all documents created this way end up with
status: 'failed' and 0 memory entries.

POST /v4/memories is the correct endpoint for plain-text memory
creation. Memories created via v4 are immediately searchable.

Before: 19/19 documents failed (0 memories)
After:  22/22 memories active and searchable
@graphite-app graphite-app Bot requested a review from Dhravya June 3, 2026 13:19
The MCP client's createMemory() previously threw a raw Error for non-ok HTTP
responses.  handleError() checks for a .status property to dispatch per-status
messages — without it every status came back as 'Failed to create memory: N'.

Fix: attach .status to the error object before throwing.

Test coverage (12 tests, all pass):
- Endpoint: POST /v4/memories vs POST /v3/documents (the bug)
- Payload format: {containerTag, memories: [{content, metadata}]}
- Response mapping: status, id, containerTag
- Auth header passthrough
- Error handling: 401 / 402 / 429 / 500 / network error
- Contract guard: v3 vs v4 payload shapes
@ZongrongLi ZongrongLi changed the title fix(mcp): use POST /v4/memories instead of client.add() for memory creation fix(mcp): use POST /v4/memories + add test suite reproducing v3 bug Jun 3, 2026
@socket-security
Copy link
Copy Markdown

socket-security Bot commented Jun 3, 2026

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

…critical RCE (GHSA-9qr9-h5gf-34mp)

Socket flagged next@16.0.3 as a Critical CVE (RCE in React flight protocol).
Aligning with apps/web (^16.0.11); both now dedupe to next@16.1.6.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ZongrongLi ZongrongLi force-pushed the fix/mcp-memory-api-v4 branch from c08668e to b1de8a0 Compare June 3, 2026 14:11
Copy link
Copy Markdown
Contributor

@ishaanxgupta ishaanxgupta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we either remove the unrelated apps/memory-graph-playground/package.json & bun.lock churn?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants