()
| 291 | } |
| 292 | |
| 293 | func (*RootCmd) mcpConfigureCursor() *serpent.Command { |
| 294 | var project bool |
| 295 | cmd := &serpent.Command{ |
| 296 | Use: "cursor", |
| 297 | Short: "Configure Cursor to use Coder MCP.", |
| 298 | Options: serpent.OptionSet{ |
| 299 | serpent.Option{ |
| 300 | Flag: "project", |
| 301 | Env: "CODER_MCP_CURSOR_PROJECT", |
| 302 | Description: "Use to configure a local project to use the Cursor MCP.", |
| 303 | Value: serpent.BoolOf(&project), |
| 304 | }, |
| 305 | }, |
| 306 | Handler: func(_ *serpent.Invocation) error { |
| 307 | dir, err := os.Getwd() |
| 308 | if err != nil { |
| 309 | return err |
| 310 | } |
| 311 | if !project { |
| 312 | dir, err = os.UserHomeDir() |
| 313 | if err != nil { |
| 314 | return err |
| 315 | } |
| 316 | } |
| 317 | cursorDir := filepath.Join(dir, ".cursor") |
| 318 | err = os.MkdirAll(cursorDir, 0o755) |
| 319 | if err != nil { |
| 320 | return err |
| 321 | } |
| 322 | mcpConfig := filepath.Join(cursorDir, "mcp.json") |
| 323 | _, err = os.Stat(mcpConfig) |
| 324 | contents := map[string]any{} |
| 325 | if err != nil { |
| 326 | if !os.IsNotExist(err) { |
| 327 | return err |
| 328 | } |
| 329 | } else { |
| 330 | data, err := os.ReadFile(mcpConfig) |
| 331 | if err != nil { |
| 332 | return err |
| 333 | } |
| 334 | // The config can be empty, so we don't want to return an error if it is. |
| 335 | if len(data) > 0 { |
| 336 | err = json.Unmarshal(data, &contents) |
| 337 | if err != nil { |
| 338 | return err |
| 339 | } |
| 340 | } |
| 341 | } |
| 342 | mcpServers, ok := contents["mcpServers"].(map[string]any) |
| 343 | if !ok { |
| 344 | mcpServers = map[string]any{} |
| 345 | } |
| 346 | binPath, err := os.Executable() |
| 347 | if err != nil { |
| 348 | return err |
| 349 | } |
| 350 | mcpServers["coder"] = map[string]any{ |
no test coverage detected