mcp.go

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