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}