Skip to main content

Connection

Struct Connection 

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

An active connection to an MCP server using the Streamable HTTP transport.

Cheaply clonable (one Arc bump). When the last clone is dropped, the inner Arc ref count hits zero, the _listener_cancel_guard field is dropped, and the SSE listener task is cancelled — exiting any in-flight lines.next_line(), reconnect send(), or backoff sleep immediately without retrying against the now-dead proxy session.

Use the public methods (list_tools, call_tool, list_resources, read_resource, call_tool_as_message, tool_key) for the upstream MCP protocol surface. The inner state (ConnectionInner) is also reachable via Deref for read-only field access (e.g. connection.url, connection.initialize_result.server_info.name), but its methods are private — you must go through Connection.

Implementations§

Source§

impl Connection

Source

pub async fn delete(&self) -> Result<(), Error>

Tear this connection down explicitly.

  1. Cancels the long-lived list-changed listener task immediately (drops the DropGuard in ConnectionInner::_listener_cancel_guard), so by the time the HTTP DELETE goes out the listener isn’t still holding an SSE read open against the upstream we’re about to close.
  2. Issues DELETE / to the upstream with this connection’s Mcp-Session-Id and the same merged header set every other RPC stamps. Reuses ConnectionInner::call_timeout.
  3. Treats 404 / 401 / 403 as success — the upstream is unreachable from these credentials anyway, which is the desired terminal state. Other non-2xx surfaces as super::Error::BadStatus.

Takes &self: the listener cancel is in-place, and dropping the surrounding Arc<ConnectionInner> (which closes the rest of the connection’s owned state) is the caller’s responsibility — usually by dropping the Arc<Session> holding it. Stateless callers that don’t hold a Connection should use Client::delete instead.

In-flight RPC ordering. This method does not block on in-flight call_tool / read_resource / list_tools / list_resources calls on the same connection. If one is outstanding when delete lands, the upstream may see DELETE before the RPC’s reply makes it back; the in-flight call then surfaces as a closed-connection error to whoever started it. That’s the spec-correct order (client said terminate) — drain on the caller side first if you need different semantics.

Source

pub fn tool_key(&self) -> String

Returns a key identifying this connection for tool namespacing.

Source

pub fn session_id(&self) -> &str

Returns the session ID for this connection.

Source

pub async fn list_tools(&self) -> Result<Arc<Vec<Tool>>, Arc<Error>>

Returns all tools from the upstream server.

Source

pub async fn call_tool( &self, params: &CallToolRequestParams, ) -> Result<CallToolResult, Error>

Calls a tool on the upstream server.

Source

pub async fn call_tool_as_message( &self, params: &CallToolRequestParams, tool_call_id: String, ) -> Result<ToolMessage, Error>

Calls a tool and converts the result into a [ToolMessage].

Source

pub async fn list_resources(&self) -> Result<Arc<Vec<Resource>>, Arc<Error>>

Returns all resources from the upstream server.

Source

pub async fn read_resource( &self, uri: &str, ) -> Result<ReadResourceResult, Error>

Reads a resource from the upstream server.

Source

pub fn set_on_tools_list_changed<F>(&self, callback: F)
where F: Fn() + Send + Sync + 'static,

Register a callback to fire whenever the upstream emits notifications/tools/list_changed.

Timing: the callback runs after the tool cache’s write lock is acquired but before the network paginate that replaces it. That means readers blocked on the read lock won’t return until the new list is in place, and the callback observes the moment the staleness window opens. The proxy uses this to emit its own notifications/tools/list_changed to downstream clients at the right instant.

Replaces any previously-registered tools-list-changed callback. All clones of this Connection share the same callback slot.

Source

pub fn set_on_resources_list_changed<F>(&self, callback: F)
where F: Fn() + Send + Sync + 'static,

Register a callback to fire whenever the upstream emits notifications/resources/list_changed. Same timing contract as Connection::set_on_tools_list_changed.

Replaces any previously-registered resources-list-changed callback. All clones of this Connection share the same callback slot.

Source

pub async fn set_extra_headers(&self, extras: IndexMap<String, String>)

Atomically replace the connection’s ConnectionInner::extra_headers bag. Every subsequent outbound HTTP request from this connection stamps the new map AFTER headers, with HeaderMap::insert REPLACE semantics — keys in extras override the same key in the per-URL headers bag set at Client::connect. Caller supplies the FULL replacement map; missing keys are dropped (no merge).

Used by the proxy to inject session-global headers (X-OBJECTIVEAI-RESPONSE-ID, X-OBJECTIVEAI-RESPONSE-IDS) that re-set on every inbound initialize, without re-dialing the upstream.

Trait Implementations§

Source§

impl Clone for Connection

Source§

fn clone(&self) -> Self

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 Connection

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Deref for Connection

Source§

type Target = ConnectionInner

The resulting type after dereferencing.
Source§

fn deref(&self) -> &ConnectionInner

Dereferences the value.

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<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> 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToAst for T

Source§

fn ast(self, begin: usize, end: usize) -> Spanned<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