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

supabase / cli / 19194338182

08 Nov 2025 02:29PM UTC coverage: 53.056% (-1.6%) from 54.689%
19194338182

Pull #4383

github

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

0 of 355 new or added lines in 9 files covered. (0.0%)

5 existing lines in 1 file now uncovered.

6388 of 12040 relevant lines covered (53.06%)

5.95 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
        tea "github.com/charmbracelet/bubbletea"
11
        "github.com/spf13/afero"
12
        "github.com/supabase/cli/internal/utils"
13
)
14

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

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

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

×
NEW
37
        // Prompt for config scope using dropdown
×
NEW
38
        items := []utils.PromptItem{
×
NEW
39
                {
×
NEW
40
                        Summary: "project",
×
NEW
41
                        Details: "Project-local (in .vscode/mcp.json)",
×
NEW
42
                },
×
NEW
43
                {
×
NEW
44
                        Summary: "global",
×
NEW
45
                        Details: "Global (in your home directory)",
×
NEW
46
                },
×
NEW
47
        }
×
NEW
48

×
NEW
49
        choice, err := utils.PromptChoice(ctx, "Where would you like to add the configuration?", items, tea.WithOutput(os.Stderr))
×
NEW
50
        if err != nil {
×
NEW
51
                return err
×
NEW
52
        }
×
53

NEW
54
        var configPath string
×
NEW
55
        if choice.Summary == "global" {
×
NEW
56
                // Global config
×
NEW
57
                homeDir, _ := os.UserHomeDir()
×
NEW
58
                configPath = filepath.Join(homeDir, ".vscode", "mcp.json")
×
NEW
59
        } else {
×
NEW
60
                // Project-local config
×
NEW
61
                cwd, _ := os.Getwd()
×
NEW
62
                configPath = filepath.Join(cwd, ".vscode", "mcp.json")
×
NEW
63
        }
×
64

65
        // Prepare the Supabase MCP server config
NEW
66
        supabaseConfig := map[string]interface{}{
×
NEW
67
                "type": "http",
×
NEW
68
                "url":  "http://localhost:54321/mcp",
×
NEW
69
        }
×
NEW
70

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

83
        // Ensure servers exists
NEW
84
        servers, ok := config["servers"].(map[string]interface{})
×
NEW
85
        if !ok {
×
NEW
86
                servers = make(map[string]interface{})
×
NEW
87
                config["servers"] = servers
×
NEW
88
        }
×
89

90
        // Add or update Supabase server
NEW
91
        servers["supabase"] = supabaseConfig
×
NEW
92

×
NEW
93
        // Ensure directory exists
×
NEW
94
        configDir := filepath.Dir(configPath)
×
NEW
95
        if err := fsys.MkdirAll(configDir, 0755); err != nil {
×
NEW
96
                return fmt.Errorf("failed to create config directory: %w", err)
×
NEW
97
        }
×
98

99
        // Write config
NEW
100
        configJSON, err := json.MarshalIndent(config, "", "  ")
×
NEW
101
        if err != nil {
×
NEW
102
                return fmt.Errorf("failed to marshal config: %w", err)
×
NEW
103
        }
×
104

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

109
        // Generate example for display
NEW
110
        configExample, _ := json.MarshalIndent(map[string]interface{}{
×
NEW
111
                "servers": map[string]interface{}{
×
NEW
112
                        "supabase": supabaseConfig,
×
NEW
113
                },
×
NEW
114
        }, "", "  ")
×
NEW
115

×
NEW
116
        fmt.Println()
×
NEW
117
        fmt.Printf("✓ Successfully configured VS Code at: %s\n", configPath)
×
NEW
118
        fmt.Println()
×
NEW
119
        fmt.Println("Configuration added:")
×
NEW
120
        fmt.Println(string(configExample))
×
NEW
121
        fmt.Println()
×
NEW
122
        fmt.Println("The Supabase MCP server is now available in VS Code!")
×
NEW
123
        return nil
×
124
}
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