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}