use serde::{
Deserialize,
Serialize,
};
pub const PROTOCOL_VERSION: &str = "2025-03-26";
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeParams {
pub protocol_version: String,
#[serde(default)]
pub capabilities: ClientCapabilities,
#[serde(default)]
pub client_info: Option<Implementation>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientCapabilities {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub experimental: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Implementation {
pub name: String,
pub version: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeResult {
pub protocol_version: String,
pub capabilities: ServerCapabilities,
pub server_info: Implementation,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct ServerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<ToolsCapability>,
}
#[derive(Debug, Clone, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ToolsCapability {
pub list_changed: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ListToolsParams {
#[serde(default)]
pub cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListToolsResult {
pub tools: Vec<ToolDescriptor>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ToolDescriptor {
pub name: String,
pub description: String,
pub input_schema: serde_json::Value,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CallToolParams {
pub name: String,
#[serde(default)]
pub arguments: serde_json::Value,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallToolResult {
pub content: Vec<Content>,
#[serde(default)]
pub is_error: bool,
}
#[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum Content {
Text { text: String },
}
impl Content {
pub fn text(s: impl Into<String>) -> Self {
Self::Text { text: s.into() }
}
}
impl CallToolResult {
pub fn ok_text(s: impl Into<String>) -> Self {
Self {
content: vec![Content::text(s)],
is_error: false,
}
}
pub fn ok_json(value: &serde_json::Value) -> Self {
let text = serde_json::to_string_pretty(value).unwrap_or_default();
Self {
content: vec![Content::text(text)],
is_error: false,
}
}
pub fn error_text(s: impl Into<String>) -> Self {
Self {
content: vec![Content::text(s)],
is_error: true,
}
}
}