Skip to main content

RequestContext

Struct RequestContext 

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

Context for a request, providing progress, cancellation, and client request support

Implementations§

Source§

impl RequestContext

Source

pub fn supports_mcp_apps(&self) -> bool

Return whether both peers negotiated MCP Apps with the stable HTML MIME.

Source§

impl RequestContext

Source

pub fn supports_tasks(&self) -> bool

Whether both peers negotiated the final Tasks extension.

Task dispatch keys off this rather than off the protocol version: a 2026-07-28 request from a client that did not declare the extension must not receive a task.

Source§

impl RequestContext

Source

pub fn new(request_id: RequestId) -> Self

Create a new request context

Source

pub fn with_progress_token(self, token: ProgressToken) -> Self

Set the progress token

Source

pub fn with_notification_sender(self, tx: NotificationSender) -> Self

Set the notification sender

Source

pub fn with_min_log_level(self, level: Arc<RwLock<LogLevel>>) -> Self

Set the minimum log level for filtering outgoing log notifications

This is shared with the router so that logging/setLevel updates are immediately visible to all request contexts.

Source

pub fn with_client_requester(self, requester: ClientRequesterHandle) -> Self

Set the client requester for server-to-client requests

Source

pub fn with_extensions(self, extensions: Arc<Extensions>) -> Self

Set the extensions for this request context.

Extensions allow router-level state and middleware data to flow to handlers.

Source

pub fn extension<T: Send + Sync + 'static>(&self) -> Option<&T>

Get a reference to a value from the extensions map.

Returns None if no value of the given type has been inserted.

§Example
#[derive(Clone)]
struct CurrentUser { id: String }

// In a handler:
if let Some(user) = ctx.extension::<CurrentUser>() {
    println!("User: {}", user.id);
}
Source

pub fn negotiated_extensions(&self) -> Option<&NegotiatedExtensions>

Protocol extensions declared by both the client and server.

Unknown or one-sided declarations are not included. The returned view preserves each peer’s settings object for extension-specific policy.

Source

pub fn extensions_mut(&mut self) -> &mut Extensions

Get a mutable reference to the extensions.

This allows middleware to insert data that handlers can access via the Extension<T> extractor.

Source

pub fn extensions(&self) -> &Extensions

Get a reference to the extensions.

Source

pub fn per_request_meta(&self) -> Option<&StatelessRequestMeta>

SEP-2575 per-request _meta (protocol version, client info, client capabilities, log level) if the transport extracted it.

Returns Some for 2026-07-28 clients on JSON-RPC transports when the request carried a _meta object with recognized fields. Returns None when:

§Example
async fn my_tool(ctx: RequestContext, input: MyInput) -> Result<CallToolResult> {
    if let Some(meta) = ctx.per_request_meta() {
        // protocol_version, client_info, client_capabilities are all Option<_>
        if let Some(ref version) = meta.protocol_version {
            tracing::debug!(protocol_version = %version);
        }
        if let Some(ref info) = meta.client_info {
            tracing::info!(client = %info.name, version = %info.version);
        }
    }
    Ok(CallToolResult::text("ok"))
}
Source

pub fn mrtr(&self) -> Option<&MrtrRequest>

SEP-2322 continuation values supplied by the client on this attempt.

Source

pub fn input_responses(&self) -> Option<&InputResponses>

Client responses from the prior MRTR round, if any.

Source

pub fn request_state(&self) -> Option<&str>

Opaque request state echoed by the client, if any.

Source

pub fn request_state_codec(&self) -> Option<&RequestStateCodec>

Router-configured request-state codec shared by this handler.

Source

pub fn request_id(&self) -> &RequestId

Get the request ID

Source

pub fn progress_token(&self) -> Option<&ProgressToken>

Get the progress token (if any)

Source

pub fn is_cancelled(&self) -> bool

Check if the request has been cancelled

Source

pub fn cancel(&self)

Mark the request as cancelled

Source

pub async fn cancelled(&self)

Wait until the request is cancelled.

Completes when cancel is called – by a notifications/cancelled message, or by the transport when the client disconnects before the response is delivered (HTTP stateless mode). Useful in tokio::select! to abandon work early:

tokio::select! {
    result = do_work() => { /* ... */ }
    _ = ctx.cancelled() => return Err(Error::tool("cancelled")),
}
Source

pub fn cancellation_token(&self) -> CancellationToken

Get a cancellation token that can be shared

Source

pub fn with_cancellation_token(self, token: CancellationToken) -> Self

Replace this context’s cancellation source with an existing token.

Used by transports to link a request’s lifetime to an external signal (e.g. client disconnect on the HTTP stateless path). After this call, is_cancelled(), cancelled(), and tokens returned by cancellation_token all observe the given token.

Source

pub async fn report_progress( &self, progress: f64, total: Option<f64>, message: Option<&str>, )

Report progress to the client

This is a no-op if no progress token was provided or no notification sender is configured.

Source

pub fn report_progress_sync( &self, progress: f64, total: Option<f64>, message: Option<&str>, )

Report progress synchronously (non-async version)

This is a no-op if no progress token was provided or no notification sender is configured.

Source

pub fn notify_tools_list_changed(&self) -> bool

Notify subscribed clients that the tool list changed.

Source

pub fn notify_prompts_list_changed(&self) -> bool

Notify subscribed clients that the prompt list changed.

Source

pub fn notify_resources_list_changed(&self) -> bool

Notify subscribed clients that the resource list changed.

Source

pub fn notify_resource_updated(&self, uri: impl Into<String>) -> bool

Notify subscribed clients that one resource changed.

Source

pub fn send_log(&self, params: LoggingMessageParams)

Send a log message notification to the client

This is a no-op if no notification sender is configured.

§Example
use tower_mcp::protocol::{LoggingMessageParams, LogLevel};

async fn my_tool(ctx: RequestContext) {
    ctx.send_log(
        LoggingMessageParams::new(LogLevel::Info, serde_json::json!("Processing..."))
            .with_logger("my-tool")
    );
}
Source

pub fn can_sample(&self) -> bool

Check if sampling is available

Returns true if a client requester is configured and the transport supports bidirectional communication.

Source

pub async fn sample( &self, params: CreateMessageParams, ) -> Result<CreateMessageResult>

Request an LLM completion from the client

This sends a sampling/createMessage request to the client and waits for the response. The client is expected to forward this to an LLM and return the result.

Returns an error if sampling is not available (no client requester configured).

§Example
use tower_mcp::{CreateMessageParams, SamplingMessage};

async fn my_tool(ctx: RequestContext, input: MyInput) -> Result<CallToolResult> {
    let params = CreateMessageParams::new(
        vec![SamplingMessage::user("Summarize: ...")],
        500,
    );

    let result = ctx.sample(params).await?;
    Ok(CallToolResult::text(format!("{:?}", result.content)))
}
Source

pub fn can_elicit(&self) -> bool

Check if elicitation is available

Returns true if a client requester is configured and the transport supports bidirectional communication. Note that this only checks if the mechanism is available, not whether the client supports elicitation.

Source

pub async fn elicit_form( &self, params: ElicitFormParams, ) -> Result<ElicitResult>

Request user input via a form from the client

This sends an elicitation/create request to the client with a form schema. The client renders the form to the user and returns their response.

Returns an error if elicitation is not available (no client requester configured).

§Example
use tower_mcp::{ElicitFormParams, ElicitFormSchema, ElicitMode, ElicitAction};

async fn my_tool(ctx: RequestContext, input: MyInput) -> Result<CallToolResult> {
    let params = ElicitFormParams {
        mode: Some(ElicitMode::Form),
        message: "Please enter your details".to_string(),
        requested_schema: ElicitFormSchema::new()
            .string_field("name", Some("Your name"), true),
        meta: None,
    };

    let result = ctx.elicit_form(params).await?;
    match result.action {
        ElicitAction::Accept => {
            // Use result.content
            Ok(CallToolResult::text("Got your input!"))
        }
        _ => Ok(CallToolResult::text("User declined"))
    }
}
Source

pub async fn elicit_url(&self, params: ElicitUrlParams) -> Result<ElicitResult>

Request user input via URL redirect from the client

This sends an elicitation/create request to the client with a URL. The client directs the user to the URL for out-of-band input collection. The server receives the result via a callback notification.

Returns an error if elicitation is not available (no client requester configured).

Protocol note: ElicitUrlParams::elicitation_id and the callback notification it correlates with are a 2025-11-25-and-earlier pattern. The final 2026-07-28 schema removes both in favor of MRTR (SEP-2322). Use an MRTR-capable tool, prompt, or resource handler there; the client learns the outcome by retrying the original request instead of receiving a completion notification.

§Example
use tower_mcp::{ElicitUrlParams, ElicitMode, ElicitAction};

async fn my_tool(ctx: RequestContext, input: MyInput) -> Result<CallToolResult> {
    let params = ElicitUrlParams {
        mode: Some(ElicitMode::Url),
        elicitation_id: "unique-id-123".to_string(),
        message: "Please authorize via the link".to_string(),
        url: "https://example.com/auth?id=unique-id-123".to_string(),
        meta: None,
    };

    let result = ctx.elicit_url(params).await?;
    match result.action {
        ElicitAction::Accept => Ok(CallToolResult::text("Authorization complete!")),
        _ => Ok(CallToolResult::text("Authorization cancelled"))
    }
}
Source

pub async fn confirm(&self, message: impl Into<String>) -> Result<bool>

Request simple confirmation from the user.

This is a convenience method for simple yes/no confirmation dialogs. It creates an elicitation form with a single boolean “confirm” field and returns true if the user accepts, false otherwise.

Returns an error if elicitation is not available (no client requester configured).

§Example
use tower_mcp::{RequestContext, CallToolResult};

async fn delete_item(ctx: RequestContext) -> Result<CallToolResult> {
    let confirmed = ctx.confirm("Are you sure you want to delete this item?").await?;
    if confirmed {
        // Perform deletion
        Ok(CallToolResult::text("Item deleted"))
    } else {
        Ok(CallToolResult::text("Deletion cancelled"))
    }
}
Source

pub async fn list_tasks( &self, status: Option<TaskStatus>, ) -> Result<ListTasksResult>

👎Deprecated since 0.13.0:

final SEP-2663 removes tasks/list; a conforming peer answers MethodNotFound (-32601). Only useful against legacy SEP-1686 clients.

List tasks tracked by the connected client (legacy SEP-1686).

Sends a tasks/list request to the client and returns the result. Pass Some(status) to filter to a single status, or None for all tasks. Pagination is exposed via ListTasksResult::next_cursor; use request_raw for cursor-driven calls.

Returns an error if no client requester is configured or the client does not advertise task support.

Source

pub async fn get_task_info( &self, task_id: impl Into<String>, ) -> Result<TaskObject>

Fetch metadata for a single task tracked by the client (SEP-1686).

Sends a tasks/get request and returns the task object, including the current status, timestamps, and TTL.

Source

pub async fn get_task_result( &self, task_id: impl Into<String>, ) -> Result<CallToolResult>

👎Deprecated since 0.13.0:

final SEP-2663 removes tasks/result (results are inlined in the tasks/get DetailedTask); a conforming peer answers MethodNotFound (-32601). Only useful against legacy SEP-1686 clients.

Fetch the terminal result for a task tracked by the client (legacy SEP-1686).

Sends a tasks/result request. The client is expected to block until the task reaches a terminal state and then return the underlying CallToolResult. For long-running tasks, prefer polling with get_task_info and only call this once the status is terminal.

Source

pub async fn cancel_task( &self, task_id: impl Into<String>, reason: Option<String>, ) -> Result<()>

Cancel a task tracked by the client.

Sends a tasks/cancel request. Per final SEP-2663 the acknowledgment is an empty result and the observable task status is polled via get_task_info; the ack body is discarded, so this also tolerates legacy SEP-1686 peers that return the task object.

Source

pub async fn request_raw(&self, method: &str, params: Value) -> Result<Value>

Send an arbitrary JSON-RPC request to the client.

Escape hatch for methods not covered by the typed helpers (e.g. when a tasks/list cursor needs to be passed). Most callers should prefer the typed methods.

Trait Implementations§

Source§

impl Clone for RequestContext

Source§

fn clone(&self) -> RequestContext

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RequestContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

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<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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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