Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/rmcp/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl ProtocolVersion {
pub const V_2025_06_18: Self = Self(Cow::Borrowed("2025-06-18"));
pub const V_2025_03_26: Self = Self(Cow::Borrowed("2025-03-26"));
pub const V_2024_11_05: Self = Self(Cow::Borrowed("2024-11-05"));
pub const LATEST: Self = Self::V_2025_03_26;
pub const LATEST: Self = Self::V_2025_06_18;
}

impl Serialize for ProtocolVersion {
Expand Down
18 changes: 9 additions & 9 deletions crates/rmcp/src/model/annotated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub struct Annotations {
pub audience: Option<Vec<Role>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none", rename = "lastModified")]
pub last_modified: Option<DateTime<Utc>>,
}

impl Annotations {
Expand All @@ -30,7 +30,7 @@ impl Annotations {
);
Annotations {
priority: Some(priority),
timestamp: Some(timestamp),
last_modified: Some(timestamp),
audience: None,
}
}
Expand Down Expand Up @@ -72,7 +72,7 @@ impl<T: AnnotateAble> Annotated<T> {
self.annotations.as_ref().and_then(|a| a.priority)
}
pub fn timestamp(&self) -> Option<DateTime<Utc>> {
self.annotations.as_ref().and_then(|a| a.timestamp)
self.annotations.as_ref().and_then(|a| a.last_modified)
}
pub fn with_audience(self, audience: Vec<Role>) -> Annotated<T>
where
Expand All @@ -92,7 +92,7 @@ impl<T: AnnotateAble> Annotated<T> {
annotations: Some(Annotations {
audience: Some(audience),
priority: None,
timestamp: None,
last_modified: None,
}),
}
}
Expand All @@ -114,7 +114,7 @@ impl<T: AnnotateAble> Annotated<T> {
raw: self.raw,
annotations: Some(Annotations {
priority: Some(priority),
timestamp: None,
last_modified: None,
audience: None,
}),
}
Expand All @@ -128,15 +128,15 @@ impl<T: AnnotateAble> Annotated<T> {
Annotated {
raw: self.raw,
annotations: Some(Annotations {
timestamp: Some(timestamp),
last_modified: Some(timestamp),
..annotations
}),
}
} else {
Annotated {
raw: self.raw,
annotations: Some(Annotations {
timestamp: Some(timestamp),
last_modified: Some(timestamp),
priority: None,
audience: None,
}),
Expand Down Expand Up @@ -211,7 +211,7 @@ pub trait AnnotateAble: sealed::Sealed {
Self: Sized,
{
self.annotate(Annotations {
timestamp: Some(timestamp),
last_modified: Some(timestamp),
..Default::default()
})
}
Expand Down
11 changes: 10 additions & 1 deletion crates/rmcp/src/model/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use super::{AnnotateAble, Annotated, resource::ResourceContents};
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct RawTextContent {
pub text: String,
/// Optional protocol-level metadata for this content block
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<super::Meta>,
}
pub type TextContent = Annotated<RawTextContent>;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand All @@ -20,13 +23,17 @@ pub struct RawImageContent {
/// The base64-encoded image
pub data: String,
pub mime_type: String,
/// Optional protocol-level metadata for this content block
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<super::Meta>,
}

pub type ImageContent = Annotated<RawImageContent>;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct RawEmbeddedResource {
/// Optional protocol-level metadata for this content block
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<super::Meta>,
pub resource: ResourceContents,
Expand Down Expand Up @@ -79,13 +86,14 @@ impl RawContent {
}

pub fn text<S: Into<String>>(text: S) -> Self {
RawContent::Text(RawTextContent { text: text.into() })
RawContent::Text(RawTextContent { text: text.into(), meta: None })
}

pub fn image<S: Into<String>, T: Into<String>>(data: S, mime_type: T) -> Self {
RawContent::Image(RawImageContent {
data: data.into(),
mime_type: mime_type.into(),
meta: None,
})
}

Expand Down Expand Up @@ -209,6 +217,7 @@ mod tests {
let image_content = RawImageContent {
data: "base64data".to_string(),
mime_type: "image/png".to_string(),
meta: None,
};

let json = serde_json::to_string(&image_content).unwrap();
Expand Down
23 changes: 23 additions & 0 deletions crates/rmcp/src/model/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,27 @@ impl PromptMessage {
content: PromptMessageContent::Text { text: text.into() },
}
}

/// Create a new text message with meta
pub fn new_text_with_meta<S: Into<String>>(
role: PromptMessageRole,
text: S,
meta: Option<crate::model::Meta>,
) -> Self {
use crate::model::{AnnotateAble, RawTextContent};
let annotated = RawTextContent {
text: text.into(),
meta,
}
.no_annotation();
// Map into Content using same tagging as PromptMessageContent::Text
Self {
role,
content: PromptMessageContent::Text {
text: annotated.raw.text,
},
}
}
#[cfg(feature = "base64")]
pub fn new_image(
role: PromptMessageRole,
Expand All @@ -131,6 +152,7 @@ impl PromptMessage {
image: RawImageContent {
data: base64,
mime_type,
meta: None,
}
.optional_annotate(annotations),
},
Expand Down Expand Up @@ -184,6 +206,7 @@ mod tests {
let image_content = RawImageContent {
data: "base64data".to_string(),
mime_type: "image/png".to_string(),
meta: None,
};

let json = serde_json::to_string(&image_content).unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,19 @@
"$ref": "#/definitions/Role"
}
},
"priority": {
"lastModified": {
"type": [
"number",
"string",
"null"
],
"format": "float"
"format": "date-time"
},
"timestamp": {
"priority": {
"type": [
"string",
"number",
"null"
],
"format": "date-time"
"format": "float"
}
}
},
Expand Down Expand Up @@ -859,6 +859,7 @@
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
Expand All @@ -876,6 +877,14 @@
"RawImageContent": {
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
],
"additionalProperties": true
},
"data": {
"description": "The base64-encoded image",
"type": "string"
Expand Down Expand Up @@ -933,6 +942,14 @@
"RawTextContent": {
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
],
"additionalProperties": true
},
"text": {
"type": "string"
}
Expand Down
Loading
Loading