1use crate::error::Error;
6use crate::error::Result;
7use serde::Deserialize;
8use serde::Serialize;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[repr(u8)]
13pub enum MessageType {
14 Init = 0x01,
16 InitAck = 0x02,
17
18 ListTools = 0x10,
20 ListToolsResponse = 0x11,
21 CallTool = 0x12,
22 CallToolResponse = 0x13,
23
24 ListResources = 0x20,
26 ListResourcesResponse = 0x21,
27 ReadResource = 0x22,
28 ReadResourceResponse = 0x23,
29
30 ListPrompts = 0x30,
32 ListPromptsResponse = 0x31,
33 GetPrompt = 0x32,
34 GetPromptResponse = 0x33,
35
36 AddServer = 0x40,
38 AddServerResponse = 0x41,
39 RemoveServer = 0x42,
40 RemoveServerResponse = 0x43,
41 ListServers = 0x44,
42 ListServersResponse = 0x45,
43
44 Error = 0xFE,
46 Close = 0xFF,
47}
48
49impl TryFrom<u8> for MessageType {
50 type Error = Error;
51
52 fn try_from(value: u8) -> Result<Self> {
53 match value {
54 0x01 => Ok(Self::Init),
55 0x02 => Ok(Self::InitAck),
56 0x10 => Ok(Self::ListTools),
57 0x11 => Ok(Self::ListToolsResponse),
58 0x12 => Ok(Self::CallTool),
59 0x13 => Ok(Self::CallToolResponse),
60 0x20 => Ok(Self::ListResources),
61 0x21 => Ok(Self::ListResourcesResponse),
62 0x22 => Ok(Self::ReadResource),
63 0x23 => Ok(Self::ReadResourceResponse),
64 0x30 => Ok(Self::ListPrompts),
65 0x31 => Ok(Self::ListPromptsResponse),
66 0x32 => Ok(Self::GetPrompt),
67 0x33 => Ok(Self::GetPromptResponse),
68 0x40 => Ok(Self::AddServer),
69 0x41 => Ok(Self::AddServerResponse),
70 0x42 => Ok(Self::RemoveServer),
71 0x43 => Ok(Self::RemoveServerResponse),
72 0x44 => Ok(Self::ListServers),
73 0x45 => Ok(Self::ListServersResponse),
74 0xFE => Ok(Self::Error),
75 0xFF => Ok(Self::Close),
76 _ => Err(Error::InvalidMessageType(value)),
77 }
78 }
79}
80
81#[derive(Debug, Clone)]
83pub enum Message {
84 Init(ClientInfo),
86 InitAck(ServerInfo),
87
88 ListTools,
90 ListToolsResponse(Vec<Tool>),
91 CallTool(ToolCall),
92 CallToolResponse(ToolResult),
93
94 ListResources,
96 ListResourcesResponse(Vec<Resource>),
97 ReadResource(String),
98 ReadResourceResponse(ResourceContent),
99
100 ListPrompts,
102 ListPromptsResponse(Vec<Prompt>),
103 GetPrompt(GetPromptRequest),
104 GetPromptResponse(Vec<PromptMessage>),
105
106 AddServer(AddServerRequest),
108 AddServerResponse(String),
109 RemoveServer(String),
110 RemoveServerResponse(bool),
111 ListServers,
112 ListServersResponse(Vec<ConnectedServer>),
113
114 Error(ErrorMessage),
116 Close,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct ClientInfo {
122 pub name: String,
123 pub version: String,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct ServerInfo {
129 pub name: String,
130 pub version: String,
131 pub capabilities: Capabilities,
132}
133
134#[derive(Debug, Clone, Default, Serialize, Deserialize)]
136pub struct Capabilities {
137 pub tools: bool,
138 pub resources: bool,
139 pub prompts: bool,
140 pub logging: bool,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct Tool {
146 pub name: String,
147 pub description: String,
148 #[serde(rename = "inputSchema")]
149 pub input_schema: serde_json::Value,
150 #[serde(default)]
151 pub annotations: std::collections::HashMap<String, String>,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct ToolCall {
157 pub id: String,
158 pub name: String,
159 #[serde(rename = "arguments")]
160 pub args: serde_json::Value,
161 #[serde(default)]
162 pub metadata: std::collections::HashMap<String, String>,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct ToolResult {
168 pub id: String,
169 pub content: serde_json::Value,
170 #[serde(skip_serializing_if = "Option::is_none")]
171 pub error: Option<String>,
172 #[serde(default)]
173 pub metadata: std::collections::HashMap<String, String>,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct Resource {
179 pub uri: String,
180 pub name: String,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 pub description: Option<String>,
183 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
184 pub mime_type: Option<String>,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct ResourceContent {
190 pub uri: String,
191 #[serde(rename = "mimeType")]
192 pub mime_type: String,
193 pub content: ResourceContentType,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198#[serde(untagged)]
199pub enum ResourceContentType {
200 Text(String),
201 Binary(Vec<u8>),
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct Prompt {
207 pub name: String,
208 pub description: String,
209 #[serde(default)]
210 pub arguments: Vec<PromptArgument>,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct PromptArgument {
216 pub name: String,
217 pub description: String,
218 pub required: bool,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
223pub struct PromptMessage {
224 pub role: PromptRole,
225 pub content: String,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize)]
230#[serde(rename_all = "lowercase")]
231pub enum PromptRole {
232 User,
233 Assistant,
234 System,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct GetPromptRequest {
240 pub name: String,
241 #[serde(default)]
242 pub arguments: std::collections::HashMap<String, String>,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct AddServerRequest {
248 pub name: String,
249 pub url: String,
250 #[serde(skip_serializing_if = "Option::is_none")]
251 pub auth: Option<String>,
252}
253
254#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct ConnectedServer {
257 pub id: String,
258 pub name: String,
259 pub url: String,
260 pub status: ServerStatus,
261 pub tools: u32,
262 pub resources: u32,
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize)]
267#[serde(rename_all = "lowercase")]
268pub enum ServerStatus {
269 Connecting,
270 Connected,
271 Disconnected,
272 Error,
273}
274
275#[derive(Debug, Clone, Serialize, Deserialize)]
277pub struct ErrorMessage {
278 pub code: i32,
279 pub message: String,
280}