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

supabase / cli / 19105505226

05 Nov 2025 02:34PM UTC coverage: 53.269% (-1.4%) from 54.699%
19105505226

Pull #4383

github

web-flow
Merge 79948e448 into 4054f205d
Pull Request #4383: feat(mcp): add `supabase mcp init` command to configure MCP clients

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

5 existing lines in 1 file now uncovered.

6388 of 11992 relevant lines covered (53.27%)

5.97 hits per line

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

0.0
/internal/mcp/init/cursor.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
// cursorClient implements the Client interface for Cursor
14
type cursorClient struct {
15
        baseClient
16
}
17

NEW
18
func newCursorClient() *cursorClient {
×
NEW
19
        return &cursorClient{
×
NEW
20
                baseClient: baseClient{
×
NEW
21
                        name:                "cursor",
×
NEW
22
                        displayName:         "Cursor",
×
NEW
23
                        installInstructions: "Download from https://cursor.sh",
×
NEW
24
                        checkInstalled: func() bool {
×
NEW
25
                                return commandExists("cursor") || appExists("Cursor")
×
NEW
26
                        },
×
27
                },
28
        }
29
}
30

NEW
31
func (c *cursorClient) Configure(ctx context.Context, fsys afero.Fs) error {
×
NEW
32
        fmt.Println("Configuring Cursor...")
×
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 .cursor/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, ".cursor", "mcp.json")
×
NEW
54
        } else {
×
NEW
55
                // Project-local config
×
NEW
56
                cwd, _ := os.Getwd()
×
NEW
57
                configPath = filepath.Join(cwd, ".cursor", "mcp.json")
×
NEW
58
        }
×
59

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

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

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

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

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

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

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

NEW
103
        fmt.Println()
×
NEW
104
        fmt.Printf("✓ Successfully configured Cursor at: %s\n", configPath)
×
NEW
105
        fmt.Println()
×
NEW
106
        fmt.Println("Configuration added:")
×
NEW
107
        fmt.Println(`{
×
NEW
108
  "mcpServers": {
×
NEW
109
    "supabase": {
×
NEW
110
      "url": "https://mcp.supabase.com/mcp"
×
NEW
111
    }
×
NEW
112
  }
×
NEW
113
}`)
×
NEW
114
        fmt.Println()
×
NEW
115
        fmt.Println("The Supabase MCP server is now available in Cursor!")
×
NEW
116
        return nil
×
117
}
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