Skip to content

Commit

Permalink
✨ Split tools into their own files
Browse files Browse the repository at this point in the history
  • Loading branch information
wesen committed Jan 24, 2025
1 parent 792daa8 commit 78be450
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 285 deletions.
62 changes: 62 additions & 0 deletions cmd/mcp-client/cmds/helpers/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package helpers

import (
"context"
"fmt"

"github.com/go-go-golems/go-go-mcp/pkg/client"
"github.com/go-go-golems/go-go-mcp/pkg/protocol"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

// CreateClient initializes and returns a new MCP client based on the provided flags.
func CreateClient(cmd *cobra.Command) (*client.Client, error) {
transport, err := cmd.Flags().GetString("transport")
if err != nil {
return nil, fmt.Errorf("failed to get transport flag: %w", err)
}

serverURL, err := cmd.Flags().GetString("server")
if err != nil {
return nil, fmt.Errorf("failed to get server flag: %w", err)
}

cmdArgs, err := cmd.Flags().GetStringSlice("command")
if err != nil {
return nil, fmt.Errorf("failed to get command flag: %w", err)
}

var t client.Transport

switch transport {
case "command":
if len(cmdArgs) == 0 {
return nil, fmt.Errorf("command is required for command transport")
}
log.Debug().Msgf("Creating command transport with args: %v", cmdArgs)
t, err = client.NewCommandStdioTransport(log.Logger, cmdArgs[0], cmdArgs[1:]...)
if err != nil {
return nil, fmt.Errorf("failed to create command transport: %w", err)
}
case "sse":
log.Debug().Msgf("Creating SSE transport with server URL: %s", serverURL)
t = client.NewSSETransport(serverURL, log.Logger)
default:
return nil, fmt.Errorf("invalid transport type: %s", transport)
}

// Create and initialize client
c := client.NewClient(log.Logger, t)
log.Debug().Msgf("Initializing client")
err = c.Initialize(context.Background(), protocol.ClientCapabilities{
Sampling: &protocol.SamplingCapability{},
})
if err != nil {
return nil, fmt.Errorf("failed to initialize client: %w", err)
}

log.Debug().Msgf("Client initialized")

return c, nil
}
91 changes: 91 additions & 0 deletions cmd/mcp-client/cmds/prompts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package cmds

import (
"encoding/json"
"fmt"

"github.com/go-go-golems/go-go-mcp/cmd/mcp-client/cmds/helpers"
"github.com/spf13/cobra"
)

var (
promptArgs string
)

// PromptsCmd handles the "prompts" command group
var PromptsCmd = &cobra.Command{
Use: "prompts",
Short: "Interact with prompts",
Long: `List available prompts and execute specific prompts.`,
}

var listPromptsCmd = &cobra.Command{
Use: "list",
Short: "List available prompts",
RunE: func(cmd *cobra.Command, args []string) error {
client, err := helpers.CreateClient(cmd)
if err != nil {
return err
}
defer client.Close(cmd.Context())

prompts, cursor, err := client.ListPrompts(cmd.Context(), "")
if err != nil {
return err
}

for _, prompt := range prompts {
fmt.Printf("Name: %s\n", prompt.Name)
fmt.Printf("Description: %s\n", prompt.Description)
fmt.Printf("Arguments:\n")
for _, arg := range prompt.Arguments {
fmt.Printf(" - %s (required: %v): %s\n",
arg.Name, arg.Required, arg.Description)
}
fmt.Println()
}

if cursor != "" {
fmt.Printf("Next cursor: %s\n", cursor)
}

return nil
},
}

var executePromptCmd = &cobra.Command{
Use: "execute [prompt-name]",
Short: "Execute a specific prompt",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
client, err := helpers.CreateClient(cmd)
if err != nil {
return err
}
defer client.Close(cmd.Context())

// Parse prompt arguments
promptArgMap := make(map[string]string)
if promptArgs != "" {
if err := json.Unmarshal([]byte(promptArgs), &promptArgMap); err != nil {
return fmt.Errorf("invalid prompt arguments JSON: %w", err)
}
}

message, err := client.GetPrompt(cmd.Context(), args[0], promptArgMap)
if err != nil {
return err
}

// Pretty print the response
fmt.Printf("Role: %s\n", message.Role)
fmt.Printf("Content: %s\n", message.Content.Text)
return nil
},
}

func init() {
PromptsCmd.AddCommand(listPromptsCmd)
PromptsCmd.AddCommand(executePromptCmd)
executePromptCmd.Flags().StringVarP(&promptArgs, "args", "a", "", "Prompt arguments as JSON string")
}
74 changes: 74 additions & 0 deletions cmd/mcp-client/cmds/resources.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package cmds

import (
"fmt"

"github.com/go-go-golems/go-go-mcp/cmd/mcp-client/cmds/helpers"
"github.com/spf13/cobra"
)

// ResourcesCmd handles the "resources" command group
var ResourcesCmd = &cobra.Command{
Use: "resources",
Short: "Interact with resources",
Long: `List available resources and read specific resources.`,
}

var listResourcesCmd = &cobra.Command{
Use: "list",
Short: "List available resources",
RunE: func(cmd *cobra.Command, args []string) error {
client, err := helpers.CreateClient(cmd)
if err != nil {
return err
}
defer client.Close(cmd.Context())

resources, cursor, err := client.ListResources(cmd.Context(), "")
if err != nil {
return err
}

for _, resource := range resources {
fmt.Printf("URI: %s\n", resource.URI)
fmt.Printf("Name: %s\n", resource.Name)
fmt.Printf("Description: %s\n", resource.Description)
fmt.Printf("MimeType: %s\n", resource.MimeType)
fmt.Println()
}

if cursor != "" {
fmt.Printf("Next cursor: %s\n", cursor)
}

return nil
},
}

var readResourceCmd = &cobra.Command{
Use: "read [resource-uri]",
Short: "Read a specific resource",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
client, err := helpers.CreateClient(cmd)
if err != nil {
return err
}
defer client.Close(cmd.Context())

content, err := client.ReadResource(cmd.Context(), args[0])
if err != nil {
return err
}

fmt.Printf("URI: %s\n", content.URI)
fmt.Printf("MimeType: %s\n", content.MimeType)
fmt.Printf("Content:\n%s\n", content.Text)
return nil
},
}

func init() {
ResourcesCmd.AddCommand(listResourcesCmd)
ResourcesCmd.AddCommand(readResourceCmd)
}
95 changes: 95 additions & 0 deletions cmd/mcp-client/cmds/tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package cmds

import (
"encoding/json"
"fmt"

"github.com/go-go-golems/go-go-mcp/cmd/mcp-client/cmds/helpers"
"github.com/spf13/cobra"
)

var (
toolArgs string
)

// ToolsCmd handles the "tools" command group
var ToolsCmd = &cobra.Command{
Use: "tools",
Short: "Interact with tools",
Long: `List available tools and execute specific tools.`,
}

var listToolsCmd = &cobra.Command{
Use: "list",
Short: "List available tools",
RunE: func(cmd *cobra.Command, args []string) error {
client, err := helpers.CreateClient(cmd)
if err != nil {
return err
}
defer client.Close(cmd.Context())

tools, cursor, err := client.ListTools(cmd.Context(), "")
if err != nil {
return err
}

for _, tool := range tools {
fmt.Printf("Name: %s\n", tool.Name)
fmt.Printf("Description: %s\n", tool.Description)
fmt.Println()
}

if cursor != "" {
fmt.Printf("Next cursor: %s\n", cursor)
}

return nil
},
}

var callToolCmd = &cobra.Command{
Use: "call [tool-name]",
Short: "Call a specific tool",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
client, err := helpers.CreateClient(cmd)
if err != nil {
return err
}
defer client.Close(cmd.Context())

// Parse tool arguments
toolArgMap := make(map[string]interface{})
if toolArgs != "" {
if err := json.Unmarshal([]byte(toolArgs), &toolArgMap); err != nil {
return fmt.Errorf("invalid tool arguments JSON: %w", err)
}
}

result, err := client.CallTool(cmd.Context(), args[0], toolArgMap)
if err != nil {
return err
}

// Pretty print the result
for _, content := range result.Content {
fmt.Printf("Type: %s\n", content.Type)
if content.Type == "text" {
fmt.Printf("Content:\n%s\n", content.Text)
} else if content.Type == "image" {
fmt.Printf("Image:\n%s\n", content.Data)
} else if content.Type == "resource" {
fmt.Printf("URI: %s\n", content.Resource.URI)
fmt.Printf("MimeType: %s\n", content.Resource.MimeType)
}
}
return nil
},
}

func init() {
ToolsCmd.AddCommand(listToolsCmd)
ToolsCmd.AddCommand(callToolCmd)
callToolCmd.Flags().StringVarP(&toolArgs, "args", "a", "", "Tool arguments as JSON string")
}
25 changes: 25 additions & 0 deletions cmd/mcp-client/cmds/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cmds

import (
"fmt"

"github.com/spf13/cobra"
)

// Version information
var (
Version = "dev"
BuildTime = "unknown"
GitCommit = "none"
)

// VersionCmd handles the "version" command
var VersionCmd = &cobra.Command{
Use: "version",
Short: "Print version information",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("mcp-client version %s\n", Version)
fmt.Printf(" Build time: %s\n", BuildTime)
fmt.Printf(" Git commit: %s\n", GitCommit)
},
}
Loading

0 comments on commit 78be450

Please sign in to comment.