package harness import ( "bufio" "encoding/json" "fmt" "net" "sync" ) type MCPClient struct { conn net.Conn r *bufio.Reader mu sync.Mutex next int } type RPCError struct { Code int `json:"code"` Message string `json:"message"` Data any `json:"data,omitempty"` } func (e *RPCError) Error() string { return fmt.Sprintf("json-rpc error %d: %s", e.Code, e.Message) } func DialMCP(socket string) (*MCPClient, error) { conn, err := net.Dial("unix", socket) if err != nil { return nil, err } if _, err := conn.Write([]byte("{\"patterm_identity\":\"harness\"}\n")); err != nil { _ = conn.Close() return nil, err } return &MCPClient{conn: conn, r: bufio.NewReader(conn)}, nil } func (c *MCPClient) Close() error { if c == nil || c.conn == nil { return nil } return c.conn.Close() } func (c *MCPClient) Call(method string, params any) (json.RawMessage, error) { c.mu.Lock() defer c.mu.Unlock() c.next++ req := map[string]any{ "jsonrpc": "2.0", "id": c.next, "method": method, } if params != nil { req["params"] = params } b, err := json.Marshal(req) if err != nil { return nil, err } b = append(b, '\n') if _, err := c.conn.Write(b); err != nil { return nil, err } line, err := c.r.ReadBytes('\n') if err != nil { return nil, err } var resp struct { Result json.RawMessage `json:"result"` Error *RPCError `json:"error"` } if err := json.Unmarshal(line, &resp); err != nil { return nil, fmt.Errorf("parse response: %w: %s", err, string(line)) } if resp.Error != nil { return nil, resp.Error } return resp.Result, nil }