diff --git a/changelog.md b/changelog.md index 7dda47e..ba2ff8b 100644 --- a/changelog.md +++ b/changelog.md @@ -973,10 +973,18 @@ Added safety check when adding MCP servers and option to overwrite: - ✨ Added `--overwrite` flag to force update of existing servers - 📝 Updated success messages to indicate whether server was added or updated -# Claude Desktop Configuration Documentation +# Enhanced Claude Desktop Configuration Documentation -Added comprehensive documentation for configuring Claude desktop with MCP servers, including: -- Configuration file format explanation -- Multiple example configurations -- Troubleshooting guide -- Best practices and common patterns \ No newline at end of file +Updated the Claude desktop configuration documentation with: +- Comprehensive command-line examples for all claude-config commands +- Detailed examples of using init, edit, add-mcp-server, remove-mcp-server, and list-servers +- Clear explanations of command flags and options +- Improved organization and readability + +# Added Server Enable/Disable Support + +Added ability to temporarily disable MCP servers without removing their configuration: +- ✨ Added `disable-server` and `enable-server` commands to claude-config +- 🏗️ Added `DisabledMCPServers` field to configuration format +- 📝 Updated list-servers command to show disabled status +- 🔧 Added helper functions for managing server state \ No newline at end of file diff --git a/cmd/go-go-mcp/cmds/claude_config.go b/cmd/go-go-mcp/cmds/claude_config.go index 361436c..6de9dcf 100644 --- a/cmd/go-go-mcp/cmds/claude_config.go +++ b/cmd/go-go-mcp/cmds/claude_config.go @@ -23,6 +23,8 @@ func NewClaudeConfigCommand() *cobra.Command { newClaudeConfigAddMCPServerCommand(), newClaudeConfigRemoveMCPServerCommand(), newClaudeConfigListServersCommand(), + newClaudeConfigEnableServerCommand(), + newClaudeConfigDisableServerCommand(), ) return cmd @@ -209,7 +211,11 @@ func newClaudeConfigListServersCommand() *cobra.Command { fmt.Printf("Configured MCP servers in %s:\n\n", editor.GetConfigPath()) for name, server := range servers { - fmt.Printf("%s:\n", name) + disabled := "" + if editor.IsServerDisabled(name) { + disabled = " (disabled)" + } + fmt.Printf("%s%s:\n", name, disabled) fmt.Printf(" Command: %s\n", server.Command) if len(server.Args) > 0 { fmt.Printf(" Args: %v\n", server.Args) @@ -223,6 +229,85 @@ func newClaudeConfigListServersCommand() *cobra.Command { fmt.Println() } + // List disabled servers + disabled := editor.ListDisabledServers() + if len(disabled) > 0 { + fmt.Println("Disabled servers:") + for _, name := range disabled { + fmt.Printf(" - %s\n", name) + } + } + + return nil + }, + } + + cmd.Flags().StringVarP(&configPath, "config", "c", "", "Path to config file (default: $XDG_CONFIG_HOME/Claude/claude_desktop_config.json)") + + return cmd +} + +func newClaudeConfigEnableServerCommand() *cobra.Command { + var configPath string + + cmd := &cobra.Command{ + Use: "enable-server NAME", + Short: "Enable a disabled MCP server", + Long: `Enables a previously disabled MCP server configuration.`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + editor, err := config.NewClaudeDesktopEditor(configPath) + if err != nil { + return err + } + + name := args[0] + if err := editor.EnableMCPServer(name); err != nil { + return err + } + + if err := editor.Save(); err != nil { + return err + } + + fmt.Printf("Successfully enabled MCP server '%s'\n", name) + fmt.Printf("Configuration saved to: %s\n", editor.GetConfigPath()) + + return nil + }, + } + + cmd.Flags().StringVarP(&configPath, "config", "c", "", "Path to config file (default: $XDG_CONFIG_HOME/Claude/claude_desktop_config.json)") + + return cmd +} + +func newClaudeConfigDisableServerCommand() *cobra.Command { + var configPath string + + cmd := &cobra.Command{ + Use: "disable-server NAME", + Short: "Disable an MCP server", + Long: `Disables an MCP server configuration without removing it.`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + editor, err := config.NewClaudeDesktopEditor(configPath) + if err != nil { + return err + } + + name := args[0] + if err := editor.DisableMCPServer(name); err != nil { + return err + } + + if err := editor.Save(); err != nil { + return err + } + + fmt.Printf("Successfully disabled MCP server '%s'\n", name) + fmt.Printf("Configuration saved to: %s\n", editor.GetConfigPath()) + return nil }, } diff --git a/pkg/config/claude_desktop.go b/pkg/config/claude_desktop.go index a872d0b..84449e9 100644 --- a/pkg/config/claude_desktop.go +++ b/pkg/config/claude_desktop.go @@ -9,8 +9,9 @@ import ( // ClaudeDesktopConfig represents the configuration for the Claude desktop application type ClaudeDesktopConfig struct { - MCPServers map[string]MCPServer `json:"mcpServers"` - GoGoMCP MCPServer `json:"go-go-mcp"` + MCPServers map[string]MCPServer `json:"mcpServers"` + DisabledMCPServers []string `json:"disabledMCPServers,omitempty"` + GoGoMCP MCPServer `json:"go-go-mcp"` } // MCPServer represents a server configuration @@ -154,3 +155,73 @@ func (e *ClaudeDesktopEditor) ListServers() map[string]MCPServer { return servers } + +// EnableMCPServer enables a previously disabled MCP server +func (e *ClaudeDesktopEditor) EnableMCPServer(name string) error { + if e.config.DisabledMCPServers == nil { + return fmt.Errorf("MCP server '%s' is not disabled", name) + } + + // Check if server exists + if _, exists := e.config.MCPServers[name]; !exists { + return fmt.Errorf("MCP server '%s' not found", name) + } + + // Find and remove from disabled list + for i, disabled := range e.config.DisabledMCPServers { + if disabled == name { + e.config.DisabledMCPServers = append(e.config.DisabledMCPServers[:i], e.config.DisabledMCPServers[i+1:]...) + if len(e.config.DisabledMCPServers) == 0 { + e.config.DisabledMCPServers = nil + } + return nil + } + } + + return fmt.Errorf("MCP server '%s' is not disabled", name) +} + +// DisableMCPServer disables an MCP server without removing its configuration +func (e *ClaudeDesktopEditor) DisableMCPServer(name string) error { + // Check if server exists + if _, exists := e.config.MCPServers[name]; !exists { + return fmt.Errorf("MCP server '%s' not found", name) + } + + // Check if already disabled + if e.config.DisabledMCPServers != nil { + for _, disabled := range e.config.DisabledMCPServers { + if disabled == name { + return fmt.Errorf("MCP server '%s' is already disabled", name) + } + } + } + + // Add to disabled list + if e.config.DisabledMCPServers == nil { + e.config.DisabledMCPServers = make([]string, 0) + } + e.config.DisabledMCPServers = append(e.config.DisabledMCPServers, name) + return nil +} + +// IsServerDisabled checks if a server is disabled +func (e *ClaudeDesktopEditor) IsServerDisabled(name string) bool { + if e.config.DisabledMCPServers == nil { + return false + } + for _, disabled := range e.config.DisabledMCPServers { + if disabled == name { + return true + } + } + return false +} + +// ListDisabledServers returns a list of disabled server names +func (e *ClaudeDesktopEditor) ListDisabledServers() []string { + if e.config.DisabledMCPServers == nil { + return []string{} + } + return append([]string{}, e.config.DisabledMCPServers...) +} diff --git a/pkg/doc/topics/03-mcp-in-practice.md b/pkg/doc/topics/03-mcp-in-practice.md index df6a5f4..9f14dac 100644 --- a/pkg/doc/topics/03-mcp-in-practice.md +++ b/pkg/doc/topics/03-mcp-in-practice.md @@ -36,6 +36,52 @@ Each section includes practical exercises to help reinforce the concepts. 4. [Running the Server](#running-the-server) 5. [Testing with the Client](#testing-with-the-client) +## Using MCP with Claude Desktop 🤖 + +Claude desktop can be configured to use MCP servers through its configuration file. This allows you to use MCP tools directly through Claude's edit verbs. + +### Configuration + +First, configure Claude desktop to use your MCP server: + +```bash +# Initialize Claude desktop configuration +go-go-mcp claude-config init + +# Add an MCP server configuration +go-go-mcp claude-config add-mcp-server dev \ + --command go-go-mcp \ + --args start --profile development --log-level debug +``` + +### Using Edit Verbs + +Once configured, you can use MCP tools through Claude's edit verbs: + +1. **@tool**: Execute an MCP tool + ``` + @tool list-github-issues --state open --assignee me + ``` + +2. **@run**: Run a shell command through MCP + ``` + @run git status + ``` + +3. **@fetch**: Fetch and process web content + ``` + @fetch https://example.com + ``` + +The output from these commands will be automatically processed and included in Claude's context, allowing for natural interaction with the results. + +### Best Practices + +1. Use descriptive tool names that reflect their purpose +2. Keep sensitive data in environment variables +3. Use debug logging during development +4. Create specific profiles for different use cases + ## Setting Up the Project Structure MCP works best with a well-organized project structure that groups tools by their purpose and functionality. We'll create a structure that follows these principles: diff --git a/pkg/doc/topics/04-claude-edit.md b/pkg/doc/topics/04-claude-edit.md index 9dca7f8..cffc2f8 100644 --- a/pkg/doc/topics/04-claude-edit.md +++ b/pkg/doc/topics/04-claude-edit.md @@ -33,25 +33,110 @@ Claude desktop looks for its configuration file in your system's config director - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Windows: `%APPDATA%\Claude\claude_desktop_config.json` +## Command Line Configuration 🛠️ + +The `go-go-mcp claude-config` command provides a suite of tools to manage your Claude desktop configuration: + +### Initialize Configuration + +Create a new configuration file: + +```bash +# Create with default path +go-go-mcp claude-config init + +# Create with custom path +go-go-mcp claude-config init --config /path/to/config.json +``` + +### Edit Configuration + +Open the configuration file in your default editor: + +```bash +# Edit default config +go-go-mcp claude-config edit + +# Edit custom config +go-go-mcp claude-config edit --config /path/to/config.json +``` + +### Add MCP Server + +Add or update an MCP server configuration: + +```bash +# Add a basic server +go-go-mcp claude-config add-mcp-server dev \ + --command go-go-mcp \ + --args start --profile development --log-level debug + +# Add with environment variables +go-go-mcp claude-config add-mcp-server github \ + --command go-go-mcp \ + --args start --profile github \ + --env GITHUB_TOKEN=your-token \ + --env DEBUG=true + +# Update existing server +go-go-mcp claude-config add-mcp-server dev \ + --command go-go-mcp \ + --args start --profile development \ + --overwrite +``` + +### Remove MCP Server + +Remove an existing server configuration: + +```bash +# Remove a server +go-go-mcp claude-config remove-mcp-server dev + +# Remove from custom config +go-go-mcp claude-config remove-mcp-server dev --config /path/to/config.json +``` + +### List Servers + +View all configured servers: + +```bash +# List all servers +go-go-mcp claude-config list-servers + +# List from custom config +go-go-mcp claude-config list-servers --config /path/to/config.json +``` + ## Understanding the Configuration Format 🔧 -The configuration file uses JSON format with one main section: +The configuration file uses JSON format with two main sections: 1. `mcpServers`: A map of named MCP server configurations +2. `disabledMCPServers`: An optional list of disabled server names Here's the anatomy of an MCP server configuration: ```json { - "command": "executable-name", // The command to run - "args": [ // List of command arguments - "--flag1", "value1", - "--flag2", "value2" - ], - "env": { // Optional environment variables - "ENV_VAR1": "value1", - "ENV_VAR2": "value2" - } + "mcpServers": { + "server1": { + "command": "executable-name", // The command to run + "args": [ // List of command arguments + "--flag1", "value1", + "--flag2", "value2" + ], + "env": { // Optional environment variables + "ENV_VAR1": "value1", + "ENV_VAR2": "value2" + } + } + }, + "disabledMCPServers": [ // Optional list of disabled servers + "server2", + "server3" + ] } ``` @@ -129,44 +214,43 @@ Let's explore some powerful configurations that showcase what you can do: } ``` -### 4. GitHub Integration Setup +### Enable/Disable Servers -```json -{ - "mcpServers": { - "github": { - "command": "go-go-mcp", - "args": [ - "start", - "--profile", "github", - ], - "env": { - "GITHUB_TOKEN": "your-github-token" - } - } - } -} +You can temporarily disable servers without removing their configuration: + +```bash +# Disable a server +go-go-mcp claude-config disable-server dev + +# Enable a previously disabled server +go-go-mcp claude-config enable-server dev ``` -### 5. Development with Hot Reloading +When listing servers, disabled servers will be marked: -```json -{ - "mcpServers": { - "hot-reload": { - "command": "go-go-mcp", - "args": [ - "start", - "--profile", "development", - "--watch" - ], - "env": { - "DEBUG": "true", - "RELOAD_DELAY": "500ms" - } - } - } -} +```bash +# List all servers including disabled ones +go-go-mcp claude-config list-servers +``` + +Example output: +``` +Configured MCP servers in ~/.config/Claude/claude_desktop_config.json: + +dev (disabled): + Command: go-go-mcp + Args: [start --profile development --log-level debug] + Environment: + DEVELOPMENT: true + +github: + Command: go-go-mcp + Args: [start --profile github] + Environment: + GITHUB_TOKEN: your-token + +Disabled servers: + - dev ``` ## Pro Tips 💡