feat: add type-safe elicitation schema support (#465) (#466)

* 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:
sktrpathi 2025-10-15 15:25:10 +05:30 • committed by GitHub
commit 11093bc830
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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(