pub struct ControlClient { /* private fields */ }Expand description
A connected mcpmesh-local/1 client: the framed stream + the server’s Hello.
Implementations§
Source§impl ControlClient
impl ControlClient
pub fn hello(&self) -> &Hello
Sourcepub async fn request(&mut self, request: Request) -> Result<Value, ClientError>
pub async fn request(&mut self, request: Request) -> Result<Value, ClientError>
Issue a typed request; return the JSON-RPC result (or ClientError::Api on a
JSON-RPC error).
Sourcepub async fn request_value(
&mut self,
request: &Value,
) -> Result<Value, ClientError>
pub async fn request_value( &mut self, request: &Value, ) -> Result<Value, ClientError>
Issue a RAW request frame — the escape hatch for methods outside the typed
Request surface (the daemon-internal shutdown, third-party
{"method":..,"params":{}} shapes the dispatcher tolerates). Returns the JSON-RPC
result value (or ClientError::Api on a JSON-RPC error).
Sourcepub async fn open_session(
self,
peer: String,
service: String,
) -> Result<(FrameReader<ControlRead>, ControlWrite), ClientError>
pub async fn open_session( self, peer: String, service: String, ) -> Result<(FrameReader<ControlRead>, ControlWrite), ClientError>
Send a request WITHOUT reading a response — for OpenSession, after which the
socket stops being JSON-RPC and becomes a raw MCP byte pipe (protocol.rs). Returns
the framed halves so the caller can pump the session — the SAME FrameReader that
read the Hello, so bytes the daemon pipelined behind it are never lost. A caller
that must re-box the read half calls FrameReader::into_inner, which returns the
BUFFERED reader (its read-ahead travels with it — see the pipelining test below).
Sourcepub async fn open_stream(
self,
method: &str,
) -> Result<(FrameReader<ControlRead>, ControlWrite), ClientError>
pub async fn open_stream( self, method: &str, ) -> Result<(FrameReader<ControlRead>, ControlWrite), ClientError>
Send a parameterless stream-upgrade request WITHOUT reading a response — like
open_session, but generic on the method: after this call the
socket stops being request/response and becomes a one-way push stream of frames the caller
READS (the subscribe telemetry surface). Returns the framed halves — the SAME
FrameReader that read the Hello, so any frame the daemon pipelined behind it is never
lost. The write half is handed back so the caller can hold the connection open (a watcher
only reads, but dropping the writer would half-close the socket).
Sourcepub async fn status(&mut self) -> Result<StatusResult, ClientError>
pub async fn status(&mut self) -> Result<StatusResult, ClientError>
The daemon’s status picture: services served, known peers, roster/presence state,
self identity, recent pairings, and advisory reachability.
Sourcepub async fn register_service(
&mut self,
name: &str,
backend: BackendSpec,
allow: Vec<String>,
) -> Result<(), ClientError>
pub async fn register_service( &mut self, name: &str, backend: BackendSpec, allow: Vec<String>, ) -> Result<(), ClientError>
Register/update a [services.*] entry idempotently (the daemon persists it and hot-reloads
serving). The daemon acks; the ack body is discarded.
Sourcepub async fn register_service_with(
&mut self,
name: &str,
backend: BackendSpec,
allow: Vec<String>,
ephemeral: bool,
) -> Result<(), ClientError>
pub async fn register_service_with( &mut self, name: &str, backend: BackendSpec, allow: Vec<String>, ephemeral: bool, ) -> Result<(), ClientError>
register_service with an explicit ephemeral flag (#36). When
ephemeral is true the registration lives only in daemon memory and is unregistered
automatically when THIS control connection closes — no config write, nothing to clean up.
Ideal for an embedder serving a socket backend from a fresh path each run.
Sourcepub async fn invite(
&mut self,
services: Vec<String>,
) -> Result<InviteResult, ClientError>
pub async fn invite( &mut self, services: Vec<String>, ) -> Result<InviteResult, ClientError>
Mint a one-time pairing invite granting services; return the copyable
mcpmesh-invite: line + its expiry.
Sourcepub async fn invite_with(
&mut self,
services: Vec<String>,
app_label: Option<String>,
) -> Result<InviteResult, ClientError>
pub async fn invite_with( &mut self, services: Vec<String>, app_label: Option<String>, ) -> Result<InviteResult, ClientError>
invite with an opaque app_label (#31) carried through to the redeemer’s
pair result. mcpmesh never interprets the label; the embedder does (e.g. its own URN).
Sourcepub async fn pair(
&mut self,
invite_line: &str,
) -> Result<PairResult, ClientError>
pub async fn pair( &mut self, invite_line: &str, ) -> Result<PairResult, ClientError>
Redeem a pairing invite; return the inviter’s suggested nickname, the display-only SAS code, and the granted services.
Sourcepub async fn peer_remove(&mut self, nickname: &str) -> Result<(), ClientError>
pub async fn peer_remove(&mut self, nickname: &str) -> Result<(), ClientError>
Unpair a peer by nickname: drops its identity row AND its every-allow membership
(idempotent; live sessions are not severed). The daemon acks; the ack body is discarded.
Sourcepub async fn peer_rename(
&mut self,
user_id: Option<String>,
nickname: Option<String>,
to: &str,
) -> Result<(), ClientError>
pub async fn peer_rename( &mut self, user_id: Option<String>, nickname: Option<String>, to: &str, ) -> Result<(), ClientError>
Rename a contact’s nickname to to — every device sharing user_id when given, else the
single provisional nickname entry — carrying its grants along. The daemon refuses (a
ClientError::Api) when to is empty or already names a different identity. The daemon
acks; the ack body is discarded.
Sourcepub async fn roster_install(
&mut self,
path: &str,
org_root_pk: Option<String>,
) -> Result<RosterInstallResult, ClientError>
pub async fn roster_install( &mut self, path: &str, org_root_pk: Option<String>, ) -> Result<RosterInstallResult, ClientError>
Install a signed roster from the LOCAL file at path (org_root_pk pins the org root on
FIRST install); return the installed org id + serial + severed-session count.
Sourcepub async fn org_join(
&mut self,
org_id: &str,
org_root_pk: &str,
user_id: &str,
user_key: &str,
) -> Result<OrgJoinResult, ClientError>
pub async fn org_join( &mut self, org_id: &str, org_root_pk: &str, user_id: &str, user_key: &str, ) -> Result<OrgJoinResult, ClientError>
Pin the org root on a JOINER (no roster yet). user_key is a LOCAL path — the key never
crosses the API. Returns the pinned org id.
Sourcepub async fn set_roster_url(&mut self, url: &str) -> Result<(), ClientError>
pub async fn set_roster_url(&mut self, url: &str) -> Result<(), ClientError>
Pin the HTTPS roster URL ([roster].url) in the daemon’s config. The daemon acks; the
ack body is discarded.
Sourcepub async fn audit_summary(&mut self) -> Result<AuditSummaryResult, ClientError>
pub async fn audit_summary(&mut self) -> Result<AuditSummaryResult, ClientError>
Summarize the daemon’s LOCAL audit log into per-peer / per-service session counts (local-only — nothing is transmitted).
Sourcepub async fn blob_publish(
&mut self,
scope: &str,
path: &str,
) -> Result<BlobPublishResult, ClientError>
pub async fn blob_publish( &mut self, scope: &str, path: &str, ) -> Result<BlobPublishResult, ClientError>
Publish a local file into scope; return the minted mcpmesh/blob/1 ticket + hash.
Sourcepub async fn blob_list(&mut self) -> Result<BlobScopeList, ClientError>
pub async fn blob_list(&mut self) -> Result<BlobScopeList, ClientError>
List the daemon’s blob scopes (name → hashes + grants).
Sourcepub async fn blob_fetch(
&mut self,
ticket: &str,
dest_path: &str,
) -> Result<BlobFetchResult, ClientError>
pub async fn blob_fetch( &mut self, ticket: &str, dest_path: &str, ) -> Result<BlobFetchResult, ClientError>
Fetch a mcpmesh/blob/1 ticket THROUGH the daemon (BLAKE3-verified), export to
dest_path; return the verified hash + byte length.
Sourcepub async fn blob_grant(
&mut self,
scope: &str,
principal: &str,
) -> Result<(), ClientError>
pub async fn blob_grant( &mut self, scope: &str, principal: &str, ) -> Result<(), ClientError>
Grant a scope to a principal — any flat-namespace entry: a group name, a user_id,
or a nickname (the shared principal_set expansion).
The daemon acks; the ack body is discarded (a JSON-RPC error surfaces as
ClientError::Api). Granting a scope to your own user_id reaches ALL of that
person’s devices.
Sourcepub async fn subscribe(self) -> Result<StreamSubscription, ClientError>
pub async fn subscribe(self) -> Result<StreamSubscription, ClientError>
The TYPED subscribe upgrade: send Request::Subscribe (after which the connection
stops being request/response — see open_stream) and return a
StreamSubscription yielding StreamFrames. For raw frames (e.g. to tolerate frame
types newer than this crate), use open_stream("subscribe") instead.