Skip to main content

McpClient

Struct McpClient 

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

A connected (and, after McpClient::initialize, handshaken) remote MCP server over Streamable HTTP.

Implementations§

Source§

impl McpClient

Source

pub fn connect( name: &str, endpoint: &str, headers: Vec<(String, String)>, timeout: Duration, ) -> Result<McpClient, McpError>

Connect to a remote MCP server over Streamable HTTP. endpoint is https://… / http://… / unix:/path / vsock:cid:port. headers are caller-owned request headers (auth/framing — already-resolved secret values, never templates, and never logged). No process is spawned. Call Self::initialize before any tool/resource call.

Source

pub fn connect_signed( name: &str, endpoint: &str, headers: Vec<(String, String)>, timeout: Duration, signer: Option<Arc<dyn RequestSigner>>, ) -> Result<McpClient, McpError>

Self::connect with an optional per-request AAuth signer — every outbound request to this server is then signed, including the long-lived notification stream. None = unsigned (the connect default).

Source

pub fn with_client_info(self, info: Implementation) -> McpClient

Override the client identity sent to servers (name + version). agentd sets its own; other hosts of the mcp crate set theirs.

Source

pub fn with_elicitation(self, handler: Arc<dyn Handler>) -> McpClient

Answer server→client elicitation requests through handler: a server may ask the operator a question mid-call and get a typed answer back. Declares the elicitation client capability, so a server only asks when we can actually deliver the question to a human.

Source

pub fn with_roots(self, handler: Arc<dyn Handler>) -> McpClient

Answer roots/list through handler — the URI roots this client permits a server to operate on. Declares the roots capability.

Source

pub fn with_tasks(self) -> McpClient

Advertise support for the tasks extension (io.modelcontextprotocol/ tasks) — a server may then return an async task handle from a supported request instead of blocking (poll it with Self::get_task).

Source

pub fn with_identity(self, identity: ClientIdentity) -> McpClient

Attach a mutual-TLS client identity (a mounted cert chain + key) for a https:// endpoint. A no-op on non-TLS endpoints (the identity is only presented during the TLS handshake). The private key is read from a mounted file and never leaves the process — it is not logged, rendered into an error, or copied onto the wire (see net::tls).

Source

pub fn name(&self) -> &str

Source

pub fn capabilities(&self) -> &ServerCapabilities

Source

pub fn set_tool_meta(&mut self, meta: Value)

Set the _meta stamped onto every tools/call (e.g. the run id), so a server can recognize a retried call and dedupe its side effect. Call after initialize.

Source

pub fn initialize(&mut self) -> Result<(), McpError>

MCP lifecycle handshake: initialize → store capabilities → notifications/initialized. Uses the default per-request timeout.

Source

pub fn initialize_within(&mut self, timeout: Duration) -> Result<(), McpError>

Self::initialize with a caller-supplied timeout for the initialize round-trip — the SHORT management bound. Used by the hot-reload re-handshake, which adds a server ON the reactor thread mid-loop: a slow-but-alive added server must not block the reactor (and starve the liveness heartbeat) for the full default bound. A timeout is contained, reported as mcp.connect.fail, and the server is simply treated as absent rather than failing the reload.

Source

pub fn era(&self) -> Era

The protocol era established on connect (legacy handshake vs modern stateless). Governs how each request is built.

Source

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

The protocol version negotiated with the server (None before connect). Sent as MCP-Protocol-Version on every subsequent request.

Source

pub fn list_tools(&self) -> Result<Vec<Tool>, McpError>

tools/list, following cursor pagination to completion. Empty when the server doesn’t advertise tools. Uses the default per-request timeout.

Source

pub fn list_tools_within( &self, _timeout: Duration, ) -> Result<Vec<Tool>, McpError>

tools/list for the reactor-thread management path (hot-reload re-handshake, claim coordination re-validation), which wants a shorter bound than the data path so a slow-but-alive coordination server cannot outrun the liveness heartbeat. A timeout surfaces as the usual McpError::Timeout, which those callers treat as a best-effort failure. The listing is served by the SDK connection, whose own request bound applies; timeout is accepted for call-site symmetry.

Source

pub fn call_tool( &self, name: &str, arguments: Option<Value>, ) -> Result<CallToolResult, McpError>

tools/call. The returned CallToolResult carries isError (a tool-domain failure the model sees as an observation) — distinct from an Err here, which is a transport/protocol failure and fails the call.

Source

pub fn call_tool_with_meta( &self, name: &str, arguments: Option<Value>, extra_meta: Value, ) -> Result<CallToolResult, McpError>

tools/call with per-call _meta merged on top of the persistent Self::set_tool_meta for this one call only — without mutating the stored meta. Used by the work-claim client, where agent/claim_key identifies one work item and must ride only that call — stamping it persistently would attach one item’s key to every later call. extra_meta (an object) wins key-by-key over the persistent meta; a non-object extra_meta replaces it. The persistent meta is left untouched.

Source

pub fn call_tool_with_meta_within( &self, name: &str, arguments: Option<Value>, extra_meta: Value, timeout: Duration, ) -> Result<CallToolResult, McpError>

tools/call with per-call _meta AND a caller-supplied per-request timeout — the SHORT management bound rather than the long data-path default. Used by the reactor-thread lease management path (claim renew/ack/release) — a slow coordination server must not block the reactor past the liveness staleness window. Behaviour is otherwise identical to Self::call_tool_with_meta; a timeout surfaces as McpError::Timeout, which the lease callers already treat as a best-effort failure. The data path (subagent tool calls) never uses this — it keeps the default timeout.

Source

pub fn list_resources(&self) -> Result<Vec<Resource>, McpError>

Source

pub fn list_prompts(&self) -> Result<Vec<Prompt>, McpError>

prompts/list, following cursor pagination to completion. Empty when the server doesn’t advertise prompts.

Source

pub fn get_prompt( &self, name: &str, arguments: Option<Value>, ) -> Result<GetPromptResult, McpError>

prompts/get — render the named prompt template with arguments (a flat string map). Gated on the server advertising prompts.

Source

pub fn complete( &self, reference: Value, argument: Value, ) -> Result<CompleteResult, McpError>

completion/complete — argument autocompletion for a prompt / resource- template reference. Gated on the server advertising completions.

Source

pub fn list_resource_templates(&self) -> Result<Vec<ResourceTemplate>, McpError>

resources/templates/list, paginated. Empty when the server doesn’t advertise resources.

Source

pub fn ping(&self) -> Result<(), McpError>

ping — a liveness round-trip both sides of MCP must answer. Returns Ok(()) if the server answers within the default timeout.

Source

pub fn as_task(&self, result: &Value) -> Option<Task>

If result is a task handle (resultType: "task", the async shape a task-augmented request returns instead of blocking), parse it. Enable the extension with Self::with_tasks; poll the handle with Self::get_task.

Source

pub fn get_task(&self, task_id: &str) -> Result<Task, McpError>

tasks/get — poll one async task’s current state (the tasks extension).

Source

pub fn update_task( &self, task_id: &str, input_responses: Value, ) -> Result<(), McpError>

tasks/update — supply inputResponses for a task in input_required (the MRTR fulfilment path). Acknowledged with an empty result.

Source

pub fn cancel_task(&self, task_id: &str) -> Result<(), McpError>

tasks/cancel — request cancellation of a task (cooperative; the server may still reach a non-cancelled terminal state). Acknowledged with an empty result.

Source

pub fn await_task( &self, task_id: &str, deadline: Instant, ) -> Result<Task, McpError>

Poll tasks/get until the task reaches a terminal status or deadline, honoring the server’s pollIntervalMs (bounded to a sane window). Returns the terminal Task (the caller reads result/error); a task that stops on input_required is returned so the caller can drive the MRTR loop.

Source

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

Source

pub fn read_resource_within( &self, uri: &str, _timeout: Duration, ) -> Result<ReadResourceResult, McpError>

resources/read for the reactor thread’s notify-then-read (read_current), which blocks on it and therefore wants a shorter bound than the data path: a slow-but-alive resource server must not outrun the liveness heartbeat. A timeout surfaces as McpError::Timeout; because the reactor is level-triggered it treats a timed-out read exactly like any read failure (act on empty / skip), so a transient slow read is recovered on the next updated notification or re-read. The read is served by the SDK connection, whose own request bound applies; timeout is accepted for call-site symmetry.

Source

pub fn subscribe(&self, uri: &str) -> Result<(), McpError>

resources/subscribe, gated on the server advertising resources.subscribe — subscribing to a server that never pushes would leave the reactor idle.

Source

pub fn subscribe_within( &self, uri: &str, _timeout: Duration, ) -> Result<(), McpError>

Self::subscribe for the reactor-thread reload re-handshake, where a slow-but-alive server arming a subscription must not block the reactor. The call is served by the SDK connection, whose own request bound applies; timeout is accepted for call-site symmetry.

Source

pub fn unsubscribe(&self, uri: &str) -> Result<(), McpError>

Source

pub fn unsubscribe_within( &self, uri: &str, _timeout: Duration, ) -> Result<(), McpError>

Self::unsubscribe for the reactor-thread reload reconcile and the drain unsubscribe, both best-effort: a slow server here must not block the reactor past the liveness window or overrun the drain budget. The call is served by the SDK connection, whose own request bound applies; timeout is accepted for call-site symmetry.

Source

pub fn drain_notifications(&self) -> Vec<Notification>

Drain any notifications queued since the last drain (e.g. notifications/resources/updated). The reactive router (triggers/mode.rs) drains these between runs to drive re-reactions.

Trait Implementations§

Source§

impl Drop for McpClient

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl McpCall for McpClient

Source§

fn call( &self, tool: &str, args: Value, meta: Value, timeout: Duration, ) -> Result<CallToolResult, String>

Source§

fn server_name(&self) -> String

Source§

impl SkillServer for McpClient

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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