Skip to main content

agentic_evolve_mcp/types/
response.rs

1//! MCP response types for tools, resources, and prompts.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// Content types that can be returned by tools.
7#[derive(Debug, Clone, Serialize, Deserialize)]
8#[serde(tag = "type")]
9pub enum ToolContent {
10    /// Text content.
11    #[serde(rename = "text")]
12    Text {
13        /// The text content.
14        text: String,
15    },
16    /// Image content (base64-encoded).
17    #[serde(rename = "image")]
18    Image {
19        /// Base64-encoded image data.
20        data: String,
21        /// MIME type (e.g. "image/png").
22        #[serde(rename = "mimeType")]
23        mime_type: String,
24    },
25    /// Embedded resource content.
26    #[serde(rename = "resource")]
27    Resource {
28        /// The embedded resource.
29        resource: ResourceContent,
30    },
31}
32
33/// Result from a tools/call invocation.
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct ToolCallResult {
36    /// Content returned by the tool.
37    pub content: Vec<ToolContent>,
38    /// Whether the tool call errored.
39    #[serde(default, rename = "isError", skip_serializing_if = "Option::is_none")]
40    pub is_error: Option<bool>,
41}
42
43impl ToolCallResult {
44    /// Create a successful text result.
45    pub fn text(text: String) -> Self {
46        Self {
47            content: vec![ToolContent::Text { text }],
48            is_error: None,
49        }
50    }
51
52    /// Create a JSON result.
53    pub fn json(value: &impl Serialize) -> Self {
54        let text = serde_json::to_string_pretty(value).unwrap_or_else(|e| e.to_string());
55        Self::text(text)
56    }
57
58    /// Create an error result.
59    pub fn error(message: String) -> Self {
60        Self {
61            content: vec![ToolContent::Text { text: message }],
62            is_error: Some(true),
63        }
64    }
65}
66
67/// Tool definition for tools/list.
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct ToolDefinition {
70    /// Tool name (unique).
71    pub name: String,
72    /// Human-readable description.
73    #[serde(default, skip_serializing_if = "Option::is_none")]
74    pub description: Option<String>,
75    /// JSON Schema for the input parameters.
76    #[serde(rename = "inputSchema")]
77    pub input_schema: Value,
78}
79
80/// Result from tools/list.
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct ToolListResult {
83    /// Available tools.
84    pub tools: Vec<ToolDefinition>,
85    /// Cursor for next page.
86    #[serde(
87        default,
88        rename = "nextCursor",
89        skip_serializing_if = "Option::is_none"
90    )]
91    pub next_cursor: Option<String>,
92}
93
94/// Token conservation metrics returned alongside MCP responses.
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct McpResponseMetrics {
97    /// Which processing layer served this response.
98    pub layer: String,
99    /// Tokens actually consumed.
100    pub tokens_used: u64,
101    /// Tokens saved compared to a full retrieval.
102    pub tokens_saved: u64,
103    /// Whether the result was served from cache.
104    pub cache_hit: bool,
105}
106
107/// Resource content.
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct ResourceContent {
110    /// Resource URI.
111    pub uri: String,
112    /// MIME type.
113    #[serde(default, rename = "mimeType", skip_serializing_if = "Option::is_none")]
114    pub mime_type: Option<String>,
115    /// Text content.
116    #[serde(default, skip_serializing_if = "Option::is_none")]
117    pub text: Option<String>,
118    /// Binary content (base64).
119    #[serde(default, skip_serializing_if = "Option::is_none")]
120    pub blob: Option<String>,
121}
122
123/// Resource definition for resources/list.
124#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct ResourceDefinition {
126    /// Resource URI.
127    pub uri: String,
128    /// Human-readable name.
129    pub name: String,
130    /// Description.
131    #[serde(default, skip_serializing_if = "Option::is_none")]
132    pub description: Option<String>,
133    /// MIME type.
134    #[serde(default, rename = "mimeType", skip_serializing_if = "Option::is_none")]
135    pub mime_type: Option<String>,
136}
137
138/// Result from resources/list.
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct ResourceListResult {
141    /// Available resources.
142    pub resources: Vec<ResourceDefinition>,
143    /// Cursor for next page.
144    #[serde(
145        default,
146        rename = "nextCursor",
147        skip_serializing_if = "Option::is_none"
148    )]
149    pub next_cursor: Option<String>,
150}
151
152/// Prompt argument definition.
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct PromptArgument {
155    /// Argument name.
156    pub name: String,
157    /// Description.
158    #[serde(default, skip_serializing_if = "Option::is_none")]
159    pub description: Option<String>,
160    /// Whether this argument is required.
161    #[serde(default)]
162    pub required: bool,
163}
164
165/// Prompt definition for prompts/list.
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct PromptDefinition {
168    /// Prompt name (unique).
169    pub name: String,
170    /// Human-readable description.
171    #[serde(default, skip_serializing_if = "Option::is_none")]
172    pub description: Option<String>,
173    /// Arguments the prompt accepts.
174    #[serde(default, skip_serializing_if = "Option::is_none")]
175    pub arguments: Option<Vec<PromptArgument>>,
176}
177
178/// Result from prompts/list.
179#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct PromptListResult {
181    /// Available prompts.
182    pub prompts: Vec<PromptDefinition>,
183    /// Cursor for next page.
184    #[serde(
185        default,
186        rename = "nextCursor",
187        skip_serializing_if = "Option::is_none"
188    )]
189    pub next_cursor: Option<String>,
190}
191
192/// A message in a prompt's expanded output.
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct PromptMessage {
195    /// Role: "user" or "assistant".
196    pub role: String,
197    /// Content of the message.
198    pub content: ToolContent,
199}
200
201/// Result from prompts/get.
202#[derive(Debug, Clone, Serialize, Deserialize)]
203pub struct PromptGetResult {
204    /// Optional description for this prompt expansion.
205    #[serde(default, skip_serializing_if = "Option::is_none")]
206    pub description: Option<String>,
207    /// The expanded prompt messages.
208    pub messages: Vec<PromptMessage>,
209}