pub struct Bridge { /* private fields */ }Expand description
A stdio session forwarded to a shared server.
Besides the frames, the bridge keeps two things it saw pass through: the client’s
initialize, so that a session can be re-opened without the client noticing, and the
arguments of every accepted announcement the client has made, so that what the client
said it was working on outlives the server it said it to. An announcement was the one
fact that died with a server: on 2026-09-09 a session’s intent vanished from the board
when its transport was re-established, and eight peers could not see it for three hours.
The bridge is the one place that sees both the announcement and the reconnection, so
the bridge replays them — after a re-attach through Bridge::reinitialize, and, for a
takeover, through Bridge::announcements onto the new server’s own board.
Every announcement, one per claim name, and not merely the last one: a client may hold several claims at once, and replaying only the most recent would restore one of them and quietly drop the rest — which is the same loss the replay exists to prevent, arriving by a different route.
Implementations§
Source§impl Bridge
impl Bridge
Sourcepub fn new(url: String) -> Self
pub fn new(url: String) -> Self
A bridge to the server at url, with no session yet, waiting REQUEST_TIMEOUT
for each answer.
Sourcepub fn with_timeout(url: String, timeout: Duration) -> Self
pub fn with_timeout(url: String, timeout: Duration) -> Self
A bridge to the server at url that waits timeout for each answer. A call that
outlasts it is BridgeError::Unanswered: it was sent, and whether it ran is unknown.
use majordomus_cli::mcp::bridge::Bridge;
use std::time::Duration;
let bridge = Bridge::with_timeout("http://127.0.0.1:8741".into(), Duration::from_secs(5));
assert_eq!(bridge.url(), "http://127.0.0.1:8741");Sourcepub fn announcements(&self) -> impl Iterator<Item = &Value>
pub fn announcements(&self) -> impl Iterator<Item = &Value>
The arguments of every announcement the server accepted, one per claim name, in name order: what a takeover replays onto the new server’s board.
Empty when the client has announced nothing, which is every bridge that has only just been made — nothing has passed through it yet to be remembered.
use majordomus_cli::mcp::bridge::Bridge;
let bridge = Bridge::new("http://127.0.0.1:8741/mcp".into());
assert_eq!(bridge.announcements().count(), 0);Sourcepub fn client(&self) -> Option<&ClientInfo>
pub fn client(&self) -> Option<&ClientInfo>
What the client said in initialize, once it has.
Sourcepub fn move_to(&mut self, url: String)
pub fn move_to(&mut self, url: String)
Point the bridge at another server; the next message opens a session there.
Sourcepub fn handle(&mut self, message: &Value) -> Result<Option<Value>, BridgeError>
pub fn handle(&mut self, message: &Value) -> Result<Option<Value>, BridgeError>
Forward one message; None when the server had nothing to say (a notification).
Sourcepub fn reinitialize(&mut self) -> Result<(), BridgeError>
pub fn reinitialize(&mut self) -> Result<(), BridgeError>
Open a new session with the initialize the client sent earlier. A no-op when it has not sent one yet.
Sourcepub fn heartbeat(&mut self) -> Result<(), BridgeError>
pub fn heartbeat(&mut self) -> Result<(), BridgeError>
Keep the session alive.