Skip to content

Commit d8df8d0

Browse files
authored
feat: elicit helper methods (#88)
1 parent efaff3c commit d8df8d0

File tree

10 files changed

+526
-86
lines changed

10 files changed

+526
-86
lines changed

src/generated_schema/2024_11_05/mcp_schema.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
/// modify or extend the implementations as needed, but please do so at your own risk.
66
///
77
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
8-
/// Hash : a470342d05c345b580642821605b9c885bad237b
9-
/// Generated at : 2025-08-29 19:12:22
8+
/// Hash : 3473e6e72b222f44163b41eab8d4b0973ac106b6
9+
/// Generated at : 2025-09-17 19:15:48
1010
/// ----------------------------------------------------------------------------
1111
///
1212
/// MCP Protocol Version

src/generated_schema/2024_11_05/schema_utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,7 @@ impl CallToolError {
14791479
let message = message.unwrap_or(default_message);
14801480

14811481
// Format the full error message
1482-
let full_message = format!("Invalid arguments for tool '{tool_name}': {message}");
1482+
let full_message = format!("Invalid arguments for tool '{tool_name}': {message}" );
14831483

14841484
Self::from_message(full_message)
14851485
}
@@ -1521,6 +1521,7 @@ impl CallToolError {
15211521
}
15221522
}
15231523

1524+
15241525
/// Converts a `CallToolError` into a `RpcError`.
15251526
///
15261527
/// The conversion creates an internal error variant of `RpcError`

src/generated_schema/2025_03_26/mcp_schema.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
/// modify or extend the implementations as needed, but please do so at your own risk.
66
///
77
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
8-
/// Hash : a470342d05c345b580642821605b9c885bad237b
9-
/// Generated at : 2025-08-29 19:12:23
8+
/// Hash : 3473e6e72b222f44163b41eab8d4b0973ac106b6
9+
/// Generated at : 2025-09-17 19:15:50
1010
/// ----------------------------------------------------------------------------
1111
///
1212
/// MCP Protocol Version

src/generated_schema/2025_03_26/schema_utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,7 @@ impl CallToolError {
14791479
let message = message.unwrap_or(default_message);
14801480

14811481
// Format the full error message
1482-
let full_message = format!("Invalid arguments for tool '{tool_name}': {message}");
1482+
let full_message = format!("Invalid arguments for tool '{tool_name}': {message}" );
14831483

14841484
Self::from_message(full_message)
14851485
}
@@ -1521,6 +1521,7 @@ impl CallToolError {
15211521
}
15221522
}
15231523

1524+
15241525
/// Converts a `CallToolError` into a `RpcError`.
15251526
///
15261527
/// The conversion creates an internal error variant of `RpcError`

src/generated_schema/2025_06_18/mcp_schema.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
/// modify or extend the implementations as needed, but please do so at your own risk.
66
///
77
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
8-
/// Hash : a470342d05c345b580642821605b9c885bad237b
9-
/// Generated at : 2025-08-29 19:12:24
8+
/// Hash : 3473e6e72b222f44163b41eab8d4b0973ac106b6
9+
/// Generated at : 2025-09-17 19:15:50
1010
/// ----------------------------------------------------------------------------
1111
///
1212
/// MCP Protocol Version
@@ -1693,7 +1693,7 @@ pub struct ElicitRequestParams {
16931693
///The message to present to the user.
16941694
pub message: ::std::string::String,
16951695
#[serde(rename = "requestedSchema")]
1696-
pub requested_schema: ElicitRequestParamsRequestedSchema,
1696+
pub requested_schema: ElicitRequestedSchema,
16971697
}
16981698
/**A restricted subset of JSON Schema.
16991699
Only top-level properties are allowed, without nesting.*/
@@ -1730,14 +1730,14 @@ Only top-level properties are allowed, without nesting.*/
17301730
/// ```
17311731
/// </details>
17321732
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1733-
pub struct ElicitRequestParamsRequestedSchema {
1733+
pub struct ElicitRequestedSchema {
17341734
pub properties: ::std::collections::HashMap<::std::string::String, PrimitiveSchemaDefinition>,
17351735
#[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
17361736
pub required: ::std::vec::Vec<::std::string::String>,
17371737
#[serde(rename = "type")]
17381738
type_: ::std::string::String,
17391739
}
1740-
impl ElicitRequestParamsRequestedSchema {
1740+
impl ElicitRequestedSchema {
17411741
pub fn new(
17421742
properties: ::std::collections::HashMap<::std::string::String, PrimitiveSchemaDefinition>,
17431743
required: ::std::vec::Vec<::std::string::String>,
@@ -7169,3 +7169,5 @@ impl ServerNotification {
71697169
}
71707170
#[deprecated(since = "0.3.0", note = "Use `RpcError` instead.")]
71717171
pub type JsonrpcErrorError = RpcError;
7172+
#[deprecated(since = "0.7.0", note = "Use `ElicitRequestedSchema` instead.")]
7173+
pub type ElicitRequestParamsRequestedSchema = ElicitRequestedSchema;

src/generated_schema/2025_06_18/schema_utils.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,6 +1791,122 @@ impl From<Vec<MessageFromClient>> for MessagesFromClient {
17911791
}
17921792
}
17931793

1794+
#[derive(Debug)]
1795+
pub struct StringSchemaFormatError {
1796+
invalid_value: String,
1797+
}
1798+
1799+
impl core::fmt::Display for StringSchemaFormatError {
1800+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1801+
write!(f, "Invalid string schema format: '{}'", self.invalid_value)
1802+
}
1803+
}
1804+
1805+
impl std::error::Error for StringSchemaFormatError {}
1806+
1807+
impl FromStr for StringSchemaFormat {
1808+
type Err = StringSchemaFormatError;
1809+
1810+
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
1811+
match s {
1812+
"date" => Ok(Self::Date),
1813+
"date-time" => Ok(Self::DateTime),
1814+
"email" => Ok(Self::Email),
1815+
"uri" => Ok(Self::Uri),
1816+
_ => Err(StringSchemaFormatError {
1817+
invalid_value: s.to_string(),
1818+
}),
1819+
}
1820+
}
1821+
}
1822+
1823+
impl TryFrom<&serde_json::Map<String, Value>> for PrimitiveSchemaDefinition {
1824+
type Error = RpcError;
1825+
1826+
fn try_from(value: &serde_json::Map<String, serde_json::Value>) -> result::Result<Self, Self::Error> {
1827+
let input_type = value
1828+
.get("type")
1829+
.and_then(|v| v.as_str())
1830+
.or_else(|| value.get("oneOf").map(|_| "enum")) // if "oneOf" exists, return "enum"
1831+
.ok_or_else(|| {
1832+
RpcError::parse_error().with_message("'type' is missing and data type is not supported!".to_string())
1833+
})?;
1834+
1835+
let description = value.get("description").and_then(|v| v.as_str().map(|s| s.to_string()));
1836+
let title = value.get("title").and_then(|v| v.as_str().map(|s| s.to_string()));
1837+
1838+
let schema_definition: PrimitiveSchemaDefinition = match input_type {
1839+
"string" => {
1840+
let max_length = value.get("maxLength").and_then(|v| v.as_number().and_then(|n| n.as_i64()));
1841+
let min_length = value.get("minLength").and_then(|v| v.as_number().and_then(|n| n.as_i64()));
1842+
1843+
let format_str = value.get("format").and_then(|v| v.as_str());
1844+
let format = format_str.and_then(|s| StringSchemaFormat::from_str(s).ok());
1845+
1846+
PrimitiveSchemaDefinition::StringSchema(StringSchema::new(
1847+
description,
1848+
format,
1849+
max_length,
1850+
min_length,
1851+
title,
1852+
))
1853+
}
1854+
"number" | "integer" => {
1855+
let maximum = value.get("maximum").and_then(|v| v.as_number().and_then(|n| n.as_i64()));
1856+
let minimum = value.get("minimum").and_then(|v| v.as_number().and_then(|n| n.as_i64()));
1857+
PrimitiveSchemaDefinition::NumberSchema(NumberSchema {
1858+
description,
1859+
maximum,
1860+
minimum,
1861+
title,
1862+
type_: if input_type == "integer" {
1863+
NumberSchemaType::Integer
1864+
} else {
1865+
NumberSchemaType::Number
1866+
},
1867+
})
1868+
}
1869+
"boolean" => {
1870+
let default = value.get("default").and_then(|v| v.as_bool().map(|s| s.to_owned()));
1871+
PrimitiveSchemaDefinition::BooleanSchema(BooleanSchema::new(default, description, title))
1872+
}
1873+
1874+
"enum" => {
1875+
let mut enum_values: ::std::vec::Vec<::std::string::String> = vec![];
1876+
let mut enum_names: ::std::vec::Vec<::std::string::String> = vec![];
1877+
let values = value.get("oneOf").and_then(|v| v.as_array()).ok_or_else(|| {
1878+
RpcError::parse_error()
1879+
.with_message("Unsupported enum type, only simple enums are supported!".to_string())
1880+
})?;
1881+
1882+
for v in values {
1883+
let title = v.get("title").and_then(|v| v.as_str().map(|s| s.to_string()));
1884+
let enum_value = v.get("enum").and_then(|v| v.as_array()).ok_or_else(|| {
1885+
RpcError::parse_error()
1886+
.with_message("Unsupported enum type. only simple enums are supported!".to_string())
1887+
})?;
1888+
let enum_value = enum_value
1889+
.first()
1890+
.and_then(|s| s.as_str().map(|s| s.to_string()))
1891+
.ok_or_else(|| {
1892+
RpcError::parse_error()
1893+
.with_message("Unsupported enum value, only simple enums are supported!".to_string())
1894+
})?;
1895+
1896+
enum_values.push(enum_value.to_owned());
1897+
enum_names.push(title.unwrap_or(enum_value));
1898+
}
1899+
PrimitiveSchemaDefinition::EnumSchema(EnumSchema::new(enum_values, enum_names, description, title))
1900+
}
1901+
other => {
1902+
panic!("'{other}' type is not currently supported");
1903+
}
1904+
};
1905+
1906+
Ok(schema_definition)
1907+
}
1908+
}
1909+
17941910
#[deprecated(since = "0.4.0", note = "This trait was renamed to RpcMessage. Use RpcMessage instead.")]
17951911
pub type RPCMessage = ();
17961912
#[deprecated(since = "0.4.0", note = "This trait was renamed to McpMessage. Use McpMessage instead.")]

0 commit comments

Comments
 (0)