package mcp import ( "context" "encoding/json" "net/http" "github.com/mathiasbq/supervisor/internal/registry" ) type request struct { JSONRPC string `json:"jsonrpc"` ID any `json:"id"` Method string `json:"method"` Params json.RawMessage `json:"params"` } type response struct { JSONRPC string `json:"jsonrpc"` ID any `json:"id,omitempty"` Result any `json:"result,omitempty"` Error *rpcError `json:"error,omitempty"` } type rpcError struct { Code int `json:"code"` Message string `json:"message"` } // Server is an HTTP handler implementing the MCP JSON-RPC protocol. type Server struct { reg *registry.Registry } func NewServer(reg *registry.Registry) *Server { return &Server{reg: reg} } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { var req request if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, nil, -32700, "parse error") return } var result any var rpcErr *rpcError switch req.Method { case "initialize": result = map[string]any{ "protocolVersion": "2024-11-05", "capabilities": map[string]any{"tools": map[string]any{}}, "serverInfo": map[string]any{"name": "supervisor", "version": "0.1.0"}, } case "tools/list": result = map[string]any{"tools": s.reg.Tools()} case "tools/call": var p struct { Name string `json:"name"` Arguments json.RawMessage `json:"arguments"` } if err := json.Unmarshal(req.Params, &p); err != nil { rpcErr = &rpcError{Code: -32602, Message: "invalid params"} break } out, err := s.reg.Dispatch(context.Background(), p.Name, p.Arguments) if err != nil { rpcErr = &rpcError{Code: -32000, Message: err.Error()} break } result = map[string]any{ "content": []map[string]any{{"type": "text", "text": string(out)}}, } default: rpcErr = &rpcError{Code: -32601, Message: "method not found: " + req.Method} } w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(response{ JSONRPC: "2.0", ID: req.ID, Result: result, Error: rpcErr, }) } func writeError(w http.ResponseWriter, id any, code int, msg string) { w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(response{ JSONRPC: "2.0", ID: id, Error: &rpcError{Code: code, Message: msg}, }) }