pub struct McpClient { /* private fields */ }Expand description
A connected (and, after McpClient::initialize, handshaken) remote MCP
server over Streamable HTTP.
Implementations§
Source§impl McpClient
impl McpClient
Sourcepub fn connect(
name: &str,
endpoint: &str,
headers: Vec<(String, String)>,
timeout: Duration,
) -> Result<McpClient, McpError>
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.
Sourcepub fn connect_signed(
name: &str,
endpoint: &str,
headers: Vec<(String, String)>,
timeout: Duration,
signer: Option<Arc<dyn RequestSigner>>,
) -> Result<McpClient, McpError>
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).
Sourcepub fn with_client_info(self, info: Implementation) -> McpClient
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.
Sourcepub fn with_elicitation(self, handler: Arc<dyn Handler>) -> McpClient
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.
Sourcepub fn with_roots(self, handler: Arc<dyn Handler>) -> McpClient
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.
Sourcepub fn with_tasks(self) -> McpClient
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).
Sourcepub fn with_identity(self, identity: ClientIdentity) -> McpClient
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).
pub fn name(&self) -> &str
pub fn capabilities(&self) -> &ServerCapabilities
Sourcepub fn set_tool_meta(&mut self, meta: Value)
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.
Sourcepub fn initialize(&mut self) -> Result<(), McpError>
pub fn initialize(&mut self) -> Result<(), McpError>
MCP lifecycle handshake: initialize → store capabilities →
notifications/initialized. Uses the default per-request timeout.
Sourcepub fn initialize_within(&mut self, timeout: Duration) -> Result<(), McpError>
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.
Sourcepub fn era(&self) -> Era
pub fn era(&self) -> Era
The protocol era established on connect (legacy handshake vs modern stateless). Governs how each request is built.
Sourcepub fn protocol_version(&self) -> Option<&str>
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.
Sourcepub fn list_tools(&self) -> Result<Vec<Tool>, McpError>
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.
Sourcepub fn list_tools_within(
&self,
_timeout: Duration,
) -> Result<Vec<Tool>, McpError>
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.
Sourcepub fn call_tool(
&self,
name: &str,
arguments: Option<Value>,
) -> Result<CallToolResult, McpError>
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.
Sourcepub fn call_tool_with_meta(
&self,
name: &str,
arguments: Option<Value>,
extra_meta: Value,
) -> Result<CallToolResult, McpError>
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.
Sourcepub fn call_tool_with_meta_within(
&self,
name: &str,
arguments: Option<Value>,
extra_meta: Value,
timeout: Duration,
) -> Result<CallToolResult, McpError>
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.
pub fn list_resources(&self) -> Result<Vec<Resource>, McpError>
Sourcepub fn list_prompts(&self) -> Result<Vec<Prompt>, McpError>
pub fn list_prompts(&self) -> Result<Vec<Prompt>, McpError>
prompts/list, following cursor pagination to completion. Empty when the
server doesn’t advertise prompts.
Sourcepub fn get_prompt(
&self,
name: &str,
arguments: Option<Value>,
) -> Result<GetPromptResult, McpError>
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.
Sourcepub fn complete(
&self,
reference: Value,
argument: Value,
) -> Result<CompleteResult, McpError>
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.
Sourcepub fn list_resource_templates(&self) -> Result<Vec<ResourceTemplate>, McpError>
pub fn list_resource_templates(&self) -> Result<Vec<ResourceTemplate>, McpError>
resources/templates/list, paginated. Empty when the server doesn’t
advertise resources.
Sourcepub fn ping(&self) -> Result<(), McpError>
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.
Sourcepub fn as_task(&self, result: &Value) -> Option<Task>
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.
Sourcepub fn get_task(&self, task_id: &str) -> Result<Task, McpError>
pub fn get_task(&self, task_id: &str) -> Result<Task, McpError>
tasks/get — poll one async task’s current state (the tasks extension).
Sourcepub fn update_task(
&self,
task_id: &str,
input_responses: Value,
) -> Result<(), McpError>
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.
Sourcepub fn cancel_task(&self, task_id: &str) -> Result<(), McpError>
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.
Sourcepub fn await_task(
&self,
task_id: &str,
deadline: Instant,
) -> Result<Task, McpError>
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.
pub fn read_resource(&self, uri: &str) -> Result<ReadResourceResult, McpError>
Sourcepub fn read_resource_within(
&self,
uri: &str,
_timeout: Duration,
) -> Result<ReadResourceResult, McpError>
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.
Sourcepub fn subscribe(&self, uri: &str) -> Result<(), McpError>
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.
Sourcepub fn subscribe_within(
&self,
uri: &str,
_timeout: Duration,
) -> Result<(), McpError>
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.
pub fn unsubscribe(&self, uri: &str) -> Result<(), McpError>
Sourcepub fn unsubscribe_within(
&self,
uri: &str,
_timeout: Duration,
) -> Result<(), McpError>
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.
Sourcepub fn drain_notifications(&self) -> Vec<Notification>
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.