pinkpixel-dev/mem0-mcp
critical✨ mem0 MCP Server: A memory system using mem0 for AI applications with model context protocl (MCP) integration. Enables long-term memory for AI agents as a drop-in MCP server.
This MCP server provides persistent memory capabilities for AI agents by integrating with Mem0.ai. It allows storing, searching, and deleting memories...
548headers: {
549 'Authorization': `Token ${process.env.MEM0_API_KEY}`,
550 'Content-Type': 'application/json'
551}// Network-exposed MCP server; API key could be intercepted over the network if HTTPS is not strictly enforced.
The server makes direct HTTP requests to the Mem0 API and includes the MEM0_API_KEY in the Authorization header. While this is necessary for the API call, the key is passed in plaintext and could be exposed if the request is intercepted or logged. Additionally, the key is stored in an environment variable and used without any encryption or masking.
ImpactAn attacker with access to the server's environment or network traffic could obtain the Mem0 API key, leading to unauthorized access to the memory storage and potential data breach.
FixUse the official SDK client which handles authentication securely. Avoid making raw HTTP requests with the API key. If direct API calls are necessary, ensure HTTPS is enforced and consider using a secrets manager.
544const response = await fetch(apiUrl, {
545 method: 'POST',
546 headers: {
547 'Authorization': `Token ${process.env.MEM0_API_KEY}`,
548 'Content-Type': 'application/json'
549 },
550 body: JSON.stringify(requestBody)
551});// Exploitable only if MCP is exposed to untrusted prompts or if error messages are logged externally.
The code directly uses process.env.MEM0_API_KEY in the Authorization header of fetch requests. While this is standard for API calls, the key is also exposed in error messages when the API call fails (line 555), which could leak the key in logs or error responses returned to the LLM.
ImpactIf an error occurs, the API key may be included in the error message returned to the LLM, potentially leaking it to an attacker who can control the LLM's prompts.
FixAvoid including the API key in error messages. Use a placeholder or sanitize the error text before returning it.
538const apiUrl = 'https://api.mem0.ai/v1/memories/';
539const requestBody = {
540 messages: messages,
541 ...options
542};// Network-exposed MCP server; SSRF risk is low due to hardcoded URL, but data exfiltration is possible if the endpoint is compromised.
The server makes HTTP requests to a hardcoded URL (api.mem0.ai). While the URL is not user-controlled, the request body includes user-provided data (messages, options) that could be manipulated. If the Mem0 API endpoint were to be compromised or if an attacker could perform DNS spoofing, they could receive sensitive data. Additionally, the server does not validate the response from the external API, which could lead to SSRF if the URL were ever made configurable.
ImpactAn attacker could potentially exploit SSRF if the URL becomes user-controlled, or could receive sensitive data if the external endpoint is compromised. Currently, the risk is limited due to the hardcoded URL.
FixEnsure the URL is not user-configurable. Validate and sanitize any data sent to external endpoints. Consider using the SDK which abstracts network calls.
480if (!content) {
481 throw new McpError(ErrorCode.InvalidParams, "Missing required argument: content");
482}// Network-exposed MCP server; exploitable by any user sending tool requests.
The add_memory and search_memory tools accept 'content' and 'query' strings without any length or content validation. An attacker could provide extremely large inputs, leading to resource exhaustion or denial of service. Additionally, no sanitization is performed on the input before passing it to the Mem0 API or local storage.
ImpactAn attacker could cause denial of service by sending very large memory entries or search queries, potentially exhausting memory or storage resources.
FixImplement input validation to limit the length of content and query strings. Add checks for reasonable size limits (e.g., 10KB for content, 1KB for query).
813private async handleDeleteMemory(args: Mem0DeleteToolArgs): Promise<any> {
814 const { memoryId, userId, agentId, appId, projectId, orgId } = args;
815 if (!memoryId) {
816 throw new McpError(ErrorCode.InvalidParams, "Missing required argument: memoryId");
817 }
818 const finalUserId = userId || process.env.DEFAULT_USER_ID;
819 if (!finalUserId) {
820 throw new McpError(ErrorCode.InvalidParams, "Missing required argument: userId (and no DEFAULT_USER_ID environment variable set)");
821 }
822 // ... deletion logic// Network-exposed MCP server; exploitable by any user with access to the tool.
The delete_memory tool accepts a memoryId and userId but does not verify that the memory belongs to the specified user. An attacker could delete memories belonging to other users by providing a valid memoryId and any userId. The tool also attempts to access private properties of the client (_vectorstore) to perform deletion, which is fragile and could lead to unexpected behavior.
ImpactAn attacker could delete arbitrary memories from the system, causing data loss for other users. This violates the intended purpose of per-user memory management.
FixImplement authorization checks to ensure the memoryId belongs to the provided userId. Use the official SDK methods for deletion instead of accessing private properties.
536if (finalAppId || sessionId) {
537 try {
538 const apiUrl = 'https://api.mem0.ai/v1/memories/';
539 const requestBody = {
540 messages: messages,
541 ...options
542 };
543
544 const response = await fetch(apiUrl, {
545 method: 'POST',
546 headers: {
547 'Authorization': `Token ${process.env.MEM0_API_KEY}`,
548 'Content-Type': 'application/json'
549 },
550 body: JSON.stringify(requestBody)
551 });
552
553 if (!response.ok) {
554 const errorText = await response.text();
555 throw new Error(`Direct API call failed: ${response.status} ${response.statusText} - ${errorText}`);
556 }
557
558 result = await response.json();
559 usedDirectAPI = true;
560 } catch (directError: any) {
561 // Fall through to SDK attempt
562 }
563}// Local-only MCP, requires compromised LLM to exploit.
The code makes direct HTTP requests to the Mem0 API instead of using the SDK, bypassing any input validation or rate limiting the SDK might provide. This could allow sending arbitrary parameters to the API, potentially exceeding the intended scope of the tool.
ImpactAn attacker could craft requests with unexpected parameters, potentially accessing or modifying data outside the intended scope.
FixUse the SDK exclusively and avoid direct API calls unless absolutely necessary. If direct calls are needed, validate all parameters against a whitelist.
813private async handleDeleteMemory(args: Mem0DeleteToolArgs): Promise<any> {
814 const { memoryId, userId, agentId, appId, projectId, orgId } = args;
815
816 if (!memoryId) {
817 throw new McpError(ErrorCode.InvalidParams, "Missing required argument: memoryId");
818 }
819
820 // Use DEFAULT_USER_ID as fallback if userId is not provided
821 const finalUserId = userId || process.env.DEFAULT_USER_ID;
822 if (!finalUserId) {
823 throw new McpError(ErrorCode.InvalidParams, "Missing required argument: userId (and no DEFAULT_USER_ID environment variable set)");
824 }// Local-only MCP, requires compromised LLM to exploit.
The delete_memory tool only checks that memoryId is not empty, but does not validate its format or content. An attacker could provide arbitrary strings, potentially leading to injection or unintended deletion if the underlying API or storage interprets the ID in a special way.
ImpactAn attacker could potentially delete memories by providing crafted memoryId values, though the actual impact depends on the backend implementation.
FixValidate that memoryId matches an expected format (e.g., alphanumeric, UUID) before passing it to the backend.
499const messages: Mem0Message[] = [{
500 role: "user",
501 content
502}];// Network-exposed MCP server; risk is indirect and depends on how memories are used by downstream LLMs.
The content provided by the user is directly included in the messages array sent to the Mem0 API. If the Mem0 API processes this content in a way that could be exploited (e.g., rendering in a dashboard), it could lead to prompt injection or stored XSS. However, since the Mem0 API is a memory storage service, the risk is primarily to the LLM that later retrieves these memories.
ImpactAn attacker could inject malicious prompts into stored memories that, when retrieved by another LLM, could cause that LLM to behave unexpectedly or leak information.
FixSanitize or escape user input before storing. Consider adding a note that memories may be retrieved by LLMs and should be treated as untrusted.