Skip to main content

hanzo_zap/
message.rs

1//! ZAP message types.
2//!
3//! These types are compatible with MCP semantics but use binary encoding.
4
5use crate::error::Error;
6use crate::error::Result;
7use serde::Deserialize;
8use serde::Serialize;
9
10/// Message types for ZAP protocol.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[repr(u8)]
13pub enum MessageType {
14    // Handshake
15    Init = 0x01,
16    InitAck = 0x02,
17
18    // Tool operations
19    ListTools = 0x10,
20    ListToolsResponse = 0x11,
21    CallTool = 0x12,
22    CallToolResponse = 0x13,
23
24    // Resource operations
25    ListResources = 0x20,
26    ListResourcesResponse = 0x21,
27    ReadResource = 0x22,
28    ReadResourceResponse = 0x23,
29
30    // Prompt operations
31    ListPrompts = 0x30,
32    ListPromptsResponse = 0x31,
33    GetPrompt = 0x32,
34    GetPromptResponse = 0x33,
35
36    // Gateway operations
37    AddServer = 0x40,
38    AddServerResponse = 0x41,
39    RemoveServer = 0x42,
40    RemoveServerResponse = 0x43,
41    ListServers = 0x44,
42    ListServersResponse = 0x45,
43
44    // Control
45    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/// A ZAP message.
82#[derive(Debug, Clone)]
83pub enum Message {
84    // Handshake
85    Init(ClientInfo),
86    InitAck(ServerInfo),
87
88    // Tools
89    ListTools,
90    ListToolsResponse(Vec<Tool>),
91    CallTool(ToolCall),
92    CallToolResponse(ToolResult),
93
94    // Resources
95    ListResources,
96    ListResourcesResponse(Vec<Resource>),
97    ReadResource(String),
98    ReadResourceResponse(ResourceContent),
99
100    // Prompts
101    ListPrompts,
102    ListPromptsResponse(Vec<Prompt>),
103    GetPrompt(GetPromptRequest),
104    GetPromptResponse(Vec<PromptMessage>),
105
106    // Gateway
107    AddServer(AddServerRequest),
108    AddServerResponse(String),
109    RemoveServer(String),
110    RemoveServerResponse(bool),
111    ListServers,
112    ListServersResponse(Vec<ConnectedServer>),
113
114    // Control
115    Error(ErrorMessage),
116    Close,
117}
118
119/// Client information for handshake.
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct ClientInfo {
122    pub name: String,
123    pub version: String,
124}
125
126/// Server information for handshake.
127#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct ServerInfo {
129    pub name: String,
130    pub version: String,
131    pub capabilities: Capabilities,
132}
133
134/// Server capabilities.
135#[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/// A tool definition (MCP-compatible).
144#[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/// A tool call request.
155#[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/// A tool call result.
166#[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/// A resource definition (MCP-compatible).
177#[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/// Resource content.
188#[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/// Resource content type (text or binary).
197#[derive(Debug, Clone, Serialize, Deserialize)]
198#[serde(untagged)]
199pub enum ResourceContentType {
200    Text(String),
201    Binary(Vec<u8>),
202}
203
204/// A prompt definition (MCP-compatible).
205#[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/// A prompt argument.
214#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct PromptArgument {
216    pub name: String,
217    pub description: String,
218    pub required: bool,
219}
220
221/// A prompt message.
222#[derive(Debug, Clone, Serialize, Deserialize)]
223pub struct PromptMessage {
224    pub role: PromptRole,
225    pub content: String,
226}
227
228/// Prompt message role.
229#[derive(Debug, Clone, Serialize, Deserialize)]
230#[serde(rename_all = "lowercase")]
231pub enum PromptRole {
232    User,
233    Assistant,
234    System,
235}
236
237/// Get prompt request.
238#[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/// Add server request.
246#[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/// Connected server info.
255#[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/// Server status.
266#[derive(Debug, Clone, Serialize, Deserialize)]
267#[serde(rename_all = "lowercase")]
268pub enum ServerStatus {
269    Connecting,
270    Connected,
271    Disconnected,
272    Error,
273}
274
275/// Error message.
276#[derive(Debug, Clone, Serialize, Deserialize)]
277pub struct ErrorMessage {
278    pub code: i32,
279    pub message: String,
280}