Skip to content

Commit e750318

Browse files
authored
Add: mcpd config tools remove (#75)
* Add new command: mcpd config tools remove * config env remove and config args remove have cleaner looking output
1 parent aab7e7e commit e750318

File tree

6 files changed

+153
-5
lines changed

6 files changed

+153
-5
lines changed

cmd/config/args/remove.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,6 @@ func (c *RemoveCmd) run(cmd *cobra.Command, args []string) error {
7272
}
7373
}
7474

75-
fmt.Fprintf(cmd.OutOrStdout(), "✓ Args removed for server '%s': %v\n", serverName, argMap)
75+
fmt.Fprintf(cmd.OutOrStdout(), "✓ Args removed for server '%s': %v\n", serverName, slices.Collect(maps.Keys(argMap)))
7676
return nil
7777
}

cmd/config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/mozilla-ai/mcpd/v2/cmd/config/args"
77
"github.com/mozilla-ai/mcpd/v2/cmd/config/env"
8+
"github.com/mozilla-ai/mcpd/v2/cmd/config/tools"
89
"github.com/mozilla-ai/mcpd/v2/internal/cmd"
910
"github.com/mozilla-ai/mcpd/v2/internal/cmd/options"
1011
)
@@ -18,8 +19,9 @@ func NewConfigCmd(baseCmd *cmd.BaseCmd, opt ...options.CmdOption) (*cobra.Comman
1819

1920
// Sub-commands for: mcpd config
2021
fns := []func(baseCmd *cmd.BaseCmd, opt ...options.CmdOption) (*cobra.Command, error){
21-
args.NewCmd, // args
22-
env.NewCmd, // env
22+
args.NewCmd, // args
23+
env.NewCmd, // env
24+
tools.NewCmd, // tools
2325
}
2426

2527
for _, fn := range fns {

cmd/config/env/remove.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package env
22

33
import (
44
"fmt"
5+
"maps"
6+
"slices"
57
"strings"
68

79
"github.com/spf13/cobra"
@@ -65,6 +67,6 @@ func (c *RemoveCmd) run(cmd *cobra.Command, args []string) error {
6567
}
6668
}
6769

68-
fmt.Fprintf(cmd.OutOrStdout(), "✓ Environment variables removed for server '%s': %v\n", serverName, envMap)
70+
fmt.Fprintf(cmd.OutOrStdout(), "✓ Environment variables removed for server '%s': %v\n", serverName, slices.Collect(maps.Keys(envMap)))
6971
return nil
7072
}

cmd/config/env/set.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package env
22

33
import (
44
"fmt"
5+
"maps"
6+
"slices"
57
"strings"
68

79
"github.com/spf13/cobra"
@@ -71,6 +73,6 @@ func (c *SetCmd) run(cmd *cobra.Command, args []string) error {
7173
return fmt.Errorf("failed to save config: %w", err)
7274
}
7375

74-
fmt.Fprintf(cmd.OutOrStdout(), "✓ Environment variables set for server '%s': %v\n", serverName, envMap)
76+
fmt.Fprintf(cmd.OutOrStdout(), "✓ Environment variables set for server '%s': %v\n", serverName, slices.Collect(maps.Keys(envMap)))
7577
return nil
7678
}

cmd/config/tools/cmd.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package tools
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"github.com/mozilla-ai/mcpd/v2/internal/cmd"
7+
"github.com/mozilla-ai/mcpd/v2/internal/cmd/options"
8+
)
9+
10+
type Cmd struct {
11+
*cmd.BaseCmd
12+
}
13+
14+
func NewCmd(baseCmd *cmd.BaseCmd, opt ...options.CmdOption) (*cobra.Command, error) {
15+
cobraCmd := &cobra.Command{
16+
Use: "tools",
17+
Short: "Manages tools configuration for a registered MCP server",
18+
Long: "Manages tools configuration for a registered MCP server, " +
19+
"dealing with setting, removing, and listing tools",
20+
}
21+
22+
// Sub-commands for: mcpd config env
23+
fns := []func(baseCmd *cmd.BaseCmd, opt ...options.CmdOption) (*cobra.Command, error){
24+
// NewSetCmd, // set
25+
NewRemoveCmd, // remove
26+
// NewListCmd, // list
27+
}
28+
29+
for _, fn := range fns {
30+
tempCmd, err := fn(baseCmd, opt...)
31+
if err != nil {
32+
return nil, err
33+
}
34+
cobraCmd.AddCommand(tempCmd)
35+
}
36+
37+
return cobraCmd, nil
38+
}

cmd/config/tools/remove.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package tools
2+
3+
import (
4+
"fmt"
5+
"maps"
6+
"slices"
7+
"strings"
8+
9+
"github.com/spf13/cobra"
10+
11+
"github.com/mozilla-ai/mcpd/v2/internal/cmd"
12+
cmdopts "github.com/mozilla-ai/mcpd/v2/internal/cmd/options"
13+
"github.com/mozilla-ai/mcpd/v2/internal/config"
14+
"github.com/mozilla-ai/mcpd/v2/internal/flags"
15+
)
16+
17+
type RemoveCmd struct {
18+
*cmd.BaseCmd
19+
cfgLoader config.Loader
20+
Tools []string
21+
}
22+
23+
func NewRemoveCmd(baseCmd *cmd.BaseCmd, opt ...cmdopts.CmdOption) (*cobra.Command, error) {
24+
opts, err := cmdopts.NewOptions(opt...)
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
c := &RemoveCmd{
30+
BaseCmd: baseCmd,
31+
cfgLoader: opts.ConfigLoader,
32+
}
33+
34+
// mcpd config tools remove time TOOL [TOOL ...]
35+
cobraCmd := &cobra.Command{
36+
Use: "remove <server-name> TOOL [TOOL ...]",
37+
Short: "Remove allowed-listed tools for an MCP server from configuration",
38+
Long: "Remove allowed-listed tools for an MCP server from configuration, " +
39+
"if the specified tools are present in config they will be removed",
40+
RunE: c.run,
41+
Args: cobra.MinimumNArgs(2), // server-name + TOOL ...
42+
}
43+
44+
return cobraCmd, nil
45+
}
46+
47+
func (c *RemoveCmd) run(cmd *cobra.Command, args []string) error {
48+
serverName := strings.TrimSpace(args[0])
49+
if serverName == "" {
50+
return fmt.Errorf("server-name is required")
51+
}
52+
53+
tools := args[1:]
54+
toolsMap := make(map[string]struct{}, len(tools))
55+
for _, key := range tools {
56+
key = strings.TrimSpace(key)
57+
toolsMap[key] = struct{}{}
58+
}
59+
60+
cfg, err := c.cfgLoader.Load(flags.ConfigFile)
61+
if err != nil {
62+
return err
63+
}
64+
65+
for _, srv := range cfg.ListServers() {
66+
if srv.Name != serverName {
67+
continue
68+
}
69+
70+
removed := map[string]struct{}{}
71+
72+
for k := range toolsMap {
73+
if idx := slices.Index(srv.Tools, k); idx >= 0 {
74+
srv.Tools = slices.Delete(srv.Tools, idx, idx+1)
75+
removed[k] = struct{}{}
76+
}
77+
}
78+
79+
// Update server in config by removing and re-adding.
80+
err = cfg.RemoveServer(serverName)
81+
if err != nil {
82+
return fmt.Errorf("error removing server, unable to remove tools for server %s: %w", serverName, err)
83+
}
84+
85+
err = cfg.AddServer(srv)
86+
if err != nil {
87+
return fmt.Errorf("error adding server, unable to remove tools for server %s: %w", serverName, err)
88+
}
89+
90+
msg := "✓ Command completed successfully, no tools required removal\n"
91+
if len(removed) > 0 {
92+
msg = fmt.Sprintf("✓ Tools removed for server '%s': %v\n", serverName, slices.Collect(maps.Keys(removed)))
93+
}
94+
95+
_, err = fmt.Fprintf(cmd.OutOrStdout(), msg)
96+
if err != nil {
97+
return err
98+
}
99+
100+
break
101+
}
102+
103+
return nil
104+
}

0 commit comments

Comments
 (0)