Skip to main content

mcp_kit/types/
resource.rs

1use serde::{Deserialize, Serialize};
2
3use crate::types::content::ResourceContents;
4
5/// A resource exposed by the server
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct Resource {
9    pub uri: String,
10    pub name: String,
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub description: Option<String>,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub mime_type: Option<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub size: Option<u64>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub annotations: Option<ResourceAnnotations>,
19}
20
21impl Resource {
22    pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
23        Self {
24            uri: uri.into(),
25            name: name.into(),
26            description: None,
27            mime_type: None,
28            size: None,
29            annotations: None,
30        }
31    }
32
33    pub fn with_description(mut self, description: impl Into<String>) -> Self {
34        self.description = Some(description.into());
35        self
36    }
37
38    pub fn with_mime_type(mut self, mime_type: impl Into<String>) -> Self {
39        self.mime_type = Some(mime_type.into());
40        self
41    }
42}
43
44#[derive(Debug, Clone, Default, Serialize, Deserialize)]
45pub struct ResourceAnnotations {
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub title: Option<String>,
48}
49
50/// A URI template for parameterised resources (RFC 6570)
51#[derive(Debug, Clone, Serialize, Deserialize)]
52#[serde(rename_all = "camelCase")]
53pub struct ResourceTemplate {
54    pub uri_template: String,
55    pub name: String,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub description: Option<String>,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub mime_type: Option<String>,
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub annotations: Option<ResourceAnnotations>,
62}
63
64impl ResourceTemplate {
65    pub fn new(uri_template: impl Into<String>, name: impl Into<String>) -> Self {
66        Self {
67            uri_template: uri_template.into(),
68            name: name.into(),
69            description: None,
70            mime_type: None,
71            annotations: None,
72        }
73    }
74
75    pub fn with_description(mut self, description: impl Into<String>) -> Self {
76        self.description = Some(description.into());
77        self
78    }
79
80    pub fn with_mime_type(mut self, mime_type: impl Into<String>) -> Self {
81        self.mime_type = Some(mime_type.into());
82        self
83    }
84}
85
86/// Result type for resources/read
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct ReadResourceResult {
89    pub contents: Vec<ResourceContents>,
90}
91
92impl ReadResourceResult {
93    pub fn text(uri: impl Into<String>, text: impl Into<String>) -> Self {
94        Self {
95            contents: vec![ResourceContents::text(uri, text)],
96        }
97    }
98}
99
100/// Result type for resources/templates/list
101#[derive(Debug, Clone, Default, Serialize, Deserialize)]
102pub struct ListResourceTemplatesResult {
103    pub resource_templates: Vec<ResourceTemplate>,
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub next_cursor: Option<String>,
106}