use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "method")]
pub enum MCPRequest {
#[serde(rename = "initialize")]
Initialize {
id: String,
params: InitializeParams,
},
#[serde(rename = "tools/list")]
ListTools { id: String },
#[serde(rename = "tools/call")]
CallTool { id: String, params: ToolCallParams },
#[serde(rename = "notifications/initialized")]
Initialized,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum MCPResponse {
#[serde(rename = "result")]
Result { id: String, result: ResponseResult },
#[serde(rename = "error")]
Error { id: String, error: MCPError },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ResponseResult {
Initialize(InitializeResult),
ListTools(ListToolsResult),
CallTool(CallToolResult),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InitializeParams {
pub protocol_version: String,
pub capabilities: ClientCapabilities,
pub client_info: ClientInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InitializeResult {
pub protocol_version: String,
pub capabilities: ServerCapabilities,
pub server_info: ServerInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClientCapabilities {
pub roots: Option<RootsCapability>,
pub sampling: Option<SamplingCapability>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerCapabilities {
pub logging: Option<LoggingCapability>,
pub prompts: Option<PromptsCapability>,
pub resources: Option<ResourcesCapability>,
pub tools: Option<ToolsCapability>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RootsCapability {
pub list_changed: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SamplingCapability {}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoggingCapability {}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PromptsCapability {
pub list_changed: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourcesCapability {
pub subscribe: Option<bool>,
pub list_changed: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolsCapability {
pub list_changed: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClientInfo {
pub name: String,
pub version: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerInfo {
pub name: String,
pub version: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListToolsResult {
pub tools: Vec<ToolDefinition>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolDefinition {
pub name: String,
pub description: Option<String>,
pub input_schema: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolCallParams {
pub name: String,
pub arguments: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CallToolResult {
pub content: Vec<ToolContent>,
pub is_error: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum ToolContent {
#[serde(rename = "text")]
Text { text: String },
#[serde(rename = "image")]
Image { data: String, mime_type: String },
#[serde(rename = "resource")]
Resource { resource: ResourceReference },
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ResourceReference {
pub uri: String,
pub mime_type: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MCPError {
pub code: i32,
pub message: String,
pub data: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum MCPMessage {
Request(MCPRequest),
Response(MCPResponse),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolCall {
pub name: String,
pub arguments: HashMap<String, serde_json::Value>,
}
impl MCPRequest {
pub fn get_id(&self) -> Option<&str> {
match self {
MCPRequest::Initialize { id, .. } => Some(id),
MCPRequest::ListTools { id } => Some(id),
MCPRequest::CallTool { id, .. } => Some(id),
MCPRequest::Initialized => None,
}
}
}
impl MCPResponse {
pub fn get_id(&self) -> &str {
match self {
MCPResponse::Result { id, .. } => id,
MCPResponse::Error { id, .. } => id,
}
}
}