fix(mcp): hide containerTag from tool schemas when x-sm-project header is set (#749)

### 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
This commit is contained in:
Prasanna721 2026-02-20 04:34:57 +00:00
parent 7030c8bdb0
commit c82dcdc30a

View file

@ -50,47 +50,52 @@ export class SupermemoryMCP extends McpAgent<Env, unknown, Props> {
}
}
await this.refreshContainerTags() // Fetch available projects for schema descriptions
await this.refreshContainerTags()
const containerTagDescription = this.getContainerTagDescription()
const hasRootContainerTag = !!this.props?.containerTag
const containerTagField = {
containerTag: z
.string()
.max(128, "Container tag exceeds maximum length")
.describe(this.getContainerTagDescription())
.optional(),
}
const memorySchema = z.object({
content: z
.string()
.max(200000, "Content exceeds maximum length of 200,000 characters")
.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"),
containerTag: z
.string()
.max(128, "Container tag exceeds maximum length")
.describe(containerTagDescription)
.optional(),
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<typeof contextPromptSchema>
@ -289,7 +294,8 @@ export class SupermemoryMCP extends McpAgent<Env, unknown, Props> {
// @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()