* feat: add type-safe elicitation schema support (#465) Implement type-safe schema definitions for MCP elicitation requests, replacing generic `JsonObject` with strongly-typed primitive schemas per the [MCP 2025-06-18 specification](https://spec.modelcontextprotocol.io/specification/2025-06-18/server/elicitation/). Features: - Type-safe schema hierarchy (`StringSchema`, `NumberSchema`, `IntegerSchema`, `BooleanSchema`) - Builder pattern with fluent API and 20+ convenience methods - Build-time validation ensuring required fields exist in properties - Private fields enforcing invariants through validated constructors - Comprehensive validation support (range, length, format, enums) - Typed property methods for cleaner schema construction Benefits: - Compile-time type safety prevents invalid schema construction - 60-70% reduction in boilerplate through convenience methods - Enforces MCP specification requirement for primitive-only properties - Better IDE autocomplete and type inference - Runtime validation catches schema errors early Breaking changes: - `CreateElicitationRequestParam.requested_schema` changed from `JsonObject` to `ElicitationSchema` - `ElicitationSchemaBuilder::build()` now returns `Result` instead of direct value Fixes #465 * fix: fix RMCP compliance * feat: add conversion methods to ElicitationSchema Add from_json_schema() and from_type() methods to ElicitationSchema for easier type-to-schema conversion. This addresses feedback about improving ergonomics when working with generated schemas. Also make all struct fields public for better flexibility. * chore: change `StringFormat` to enum
This commit is contained in:
parent
d929e6918e
commit
11093bc830
7 changed files with 2253 additions and 137 deletions
|
|
@ -2,6 +2,7 @@ use std::{borrow::Cow, sync::Arc};
|
|||
mod annotated;
|
||||
mod capabilities;
|
||||
mod content;
|
||||
mod elicitation_schema;
|
||||
mod extension;
|
||||
mod meta;
|
||||
mod prompt;
|
||||
|
|
@ -11,6 +12,7 @@ mod tool;
|
|||
pub use annotated::*;
|
||||
pub use capabilities::*;
|
||||
pub use content::*;
|
||||
pub use elicitation_schema::*;
|
||||
pub use extension::*;
|
||||
pub use meta::*;
|
||||
pub use prompt::*;
|
||||
|
|
@ -1377,7 +1379,21 @@ pub enum ElicitationAction {
|
|||
///
|
||||
/// This structure contains everything needed to request interactive input from a user:
|
||||
/// - A human-readable message explaining what information is needed
|
||||
/// - A JSON schema defining the expected structure of the response
|
||||
/// - A type-safe schema defining the expected structure of the response
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use rmcp::model::*;
|
||||
///
|
||||
/// let params = CreateElicitationRequestParam {
|
||||
/// message: "Please provide your email".to_string(),
|
||||
/// requested_schema: ElicitationSchema::builder()
|
||||
/// .required_email("email")
|
||||
/// .build()
|
||||
/// .unwrap(),
|
||||
/// };
|
||||
/// ```
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
|
@ -1387,10 +1403,10 @@ pub struct CreateElicitationRequestParam {
|
|||
/// what information they need to provide.
|
||||
pub message: String,
|
||||
|
||||
/// JSON Schema defining the expected structure and validation rules for the user's response.
|
||||
/// This allows clients to validate input and provide appropriate UI controls.
|
||||
/// Must be a valid JSON Schema Draft 2020-12 object.
|
||||
pub requested_schema: JsonObject,
|
||||
/// Type-safe schema defining the expected structure and validation rules for the user's response.
|
||||
/// This enforces the MCP 2025-06-18 specification that elicitation schemas must be objects
|
||||
/// with primitive-typed properties.
|
||||
pub requested_schema: ElicitationSchema,
|
||||
}
|
||||
|
||||
/// The result returned by a client in response to an elicitation request.
|
||||
|
|
|
|||
1180
crates/rmcp/src/model/elicitation_schema.rs
Normal file
1180
crates/rmcp/src/model/elicitation_schema.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -677,7 +677,16 @@ impl Peer<RoleServer> {
|
|||
}
|
||||
|
||||
// Generate schema automatically from type
|
||||
let schema = crate::handler::server::tool::schema_for_type::<T>();
|
||||
let schema = crate::model::ElicitationSchema::from_type::<T>().map_err(|e| {
|
||||
ElicitationError::Service(ServiceError::McpError(crate::ErrorData::invalid_params(
|
||||
format!(
|
||||
"Invalid schema for type {}: {}",
|
||||
std::any::type_name::<T>(),
|
||||
e
|
||||
),
|
||||
None,
|
||||
)))
|
||||
})?;
|
||||
|
||||
let response = self
|
||||
.create_elicitation_with_timeout(
|
||||
|
|
|
|||
|
|
@ -39,23 +39,14 @@ async fn test_elicitation_serialization() {
|
|||
/// Test CreateElicitationRequestParam structure serialization/deserialization
|
||||
#[tokio::test]
|
||||
async fn test_elicitation_request_param_serialization() {
|
||||
let schema_object = json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email"
|
||||
}
|
||||
},
|
||||
"required": ["email"]
|
||||
})
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let schema = ElicitationSchema::builder()
|
||||
.required_property("email", PrimitiveSchema::String(StringSchema::email()))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let request_param = CreateElicitationRequestParam {
|
||||
message: "Please provide your email address".to_string(),
|
||||
requested_schema: schema_object,
|
||||
requested_schema: schema,
|
||||
};
|
||||
|
||||
// Test serialization
|
||||
|
|
@ -123,16 +114,13 @@ async fn test_elicitation_result_serialization() {
|
|||
/// Test that elicitation requests can be created and handled through the JSON-RPC protocol
|
||||
#[tokio::test]
|
||||
async fn test_elicitation_json_rpc_protocol() {
|
||||
let schema = json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"confirmation": {"type": "boolean"}
|
||||
},
|
||||
"required": ["confirmation"]
|
||||
})
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let schema = ElicitationSchema::builder()
|
||||
.required_property(
|
||||
"confirmation",
|
||||
PrimitiveSchema::Boolean(BooleanSchema::new()),
|
||||
)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create a complete JSON-RPC request for elicitation
|
||||
let request = JsonRpcRequest {
|
||||
|
|
@ -223,19 +211,22 @@ async fn test_elicitation_spec_compliance() {
|
|||
/// Test error handling and edge cases for elicitation
|
||||
#[tokio::test]
|
||||
async fn test_elicitation_error_handling() {
|
||||
// Test invalid JSON schema handling
|
||||
let invalid_schema_request = CreateElicitationRequestParam {
|
||||
// Test minimal schema handling (empty properties is technically valid)
|
||||
let minimal_schema_request = CreateElicitationRequestParam {
|
||||
message: "Test message".to_string(),
|
||||
requested_schema: serde_json::Map::new(), // Empty schema is technically valid
|
||||
requested_schema: ElicitationSchema::builder().build().unwrap(),
|
||||
};
|
||||
|
||||
// Should serialize without error
|
||||
let _json = serde_json::to_value(&invalid_schema_request).unwrap();
|
||||
let _json = serde_json::to_value(&minimal_schema_request).unwrap();
|
||||
|
||||
// Test empty message
|
||||
let empty_message_request = CreateElicitationRequestParam {
|
||||
message: "".to_string(),
|
||||
requested_schema: json!({"type": "string"}).as_object().unwrap().clone(),
|
||||
requested_schema: ElicitationSchema::builder()
|
||||
.property("value", PrimitiveSchema::String(StringSchema::new()))
|
||||
.build()
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
// Should serialize without error (validation is up to the implementation)
|
||||
|
|
@ -250,15 +241,10 @@ async fn test_elicitation_error_handling() {
|
|||
/// Benchmark-style test for elicitation performance
|
||||
#[tokio::test]
|
||||
async fn test_elicitation_performance() {
|
||||
let schema = json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {"type": "string"}
|
||||
}
|
||||
})
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let schema = ElicitationSchema::builder()
|
||||
.property("data", PrimitiveSchema::String(StringSchema::new()))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let request = CreateElicitationRequestParam {
|
||||
message: "Performance test message".to_string(),
|
||||
|
|
@ -383,51 +369,52 @@ async fn test_elicitation_convenience_methods() {
|
|||
.contains("Option A")
|
||||
);
|
||||
|
||||
// Test that CreateElicitationRequestParam can be created with these schemas
|
||||
// Test that CreateElicitationRequestParam can be created with type-safe schemas
|
||||
let confirmation_request = CreateElicitationRequestParam {
|
||||
message: "Test confirmation".to_string(),
|
||||
requested_schema: confirmation_schema.as_object().unwrap().clone(),
|
||||
requested_schema: ElicitationSchema::builder()
|
||||
.property(
|
||||
"confirmed",
|
||||
PrimitiveSchema::Boolean(
|
||||
BooleanSchema::new()
|
||||
.description("User confirmation (true for yes, false for no)"),
|
||||
),
|
||||
)
|
||||
.build()
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
// Test serialization of convenience method request
|
||||
let json = serde_json::to_value(&confirmation_request).unwrap();
|
||||
assert_eq!(json["message"], "Test confirmation");
|
||||
assert_eq!(json["requestedSchema"]["type"], "boolean");
|
||||
assert_eq!(json["requestedSchema"]["type"], "object");
|
||||
assert_eq!(
|
||||
json["requestedSchema"]["properties"]["confirmed"]["type"],
|
||||
"boolean"
|
||||
);
|
||||
}
|
||||
|
||||
/// Test structured input with complex schemas
|
||||
/// Ensures that complex JSON schemas work correctly with elicitation
|
||||
/// Test structured input with multiple primitive properties
|
||||
/// Ensures that schemas with multiple primitive properties work correctly with elicitation
|
||||
#[tokio::test]
|
||||
async fn test_elicitation_structured_schemas() {
|
||||
// Test complex nested object schema
|
||||
let complex_schema = json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"email": {"type": "string", "format": "email"},
|
||||
"preferences": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"theme": {"type": "string", "enum": ["light", "dark"]},
|
||||
"notifications": {"type": "boolean"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"required": ["user"]
|
||||
});
|
||||
// Test schema with multiple primitive properties
|
||||
let schema = ElicitationSchema::builder()
|
||||
.required_string_with("name", |s| s.length(1, 100))
|
||||
.required_email("email")
|
||||
.required_integer("age", 0, 150)
|
||||
.optional_bool("newsletter", false)
|
||||
.required_enum(
|
||||
"country",
|
||||
vec!["US".to_string(), "UK".to_string(), "CA".to_string()],
|
||||
)
|
||||
.description("User registration information")
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let request = CreateElicitationRequestParam {
|
||||
message: "Please provide your user information".to_string(),
|
||||
requested_schema: complex_schema.as_object().unwrap().clone(),
|
||||
requested_schema: schema,
|
||||
};
|
||||
|
||||
// Test that complex schemas serialize/deserialize correctly
|
||||
|
|
@ -435,36 +422,41 @@ async fn test_elicitation_structured_schemas() {
|
|||
let deserialized: CreateElicitationRequestParam = serde_json::from_value(json).unwrap();
|
||||
|
||||
assert_eq!(deserialized.message, "Please provide your user information");
|
||||
assert_eq!(deserialized.requested_schema.properties.len(), 5);
|
||||
assert!(
|
||||
deserialized
|
||||
.requested_schema
|
||||
.properties
|
||||
.contains_key("name")
|
||||
);
|
||||
assert!(
|
||||
deserialized
|
||||
.requested_schema
|
||||
.properties
|
||||
.contains_key("email")
|
||||
);
|
||||
assert!(deserialized.requested_schema.properties.contains_key("age"));
|
||||
assert!(
|
||||
deserialized
|
||||
.requested_schema
|
||||
.properties
|
||||
.contains_key("newsletter")
|
||||
);
|
||||
assert!(
|
||||
deserialized
|
||||
.requested_schema
|
||||
.properties
|
||||
.contains_key("country")
|
||||
);
|
||||
assert_eq!(
|
||||
deserialized.requested_schema["properties"]["user"]["properties"]["name"]["type"],
|
||||
"string"
|
||||
deserialized.requested_schema.required,
|
||||
Some(vec![
|
||||
"name".to_string(),
|
||||
"email".to_string(),
|
||||
"age".to_string(),
|
||||
"country".to_string()
|
||||
])
|
||||
);
|
||||
|
||||
// Test array schema
|
||||
let array_schema = json!({
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer"},
|
||||
"name": {"type": "string"}
|
||||
},
|
||||
"required": ["id", "name"]
|
||||
},
|
||||
"minItems": 1,
|
||||
"maxItems": 10
|
||||
});
|
||||
|
||||
let array_request = CreateElicitationRequestParam {
|
||||
message: "Please provide a list of items".to_string(),
|
||||
requested_schema: array_schema.as_object().unwrap().clone(),
|
||||
};
|
||||
|
||||
// Verify array schema
|
||||
let json = serde_json::to_value(&array_request).unwrap();
|
||||
assert_eq!(json["requestedSchema"]["type"], "array");
|
||||
assert_eq!(json["requestedSchema"]["minItems"], 1);
|
||||
assert_eq!(json["requestedSchema"]["maxItems"], 10);
|
||||
}
|
||||
|
||||
// Typed elicitation tests using the API with schemars
|
||||
|
|
@ -649,13 +641,13 @@ async fn test_elicitation_direction_server_to_client() {
|
|||
use serde_json::json;
|
||||
|
||||
// Test that server can create elicitation requests
|
||||
let schema = json!({
|
||||
"type": "string",
|
||||
"description": "Enter your name"
|
||||
})
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let schema = ElicitationSchema::builder()
|
||||
.property(
|
||||
"name",
|
||||
PrimitiveSchema::String(StringSchema::new().description("Enter your name")),
|
||||
)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let elicitation_request = CreateElicitationRequestParam {
|
||||
message: "Please enter your name".to_string(),
|
||||
|
|
@ -665,7 +657,7 @@ async fn test_elicitation_direction_server_to_client() {
|
|||
// Verify request can be serialized
|
||||
let serialized = serde_json::to_value(&elicitation_request).unwrap();
|
||||
assert_eq!(serialized["message"], "Please enter your name");
|
||||
assert_eq!(serialized["requestedSchema"]["type"], "string");
|
||||
assert_eq!(serialized["requestedSchema"]["type"], "object");
|
||||
|
||||
// Test that elicitation requests are part of ServerRequest
|
||||
let _server_request = ServerRequest::CreateElicitationRequest(CreateElicitationRequest {
|
||||
|
|
@ -697,13 +689,13 @@ async fn test_elicitation_json_rpc_direction() {
|
|||
use rmcp::model::*;
|
||||
use serde_json::json;
|
||||
|
||||
let schema = json!({
|
||||
"type": "boolean",
|
||||
"description": "Do you want to continue?"
|
||||
})
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let schema = ElicitationSchema::builder()
|
||||
.property(
|
||||
"continue",
|
||||
PrimitiveSchema::Boolean(BooleanSchema::new().description("Do you want to continue?")),
|
||||
)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// 1. Server creates elicitation request
|
||||
let server_request = ServerJsonRpcMessage::request(
|
||||
|
|
@ -1143,17 +1135,11 @@ async fn test_create_elicitation_with_timeout_basic() {
|
|||
use std::time::Duration;
|
||||
|
||||
// This test verifies that the method accepts timeout parameter
|
||||
let schema = json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"email": {"type": "string"}
|
||||
},
|
||||
"required": ["name", "email"]
|
||||
})
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let schema = ElicitationSchema::builder()
|
||||
.required_property("name", PrimitiveSchema::String(StringSchema::new()))
|
||||
.required_property("email", PrimitiveSchema::String(StringSchema::new()))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let _params = CreateElicitationRequestParam {
|
||||
message: "Enter your details".to_string(),
|
||||
|
|
@ -1473,3 +1459,146 @@ async fn test_elicitation_examples_compile() {
|
|||
_assert_safe::<UserProfile>();
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// BUILD-TIME VALIDATION TESTS
|
||||
// =============================================================================
|
||||
|
||||
/// Test that build() validates required fields exist in properties
|
||||
#[tokio::test]
|
||||
async fn test_build_validation_required_field_not_in_properties() {
|
||||
// Try to mark a field as required that doesn't exist in properties
|
||||
let result = ElicitationSchema::builder()
|
||||
.property("email", PrimitiveSchema::String(StringSchema::email()))
|
||||
.mark_required("nonexistent_field")
|
||||
.build();
|
||||
|
||||
// Should return an error
|
||||
assert!(result.is_err());
|
||||
assert_eq!(
|
||||
result.unwrap_err(),
|
||||
"Required field does not exist in properties"
|
||||
);
|
||||
}
|
||||
|
||||
/// Test that build() succeeds when all required fields exist
|
||||
#[tokio::test]
|
||||
async fn test_build_validation_required_field_exists() {
|
||||
let result = ElicitationSchema::builder()
|
||||
.property("email", PrimitiveSchema::String(StringSchema::email()))
|
||||
.property("name", PrimitiveSchema::String(StringSchema::new()))
|
||||
.mark_required("email")
|
||||
.mark_required("name")
|
||||
.build();
|
||||
|
||||
// Should succeed
|
||||
assert!(result.is_ok());
|
||||
let schema = result.unwrap();
|
||||
assert_eq!(schema.properties.len(), 2);
|
||||
assert_eq!(
|
||||
schema.required,
|
||||
Some(vec!["email".to_string(), "name".to_string()])
|
||||
);
|
||||
}
|
||||
|
||||
/// Test that build_unchecked() panics on validation errors
|
||||
#[tokio::test]
|
||||
#[should_panic(expected = "Invalid elicitation schema")]
|
||||
async fn test_build_unchecked_panics_on_invalid() {
|
||||
// build_unchecked validates but panics instead of returning Result
|
||||
let _schema = ElicitationSchema::builder()
|
||||
.property("email", PrimitiveSchema::String(StringSchema::email()))
|
||||
.mark_required("nonexistent_field")
|
||||
.build_unchecked();
|
||||
}
|
||||
|
||||
/// Test convenience methods handle validation correctly
|
||||
#[tokio::test]
|
||||
async fn test_convenience_methods_validation() {
|
||||
// required_string_property should add both property and mark as required
|
||||
let result = ElicitationSchema::builder()
|
||||
.required_string_property("name", |s| s)
|
||||
.required_email("email")
|
||||
.build();
|
||||
|
||||
assert!(result.is_ok());
|
||||
let schema = result.unwrap();
|
||||
assert_eq!(schema.properties.len(), 2);
|
||||
assert!(
|
||||
schema
|
||||
.required
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains(&"name".to_string())
|
||||
);
|
||||
assert!(
|
||||
schema
|
||||
.required
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains(&"email".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
/// Test typed property methods work correctly
|
||||
#[tokio::test]
|
||||
async fn test_typed_property_methods() {
|
||||
let result = ElicitationSchema::builder()
|
||||
.string_property("name", |s| s.length(1, 100))
|
||||
.number_property("price", |n| n.range(0.0, 1000.0))
|
||||
.integer_property("quantity", |i| i.range(1, 100))
|
||||
.bool_property("in_stock", |b| b.with_default(true))
|
||||
.build();
|
||||
|
||||
assert!(result.is_ok());
|
||||
let schema = result.unwrap();
|
||||
assert_eq!(schema.properties.len(), 4);
|
||||
|
||||
// Verify types are correct
|
||||
if let Some(PrimitiveSchema::String(_)) = schema.properties.get("name") {
|
||||
// Expected
|
||||
} else {
|
||||
panic!("name should be StringSchema");
|
||||
}
|
||||
|
||||
if let Some(PrimitiveSchema::Number(_)) = schema.properties.get("price") {
|
||||
// Expected
|
||||
} else {
|
||||
panic!("price should be NumberSchema");
|
||||
}
|
||||
|
||||
if let Some(PrimitiveSchema::Integer(_)) = schema.properties.get("quantity") {
|
||||
// Expected
|
||||
} else {
|
||||
panic!("quantity should be IntegerSchema");
|
||||
}
|
||||
|
||||
if let Some(PrimitiveSchema::Boolean(_)) = schema.properties.get("in_stock") {
|
||||
// Expected
|
||||
} else {
|
||||
panic!("in_stock should be BooleanSchema");
|
||||
}
|
||||
}
|
||||
|
||||
/// Test required typed property methods
|
||||
#[tokio::test]
|
||||
async fn test_required_typed_property_methods() {
|
||||
let result = ElicitationSchema::builder()
|
||||
.required_string_property("name", |s| s)
|
||||
.required_number_property("price", |n| n)
|
||||
.required_integer_property("age", |i| i)
|
||||
.required_bool_property("active", |b| b)
|
||||
.build();
|
||||
|
||||
assert!(result.is_ok());
|
||||
let schema = result.unwrap();
|
||||
assert_eq!(schema.properties.len(), 4);
|
||||
assert_eq!(schema.required.as_ref().unwrap().len(), 4);
|
||||
|
||||
// All should be marked as required
|
||||
let required = schema.required.as_ref().unwrap();
|
||||
assert!(required.contains(&"name".to_string()));
|
||||
assert!(required.contains(&"price".to_string()));
|
||||
assert!(required.contains(&"age".to_string()));
|
||||
assert!(required.contains(&"active".to_string()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -307,6 +307,49 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"BooleanSchema": {
|
||||
"description": "Schema definition for boolean properties.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "Default value",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BooleanTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"BooleanTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "boolean"
|
||||
},
|
||||
"CallToolResult": {
|
||||
"description": "The result of a tool call operation.\n\nContains the content returned by the tool execution and an optional\nflag indicating whether the operation resulted in an error.",
|
||||
"type": "object",
|
||||
|
|
@ -423,7 +466,7 @@
|
|||
]
|
||||
},
|
||||
"CreateElicitationRequestParam": {
|
||||
"description": "Parameters for creating an elicitation request to gather user input.\n\nThis structure contains everything needed to request interactive input from a user:\n- A human-readable message explaining what information is needed\n- A JSON schema defining the expected structure of the response",
|
||||
"description": "Parameters for creating an elicitation request to gather user input.\n\nThis structure contains everything needed to request interactive input from a user:\n- A human-readable message explaining what information is needed\n- A type-safe schema defining the expected structure of the response\n\n# Example\n\n```rust\nuse rmcp::model::*;\n\nlet params = CreateElicitationRequestParam {\n message: \"Please provide your email\".to_string(),\n requested_schema: ElicitationSchema::builder()\n .required_email(\"email\")\n .build()\n .unwrap(),\n};\n```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
|
|
@ -431,9 +474,12 @@
|
|||
"type": "string"
|
||||
},
|
||||
"requestedSchema": {
|
||||
"description": "JSON Schema defining the expected structure and validation rules for the user's response.\nThis allows clients to validate input and provide appropriate UI controls.\nMust be a valid JSON Schema Draft 2020-12 object.",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
"description": "Type-safe schema defining the expected structure and validation rules for the user's response.\nThis enforces the MCP 2025-06-18 specification that elicitation schemas must be objects\nwith primitive-typed properties.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ElicitationSchema"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -564,10 +610,108 @@
|
|||
"format": "const",
|
||||
"const": "elicitation/create"
|
||||
},
|
||||
"ElicitationSchema": {
|
||||
"description": "Type-safe elicitation schema for requesting structured user input.\n\nThis enforces the MCP 2025-06-18 specification that elicitation schemas\nmust be objects with primitive-typed properties.\n\n# Example\n\n```rust\nuse rmcp::model::*;\n\nlet schema = ElicitationSchema::builder()\n .required_email(\"email\")\n .required_integer(\"age\", 0, 150)\n .optional_bool(\"newsletter\", false)\n .build();\n```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Optional description of what this schema represents",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"description": "Property definitions (must be primitive types)",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PrimitiveSchema"
|
||||
}
|
||||
},
|
||||
"required": {
|
||||
"description": "List of required property names",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Always \"object\" for elicitation schemas",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ObjectTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"properties"
|
||||
]
|
||||
},
|
||||
"EmptyObject": {
|
||||
"description": "This is commonly used for representing empty objects in MCP messages.\n\nwithout returning any specific data.",
|
||||
"type": "object"
|
||||
},
|
||||
"EnumSchema": {
|
||||
"description": "Schema definition for enum properties.\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nEnums must have string type and can optionally include human-readable names.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"enum": {
|
||||
"description": "Allowed enum values (string values only per MCP spec)",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"enumNames": {
|
||||
"description": "Optional human-readable names for each enum value",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator (always \"string\" for enums)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"enum"
|
||||
]
|
||||
},
|
||||
"ErrorCode": {
|
||||
"description": "Standard JSON-RPC error codes used throughout the MCP protocol.\n\nThese codes follow the JSON-RPC 2.0 specification and provide\nstandardized error reporting across all MCP implementations.",
|
||||
"type": "integer",
|
||||
|
|
@ -726,6 +870,58 @@
|
|||
"serverInfo"
|
||||
]
|
||||
},
|
||||
"IntegerSchema": {
|
||||
"description": "Schema definition for integer properties.\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nSupports only the fields allowed by the MCP spec.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"maximum": {
|
||||
"description": "Maximum value (inclusive)",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "int64"
|
||||
},
|
||||
"minimum": {
|
||||
"description": "Minimum value (inclusive)",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "int64"
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/IntegerTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"IntegerTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "integer"
|
||||
},
|
||||
"JsonRpcError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -1120,11 +1316,113 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"NumberSchema": {
|
||||
"description": "Schema definition for number properties (floating-point).\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nSupports only the fields allowed by the MCP spec.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"maximum": {
|
||||
"description": "Maximum value (inclusive)",
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
],
|
||||
"format": "double"
|
||||
},
|
||||
"minimum": {
|
||||
"description": "Minimum value (inclusive)",
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
],
|
||||
"format": "double"
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/NumberTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"NumberTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "number"
|
||||
},
|
||||
"ObjectTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "object"
|
||||
},
|
||||
"PingRequestMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "ping"
|
||||
},
|
||||
"PrimitiveSchema": {
|
||||
"description": "Primitive schema definition for elicitation properties.\n\nAccording to MCP 2025-06-18 specification, elicitation schemas must have\nproperties of primitive types only (string, number, integer, boolean, enum).",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "String property (with optional enum constraint)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Number property (with optional enum constraint)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/NumberSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Integer property (with optional enum constraint)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/IntegerSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Boolean property",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BooleanSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Enum property (explicit enum schema)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/EnumSchema"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ProgressNotificationMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
@ -1900,6 +2198,96 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"StringFormat": {
|
||||
"description": "String format types allowed by the MCP specification.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Email address format",
|
||||
"type": "string",
|
||||
"const": "email"
|
||||
},
|
||||
{
|
||||
"description": "URI format",
|
||||
"type": "string",
|
||||
"const": "uri"
|
||||
},
|
||||
{
|
||||
"description": "Date format (YYYY-MM-DD)",
|
||||
"type": "string",
|
||||
"const": "date"
|
||||
},
|
||||
{
|
||||
"description": "Date-time format (ISO 8601)",
|
||||
"type": "string",
|
||||
"const": "date-time"
|
||||
}
|
||||
]
|
||||
},
|
||||
"StringSchema": {
|
||||
"description": "Schema definition for string properties.\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nSupports only the fields allowed by the MCP spec:\n- format limited to: \"email\", \"uri\", \"date\", \"date-time\"",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"description": "String format - limited to: \"email\", \"uri\", \"date\", \"date-time\"",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringFormat"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": {
|
||||
"description": "Maximum string length",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"minLength": {
|
||||
"description": "Minimum string length",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"StringTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "string"
|
||||
},
|
||||
"Tool": {
|
||||
"description": "A tool that can be used by a model.",
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -307,6 +307,49 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"BooleanSchema": {
|
||||
"description": "Schema definition for boolean properties.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "Default value",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BooleanTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"BooleanTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "boolean"
|
||||
},
|
||||
"CallToolResult": {
|
||||
"description": "The result of a tool call operation.\n\nContains the content returned by the tool execution and an optional\nflag indicating whether the operation resulted in an error.",
|
||||
"type": "object",
|
||||
|
|
@ -423,7 +466,7 @@
|
|||
]
|
||||
},
|
||||
"CreateElicitationRequestParam": {
|
||||
"description": "Parameters for creating an elicitation request to gather user input.\n\nThis structure contains everything needed to request interactive input from a user:\n- A human-readable message explaining what information is needed\n- A JSON schema defining the expected structure of the response",
|
||||
"description": "Parameters for creating an elicitation request to gather user input.\n\nThis structure contains everything needed to request interactive input from a user:\n- A human-readable message explaining what information is needed\n- A type-safe schema defining the expected structure of the response\n\n# Example\n\n```rust\nuse rmcp::model::*;\n\nlet params = CreateElicitationRequestParam {\n message: \"Please provide your email\".to_string(),\n requested_schema: ElicitationSchema::builder()\n .required_email(\"email\")\n .build()\n .unwrap(),\n};\n```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
|
|
@ -431,9 +474,12 @@
|
|||
"type": "string"
|
||||
},
|
||||
"requestedSchema": {
|
||||
"description": "JSON Schema defining the expected structure and validation rules for the user's response.\nThis allows clients to validate input and provide appropriate UI controls.\nMust be a valid JSON Schema Draft 2020-12 object.",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
"description": "Type-safe schema defining the expected structure and validation rules for the user's response.\nThis enforces the MCP 2025-06-18 specification that elicitation schemas must be objects\nwith primitive-typed properties.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ElicitationSchema"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -564,10 +610,108 @@
|
|||
"format": "const",
|
||||
"const": "elicitation/create"
|
||||
},
|
||||
"ElicitationSchema": {
|
||||
"description": "Type-safe elicitation schema for requesting structured user input.\n\nThis enforces the MCP 2025-06-18 specification that elicitation schemas\nmust be objects with primitive-typed properties.\n\n# Example\n\n```rust\nuse rmcp::model::*;\n\nlet schema = ElicitationSchema::builder()\n .required_email(\"email\")\n .required_integer(\"age\", 0, 150)\n .optional_bool(\"newsletter\", false)\n .build();\n```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Optional description of what this schema represents",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"description": "Property definitions (must be primitive types)",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PrimitiveSchema"
|
||||
}
|
||||
},
|
||||
"required": {
|
||||
"description": "List of required property names",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Always \"object\" for elicitation schemas",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ObjectTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"properties"
|
||||
]
|
||||
},
|
||||
"EmptyObject": {
|
||||
"description": "This is commonly used for representing empty objects in MCP messages.\n\nwithout returning any specific data.",
|
||||
"type": "object"
|
||||
},
|
||||
"EnumSchema": {
|
||||
"description": "Schema definition for enum properties.\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nEnums must have string type and can optionally include human-readable names.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"enum": {
|
||||
"description": "Allowed enum values (string values only per MCP spec)",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"enumNames": {
|
||||
"description": "Optional human-readable names for each enum value",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator (always \"string\" for enums)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"enum"
|
||||
]
|
||||
},
|
||||
"ErrorCode": {
|
||||
"description": "Standard JSON-RPC error codes used throughout the MCP protocol.\n\nThese codes follow the JSON-RPC 2.0 specification and provide\nstandardized error reporting across all MCP implementations.",
|
||||
"type": "integer",
|
||||
|
|
@ -726,6 +870,58 @@
|
|||
"serverInfo"
|
||||
]
|
||||
},
|
||||
"IntegerSchema": {
|
||||
"description": "Schema definition for integer properties.\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nSupports only the fields allowed by the MCP spec.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"maximum": {
|
||||
"description": "Maximum value (inclusive)",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "int64"
|
||||
},
|
||||
"minimum": {
|
||||
"description": "Minimum value (inclusive)",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "int64"
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/IntegerTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"IntegerTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "integer"
|
||||
},
|
||||
"JsonRpcError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -1120,11 +1316,113 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"NumberSchema": {
|
||||
"description": "Schema definition for number properties (floating-point).\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nSupports only the fields allowed by the MCP spec.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"maximum": {
|
||||
"description": "Maximum value (inclusive)",
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
],
|
||||
"format": "double"
|
||||
},
|
||||
"minimum": {
|
||||
"description": "Minimum value (inclusive)",
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
],
|
||||
"format": "double"
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/NumberTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"NumberTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "number"
|
||||
},
|
||||
"ObjectTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "object"
|
||||
},
|
||||
"PingRequestMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "ping"
|
||||
},
|
||||
"PrimitiveSchema": {
|
||||
"description": "Primitive schema definition for elicitation properties.\n\nAccording to MCP 2025-06-18 specification, elicitation schemas must have\nproperties of primitive types only (string, number, integer, boolean, enum).",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "String property (with optional enum constraint)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Number property (with optional enum constraint)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/NumberSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Integer property (with optional enum constraint)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/IntegerSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Boolean property",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BooleanSchema"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Enum property (explicit enum schema)",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/EnumSchema"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ProgressNotificationMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
@ -1900,6 +2198,96 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"StringFormat": {
|
||||
"description": "String format types allowed by the MCP specification.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Email address format",
|
||||
"type": "string",
|
||||
"const": "email"
|
||||
},
|
||||
{
|
||||
"description": "URI format",
|
||||
"type": "string",
|
||||
"const": "uri"
|
||||
},
|
||||
{
|
||||
"description": "Date format (YYYY-MM-DD)",
|
||||
"type": "string",
|
||||
"const": "date"
|
||||
},
|
||||
{
|
||||
"description": "Date-time format (ISO 8601)",
|
||||
"type": "string",
|
||||
"const": "date-time"
|
||||
}
|
||||
]
|
||||
},
|
||||
"StringSchema": {
|
||||
"description": "Schema definition for string properties.\n\nCompliant with MCP 2025-06-18 specification for elicitation schemas.\nSupports only the fields allowed by the MCP spec:\n- format limited to: \"email\", \"uri\", \"date\", \"date-time\"",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Human-readable description",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"description": "String format - limited to: \"email\", \"uri\", \"date\", \"date-time\"",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringFormat"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": {
|
||||
"description": "Maximum string length",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"minLength": {
|
||||
"description": "Minimum string length",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"title": {
|
||||
"description": "Optional title for the schema",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Type discriminator",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/StringTypeConst"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"StringTypeConst": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "string"
|
||||
},
|
||||
"Tool": {
|
||||
"description": "A tool that can be used by a model.",
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@ pub struct UserInfo {
|
|||
// Mark as safe for elicitation
|
||||
elicit_safe!(UserInfo);
|
||||
|
||||
/// Simple greeting message
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GreetingMessage {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// Simple tool request
|
||||
#[derive(Debug, Deserialize, JsonSchema)]
|
||||
pub struct GreetRequest {
|
||||
|
|
|
|||
Loading…
Reference in a new issue