Skip to content
Open
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
83 changes: 48 additions & 35 deletions cmd/mcpcurl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (
"github.com/spf13/viper"
)

const (
stdioServerCmdFlag = "stdio-server-cmd"
)

type (
// SchemaResponse represents the top-level response containing tools
SchemaResponse struct {
Expand Down Expand Up @@ -107,9 +111,9 @@ var (
}

// Check if the required global flag is provided
serverCmd, _ := cmd.Flags().GetString("stdio-server-cmd")
serverCmd, _ := cmd.Flags().GetString(stdioServerCmdFlag)
if serverCmd == "" {
return fmt.Errorf("--stdio-server-cmd is required")
return fmt.Errorf("--%s is required", stdioServerCmdFlag)
}
return nil
},
Expand All @@ -119,11 +123,11 @@ var (
schemaCmd = &cobra.Command{
Use: "schema",
Short: "Fetch schema from MCP server",
Long: "Fetches the tools schema from the MCP server specified by --stdio-server-cmd",
Long: "Fetches the tools schema from the MCP server specified by --" + stdioServerCmdFlag,
RunE: func(cmd *cobra.Command, _ []string) error {
serverCmd, _ := cmd.Flags().GetString("stdio-server-cmd")
serverCmd, _ := cmd.Flags().GetString(stdioServerCmdFlag)
if serverCmd == "" {
return fmt.Errorf("--stdio-server-cmd is required")
return fmt.Errorf("--%s is required", stdioServerCmdFlag)
}

// Build the JSON-RPC request for tools/list
Expand Down Expand Up @@ -153,17 +157,7 @@ var (
)

func main() {
rootCmd.AddCommand(schemaCmd)

// Add global flag for stdio server command
rootCmd.PersistentFlags().String("stdio-server-cmd", "", "Shell command to invoke MCP server via stdio (required)")
_ = rootCmd.MarkPersistentFlagRequired("stdio-server-cmd")

// Add global flag for pretty printing
rootCmd.PersistentFlags().Bool("pretty", true, "Pretty print MCP response (only for JSON or JSONL responses)")

// Add the tools command to the root command
rootCmd.AddCommand(toolsCmd)
setupFlags()

// Execute the root command once to parse flags
_ = rootCmd.ParseFlags(os.Args[1:])
Expand All @@ -174,24 +168,11 @@ func main() {
_, _ = fmt.Fprintf(os.Stderr, "Error getting pretty flag: %v\n", err)
os.Exit(1)
}
// Get server command
serverCmd, err := rootCmd.Flags().GetString("stdio-server-cmd")

// Get server command and load schema if available
serverCmd, err := rootCmd.Flags().GetString(stdioServerCmdFlag)
if err == nil && serverCmd != "" {
// Fetch schema from server
jsonRequest, err := buildJSONRPCRequest("tools/list", "", nil)
if err == nil {
response, err := executeServerCommand(serverCmd, jsonRequest)
if err == nil {
// Parse the schema response
var schemaResp SchemaResponse
if err := json.Unmarshal([]byte(response), &schemaResp); err == nil {
// Add all the generated commands as subcommands of tools
for _, tool := range schemaResp.Result.Tools {
addCommandFromTool(toolsCmd, &tool, prettyPrint)
}
}
}
}
loadSchemaAndAddCommands(serverCmd, prettyPrint)
}

// Execute
Expand All @@ -201,6 +182,38 @@ func main() {
}
}

func setupFlags() {
rootCmd.AddCommand(schemaCmd)

// Add global flag for stdio server command
rootCmd.PersistentFlags().String(stdioServerCmdFlag, "", "Shell command to invoke MCP server via stdio (required)")
_ = rootCmd.MarkPersistentFlagRequired(stdioServerCmdFlag)

// Add global flag for pretty printing
rootCmd.PersistentFlags().Bool("pretty", true, "Pretty print MCP response (only for JSON or JSONL responses)")

// Add the tools command to the root command
rootCmd.AddCommand(toolsCmd)
}

func loadSchemaAndAddCommands(serverCmd string, prettyPrint bool) {
// Fetch schema from server
jsonRequest, err := buildJSONRPCRequest("tools/list", "", nil)
if err == nil {
response, err := executeServerCommand(serverCmd, jsonRequest)
if err == nil {
// Parse the schema response
var schemaResp SchemaResponse
if err := json.Unmarshal([]byte(response), &schemaResp); err == nil {
// Add all the generated commands as subcommands of tools
for _, tool := range schemaResp.Result.Tools {
addCommandFromTool(toolsCmd, &tool, prettyPrint)
}
}
}
}
}

// addCommandFromTool creates a cobra command from a tool schema
func addCommandFromTool(toolsCmd *cobra.Command, tool *Tool, prettyPrint bool) {
// Create command from tool
Expand All @@ -222,9 +235,9 @@ func addCommandFromTool(toolsCmd *cobra.Command, tool *Tool, prettyPrint bool) {
}

// Execute the server command
serverCmd, err := cmd.Flags().GetString("stdio-server-cmd")
serverCmd, err := cmd.Flags().GetString(stdioServerCmdFlag)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "failed to get stdio-server-cmd: %v\n", err)
_, _ = fmt.Fprintf(os.Stderr, "failed to get %s: %v\n", stdioServerCmdFlag, err)
return
}
response, err := executeServerCommand(serverCmd, jsonData)
Expand Down