Skip to content

Fix nonexistent container tag handling in MCP tools#1192

Open
ved015 wants to merge 3 commits into
graphite-base/1192from
fix/mcp-invalid-container-tag
Open

Fix nonexistent container tag handling in MCP tools#1192
ved015 wants to merge 3 commits into
graphite-base/1192from
fix/mcp-invalid-container-tag

Conversation

@ved015

@ved015 ved015 commented Jul 3, 2026

Copy link
Copy Markdown
Member

Summary

  • set-active-tag accepted any container tag string, even one that does not exist (e.g. eng_949_invalid_nonexistent_tag), and happily persisted it as the active workspace. It now validates the tag against the user's actual container tag list (cached list with a one-shot refresh for freshly created tags) and returns Container tag '<tag>' does not exist. Use listSpaces to see the available container tags.
  • search_memory with a nonexistent containerTag surfaced the generic Error: Access forbidden. from the API 403. It now performs the same existence check up front and returns the clear "does not exist" error instead.
  • As defense in depth, the client's 403 mapping now names the container tag and points at listSpaces instead of the bare "Access forbidden." message, in case a 403 still reaches it through another path.
image

@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @ishaanxgupta's task in 1m 24s —— View job


Reviewing PR #1192

  • Fetch PR diff and existing review comments
  • Analyze changed files for bugs, security issues, and logic errors
  • Check surrounding code context for boundary issues
  • Submit review findings

Overview: Adds upfront container tag existence validation to set-active-tag and search_memory tools, with improved error messaging for 403 responses.

Issues found: None — this looks good to ship.

The latest commit (276d354) addresses both issues from the previous vorflux review:

  1. effectiveTag validation fixed: search_memory now validates the resolved effectiveTag (lines 57-65), not just the raw args.containerTag. If a stored activeContainerTag references a deleted tag, the check will catch it before hitting the API.

  2. Refresh failure handling fixed: refreshContainerTags() now returns boolean, and validateContainerTag() returns a three-state enum ("exists" | "missing" | "unavailable"). Transient API failures return "unavailable" with a retry-friendly error message, while confirmed missing tags return "missing" with the specific "does not exist" error.

Additional observations:

  • RBAC checks correctly precede existence checks in both tools, preventing information leakage about valid container tags
  • The improved 403 message in client/index.ts provides helpful context as defense-in-depth
  • Widget error handling properly surfaces both structured and text-only error results

Score: 10/10


@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 3, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
supermemory-mcp 99501d3 Jul 04 2026, 02:47 PM

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overview: Adds upfront container tag existence validation to set-active-tag and search_memory tools, with improved error messaging for 403 responses.

Issues found: None — this looks good to ship.

The implementation is well-structured:

  • RBAC checks correctly precede existence checks in both tools, preventing information leakage about valid container tags
  • The containerTagExists helper uses a sensible cache-first strategy with one-shot refresh to handle freshly-created tags
  • Error handling is consistent: search-memory.ts relies on its outer try-catch while set-active-tag.ts wraps the async check appropriately
  • The improved 403 message in the client provides helpful context as defense-in-depth

Score: 10/10

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 3, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
supermemory-app 99501d3 Commit Preview URL

Branch Preview URL
Jul 04 2026, 02:49 PM

…rch_memory

set-active-tag accepted any tag string even if it did not exist, and
search_memory surfaced a generic "Access forbidden" 403 for unknown tags.
Both tools now validate the tag against the user's container tag list and
return a clear "does not exist" error pointing at listSpaces.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ved015 ved015 force-pushed the fix/mcp-invalid-container-tag branch from 500a4b5 to df671c6 Compare July 3, 2026 15:15
@ved015 ved015 mentioned this pull request Jul 3, 2026

ved015 commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label Main to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@vorflux vorflux Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Summary

Reviewed — found 2 issue(s). I reviewed the MCP container-tag validation changes across apps/mcp/src/server/client/index.ts, apps/mcp/src/server/tools/search-memory.ts, apps/mcp/src/server/tools/set-active-tag.ts, and the new apps/mcp/src/server/tools/validate-container-tag.ts for correctness, missing error handling, and regressions.

Findings

apps/mcp/src/server/tools/search-memory.ts

  1. search_memory validates only an explicit args.containerTag, but the tool searches with effectiveTag after resolveContainerTag(), so an invalid stored active tag can still reach the API.

apps/mcp/src/server/tools/validate-container-tag.ts

  1. containerTagExists() converts refresh failures into a nonexistent-tag result because refreshContainerTags() can swallow failures and leave the old cache unchanged.

Verdict

⚠️ Changes requested. The new validation path still misses invalid resolved tags and can reject valid tags during transient refresh failures.


Review with Vorflux

}
if (
args.containerTag &&
!(await containerTagExists(deps, args.containerTag))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This validates only an explicit args.containerTag, but the request below uses effectiveTag after deps.resolveContainerTag(args.containerTag). If activeContainerTag already contains a deleted/nonexistent tag, calling search_memory without containerTag skips this check and still constructs the client with the invalid resolved tag. Please validate the resolved effectiveTag before deps.getClient(effectiveTag), not just the raw argument.

containerTag: string,
): Promise<boolean> {
if (deps.cachedContainerTags().includes(containerTag)) return true
await deps.refreshContainerTags()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

containerTagExists() treats deps.refreshContainerTags() as authoritative, but the current refresh implementation can catch/log failures without throwing and leave the cached list unchanged. On a cache miss, a transient /v3/container-tags/list failure then returns false here and reports a valid tag as nonexistent. Please make validation distinguish could not validate from does not exist or otherwise propagate/use the fetched refresh result instead of converting refresh failures into missing tags.

@vorflux

vorflux Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Testing

PR-scoped MCP invalid container-tag behavior passed functional verification through targeted invalid-tag coverage, real local Wrangler MCP transport checks, changed-file Biome CI, and an existing auth smoke subset. The existing OAuth smoke subset had unrelated stale-contract failures, and the temporary targeted tests verified the new invalid-tag behavior without repository code changes.

Commands run:

cd /code/supermemoryai/supermemory/apps/mcp
export PATH="$HOME/.bun/bin:$PATH"
bunx vitest run --config "/var/tmp/testing_responses/3dd136e3-1bcf-4918-9827-9b8c06734872/vitest.targeted.config.ts" --pool=forks --no-file-parallelism

cd /code/supermemoryai/supermemory/apps/mcp
export PATH="$HOME/.bun/bin:$PATH"
bun run dev:app

node "/var/tmp/testing_responses/3dd136e3-1bcf-4918-9827-9b8c06734872/local-mcp-invalid-tag.mjs"

cd /code/supermemoryai/supermemory
export PATH="$HOME/.bun/bin:$PATH"
bunx biome ci apps/mcp/src/server/client/index.ts apps/mcp/src/server/tools/search-memory.ts apps/mcp/src/server/tools/set-active-tag.ts apps/mcp/src/server/tools/validate-container-tag.ts

cd /code/supermemoryai/supermemory/apps/mcp
export PATH="$HOME/.bun/bin:$PATH"
bunx vitest run e2e/auth.test.ts e2e/oauth.test.ts --pool=forks --no-file-parallelism

NODE_OPTIONS=--max-old-space-size=8192 bunx tsc --noEmit -p apps/mcp/tsconfig.json

Result:

Targeted invalid-container-tag integration test: PASS
1 file passed, 7 tests passed

Local Wrangler MCP transport check: PASS
Wrangler ready on http://localhost:8788
TOOLS add_memory,fetch-graph-data,guided-save,listSpaces,memory-graph,save-memory,search_memory,select-workspace,set-active-tag,upload-file,upload-file-submit,whoAmI
SEARCH_IS_ERROR true
SEARCH_TEXT Error: Container tag 'definitely_missing_pr1192_...' does not exist. Use listSpaces to see the available container tags.
SET_ACTIVE_IS_ERROR true
SET_ACTIVE_TEXT Error: Container tag 'definitely_missing_pr1192_...' does not exist. Use listSpaces to see the available container tags.

Changed-file Biome CI: PASS
Checked 4 files. No fixes applied.

Existing auth smoke subset:
e2e/auth.test.ts: PASS, 4 tests passed
e2e/oauth.test.ts: FAIL, 3 existing OAuth assertions failed against live default endpoints:
- dynamic client registration returned 200, expected 201
- bogus refresh token returned 400, expected 401
- unauthenticated authorize returned 200, expected 302
Assessment: unrelated to PR #1192 container-tag changes.

TypeScript check: FAIL in unrelated existing files:
- apps/mcp/src/server/prompts/context.ts
- apps/mcp/src/server/tools/add-memory.ts
- apps/mcp/src/server/tools/fetch-graph-data.ts
- apps/mcp/src/server/tools/memory-graph.ts
Targeted changed-file tsc also reports search-memory.ts schema/type errors, but the same targeted command fails on base branch origin/mcp-revamp-followup with the same errors.

Logs:
/tmp/pr1192-targeted-vitest-3.log
/tmp/pr1192-local-mcp-invalid-tag.log
/tmp/pr1192-biome-changed.log
/tmp/pr1192-existing-e2e-auth-oauth.log
/tmp/pr1192-mcp-tsc.log
/tmp/pr1192-targeted-tsc.log
/tmp/pr1192-base-targeted-tsc.log

Verdict

Passed. PR-scoped invalid container-tag behavior was verified; the observed OAuth and TypeScript failures appear unrelated/existing rather than introduced by this PR.

@ved015 ved015 changed the base branch from mcp-revamp-followup to graphite-base/1192 July 3, 2026 15:21
@ved015 ved015 mentioned this pull request Jul 3, 2026
Return structured error views from set-active-tag so the widget shows clear user-facing copy instead of a generic unrecognized-response error. Validate the resolved workspace in search_memory, and distinguish tag list refresh failures from genuinely missing tags.

Co-authored-by: Cursor <cursoragent@cursor.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overview: Adds upfront container tag existence validation to set-active-tag and search_memory tools, with improved error messaging for 403 responses.

Issues found: None — this looks good to ship.

The latest commit (276d354) addresses both issues from the previous vorflux review:

  1. effectiveTag validation fixed: search_memory now validates the resolved effectiveTag (lines 57-65), not just the raw args.containerTag. If a stored activeContainerTag references a deleted tag, the check will catch it before hitting the API.

  2. Refresh failure handling fixed: refreshContainerTags() now returns boolean, and validateContainerTag() returns a three-state enum ("exists" | "missing" | "unavailable"). Transient API failures return "unavailable" with a retry-friendly error message, while confirmed missing tags return "missing" with the specific "does not exist" error.

Additional observations:

  • RBAC checks correctly precede existence checks in both tools, preventing information leakage about valid container tags
  • The improved 403 message in client/index.ts provides helpful context as defense-in-depth
  • Widget error handling properly surfaces both structured and text-only error results

Score: 10/10

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants