From 7030c8bdb0eb360623069164ec91d3e0aadf11f5 Mon Sep 17 00:00:00 2001 From: Dhravya Shah Date: Thu, 19 Feb 2026 20:12:19 -0800 Subject: [PATCH 1/2] fix: effective tag --- apps/mcp/src/server.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/mcp/src/server.ts b/apps/mcp/src/server.ts index 6baa9d2c0..e15ef9843 100644 --- a/apps/mcp/src/server.ts +++ b/apps/mcp/src/server.ts @@ -384,9 +384,10 @@ export class SupermemoryMCP extends McpAgent { containerTag?: string }) { const { content, action = "save", containerTag } = args + const effectiveContainerTag = containerTag || this.props?.containerTag try { - const client = this.getClient(containerTag) + const client = this.getClient(effectiveContainerTag) const clientInfo = await this.getClientInfo() if (action === "forget") { From c82dcdc30a69b34c97e68b7bbfeca1f1076ca00d Mon Sep 17 00:00:00 2001 From: Prasanna721 <106952318+Prasanna721@users.noreply.github.com> Date: Fri, 20 Feb 2026 04:34:57 +0000 Subject: [PATCH 2/2] fix(mcp): hide containerTag from tool schemas when x-sm-project header is set (#749) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### fix(mcp): prevent LLM from overriding x-sm-project container tag - When `x-sm-project` header is configured, the `containerTag` field is now excluded from memory/recall/context tool schemas - This prevents LLMs from overriding the configured project by picking a different containerTag from the available projects list - When no header is set, behavior is unchanged — containerTag remains visible in schemas for manual project selection via listProjects --- apps/mcp/src/server.ts | 48 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/apps/mcp/src/server.ts b/apps/mcp/src/server.ts index e15ef9843..b188b2c34 100644 --- a/apps/mcp/src/server.ts +++ b/apps/mcp/src/server.ts @@ -50,47 +50,52 @@ export class SupermemoryMCP extends McpAgent { } } - await this.refreshContainerTags() // Fetch available projects for schema descriptions + await this.refreshContainerTags() - const containerTagDescription = this.getContainerTagDescription() + const hasRootContainerTag = !!this.props?.containerTag - const memorySchema = z.object({ - content: z - .string() - .max(200000, "Content exceeds maximum length of 200,000 characters") - .describe("The memory content to save or forget"), - action: z.enum(["save", "forget"]).optional().default("save"), + const containerTagField = { containerTag: z .string() .max(128, "Container tag exceeds maximum length") - .describe(containerTagDescription) + .describe(this.getContainerTagDescription()) .optional(), + } + + const memorySchema = z.object({ + content: z + .string() + .max( + 200000, + "Content exceeds maximum length of 200,000 characters", + ) + .describe("The memory content to save or forget"), + action: z + .enum(["save", "forget"]) + .optional() + .default("save"), + ...(hasRootContainerTag ? {} : containerTagField), }) const recallSchema = z.object({ query: z .string() - .max(1000, "Query exceeds maximum length of 1,000 characters") + .max( + 1000, + "Query exceeds maximum length of 1,000 characters", + ) .describe("The search query to find relevant memories"), includeProfile: z.boolean().optional().default(true), - containerTag: z - .string() - .max(128, "Container tag exceeds maximum length") - .describe(containerTagDescription) - .optional(), + ...(hasRootContainerTag ? {} : containerTagField), }) const contextPromptSchema = z.object({ - containerTag: z - .string() - .max(128, "Container tag exceeds maximum length") - .describe(containerTagDescription) - .optional(), includeRecent: z .boolean() .optional() .default(true) .describe("Include recent activity in the profile"), + ...(hasRootContainerTag ? {} : containerTagField), }) type ContextPromptArgs = z.infer @@ -289,7 +294,8 @@ export class SupermemoryMCP extends McpAgent { // @ts-expect-error - zod type inference issue with MCP SDK async (args: ContextPromptArgs) => { try { - const { containerTag, includeRecent = true } = args + const { includeRecent = true } = args + const containerTag = (args as { containerTag?: string }).containerTag const client = this.getClient(containerTag) const profileResult = await client.getProfile()