Skip to main content

ExtensionHandlerRegistry

Struct ExtensionHandlerRegistry 

Source
pub struct ExtensionHandlerRegistry { /* private fields */ }
Expand description

Frozen, typed server handlers bound to one protocol descriptor registry.

The map is erased only internally. Each Self::register call fixes that method’s own decoded request and encoded response types in a serde adapter, so one registry can hold heterogeneous extension methods without weakening a handler’s typed Rust boundary. Method ownership, direction, negotiated capability activation, and descriptor receipt are still enforced by the protocol registry at every invocation.

Implementations§

Source§

impl ExtensionHandlerRegistry

Source

pub fn new(descriptor_registry: ExtensionDescriptorRegistry) -> Self

Starts a handler registry around the supplied protocol descriptor registry.

Source

pub const fn descriptor_registry(&self) -> &ExtensionDescriptorRegistry

Returns the protocol descriptor registry that governs handler admission.

Source

pub const fn is_frozen(&self) -> bool

Returns whether handler registration has been frozen.

Source

pub fn len(&self) -> usize

Returns the number of registered typed handlers.

Source

pub fn is_empty(&self) -> bool

Returns whether no typed handlers have been registered.

Source

pub fn server_metadata_len(&self) -> usize

Returns the number of descriptor-bound server metadata entries.

Source

pub fn register_server_metadata( &mut self, extension_id: ExtensionId, settings: ExtensionSettings, ) -> Result<(), ExtensionHandlerRegistrationError>

Registers the exact server discovery settings for one extension.

This is intentionally separate from request-handler registration: an extension such as MCP Apps can need a server discovery marker before it owns a client-to-server extension method. The marker is accepted only for a descriptor already linked into this registry, and is immutable once the descriptor receipt is frozen.

Source

pub fn register<Request, Response, Handler>( &mut self, extension_id: ExtensionId, method: impl Into<String>, handler: Handler, ) -> Result<(), ExtensionHandlerRegistrationError>
where Request: DeserializeOwned + 'static, Response: Serialize + 'static, Handler: ExtensionHandler<Request, Response> + 'static,

Registers one typed handler for an extension request method.

Descriptor existence, exact method ownership, and client-to-server direction are checked immediately. Self::invoke still checks request-specific admission against the current negotiated extension set before the handler can run.

Source

pub fn freeze( &mut self, ) -> Result<ExtensionRegistryReceipt, ExtensionRegistryError>

Freezes protocol descriptors and typed handlers under one immutable receipt.

Source

pub fn freeze_with_server_discovery( &mut self, ) -> Result<(ExtensionRegistryReceipt, ServerExtensionDiscovery), ExtensionRegistryError>

Freezes this registry and returns its matching discovery metadata.

Use this after extension composition is complete to inspect one frozen descriptor receipt with its matching metadata. During builder composition, ServerBuilder::extension_registry derives registered metadata directly so later official Tasks installation remains mutable.

Source

pub fn server_discovery( &self, ) -> Result<ServerExtensionDiscovery, ExtensionHandlerLookupError>

Returns the server discovery data bound to this frozen registry.

This frozen diagnostic/export surface is separate from builder-time composition, which snapshots registered metadata before freeze.

Source

pub fn lookup( &self, extension_id: &ExtensionId, method: &str, ) -> Result<&ExtensionHandlerKey, ExtensionHandlerLookupError>

Looks up one handler after freezing has made the registry immutable.

Source

pub fn invoke( &self, negotiated: &NegotiatedExtensionSet, protocol_era: ProtocolEra, extension_id: &ExtensionId, request: &JsonRpcRequest, context: &McpContext, ) -> Result<Value, ExtensionHandlerInvocationError>

Admits and invokes one typed client-to-server extension request.

The protocol admission call binds this invocation to the exact frozen descriptor receipt, current negotiated extension set, modern era, and client-to-server ownership and request envelope before the handler is looked up or executed. A handler can only be registered for a descriptor’s request method, so an id-less notification is rejected generically before its parameters can reach stateful extension code.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, _span: NoopSpan) -> Self

Instruments this future with a span (no-op when disabled).
Source§

fn in_current_span(self) -> Self

Instruments this future with the current span (no-op when disabled).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more