package mcpclient import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "time" ) // Client is a client for the Sequential Thinking MCP server type Client struct { baseURL string httpClient *http.Client } // ToolRequest represents a request to call an MCP tool type ToolRequest struct { Tool string `json:"tool"` Payload map[string]interface{} `json:"payload"` } // ToolResponse represents the response from an MCP tool call type ToolResponse struct { Result interface{} `json:"result,omitempty"` Error string `json:"error,omitempty"` } // New creates a new MCP client func New(baseURL string) *Client { return &Client{ baseURL: baseURL, httpClient: &http.Client{ Timeout: 120 * time.Second, // Longer timeout for thinking operations }, } } // Health checks if the MCP server is healthy func (c *Client) Health(ctx context.Context) error { req, err := http.NewRequestWithContext(ctx, "GET", c.baseURL+"/health", nil) if err != nil { return fmt.Errorf("create request: %w", err) } resp, err := c.httpClient.Do(req) if err != nil { return fmt.Errorf("http request: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return fmt.Errorf("health check failed: status %d", resp.StatusCode) } return nil } // CallTool calls an MCP tool func (c *Client) CallTool(ctx context.Context, req *ToolRequest) (*ToolResponse, error) { jsonData, err := json.Marshal(req) if err != nil { return nil, fmt.Errorf("marshal request: %w", err) } httpReq, err := http.NewRequestWithContext(ctx, "POST", c.baseURL+"/mcp/tool", bytes.NewReader(jsonData)) if err != nil { return nil, fmt.Errorf("create request: %w", err) } httpReq.Header.Set("Content-Type", "application/json") resp, err := c.httpClient.Do(httpReq) if err != nil { return nil, fmt.Errorf("http request: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("read response: %w", err) } if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("tool call failed: status %d, body: %s", resp.StatusCode, string(body)) } var toolResp ToolResponse if err := json.Unmarshal(body, &toolResp); err != nil { return nil, fmt.Errorf("unmarshal response: %w", err) } if toolResp.Error != "" { return nil, fmt.Errorf("tool error: %s", toolResp.Error) } return &toolResp, nil }