use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use derive_builder::Builder;
#[derive(Debug, Clone, Serialize, Deserialize, Default, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpServerInitializeResult {
pub protocol_version: String,
pub capabilities: McpServerCapabilities,
pub server_info: McpImplementation,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub instructions: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpClientInitializeResult {
pub protocol_version: String,
pub client_info: Option<McpImplementation>,
pub capabilities: Option<McpClientCapabilities>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpServerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub experimental: Option<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub logging: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub prompts: Option<McpPromptsCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub resources: Option<McpResourceCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub tools: Option<McpToolsCapability>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpPromptsCapability {
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub list_changed: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpResourceCapability {
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub subscribe: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub list_changed: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpToolsCapability {
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub list_changed: Option<bool>,
}
#[derive(Debug, Serialize, Clone, Deserialize, Default, Builder)]
pub struct McpImplementation {
pub name: String,
pub version: String,
}
#[derive(Debug, Serialize, Clone, Deserialize, Default)]
pub struct McpClientCapabilities {
pub custom: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpTool {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub description: Option<String>,
pub input_schema: McpToolInputSchema,
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpToolInputSchema {
#[builder(default = "String::from(\"object\")")]
pub r#type: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub properties: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub required: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
pub struct McpToolCall {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub arguments: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
pub struct McpToolCallResult {
pub content: Vec<McpToolCallResultContent>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_error: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum McpToolCallResultContent {
Text { text: String },
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
#[serde(rename_all = "camelCase")]
pub struct McpResource {
pub uri: String,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub mime_type: String,
}
#[allow(unused)]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_de_tool_call_result() {
let res = McpToolCallResult{
content: vec![ McpToolCallResultContent::Text { text: "molesir".to_string() } ],
is_error: Some(false)
};
assert_eq!(
serde_json::to_value(res).unwrap(),
serde_json::json!(
{
"content": [
{
"type": "text",
"text": "molesir"
}
],
"is_error": false
}
)
);
}
}