| name | mem0-mcp-modernization |
| description | Modernize and maintain the pinkpixel-dev/mem0-mcp server against Mem0 Platform API V3. Use when changing Mem0 API calls, SDK usage, MCP tool schemas, cloud/local capability behavior, tests, or documentation. |
| metadata | {"owner":"pinkpixel-dev","repository":"https://github.com/pinkpixel-dev/mem0-mcp","last_verified":"2026-06-24T00:00:00.000Z","source_of_truth":"https://docs.mem0.ai/api-reference"} |
Mem0 MCP Modernization Skill
Purpose
Maintain pinkpixel-dev/mem0-mcp as a reliable MCP interface for Mem0 while supporting its existing Cloud, Supabase, and local/in-memory modes. Prefer a stable, ergonomic MCP layer over exposing every Mem0 REST endpoint blindly.
This skill is specifically about Mem0 Platform API V3 migration and feature design. Treat older V1/V2 assumptions as potentially stale until verified against the current Mem0 docs and installed SDK types.
Non-negotiable rules
- Do not silently send old V2 request shapes to V3 endpoints.
- Do not pretend all Cloud capabilities exist in Supabase or local mode. Capability-report and fail clearly instead.
- Do not expose destructive bulk actions without an explicit confirmation field.
- Do not make callers manually poll async events by default. Provide a good default polling experience with an opt-out.
- Do not remove existing convenient MCP inputs without a compatibility path or a major-version migration note.
- Use the current official docs and installed
mem0ai package types as final authority when implementation details disagree.
Current Mem0 Platform API facts
Authentication
All hosted REST calls use token authentication:
Authorization: Token <MEM0_API_KEY>
Accept: application/json
Content-Type: application/json
Keep API keys server-side only. Never expose them in browser code, logs, test fixtures, screenshots, or generated docs.
V3 add-memory behavior is asynchronous and ADD-only
Endpoint:
POST https://api.mem0.ai/v3/memories/add/
Minimal request:
{
"messages": [
{ "role": "user", "content": "I moved to Manchester last month." }
],
"user_id": "user-123"
}
Important behavior:
- Requires
messages.
- Requires at least one entity scope:
user_id, agent_id, app_id, or run_id.
- Supports
metadata, custom_instructions, and infer.
infer: false stores messages verbatim instead of invoking memory extraction.
- Returns an async event response, usually
PENDING plus event_id.
- V3 extraction is single-pass ADD-only. It does not automatically update or delete old memories. Memories can accumulate and require deliberate maintenance.
Typical response:
{
"message": "Memory processing has been queued for background execution",
"status": "PENDING",
"event_id": "evt-uuid"
}
Event polling endpoint:
GET /v1/event/{event_id}/
Terminal statuses are expected to include SUCCEEDED and FAILED.
V3 search behavior
Endpoint:
POST https://api.mem0.ai/v3/memories/search/
Minimal request:
{
"query": "Where does the user live?",
"filters": {
"user_id": "user-123"
},
"top_k": 10
}
Important behavior:
- Search is hybrid: semantic retrieval, BM25 keyword retrieval, and entity matching.
- Entity IDs must be nested inside
filters for V3 search.
- Do not send
user_id, agent_id, app_id, or run_id as top-level search fields; V3 rejects that shape.
- At least one entity ID is required in
filters.
top_k: 1โ1000, default 10.
threshold: default 0.1; pass 0.0 to disable threshold filtering.
rerank: default false; enabling it may improve ordering but adds latency.
reference_date supports Unix epoch, YYYY-MM-DD, or ISO datetime for relative-time interpretation.
- Supported logical/comparison filtering includes
AND, OR, NOT, in, gte, lte, gt, lt, contains, icontains, ne, and wildcard *.
Example complex filter:
{
"AND": [
{ "user_id": "user-123" },
{ "categories": { "in": ["preferences"] } },
{ "run_id": "*" }
]
}
Recommended MCP tool surface
Core tools: include in the next modernization release
add_memory
search_memories
list_memories
get_memory
update_memory
delete_memory
get_memory_history
get_memory_capabilities
Quality / observability tools: add once async behavior is implemented
get_memory_event
list_memory_events
Advanced cloud tools: add only after the core tools are solid
batch_update_memories
batch_delete_memories
rate_memory
create_memory_export
get_memory_export
list_memory_users
Defer unless there is an HTTP/hosted companion service or dashboard
create_webhook
list_webhooks
update_webhook
delete_webhook
get_project_settings
update_project_settings
Webhooks and project administration are legitimate Mem0 features, but they are not core value for a local stdio MCP server.
Tool contracts and compatibility guidance
add_memory
Preferred MCP schema:
interface AddMemoryInput {
content?: string;
messages?: Array<{ role: string; content: string }>;
userId?: string;
agentId?: string;
appId?: string;
runId?: string;
metadata?: Record<string, unknown>;
infer?: boolean;
customInstructions?: string;
waitForCompletion?: boolean;
timeoutMs?: number;
}
Validation and behavior:
- Require either
content or messages; reject calls that provide neither.
- Normalize camelCase MCP names to Mem0 snake_case API fields.
- Require at least one scope ID after normalization.
- If both
content and messages are supplied, prefer messages and either warn or reject to avoid ambiguity.
- Default
waitForCompletion to true.
- When waiting: poll the event until terminal status or timeout.
- When timing out: return a structured
PENDING result with eventId, elapsedMs, and a clear message to call get_memory_event.
- Never fake a completed memory result before the event succeeds.
Suggested result shape:
interface AddMemoryResult {
status: 'SUCCEEDED' | 'PENDING' | 'FAILED';
eventId: string;
memories?: Array<unknown>;
error?: { message: string; code?: string };
elapsedMs?: number;
}
search_memories
Preferred MCP schema:
interface SearchMemoriesInput {
query: string;
userId?: string;
agentId?: string;
appId?: string;
runId?: string;
filters?: Record<string, unknown>;
topK?: number;
threshold?: number;
rerank?: boolean;
referenceDate?: string | number;
}
Normalization rule:
const scopeFilters = {
...(userId ? { user_id: userId } : {}),
...(agentId ? { agent_id: agentId } : {}),
...(appId ? { app_id: appId } : {}),
...(runId ? { run_id: runId } : {}),
};
const finalFilters = mergeFiltersSafely(scopeFilters, filters);
Rules:
- Ensure at least one scope entity exists in the final V3
filters tree.
- Do not accidentally overwrite a user-supplied logical filter when appending scope filters.
- If a caller supplies both
userId and filters.user_id with different values, reject with a clear validation error.
- Preserve advanced
AND/OR/NOT filters rather than flattening them.
- Return compact results by default; avoid stuffing huge metadata blobs into model context unless requested.
list_memories
Recommended schema:
interface ListMemoriesInput {
userId?: string;
agentId?: string;
appId?: string;
runId?: string;
filters?: Record<string, unknown>;
page?: number;
pageSize?: number;
}
Guidance:
- Default
pageSize to 25 or 50.
- Cap
pageSize to the official API limits after verifying them.
- Return pagination metadata (
count, next, previous, page, pageSize) where available.
- This tool is essential for inspection and cleanup now that V3 adds rather than auto-merges memories.
get_memory, update_memory, and get_memory_history
Use these as a safe maintenance trio:
get_memory(memoryId) before changes.
update_memory({ memoryId, text?, metadata? }) for deliberate edits.
get_memory_history(memoryId) for audit/debugging.
Do not claim that V3 add automatically resolves duplicates or stale facts. Update/delete is now a first-class management workflow.
delete_memory and bulk delete
- Single delete may be a normal core tool.
- Bulk delete must require
confirm: true.
- For bulk delete, return an explicit preview/count when feasible.
- Never accept broad unscoped destructive actions such as "delete everything" without a strong confirmation and clear scope.
Recommended bulk schema:
interface BatchDeleteMemoriesInput {
memoryIds: string[];
confirm: true;
}
get_memory_event and list_memory_events
These are support tools for V3 async operations.
get_memory_event should accept one eventId.
list_memory_events should support pagination.
- Surface failures cleanly, including event status and provider error details when safe to show.
get_memory_capabilities
Implement this even if it is server-generated rather than backed by a direct Mem0 endpoint.
Example:
{
"mode": "cloud",
"apiVersion": "v3",
"supportsAsyncEvents": true,
"supportsListMemories": true,
"supportsHistory": true,
"supportsBatchOperations": true,
"supportsExports": true,
"supportsWebhooks": true,
"supportsAdvancedFilters": true,
"supportsTemporalSearch": true
}
For Supabase/local, report only what is truly implemented. Use booleans or a string such as "server-implemented" only when the distinction helps users understand behavior.
Mode-aware architecture
The server supports multiple backends. Keep the MCP API stable where possible, but surface capability differences honestly.
| Feature | Mem0 Cloud V3 | Supabase mode | Local/in-memory mode |
|---|
| Async event IDs | Expected | Not guaranteed | No |
| Hybrid V3 search | Expected | Not guaranteed | No |
| Advanced logical filters | Expected | Backend-dependent | Usually no |
| Memory history | Cloud API | Implement only if available | Optional server implementation |
| Batch operations | Cloud API | Backend-dependent | Optional server implementation |
| Exports/webhooks/project settings | Cloud API | No | No |
Implementation pattern:
interface MemoryBackend {
readonly mode: 'cloud' | 'supabase' | 'local';
getCapabilities(): Promise<MemoryCapabilities>;
add(input: NormalizedAddInput): Promise<AddResult>;
search(input: NormalizedSearchInput): Promise<SearchResult>;
list?(input: ListInput): Promise<ListResult>;
get?(memoryId: string): Promise<MemoryRecord>;
update?(input: UpdateInput): Promise<MemoryRecord>;
delete?(memoryId: string): Promise<void>;
}
Avoid scattering if (mode === ...) checks across every MCP tool handler. Put provider-specific behavior behind backend adapters.
Recommended implementation sequence
Phase 1 โ get Cloud V3 correct
- Upgrade
mem0ai to the current compatible release.
- Read installed SDK type definitions and compare them with official REST docs.
- Implement V3
add_memory normalization and event polling.
- Implement V3
search_memories filter normalization.
- Add integration tests for raw REST payload shapes.
Phase 2 โ make memory maintenance usable
- Add
list_memories.
- Add
get_memory.
- Add
update_memory.
- Add
get_memory_history.
- Add clear documentation explaining V3 ADD-only semantics.
Phase 3 โ observability and advanced features
- Add event inspection.
- Add batch update/delete with confirmation.
- Add feedback and exports only after confirming SDK/API support.
- Add webhooks/project administration only if a hosted or HTTP-facing use case exists.
Test checklist
Add flow
Search flow
Maintenance flow
Multi-mode flow
Error-handling conventions
Use structured, actionable errors. Avoid vague messages like request failed.
Good:
{
"error": {
"code": "MEM0_SCOPE_REQUIRED",
"message": "Mem0 V3 search requires at least one entity scope. Provide userId, agentId, appId, runId, or an equivalent entity filter.",
"hint": "For example: { userId: 'user-123' }"
}
}
Good:
{
"error": {
"code": "FEATURE_UNAVAILABLE",
"message": "get_memory_history is only available in the configured Mem0 Cloud backend.",
"backend": "local"
}
}
Never include raw Authorization headers, API keys, or entire upstream error dumps in normal MCP responses.
Documentation updates to make with the release
Update the README and changelog to state:
- Cloud mode uses the Mem0 Platform V3 pipeline.
- Memory addition is asynchronous and the MCP server can wait/poll by default.
- V3 memory extraction is ADD-only; stale/conflicting memories should be maintained using get/update/delete/history tools.
- Search scope IDs are normalized into V3
filters.
- Cloud-only features are capability-gated.
- Official install source is the repository and published package only; users should verify package/repo identity before installing.
Source links โ verify before implementing
Use these official pages first when working on this codebase:
When adding a feature that is not covered above, locate the exact current API reference page from the docs index before coding. Do not infer endpoint paths or request shapes from old examples, blog posts, GitHub issues, or stale SDK snippets.