This release includes 2 security fixes for security teams reviewing exposed deployments.
Topics
Affected surfaces
Summary
AI summaryOAuth 2.1 dependency upgraded to version 5.0.0 with breaking API changes.
Full changelog
[2.3.0] - 2025-12-07
MCP 2025-11-25 Specification Support
This release adds comprehensive support for the MCP 2025-11-25 specification (final), including Tasks API, URL-mode elicitation, tool calling in sampling, enhanced metadata support, and multi-tenant infrastructure. All new features are opt-in via feature flags to maintain backward compatibility.
Added
MCP 2025-11-25 Specification Support
- Protocol Features (
turbomcp-protocol):- Tasks API (SEP-1686): Durable state machines for long-running operations with polling and deferred result retrieval
- URL Mode Elicitation (SEP-1036): Out-of-band URL-based interactions for sensitive data
- Tool Calling in Sampling (SEP-1577):
toolsandtoolChoiceparameters in sampling requests - Icon Metadata Support (SEP-973): Icons for tools, resources, resource templates, and prompts
- Enum Improvements (SEP-1330):
oneOf/anyOftitled enums, multi-select arrays, default values - Tool Execution Settings:
execution.taskSupportfield (forbidden/optional/required) - Feature flag:
mcp-draftenables all experimental features; individual flags available for granular control
- Authorization Features (
turbomcp-auth):- SSRF Protection Module: Secure HTTP fetching with redirect blocking and request validation
- Client ID Metadata Documents (SEP-991) -
mcp-cimd:- Cache-backed CIMD fetcher with concurrent access support
- Metadata discovery and validation for OAuth 2.0 clients
- Built-in type definitions for CIMD responses
- OpenID Connect Discovery (RFC 8414 + OIDC) -
mcp-oidc-discovery:- Authorization server metadata discovery
- Dynamic endpoint configuration from well-known endpoints
- Cached metadata with TTL-based expiration
- Incremental Scope Consent (SEP-835) -
mcp-incremental-consent:- WWW-Authenticate header parsing and processing
- Incremental authorization flow support
- Scope negotiation for privilege escalation workflows
Files Added:
crates/turbomcp-protocol/src/types/tasks.rs- Tasks API typescrates/turbomcp-protocol/src/types/core.rs- Enhanced protocol core typescrates/turbomcp-server/src/task_storage.rs- Task storage backendcrates/turbomcp-server/src/routing/handlers/tasks.rs- Task handlerscrates/turbomcp-auth/src/ssrf.rs- SSRF protection utilitiescrates/turbomcp-auth/src/cimd/- Client ID Metadata Documents supportcrates/turbomcp-auth/src/discovery/- OpenID Connect Discovery supportcrates/turbomcp-auth/src/incremental_consent.rs- Incremental consent handling
Design Philosophy: All draft features are opt-in via feature flags. Stable versions remain unchanged and production-ready.
Multi-Tenant SaaS Support
- New: Comprehensive multi-tenancy infrastructure for SaaS applications
TenantConfigProvidertrait with static and dynamic implementationsMultiTenantMetricswith LRU-based eviction (max 1000 tenants default)- Per-tenant configuration: rate limits, timeouts, tool permissions, request size limits
- Tenant context tracking via
RequestContext::tenant()andrequire_tenant()APIs
- New Middleware: Complete tenant extraction layer
TenantExtractortrait for flexible tenant identification strategies- Built-in extractors:
HeaderTenantExtractor,SubdomainTenantExtractor,CompositeTenantExtractor TenantExtractionLayerfor automatic tenant context injection
- New Examples: Production-ready multi-tenant server examples
multi_tenant_server.rs- Basic multi-tenant setup with configurationmulti_tenant_saas.rs- Complete SaaS example with tenant metrics, limits, and tool permissions
- Security: Tenant ownership validation via
RequestContext::validate_tenant_ownership()- Prevents cross-tenant resource access with
ResourceAccessDeniederrors - Critical for multi-tenant data isolation
- Prevents cross-tenant resource access with
Files Added:
crates/turbomcp-server/src/config/multi_tenant.rs- Tenant configuration providerscrates/turbomcp-server/src/metrics/multi_tenant.rs- Tenant metrics trackingcrates/turbomcp-server/src/middleware/tenancy.rs- Tenant extraction middlewarecrates/turbomcp/examples/multi_tenant_server.rs- Basic multi-tenant examplecrates/turbomcp/examples/multi_tenant_saas.rs- Complete SaaS example
Design Philosophy: Opt-in, zero-breaking-changes. Multi-tenancy features are completely optional and only active when explicitly configured.
Changed
Protocol Type System Enhancements
- Protocol Core (
turbomcp-protocol):- Enhanced content types with improved serialization/deserialization
- Expanded sampling workflow types with better async support
- Elicitation API Refactored:
ElicitRequestParamsis now an enum withFormandUrlvariants- Breaking: Constructor changed from struct literal to
ElicitRequestParams::form()factory method - Added
message()method to access message across variants ElicitRequestnow has optionaltaskfield (feature-gated withmcp-tasks)
- Breaking: Constructor changed from struct literal to
- Implementation struct enhanced with new optional fields (MCP 2025-11-25):
description: Option<String>- Human-readable description of implementationicons: Option<Vec<Icon>>- Icon metadata for UI integration
- Tool definition types updated for better compatibility with spec features
Client API Updates
- Client Handlers (
turbomcp-client):- Elicitation request API refactored to match new enum-based
ElicitRequestParams:ElicitationRequest::schema()now returnsOption<&ElicitationSchema>(None for URL mode)ElicitationRequest::timeout()returns None for URL modeElicitationRequest::is_cancellable()returns false for URL mode- All methods handle both Form and Url elicitation modes correctly
- Elicitation request API refactored to match new enum-based
Authorization Configuration Updates
- Authentication (
turbomcp-auth):- Module structure reorganized with feature-gated access
- New optional dependency:
dashmap6.1.0 for concurrent caching (CIMD and Discovery) - Added
mcp-ssrf,mcp-cimd,mcp-oidc-discovery, andmcp-incremental-consentfeature flags - Updated
fullfeature to include new draft specification modules - HTTP client now includes built-in SSRF protection via redirect policy
OAuth 2.1 Dependencies - Major Upgrade
- Breaking (for auth feature users): Migrated from
oauth24.4.2 → 5.0.0- Typestate System: Client now uses compile-time endpoint tracking for improved type safety
- Stateful HTTP Client: Connection pooling and reuse for better performance
- SSRF Protection: HTTP client configured with
redirect::Policy::none()to prevent redirect-based attacks - Method Renames:
set_revocation_uri()→set_revocation_url()(API breaking change) - Import Changes:
StandardRevocableTokenmoved fromoauth2::revocation::tooauth2::root
- Eliminated Duplicate Dependencies: Removed 29 transitive dependencies
- Removed
oauth2 v4.4.2(now only v5.0.0) - Removed
reqwest v0.11.27(now only v0.12.24) - Removed
base64 v0.13.1andv0.21.7(now only v0.22.1) - Build Time Impact: Reduced compilation time and binary size
- Removed
- Updated:
jsonwebtokenfrom 9.2 → 10.2.0 across workspace- Unified 8 crates to use workspace version
- Updated features: now using
aws_lc_rsbackend
OAuth2 Client Implementation (turbomcp-auth)
- Refactored:
OAuth2Clientstruct with typestate annotationsBasicClient<EndpointSet, EndpointNotSet, EndpointNotSet, EndpointNotSet, EndpointSet>- Compile-time guarantees for endpoint configuration
- Improved: HTTP client handling with stateful reqwest::Client
- Connection pooling for multiple OAuth requests
- Configured to prevent SSRF via redirect blocking
- Fixed: Optional client secret handling in oauth2 5.0
- Conditional
set_client_secret()only when secret is present - Prevents type mismatches in typestate system
- Conditional
Fixed
Request Context Error Handling
- Fixed: Double-boxing errors in
RequestContexttenant validation methodsrequire_tenant()andvalidate_tenant_ownership()were wrapping errors twice- Changed from
Box::new(Error::new(...))toError::new(...).into() - Fixes compilation errors introduced by recent context API enhancements
Files Modified: crates/turbomcp-protocol/src/context/request.rs
Known Issues
Token Revocation Temporarily Unavailable
- Limitation:
OAuth2Client::revoke_token()currently returns an error due to oauth2 5.0 typestate constraints- Cause: Conditional revocation URL configuration changes client type at compile time
- Workaround: Tokens will naturally expire based on their TTL
- Future Fix: Will address in next minor version by either:
- Making
OAuth2Clientgeneric over revocation endpoint typestate - Storing revocation URL separately and building client on-demand
- Using dynamic dispatch for client storage
- Making
- Impact: Minimal - token expiration remains functional, only explicit revocation is unavailable
Breaking Changes
- Migrated from oauth2 4.4.2 to oauth2 5.0.0 – introduces typestate system, stateful HTTP client, and method renames (e.g., set_revocation_uri → set_revocation_url).
- Removed transitive dependencies: oauth2 v4.4.2, reqwest v0.11.27, base64 versions v0.13.1 and v0.21.7; only the new versions remain.
- Elicitation API refactored: ElicitRequestParams is now an enum with Form/Url variants; constructor changed to factory method `ElicitRequestParams::form()`.
Security Fixes
- SSRF protection added to HTTP client (redirect policy set to none) in oauth2 5.0.0 integration.
- OAuth2Client now conditionally sets client secret only when present, preventing type mismatches in the new typestate system.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
Related context
Beta — feedback welcome: [email protected]