Skip to content

Conversation

@sestinj
Copy link
Contributor

@sestinj sestinj commented Dec 1, 2025

Summary by cubic

Adds Supabase-specific OAuth scopes to the mcp-remote fallback so Supabase MCP can authenticate with the right permissions after a 401. Sends static OAuth client metadata with required read scopes (organizations, projects, database, analytics, secrets, edge functions, environment, storage) to prevent scope-related auth errors.

Written for commit 24f5859. Summary will update automatically on new commits.

@sestinj sestinj requested a review from a team as a code owner December 1, 2025 16:31
@sestinj sestinj requested review from RomneyDa and removed request for a team December 1, 2025 16:31
@continue
Copy link
Contributor

continue bot commented Dec 1, 2025

Keep this PR in a mergeable state →

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts

1 similar comment
@continue-development-app
Copy link

Keep this PR in a mergeable state →

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts

@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Dec 1, 2025
@github-actions
Copy link

github-actions bot commented Dec 1, 2025

✅ Review Complete

Code Review for PR #8949

Overall Assessment

The implementation looks solid and follows a reasonable approach. The code correctly adds Supabase-specific OAuth scopes when needed. Here are some observations:

Issues & Suggestions

1. Hardcoded Scopes (Medium Priority)

  • Location: Lines 508-519
  • Issue: The OAuth scopes are hardcoded. If Supabase adds/removes scopes or if different projects need different scopes, this will require code changes.
  • Suggestion: Consider making these configurable through the server config:
    if (serverConfig.oauth?.scopes) {
      mcpRemoteArgs.push(
        "--static-oauth-client-metadata",
        JSON.stringify({ scope: serverConfig.oauth.scopes.join(" ") }),
      );
    }

2. URL Pattern Matching (Low Priority)

  • Location: Line 510
  • Issue: Using .includes("mcp.supabase.com") could match unintended URLs (e.g., fake-mcp.supabase.com.evil.com).
  • Suggestion: Use a more precise check:
    const url = new URL(serverConfig.url);
    if (url.hostname === "mcp.supabase.com" || url.hostname.endsWith(".mcp.supabase.com"))

3. Missing Tests

  • No tests added for this new logic. Consider adding tests to verify:
    • Supabase URLs correctly add OAuth scopes
    • Non-Supabase URLs don't add OAuth scopes
    • The JSON stringification works correctly

4. Documentation (Minor)

  • A comment explaining why these specific scopes are needed would help future maintainers understand the purpose.

What's Good

  • ✅ Graceful fallback handling
  • ✅ Only applies to Supabase, doesn't affect other MCP servers
  • ✅ Proper JSON stringification of the metadata

Verdict: Functionally correct, but could benefit from more robust URL validation and test coverage.


@continue
Copy link
Contributor

continue bot commented Dec 1, 2025

Added documentation update to explain the automatic OAuth fallback behavior for Supabase MCP.

Changes:

  • Added an Info note in the troubleshooting section of the Supabase MCP guide
  • Documents the automatic fallback to mcp-remote with appropriate OAuth scopes when authentication errors (401) occur
  • Lists the specific scopes used: organizations, projects, database, analytics, secrets, edge functions, environment, and storage

This keeps users informed about the seamless authentication experience without needing to understand or configure the fallback mechanism manually.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

const mcpRemoteArgs = ["-y", "mcp-remote", serverConfig.url];

// Detect Supabase MCP and add custom OAuth scopes
if (serverConfig.url.includes("mcp.supabase.com")) {

Check failure

Code scanning / CodeQL

Incomplete URL substring sanitization High

'
mcp.supabase.com
' can be anywhere in the URL, and arbitrary hosts may come before or after it.

Copilot Autofix

AI 11 days ago

To robustly determine whether serverConfig.url points to a valid Supabase MCP host, we should parse the URL and examine its hostname component, ensuring that it is either exactly mcp.supabase.com or perhaps (if required) a known set of subdomains. This avoids false positives from substring matching on path, query, or other unrelated parts of the URL.

The best fix is to replace serverConfig.url.includes("mcp.supabase.com") with a check like new URL(serverConfig.url).hostname === "mcp.supabase.com". This change should be made at line 510. Since we're writing TypeScript/Node, the global URL class can be safely used. If for any reason we suspect serverConfig.url might not be a valid URL, a try/catch could be added for resilience, but assuming well-formed input for now is reasonable.

No new imports are needed because URL is available in modern Node environments.


Suggested changeset 1
extensions/cli/src/services/MCPService.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/extensions/cli/src/services/MCPService.ts b/extensions/cli/src/services/MCPService.ts
--- a/extensions/cli/src/services/MCPService.ts
+++ b/extensions/cli/src/services/MCPService.ts
@@ -507,8 +507,9 @@
           const mcpRemoteArgs = ["-y", "mcp-remote", serverConfig.url];
 
           // Detect Supabase MCP and add custom OAuth scopes
-          if (serverConfig.url.includes("mcp.supabase.com")) {
-            const supabaseScopes = [
+          try {
+            if (new URL(serverConfig.url).hostname === "mcp.supabase.com") {
+              const supabaseScopes = [
               "organizations:read",
               "projects:read",
               "database:read",
@@ -519,10 +520,13 @@
               "storage:read",
             ].join(" ");
 
-            mcpRemoteArgs.push(
-              "--static-oauth-client-metadata",
-              JSON.stringify({ scope: supabaseScopes }),
-            );
+              mcpRemoteArgs.push(
+                "--static-oauth-client-metadata",
+                JSON.stringify({ scope: supabaseScopes }),
+              );
+            }
+          } catch (e) {
+            logger.warn(`[MCPService] Failed to parse URL '${serverConfig.url}': ${e}`);
           }
 
           const transport = this.constructStdioTransport(
EOF
@@ -507,8 +507,9 @@
const mcpRemoteArgs = ["-y", "mcp-remote", serverConfig.url];

// Detect Supabase MCP and add custom OAuth scopes
if (serverConfig.url.includes("mcp.supabase.com")) {
const supabaseScopes = [
try {
if (new URL(serverConfig.url).hostname === "mcp.supabase.com") {
const supabaseScopes = [
"organizations:read",
"projects:read",
"database:read",
@@ -519,10 +520,13 @@
"storage:read",
].join(" ");

mcpRemoteArgs.push(
"--static-oauth-client-metadata",
JSON.stringify({ scope: supabaseScopes }),
);
mcpRemoteArgs.push(
"--static-oauth-client-metadata",
JSON.stringify({ scope: supabaseScopes }),
);
}
} catch (e) {
logger.warn(`[MCPService] Failed to parse URL '${serverConfig.url}': ${e}`);
}

const transport = this.constructStdioTransport(
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

@sestinj sestinj force-pushed the nate/fix-supabase-mcp branch from 21a25c0 to 24f5859 Compare December 1, 2025 17:10
@sestinj sestinj merged commit 5ec8d74 into main Dec 1, 2025
84 of 90 checks passed
@sestinj sestinj deleted the nate/fix-supabase-mcp branch December 1, 2025 17:10
@github-project-automation github-project-automation bot moved this from Todo to Done in Issues and PRs Dec 1, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Dec 1, 2025
@sestinj
Copy link
Contributor Author

sestinj commented Dec 1, 2025

🎉 This PR is included in version 1.33.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@sestinj
Copy link
Contributor Author

sestinj commented Dec 2, 2025

🎉 This PR is included in version 1.8.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@sestinj
Copy link
Contributor Author

sestinj commented Dec 2, 2025

🎉 This PR is included in version 1.37.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@sestinj
Copy link
Contributor Author

sestinj commented Dec 4, 2025

🎉 This PR is included in version 1.7.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

released size:S This PR changes 10-29 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants