mcp.go

  1package proto
  2
  3import (
  4	"encoding/json"
  5	"errors"
  6	"fmt"
  7	"time"
  8)
  9
 10// MCPState represents the current state of an MCP client.
 11type MCPState int
 12
 13const (
 14	MCPStateDisabled MCPState = iota
 15	MCPStateStarting
 16	MCPStateConnected
 17	MCPStateError
 18)
 19
 20// MarshalText implements the [encoding.TextMarshaler] interface.
 21func (s MCPState) MarshalText() ([]byte, error) {
 22	return []byte(s.String()), nil
 23}
 24
 25// UnmarshalText implements the [encoding.TextUnmarshaler] interface.
 26func (s *MCPState) UnmarshalText(data []byte) error {
 27	switch string(data) {
 28	case "disabled":
 29		*s = MCPStateDisabled
 30	case "starting":
 31		*s = MCPStateStarting
 32	case "connected":
 33		*s = MCPStateConnected
 34	case "error":
 35		*s = MCPStateError
 36	default:
 37		return fmt.Errorf("unknown mcp state: %s", data)
 38	}
 39	return nil
 40}
 41
 42// String returns the string representation of the MCPState.
 43func (s MCPState) String() string {
 44	switch s {
 45	case MCPStateDisabled:
 46		return "disabled"
 47	case MCPStateStarting:
 48		return "starting"
 49	case MCPStateConnected:
 50		return "connected"
 51	case MCPStateError:
 52		return "error"
 53	default:
 54		return "unknown"
 55	}
 56}
 57
 58// MCPEventType represents the type of MCP event.
 59type MCPEventType string
 60
 61const (
 62	MCPEventStateChanged         MCPEventType = "state_changed"
 63	MCPEventToolsListChanged     MCPEventType = "tools_list_changed"
 64	MCPEventPromptsListChanged   MCPEventType = "prompts_list_changed"
 65	MCPEventResourcesListChanged MCPEventType = "resources_list_changed"
 66)
 67
 68// MarshalText implements the [encoding.TextMarshaler] interface.
 69func (t MCPEventType) MarshalText() ([]byte, error) {
 70	return []byte(t), nil
 71}
 72
 73// UnmarshalText implements the [encoding.TextUnmarshaler] interface.
 74func (t *MCPEventType) UnmarshalText(data []byte) error {
 75	*t = MCPEventType(data)
 76	return nil
 77}
 78
 79// MCPEvent represents an event in the MCP system.
 80type MCPEvent struct {
 81	Type          MCPEventType `json:"type"`
 82	Name          string       `json:"name"`
 83	State         MCPState     `json:"state"`
 84	Error         error        `json:"error,omitempty"`
 85	ToolCount     int          `json:"tool_count,omitempty"`
 86	PromptCount   int          `json:"prompt_count,omitempty"`
 87	ResourceCount int          `json:"resource_count,omitempty"`
 88}
 89
 90// MarshalJSON implements the [json.Marshaler] interface.
 91func (e MCPEvent) MarshalJSON() ([]byte, error) {
 92	type Alias MCPEvent
 93	return json.Marshal(&struct {
 94		Error string `json:"error,omitempty"`
 95		Alias
 96	}{
 97		Error: func() string {
 98			if e.Error != nil {
 99				return e.Error.Error()
100			}
101			return ""
102		}(),
103		Alias: (Alias)(e),
104	})
105}
106
107// UnmarshalJSON implements the [json.Unmarshaler] interface.
108func (e *MCPEvent) UnmarshalJSON(data []byte) error {
109	type Alias MCPEvent
110	aux := &struct {
111		Error string `json:"error,omitempty"`
112		Alias
113	}{
114		Alias: (Alias)(*e),
115	}
116	if err := json.Unmarshal(data, &aux); err != nil {
117		return err
118	}
119	*e = MCPEvent(aux.Alias)
120	if aux.Error != "" {
121		e.Error = errors.New(aux.Error)
122	}
123	return nil
124}
125
126// MCPClientInfo is the wire-format representation of an MCP client's
127// state, suitable for JSON transport between server and client.
128type MCPClientInfo struct {
129	Name          string    `json:"name"`
130	State         MCPState  `json:"state"`
131	Error         error     `json:"error,omitempty"`
132	ToolCount     int       `json:"tool_count,omitempty"`
133	PromptCount   int       `json:"prompt_count,omitempty"`
134	ResourceCount int       `json:"resource_count,omitempty"`
135	ConnectedAt   time.Time `json:"connected_at"`
136}
137
138// MarshalJSON implements the [json.Marshaler] interface.
139func (i MCPClientInfo) MarshalJSON() ([]byte, error) {
140	type Alias MCPClientInfo
141	return json.Marshal(&struct {
142		Error string `json:"error,omitempty"`
143		Alias
144	}{
145		Error: func() string {
146			if i.Error != nil {
147				return i.Error.Error()
148			}
149			return ""
150		}(),
151		Alias: (Alias)(i),
152	})
153}
154
155// UnmarshalJSON implements the [json.Unmarshaler] interface.
156func (i *MCPClientInfo) UnmarshalJSON(data []byte) error {
157	type Alias MCPClientInfo
158	aux := &struct {
159		Error string `json:"error,omitempty"`
160		Alias
161	}{
162		Alias: (Alias)(*i),
163	}
164	if err := json.Unmarshal(data, &aux); err != nil {
165		return err
166	}
167	*i = MCPClientInfo(aux.Alias)
168	if aux.Error != "" {
169		i.Error = errors.New(aux.Error)
170	}
171	return nil
172}