agenterra_rmcp/model/
resource.rs

1use serde::{Deserialize, Serialize};
2
3use super::Annotated;
4
5/// Represents a resource in the extension with metadata
6#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
7#[serde(rename_all = "camelCase")]
8#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
9pub struct RawResource {
10    /// URI representing the resource location (e.g., "file:///path/to/file" or "str:///content")
11    pub uri: String,
12    /// Name of the resource
13    pub name: String,
14    /// Optional description of the resource
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub description: Option<String>,
17    /// MIME type of the resource content ("text" or "blob")
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub mime_type: Option<String>,
20
21    /// The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
22    ///
23    /// This can be used by Hosts to display file sizes and estimate context window us
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub size: Option<u32>,
26}
27
28pub type Resource = Annotated<RawResource>;
29
30#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
31#[serde(rename_all = "camelCase")]
32#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
33pub struct RawResourceTemplate {
34    pub uri_template: String,
35    pub name: String,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub description: Option<String>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub mime_type: Option<String>,
40}
41
42pub type ResourceTemplate = Annotated<RawResourceTemplate>;
43
44#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
45#[serde(rename_all = "camelCase", untagged)]
46#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
47pub enum ResourceContents {
48    TextResourceContents {
49        uri: String,
50        #[serde(skip_serializing_if = "Option::is_none")]
51        mime_type: Option<String>,
52        text: String,
53    },
54    BlobResourceContents {
55        uri: String,
56        #[serde(skip_serializing_if = "Option::is_none")]
57        mime_type: Option<String>,
58        blob: String,
59    },
60}
61
62impl ResourceContents {
63    pub fn text(text: impl Into<String>, uri: impl Into<String>) -> Self {
64        Self::TextResourceContents {
65            uri: uri.into(),
66            mime_type: Some("text".into()),
67            text: text.into(),
68        }
69    }
70}
71
72impl RawResource {
73    /// Creates a new Resource from a URI with explicit mime type
74    pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
75        Self {
76            uri: uri.into(),
77            name: name.into(),
78            description: None,
79            mime_type: None,
80            size: None,
81        }
82    }
83}