Skip to content

Commit

Permalink
✨ Add functionality to enable/disable servers
Browse files Browse the repository at this point in the history
  • Loading branch information
wesen committed Feb 11, 2025
1 parent 92e7007 commit 40a1174
Show file tree
Hide file tree
Showing 5 changed files with 347 additions and 53 deletions.
20 changes: 14 additions & 6 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
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
87 changes: 86 additions & 1 deletion cmd/go-go-mcp/cmds/claude_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ func NewClaudeConfigCommand() *cobra.Command {
newClaudeConfigAddMCPServerCommand(),
newClaudeConfigRemoveMCPServerCommand(),
newClaudeConfigListServersCommand(),
newClaudeConfigEnableServerCommand(),
newClaudeConfigDisableServerCommand(),
)

return cmd
Expand Down Expand Up @@ -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)
Expand All @@ -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
},
}
Expand Down
75 changes: 73 additions & 2 deletions pkg/config/claude_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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...)
}
46 changes: 46 additions & 0 deletions pkg/doc/topics/03-mcp-in-practice.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading

0 comments on commit 40a1174

Please sign in to comment.