Skip to content

fix: actionable error for wrong-org permission failures on database tools#329

Open
barryroodt wants to merge 1 commit into
mainfrom
barryroodt/ai-178-improve-mcp-db-tool-error-for-wrong-organization-selection
Open

fix: actionable error for wrong-org permission failures on database tools#329
barryroodt wants to merge 1 commit into
mainfrom
barryroodt/ai-178-improve-mcp-db-tool-error-for-wrong-organization-selection

Conversation

@barryroodt

Copy link
Copy Markdown

Problem

Authenticating to the wrong organization (e.g. selecting the wrong org during OAuth login) makes database tools (list_tables, execute_sql, migrations) fail with a bare:

You do not have permission to perform this action

Nothing indicates that org selection is the cause — hard to debug for users, and useless to the LLM driving the session.

Linear: AI-178

Change

  • New assertProjectScopedSuccess(response, fallbackMessage, projectId) in management-api/index.ts: intercepts 403 only, preserves the upstream API message when present, and appends:

    Access to project '<ref>' was denied. If this project exists, your access token may be scoped to a different organization: re-authenticate with the MCP server and select the organization that owns this project.

    All non-403 errors fall through to the existing assertSuccess.

  • Wired into the three database platform ops (executeSql, listMigrations, applyMigration), which back execute_sql, list_tables, list_extensions, list_migrations, and apply_migration.

  • Intentionally not applied to other endpoints (billing/admin/project ops), where a 403 can mean plan or role restrictions and org-selection advice would mislead. JSDoc on the helper documents this.

Note: the target project's org can't be named in the message — with a wrong-org token the project lookup itself returns 403, so the org is unknowable. The message names the project ref and the likely cause instead.

Verification

All commands run from packages/mcp-server-supabase:

  • TDD: added two tool-level regression tests (execute_sql and list_tables against an MSW 403 override on /v1/projects/:ref/database/query). Ran pnpm vitest run src/server.test.ts -t "permission denied" before the fix — both failed with the raw upstream message (You do not have permission to perform this action) — and after:

    ✓ tools > permission denied for execute_sql suggests checking organization
    ✓ tools > permission denied for list_tables suggests checking organization
    
  • pnpm test:unit166/166 passed (10 files)

  • pnpm typecheck (tsc --noEmit) — clean

  • pnpm biome check src/management-api/index.ts src/platform/api-platform.ts src/server.test.ts — clean

Out of scope

The timeout variant from the original user report is gateway-side (tracked as AUTH-871 in the Remote MCP (HTTP API) project) and is not addressed here.

🤖 AI-assisted; human-reviewed per CONTRIBUTING.md.

…ools

A 403 from the Management API on database operations (execute_sql,
list_tables, migrations) previously surfaced as a bare 'You do not have
permission to perform this action', giving users and LLM clients no hint
that the access token was scoped to the wrong organization.

Map project-scoped 403s on database operations to a message that names
the project and suggests re-authenticating with the organization that
owns it. Other endpoints are intentionally untouched, since a 403 there
can mean plan or role restrictions.

Fixes AI-178
@barryroodt barryroodt requested a review from a team as a code owner July 14, 2026 08:23
@barryroodt barryroodt self-assigned this Jul 14, 2026
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 29317867758

Coverage increased (+0.008%) to 96.251%

Details

  • Coverage increased (+0.008%) from the base build.
  • Patch coverage: 32 of 32 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 2849
Covered Lines: 2764
Line Coverage: 97.02%
Relevant Branches: 352
Covered Branches: 317
Branch Coverage: 90.06%
Branches in Coverage %: Yes
Coverage Strength: 41.62 hits per line

💛 - Coveralls

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