• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / cli / 19043045070

03 Nov 2025 05:11PM UTC coverage: 53.318% (-1.4%) from 54.728%
19043045070

Pull #4383

github

web-flow
Merge 321c707b4 into df557dc33
Pull Request #4383: feat(mcp): add `supabase mcp init` command to configure MCP clients

0 of 297 new or added lines in 8 files covered. (0.0%)

26 existing lines in 4 files now uncovered.

6388 of 11981 relevant lines covered (53.32%)

5.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/internal/mcp/init/vscode.go
1
package mcpinit
2

3
import (
4
        "context"
5
        "encoding/json"
6
        "fmt"
7
        "os"
8
        "path/filepath"
9

10
        "github.com/spf13/afero"
11
)
12

13
// vscodeClient implements the Client interface for VS Code
14
type vscodeClient struct {
15
        baseClient
16
}
17

NEW
18
func newVSCodeClient() *vscodeClient {
×
NEW
19
        return &vscodeClient{
×
NEW
20
                baseClient: baseClient{
×
NEW
21
                        name:                "vscode",
×
NEW
22
                        displayName:         "VS Code",
×
NEW
23
                        installInstructions: "Download from https://code.visualstudio.com",
×
NEW
24
                        checkInstalled: func() bool {
×
NEW
25
                                return commandExists("code")
×
NEW
26
                        },
×
27
                },
28
        }
29
}
30

NEW
31
func (c *vscodeClient) Configure(ctx context.Context, fsys afero.Fs) error {
×
NEW
32
        fmt.Println("Configuring VS Code...")
×
NEW
33
        fmt.Println()
×
NEW
34

×
NEW
35
        // Prompt for config scope
×
NEW
36
        fmt.Println("Where would you like to add the configuration?")
×
NEW
37
        fmt.Println("  1. Project-local (in .vscode/mcp.json)")
×
NEW
38
        fmt.Println("  2. Global (in your home directory)")
×
NEW
39
        fmt.Print("Choice [1]: ")
×
NEW
40

×
NEW
41
        var choice string
×
NEW
42
        if _, err := fmt.Scanln(&choice); err != nil && err.Error() != "unexpected newline" {
×
NEW
43
                return fmt.Errorf("failed to read choice: %w", err)
×
NEW
44
        }
×
NEW
45
        if choice == "" {
×
NEW
46
                choice = "1"
×
NEW
47
        }
×
48

NEW
49
        var configPath string
×
NEW
50
        if choice == "2" {
×
NEW
51
                // Global config
×
NEW
52
                homeDir, _ := os.UserHomeDir()
×
NEW
53
                configPath = filepath.Join(homeDir, ".vscode", "mcp.json")
×
NEW
54
        } else {
×
NEW
55
                // Project-local config
×
NEW
56
                cwd, _ := os.Getwd()
×
NEW
57
                configPath = filepath.Join(cwd, ".vscode", "mcp.json")
×
NEW
58
        }
×
59

60
        // Prepare the Supabase MCP server config
NEW
61
        supabaseConfig := map[string]interface{}{
×
NEW
62
                "type": "http",
×
NEW
63
                "url":  "https://mcp.supabase.com/mcp",
×
NEW
64
        }
×
NEW
65

×
NEW
66
        // Read existing config if it exists
×
NEW
67
        var config map[string]interface{}
×
NEW
68
        existingData, err := afero.ReadFile(fsys, configPath)
×
NEW
69
        if err == nil && len(existingData) > 0 {
×
NEW
70
                if err := json.Unmarshal(existingData, &config); err != nil {
×
NEW
71
                        // If existing file is invalid JSON, start fresh
×
NEW
72
                        config = make(map[string]interface{})
×
NEW
73
                }
×
NEW
74
        } else {
×
NEW
75
                config = make(map[string]interface{})
×
NEW
76
        }
×
77

78
        // Ensure mcpServers exists
NEW
79
        mcpServers, ok := config["mcpServers"].(map[string]interface{})
×
NEW
80
        if !ok {
×
NEW
81
                mcpServers = make(map[string]interface{})
×
NEW
82
                config["mcpServers"] = mcpServers
×
NEW
83
        }
×
84

85
        // Add or update Supabase server
NEW
86
        mcpServers["supabase"] = supabaseConfig
×
NEW
87

×
NEW
88
        // Ensure directory exists
×
NEW
89
        configDir := filepath.Dir(configPath)
×
NEW
90
        if err := fsys.MkdirAll(configDir, 0755); err != nil {
×
NEW
91
                return fmt.Errorf("failed to create config directory: %w", err)
×
NEW
92
        }
×
93

94
        // Write config
NEW
95
        configJSON, err := json.MarshalIndent(config, "", "  ")
×
NEW
96
        if err != nil {
×
NEW
97
                return fmt.Errorf("failed to marshal config: %w", err)
×
NEW
98
        }
×
99

NEW
100
        if err := afero.WriteFile(fsys, configPath, configJSON, 0644); err != nil {
×
NEW
101
                return fmt.Errorf("failed to write config file: %w", err)
×
NEW
102
        }
×
103

NEW
104
        fmt.Println()
×
NEW
105
        fmt.Printf("✓ Successfully configured VS Code at: %s\n", configPath)
×
NEW
106
        fmt.Println()
×
NEW
107
        fmt.Println("Configuration added:")
×
NEW
108
        fmt.Println(`{
×
NEW
109
  "mcpServers": {
×
NEW
110
    "supabase": {
×
NEW
111
      "type": "http",
×
NEW
112
      "url": "https://mcp.supabase.com/mcp"
×
NEW
113
    }
×
NEW
114
  }
×
NEW
115
}`)
×
NEW
116
        fmt.Println()
×
NEW
117
        fmt.Println("The Supabase MCP server is now available in VS Code!")
×
NEW
118
        return nil
×
119
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc