WitNote / internal /mcp /client.go
AUXteam's picture
Upload folder using huggingface_hub
6a7089a verified
// Package mcp provides a native MCP (Model Context Protocol) server for PinchTab.
package mcp
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"
)
// Client is an HTTP client for PinchTab's REST API.
type Client struct {
BaseURL string
Token string
HTTPClient *http.Client
}
// NewClient creates a Client for the given PinchTab base URL.
func NewClient(baseURL, token string) *Client {
return &Client{
BaseURL: baseURL,
Token: token,
HTTPClient: &http.Client{
Timeout: 120 * time.Second,
},
}
}
func (c *Client) url(path string) string {
return c.BaseURL + path
}
func (c *Client) profileInstancePath(profile string) string {
return "/profiles/" + url.PathEscape(profile) + "/instance"
}
func (c *Client) dashboardProfilesURL() string {
return strings.TrimRight(c.BaseURL, "/") + "/dashboard/profiles"
}
func (c *Client) do(req *http.Request) ([]byte, int, error) {
if c.Token != "" {
req.Header.Set("Authorization", "Bearer "+c.Token)
}
resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, 0, fmt.Errorf("request %s %s: %w", req.Method, req.URL.Path, err)
}
defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(io.LimitReader(resp.Body, 10<<20)) // 10 MB limit
if err != nil {
return nil, resp.StatusCode, fmt.Errorf("read response: %w", err)
}
return body, resp.StatusCode, nil
}
// Get performs a GET request and returns the response body.
func (c *Client) Get(ctx context.Context, path string, query url.Values) ([]byte, int, error) {
u := c.url(path)
if len(query) > 0 {
u += "?" + query.Encode()
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, 0, err
}
return c.do(req)
}
// Post performs a POST request with a JSON body.
func (c *Client) Post(ctx context.Context, path string, payload any) ([]byte, int, error) {
var body io.Reader
if payload != nil {
b, err := json.Marshal(payload)
if err != nil {
return nil, 0, fmt.Errorf("marshal payload: %w", err)
}
body = bytes.NewReader(b)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.url(path), body)
if err != nil {
return nil, 0, err
}
if payload != nil {
req.Header.Set("Content-Type", "application/json")
}
return c.do(req)
}