Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions cmd/mcptools/commands/alias.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package commands

import (
"fmt"
"strings"

"github.com/f/mcptools/pkg/alias"
"github.com/spf13/cobra"
)

// AliasCmd creates the alias command.
func AliasCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "alias",
Short: "Manage MCP server aliases",
Long: `Manage aliases for MCP servers.

This command allows you to register MCP server commands with a friendly name and
reuse them later.

Aliases are stored in $HOME/.mcpt/aliases.json.

Examples:
# Add a new server alias
mcp alias add myfs npx -y @modelcontextprotocol/server-filesystem ~/

# List all registered server aliases
mcp alias list

# Remove a server alias
mcp alias remove myfs

# Use an alias with any MCP command
mcp tools myfs`,
}

cmd.AddCommand(aliasAddCmd())
cmd.AddCommand(aliasListCmd())
cmd.AddCommand(aliasRemoveCmd())

return cmd
}

func aliasAddCmd() *cobra.Command {
addCmd := &cobra.Command{
Use: "add [alias] [command args...]",
Short: "Add a new MCP server alias",
DisableFlagParsing: true,
Long: `Add a new alias for an MCP server command.

The alias will be registered and can be used in place of the server command.

Example:
mcp alias add myfs npx -y @modelcontextprotocol/server-filesystem ~/`,
Args: cobra.MinimumNArgs(2),
RunE: func(thisCmd *cobra.Command, args []string) error {
if len(args) == 1 && (args[0] == FlagHelp || args[0] == FlagHelpShort) {
_ = thisCmd.Help()
return nil
}

aliasName := args[0]
serverCommand := strings.Join(args[1:], " ")

aliases, err := alias.Load()
if err != nil {
return fmt.Errorf("error loading aliases: %w", err)
}

aliases[aliasName] = alias.ServerAlias{
Command: serverCommand,
}

if saveErr := alias.Save(aliases); saveErr != nil {
return fmt.Errorf("error saving aliases: %w", saveErr)
}

fmt.Fprintf(thisCmd.OutOrStdout(), "Alias '%s' registered for command: %s\n", aliasName, serverCommand)
return nil
},
}
return addCmd
}

func aliasListCmd() *cobra.Command {
return &cobra.Command{
Use: "list",
Short: "List all registered MCP server aliases",
RunE: func(cmd *cobra.Command, _ []string) error {
// Load existing aliases
aliases, err := alias.Load()
if err != nil {
return fmt.Errorf("error loading aliases: %w", err)
}

if len(aliases) == 0 {
fmt.Fprintln(cmd.OutOrStdout(), "No aliases registered.")
return nil
}

fmt.Fprintln(cmd.OutOrStdout(), "Registered MCP server aliases:")
for name, a := range aliases {
fmt.Fprintf(cmd.OutOrStdout(), " %s: %s\n", name, a.Command)
}

return nil
},
}
}

func aliasRemoveCmd() *cobra.Command {
return &cobra.Command{
Use: "remove <name>",
Short: "Remove an MCP server alias",
Long: `Remove a registered alias for an MCP server command.

Example:
mcp alias remove myfs`,
Args: cobra.ExactArgs(1),
RunE: func(thisCmd *cobra.Command, args []string) error {
if len(args) == 1 && (args[0] == FlagHelp || args[0] == FlagHelpShort) {
_ = thisCmd.Help()
return nil
}

aliasName := args[0]

aliases, err := alias.Load()
if err != nil {
return fmt.Errorf("error loading aliases: %w", err)
}

if _, exists := aliases[aliasName]; !exists {
return fmt.Errorf("alias '%s' does not exist", aliasName)
}

delete(aliases, aliasName)

if saveErr := alias.Save(aliases); saveErr != nil {
return fmt.Errorf("error saving aliases: %w", saveErr)
}

fmt.Fprintf(thisCmd.OutOrStdout(), "Alias '%s' removed.\n", aliasName)
return nil
},
}
}
167 changes: 167 additions & 0 deletions cmd/mcptools/commands/alias_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package commands

import (
"bytes"
"os"
"testing"

"github.com/f/mcptools/pkg/alias"
)

func TestAliasCommands(t *testing.T) {
// Create a temporary directory for test files
tmpDir := t.TempDir()
if err := os.Setenv("HOME", tmpDir); err != nil {
t.Fatalf("Failed to set HOME environment variable: %v", err)
}

// Test alias add command
t.Run("add", func(t *testing.T) {
cmd := aliasAddCmd()
buf := new(bytes.Buffer)
cmd.SetOut(buf)

// Run add command
cmd.SetArgs([]string{"myalias", "echo", "hello"})
err := cmd.Execute()
if err != nil {
t.Errorf("add command failed: %v", err)
}

// Check output
output := buf.String()
if output == "" {
t.Error("Expected output from add command, got empty string")
}

// Verify alias was saved
aliases, err := alias.Load()
if err != nil {
t.Errorf("Failed to load aliases: %v", err)
}

serverAlias, exists := aliases["myalias"]
if !exists {
t.Error("Alias 'myalias' was not saved")
} else if serverAlias.Command != "echo hello" {
t.Errorf("Incorrect command stored. Expected 'echo hello', got '%s'", serverAlias.Command)
}
})

// Test alias list command
t.Run("list", func(t *testing.T) {
// First verify the alias exists
aliases, err := alias.Load()
if err != nil {
t.Errorf("Failed to load aliases: %v", err)
}

if _, exists := aliases["myalias"]; !exists {
t.Log("Alias 'myalias' not found, adding it for list test")
// Add it back if missing
aliases["myalias"] = alias.ServerAlias{Command: "echo hello"}
err = alias.Save(aliases)
if err != nil {
t.Fatalf("Failed to save alias for test: %v", err)
}
}

// Setup cmd
cmd := aliasListCmd()
buf := new(bytes.Buffer)
cmd.SetOut(buf)

// Run list command
err = cmd.Execute()
if err != nil {
t.Errorf("list command failed: %v", err)
}

// Check output
output := buf.String()
if !bytes.Contains(buf.Bytes(), []byte("myalias")) {
t.Errorf("Expected output to contain 'myalias', got: %s", output)
}
if !bytes.Contains(buf.Bytes(), []byte("echo hello")) {
t.Errorf("Expected output to contain 'echo hello', got: %s", output)
}
})

// Test alias remove command
t.Run("remove", func(t *testing.T) {
// First verify the alias exists
aliases, err := alias.Load()
if err != nil {
t.Errorf("Failed to load aliases: %v", err)
}

if _, exists := aliases["myalias"]; !exists {
t.Log("Alias 'myalias' not found, adding it for remove test")
// Add it back if missing
aliases["myalias"] = alias.ServerAlias{Command: "echo hello"}
err = alias.Save(aliases)
if err != nil {
t.Fatalf("Failed to save alias for test: %v", err)
}
}

// Setup cmd
cmd := aliasRemoveCmd()
buf := new(bytes.Buffer)
cmd.SetOut(buf)

// Run remove command
cmd.SetArgs([]string{"myalias"})
err = cmd.Execute()
if err != nil {
t.Errorf("remove command failed: %v", err)
}

// Check output
output := buf.String()
if !bytes.Contains(buf.Bytes(), []byte("removed")) {
t.Errorf("Expected output to contain 'removed', got: %s", output)
}

// Verify alias was removed
updatedAliases, err := alias.Load()
if err != nil {
t.Errorf("Failed to load aliases: %v", err)
}

if _, exists := updatedAliases["myalias"]; exists {
t.Error("Alias 'myalias' was not removed")
}
})

// Test remove non-existent alias
t.Run("remove_nonexistent", func(t *testing.T) {
// Setup cmd
cmd := aliasRemoveCmd()
cmd.SetArgs([]string{"nonexistent"})
err := cmd.Execute()

// Should get an error
if err == nil {
t.Error("Expected error when removing non-existent alias, got nil")
}
})

// Test main alias command
t.Run("main_command_help", func(t *testing.T) {
cmd := AliasCmd()
buf := new(bytes.Buffer)
cmd.SetOut(buf)

cmd.SetArgs([]string{"--help"})
err := cmd.Execute()
if err != nil {
t.Errorf("main alias help command failed: %v", err)
}

output := buf.String()
if output == "" {
t.Error("Expected help output for main alias command, got empty string")
}
})
}
Loading