1use serde::{Deserialize, Serialize};
2use std::{collections::HashMap, fmt::Display};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct McpToolSchema {
7 #[serde(rename = "type")]
8 pub tool_type: String,
9 pub function: McpFunctionSchema,
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct McpFunctionSchema {
15 pub name: String,
16 pub description: Option<String>,
17 pub parameters: serde_json::Value,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct McpToolResult {
23 pub content: Vec<McpContent>,
24 pub is_error: Option<bool>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29#[serde(tag = "type")]
30pub enum McpContent {
31 #[serde(rename = "text")]
32 Text { text: String },
33 #[serde(rename = "image")]
34 Image { data: String, mime_type: String },
35 #[serde(rename = "resource")]
36 Resource { resource: McpResourceReference },
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct McpResourceReference {
42 pub uri: String,
43 pub text: Option<String>,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct McpServerCapabilities {
49 pub tools: Option<HashMap<String, serde_json::Value>>,
50 pub resources: Option<HashMap<String, serde_json::Value>>,
51 pub prompts: Option<HashMap<String, serde_json::Value>>,
52 pub logging: Option<HashMap<String, serde_json::Value>>,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct McpInitResult {
58 pub protocol_version: String,
59 pub capabilities: McpServerCapabilities,
60 pub server_info: McpServerInfo,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct McpServerInfo {
66 pub name: String,
67 pub version: String,
68}
69
70impl From<crate::McpToolInfo> for McpToolSchema {
71 fn from(tool_info: crate::McpToolInfo) -> Self {
72 Self {
73 tool_type: "function".to_string(),
74 function: McpFunctionSchema {
75 name: tool_info.name,
76 description: tool_info.description,
77 parameters: tool_info.input_schema,
78 },
79 }
80 }
81}
82
83impl Display for McpToolResult {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 let res = self
86 .content
87 .iter()
88 .map(|content| match content {
89 McpContent::Text { text } => text.clone(),
90 McpContent::Image { mime_type, .. } => {
91 format!("[Image: {mime_type}]")
92 }
93 McpContent::Resource { resource } => resource
94 .text
95 .clone()
96 .unwrap_or_else(|| format!("[Resource: {}]", resource.uri)),
97 })
98 .collect::<Vec<_>>()
99 .join("\n");
100
101 write!(f, "{res}")
102 }
103}