use mcpmesh_local_api::{
AuditKind, BackendKind, Hello, InviteResult, PairResult, PeerInfo, PeerReachability,
PresencePeer, RecentPairing, RosterInstallResult, RosterStatus, StatusResult, StreamFrame,
};
use crate::{client, proxy, util};
pub const SERVE_EXAMPLE: &str =
"mcpmesh serve notes -- npx -y @modelcontextprotocol/server-filesystem ~/notes";
pub fn error_lines(err: &anyhow::Error) -> Vec<String> {
for cause in err.chain() {
if let Some(client::ClientError::Api(value)) = cause.downcast_ref::<client::ClientError>() {
return control_error_lines(value);
}
}
let mut lines = vec![format!("Error: {err}")];
let mut causes = err.chain().skip(1).peekable();
if causes.peek().is_some() {
lines.push(String::new());
lines.push("Caused by:".to_string());
for cause in causes {
lines.push(format!(" {cause}"));
}
}
lines
}
fn control_error_lines(error: &serde_json::Value) -> Vec<String> {
let message = error
.get("message")
.and_then(serde_json::Value::as_str)
.unwrap_or("");
let message = strip_wire_framing(message);
if message.contains("dial the inviter") {
return vec![
"Error: could not reach the inviter's machine — are they online?".to_string(),
"(You cannot redeem your own invite on the machine that minted it — run \
`mcpmesh pair` on the other machine.)"
.to_string(),
];
}
if message.is_empty() {
return vec![
"Error: the daemon reported an unexpected error — run 'mcpmesh doctor' to diagnose"
.to_string(),
];
}
vec![format!("Error: {message}")]
}
fn strip_wire_framing(message: &str) -> &str {
match message.split_once(" failed: ") {
Some((method, rest))
if !method.is_empty()
&& !rest.is_empty()
&& method.bytes().all(|b| b == b'_' || b.is_ascii_lowercase()) =>
{
rest
}
_ => message,
}
}
pub fn invite_lines(invite: &InviteResult, services: &[String], now: u64) -> Vec<String> {
vec![
format!(
"One-time invite (expires {}). Share it out-of-band:",
friendly_expiry(invite.expires_at_epoch, now)
),
format!(" {}", invite.invite_line),
format!("Whoever redeems it can access: {}", services.join(", ")),
String::new(),
"Next: send them that line over any channel. They redeem it with `mcpmesh pair <line>`,"
.to_string(),
"which prints a short safety code — run `mcpmesh status` to see yours and confirm the two"
.to_string(),
"match, out loud. Same words = the pairing is authentic.".to_string(),
]
}
pub fn pair_lines(result: &PairResult) -> Vec<String> {
let peer = &result.peer_nickname;
let mut lines = vec![
format!("Paired with {peer} — code: {}", result.sas_code),
format!(
"Next: confirm this code matches what {peer} sees, out loud (they see it under \
`mcpmesh status`). Same words = the pairing is authentic."
),
];
if result.services.is_empty() {
return lines;
}
let mounts = result
.services
.iter()
.map(|s| format!("{peer}/{s}"))
.collect::<Vec<_>>()
.join(", ");
lines.push(String::new());
lines.push(format!("You can now use: {mounts}"));
lines.push(String::new());
lines.extend(proxy::client_instruction_lines(peer, &result.services));
lines
}
fn friendly_expiry(expires_at_epoch: u64, now: u64) -> String {
let remaining = expires_at_epoch.saturating_sub(now);
if remaining < 60 {
return "soon".to_string();
}
if remaining < 3600 {
let mins = (remaining + 30) / 60; return format!("in {mins}m");
}
let hours = (remaining + 1800) / 3600; format!("in {hours}h")
}
fn friendly_age(epoch: u64, now: u64) -> String {
let elapsed = now.saturating_sub(epoch);
if elapsed < 60 {
return "just now".to_string();
}
if elapsed < 3600 {
return format!("{}m ago", elapsed / 60);
}
if elapsed < 24 * 3600 {
return format!("{}h ago", elapsed / 3600);
}
format!("{}d ago", elapsed / (24 * 3600))
}
pub fn roster_install_line(result: &RosterInstallResult) -> String {
let sessions = if result.severed == 1 {
"session"
} else {
"sessions"
};
format!(
"Installed roster for org '{}' (serial {}). Severed {} live {sessions}.",
result.org_id, result.serial, result.severed
)
}
pub fn render_status(
fingerprint: &str,
hello: &Hello,
status: &StatusResult,
has_roster_url: bool,
) {
println!(
"{} v{} · stack {}",
hello.api, hello.api_version, hello.stack_version
);
println!("device {fingerprint}");
if let Some(user_id) = &status.self_user_id {
println!("identity {user_id}");
}
println!();
if status.services.is_empty() {
println!("no services configured");
} else {
println!("serving:");
for svc in &status.services {
let kind = backend_kind_label(svc.backend);
let allowed = if svc.allow.is_empty() {
"no one yet".to_owned()
} else if !svc.allow_display.is_empty() {
svc.allow_display.join(", ")
} else {
svc.allow
.iter()
.map(|p| {
if p.starts_with("eid:") || p.starts_with("b64u:") {
"paired-peer".to_owned()
} else {
p.clone()
}
})
.collect::<Vec<_>>()
.join(", ")
};
println!(" {} · {kind} · allowed: {allowed}", svc.name);
}
}
println!();
if status.peers.is_empty() {
println!("no peers yet");
} else {
println!("peers:");
for peer in &status.peers {
let services = if peer.services.is_empty() {
"none".to_owned()
} else {
peer.services.join(", ")
};
match &peer.user_id {
Some(user_id) => {
println!(" {} · services: {services} · {user_id}", peer.name)
}
None => println!(" {} · services: {services}", peer.name),
}
}
}
if !status.reachability.is_empty() {
println!();
println!("reachability:");
for line in reachability_lines(&status.reachability) {
println!("{line}");
}
}
if !status.recent_pairings.is_empty() {
println!();
println!("recent pairings (confirm the code with the other side):");
for line in recent_pairing_lines(&status.recent_pairings, util::epoch_now_u64()) {
println!("{line}");
}
}
if let Some(roster) = &status.roster {
println!();
for line in roster_status_lines(roster, has_roster_url) {
println!("{line}");
}
}
if !status.presence.is_empty() {
println!();
println!("reachable:");
for line in presence_lines(&status.presence) {
println!("{line}");
}
}
let next = next_steps_lines(status);
if !next.is_empty() {
println!();
for line in next {
println!("{line}");
}
}
}
pub fn reachability_lines(reachability: &[PeerReachability]) -> Vec<String> {
reachability
.iter()
.map(|r| {
let label = match (r.reachable, r.age_secs) {
(_, None) => "checking…", (true, _) => "online",
(false, _) => "offline",
};
let mut line = match r.rtt_ms {
Some(ms) if r.reachable => format!(" {} · {label} · {ms}ms", r.name),
_ => format!(" {} · {label}", r.name),
};
if r.reachable {
line.push_str(match &r.path {
mcpmesh_local_api::PeerPath::Direct => " · direct",
mcpmesh_local_api::PeerPath::Relay { .. } => " · relay",
_ => " · path unknown",
});
}
if !r.meta.is_empty() {
line.push_str(" · app: ");
line.push_str(&sanitize_meta(&r.meta));
}
line
})
.collect()
}
pub fn use_target_error(peer: &str, service: &str, peers: &[PeerInfo]) -> Option<String> {
let Some(known) = peers.iter().find(|p| p.name == peer) else {
let names: Vec<&str> = peers.iter().map(|p| p.name.as_str()).collect();
return Some(if names.is_empty() {
format!(
"no paired peer named '{peer}' — nobody is paired yet; redeem an invite with \
'mcpmesh pair <invite>'"
)
} else {
format!(
"no paired peer named '{peer}' — your peers: {} (see 'mcpmesh status')",
names.join(", ")
)
});
};
if known.services.iter().any(|s| s == service) {
return None;
}
Some(if known.services.is_empty() {
format!(
"'{peer}' does not share any services with you yet — ask them to send a new invite \
naming one"
)
} else {
format!(
"'{peer}' does not share a service named '{service}' — they share: {} \
(see 'mcpmesh status')",
known.services.join(", ")
)
})
}
pub fn next_steps_lines(status: &StatusResult) -> Vec<String> {
let mut steps = Vec::new();
if let Some((peer, service)) = status
.peers
.iter()
.find_map(|p| p.services.first().map(|s| (&p.name, s)))
{
steps.push(format!(
" Use {peer}/{service} from your AI client: `mcpmesh use {peer}/{service}`"
));
}
if status.services.is_empty() {
steps.push(
" Share one of your MCP servers: `mcpmesh serve <name> -- <command that runs it>`"
.to_string(),
);
steps.push(format!(
" No MCP server yet? Share a folder: `{SERVE_EXAMPLE}`"
));
} else if let Some(svc) = status.services.iter().find(|s| s.allow.is_empty()) {
steps.push(format!(
" Nobody can reach '{}' yet: `mcpmesh invite {}`",
svc.name, svc.name
));
}
if status.peers.is_empty() {
steps.push(" Someone sent you an invite? `mcpmesh pair mcpmesh-invite:…`".to_string());
}
if steps.is_empty() {
return steps;
}
let mut lines = vec!["next steps:".to_string()];
lines.extend(steps);
lines
}
pub fn recent_pairing_lines(pairings: &[RecentPairing], now: u64) -> Vec<String> {
pairings
.iter()
.map(|p| {
format!(
" {} · code: {} · {}",
p.peer_nickname,
p.sas_code,
friendly_age(p.paired_at_epoch, now)
)
})
.collect()
}
pub fn presence_lines(presence: &[PresencePeer]) -> Vec<String> {
presence
.iter()
.map(|p| {
let mut line = format!(
" {} · {} · {} · {}",
p.user_id,
p.device_label,
p.role,
if p.online { "online" } else { "offline" }
);
if !p.meta.is_empty() {
line.push_str(" · app: ");
line.push_str(&sanitize_meta(&p.meta));
}
line
})
.collect()
}
fn sanitize_meta(meta: &str) -> String {
const MAX: usize = 48;
let cleaned: String = meta.chars().filter(|c| !c.is_control()).collect();
if cleaned.chars().count() <= MAX {
return cleaned;
}
let cut: String = cleaned.chars().take(MAX).collect();
format!("{cut}…")
}
pub fn roster_status_lines(roster: &RosterStatus, has_roster_url: bool) -> Vec<String> {
let mut lines = vec![format!(
"roster: org {} · serial {} · {}",
roster.org_id, roster.serial, roster.state
)];
if !roster.org_root_fingerprint.is_empty() {
lines.push(format!(
" org root: {} (confirm out-of-band)",
roster.org_root_fingerprint
));
}
if !has_roster_url {
lines.push(
"hint: no roster URL configured — this node degrades after max_staleness with no way \
to re-confirm currency; set [roster].url"
.to_string(),
);
}
lines
}
fn backend_kind_label(kind: BackendKind) -> &'static str {
match kind {
BackendKind::Run => "run",
BackendKind::Socket => "socket",
}
}
fn kind_label(kind: AuditKind) -> &'static str {
match kind {
AuditKind::SessionOpen => "session_open",
AuditKind::SessionClose => "session_close",
AuditKind::Request => "request",
AuditKind::BlobFetch => "blob_fetch",
AuditKind::Trust => "trust",
}
}
pub fn render_frame(frame: &StreamFrame) -> String {
match frame {
StreamFrame::Snapshot {
active_sessions,
reachability,
self_network,
} => format!(
"snapshot: {} active session(s), {} peer(s) known{}",
active_sessions.len(),
reachability.len(),
match self_network {
Some(n) if n.online => " — online",
Some(n) if n.relays.is_empty() => "",
Some(_) => " — no relay connection",
None => "",
}
),
StreamFrame::Reachability { peer, .. } => format!(
"[reachability] {} is now {}",
peer.name,
if peer.reachable { "online" } else { "offline" }
),
StreamFrame::SelfNetwork { self_network } => {
if self_network.online {
"[self] online via relay".to_string()
} else {
"[self] relay connection lost — LAN/direct paths only".to_string()
}
}
StreamFrame::Event { record } => {
let peer = record
.peer
.as_deref()
.map(|p| format!("{p} "))
.unwrap_or_default();
let service = record
.service
.as_deref()
.map(|s| format!("→ {s}"))
.unwrap_or_default();
let status = record
.status
.as_deref()
.map(|s| format!(" ({s})"))
.unwrap_or_default();
let line = format!(
"[{}] {} {peer}{service}",
record.ts,
kind_label(record.kind)
);
format!("{}{status}", line.trim_end())
}
StreamFrame::Lagged { dropped } => {
format!("(lagged {dropped} events — reconnect for a fresh snapshot)")
}
_ => "[unknown frame]".to_string(),
}
}
#[cfg(test)]
mod tests {
use mcpmesh_local_api::{PeerInfo, ServiceInfo};
#[test]
fn render_frame_shows_a_reachability_transition() {
use mcpmesh_local_api::{PeerReachability, ReachabilitySource, StreamFrame};
let frame = |reachable| StreamFrame::Reachability {
peer: PeerReachability {
name: "bob".into(),
reachable,
rtt_ms: reachable.then_some(12),
age_secs: Some(0),
meta: String::new(),
principal: Some("eid:beef".into()),
path: Default::default(),
},
source: ReachabilitySource::Session,
};
let up = super::render_frame(&frame(true));
assert!(up.contains("bob") && up.contains("online"), "got {up}");
let down = super::render_frame(&frame(false));
assert!(
down.contains("bob") && down.contains("offline"),
"got {down}"
);
assert!(
!up.contains("eid:"),
"the DISPLAY surface stays endpoint-id-free: {up}"
);
}
use serde_json::json;
use super::*;
const DAY: u64 = 24 * 60 * 60;
#[test]
fn invite_block_has_the_expected_shape() {
let invite = InviteResult {
invite_line: "mcpmesh-invite:MFRGGZDF".into(),
expires_at_epoch: 1_000_000 + DAY,
};
let lines = invite_lines(&invite, &["notes".to_string()], 1_000_000);
assert_eq!(
lines[..3],
[
"One-time invite (expires in 24h). Share it out-of-band:".to_string(),
" mcpmesh-invite:MFRGGZDF".to_string(),
"Whoever redeems it can access: notes".to_string(),
]
);
let rendered = lines.join("\n");
assert!(
rendered.contains("Next:") && rendered.contains("mcpmesh pair"),
"the invite must name the redeemer's exact next command:\n{rendered}"
);
assert!(
rendered.contains("mcpmesh status"),
"the invite must point at where the inviter confirms the code:\n{rendered}"
);
}
#[test]
fn invite_block_lists_multiple_services() {
let invite = InviteResult {
invite_line: "mcpmesh-invite:X".into(),
expires_at_epoch: 500 + DAY,
};
let lines = invite_lines(&invite, &["notes".to_string(), "kb".to_string()], 500);
assert_eq!(lines[2], "Whoever redeems it can access: notes, kb");
assert!(lines[1].contains("mcpmesh-invite:"));
}
#[test]
fn pair_lines_render_the_sas_and_mount_targets() {
let result = PairResult {
peer_nickname: "alice".into(),
sas_code: "tango-fig-42".into(),
services: vec!["notes".into()],
app_label: None,
peer_user_id: None,
};
let lines = pair_lines(&result);
assert_eq!(lines[0], "Paired with alice — code: tango-fig-42");
assert!(lines[0].contains("code: tango-fig-42"));
let rendered = lines.join("\n");
assert!(
rendered.contains("Next: confirm this code matches what alice sees"),
"pair must name the ceremony as the next step:\n{rendered}"
);
assert!(
rendered.contains("You can now use: alice/notes"),
"pair must name the mount target:\n{rendered}"
);
assert!(
rendered.contains("claude mcp add alice-notes -- mcpmesh connect alice/notes")
&& rendered.contains("claude_desktop_config.json"),
"pair must print the client instructions inline:\n{rendered}"
);
}
#[test]
fn pair_lines_join_multiple_mount_targets_as_peer_slash_service() {
let result = PairResult {
peer_nickname: "alice".into(),
sas_code: "a-b-c".into(),
services: vec!["notes".into(), "kb".into()],
app_label: None,
peer_user_id: None,
};
let rendered = pair_lines(&result).join("\n");
assert!(
rendered.contains("You can now use: alice/notes, alice/kb"),
"both grants are named as mount targets:\n{rendered}"
);
assert!(
rendered.contains("claude mcp add alice-notes -- mcpmesh connect alice/notes")
&& rendered.contains("claude mcp add alice-kb -- mcpmesh connect alice/kb"),
"every granted service gets its own instruction:\n{rendered}"
);
}
#[test]
fn pair_lines_leak_no_endpoint_id() {
let alice_id = mcpmesh_net::iroh::SecretKey::from_bytes(&[7u8; 32])
.public()
.to_string();
let result = PairResult {
peer_nickname: "alice".into(),
sas_code: "tango-fig-42".into(),
services: vec!["notes".into()],
app_label: None,
peer_user_id: None,
};
let rendered = pair_lines(&result).join("\n");
assert!(
!rendered.contains(&alice_id),
"pair output must not leak an EndpointId: {rendered}"
);
for term in ["ALPN", "ticket", "mcpmesh/pair/1", "mcpmesh/mcp/1"] {
assert!(!rendered.contains(term), "pair output leaked '{term}'");
}
}
#[test]
fn pair_lines_tolerate_an_empty_service_grant() {
let result = PairResult {
peer_nickname: "alice".into(),
sas_code: "a-b-c".into(),
services: vec![],
app_label: None,
peer_user_id: None,
};
let lines = pair_lines(&result);
assert_eq!(lines[0], "Paired with alice — code: a-b-c");
let rendered = lines.join("\n");
assert!(rendered.contains("Next: confirm this code matches what alice sees"));
assert!(
!rendered.contains("You can now use") && !rendered.contains("claude mcp add"),
"no dangling mount/instruction block with nothing granted:\n{rendered}"
);
}
fn status_with(services: Vec<ServiceInfo>, peers: Vec<PeerInfo>) -> StatusResult {
StatusResult {
stack_version: "0".into(),
services,
peers,
roster: None,
presence: Vec::new(),
self_user_id: None,
recent_pairings: Vec::new(),
reachability: Vec::new(),
self_nickname: String::new(),
storage: None,
self_network: None,
}
}
fn service(name: &str, allow: &[&str]) -> ServiceInfo {
ServiceInfo {
name: name.into(),
allow: allow.iter().map(|s| s.to_string()).collect(),
allow_display: vec![],
backend: BackendKind::Run,
ephemeral: false,
}
}
fn peer(name: &str, services: &[&str]) -> PeerInfo {
PeerInfo {
name: name.into(),
services: services.iter().map(|s| s.to_string()).collect(),
user_id: None,
principal: None,
}
}
#[test]
fn next_steps_on_a_fresh_node_name_both_directions() {
let rendered = next_steps_lines(&status_with(vec![], vec![])).join("\n");
assert!(
rendered.contains("mcpmesh serve <name> --"),
"a fresh node must be told how to share:\n{rendered}"
);
assert!(
rendered.contains("mcpmesh pair"),
"a fresh node must be told how to redeem an invite:\n{rendered}"
);
}
#[test]
fn next_steps_offer_a_runnable_serve_example_to_someone_with_no_mcp_server() {
let rendered = next_steps_lines(&status_with(vec![], vec![])).join("\n");
assert!(
rendered.contains(SERVE_EXAMPLE),
"a fresh node must offer a runnable serve example:\n{rendered}"
);
assert!(
SERVE_EXAMPLE.contains("mcpmesh serve notes --")
&& SERVE_EXAMPLE.contains("@modelcontextprotocol/server-filesystem"),
"the example must be complete and copy-pasteable: {SERVE_EXAMPLE}"
);
}
#[test]
fn next_steps_point_a_served_but_ungranted_service_at_invite() {
let rendered =
next_steps_lines(&status_with(vec![service("notes", &[])], vec![])).join("\n");
assert!(
rendered.contains("mcpmesh invite notes"),
"an ungranted service must be pointed at `invite <name>`:\n{rendered}"
);
let granted = next_steps_lines(&status_with(
vec![service("notes", &["bob"])],
vec![peer("bob", &[])],
))
.join("\n");
assert!(
!granted.contains("mcpmesh invite notes"),
"a granted service needs no invite nag:\n{granted}"
);
}
#[test]
fn next_steps_point_a_reachable_peer_service_at_use() {
let rendered =
next_steps_lines(&status_with(vec![], vec![peer("alice", &["notes"])])).join("\n");
assert!(
rendered.contains("mcpmesh use alice/notes"),
"a reachable peer service must be pointed at `use`:\n{rendered}"
);
let bare = next_steps_lines(&status_with(vec![], vec![peer("alice", &[])])).join("\n");
assert!(
!bare.contains("mcpmesh use"),
"a peer with no grants offers no use step:\n{bare}"
);
}
#[test]
fn next_steps_are_silent_on_a_fully_configured_node() {
let lines = next_steps_lines(&status_with(
vec![service("notes", &["bob"])],
vec![peer("bob", &["code"])],
));
let rendered = lines.join("\n");
assert!(rendered.contains("mcpmesh use bob/code"));
assert!(!rendered.contains("mcpmesh serve") && !rendered.contains("mcpmesh pair"));
}
#[test]
fn reachability_lines_show_which_path_carried_the_traffic() {
let peer_at = |name: &str, path: mcpmesh_local_api::PeerPath| PeerReachability {
name: name.into(),
reachable: true,
rtt_ms: Some(12),
age_secs: Some(1),
meta: String::new(),
principal: None,
path,
};
let lines = reachability_lines(&[
peer_at("d", mcpmesh_local_api::PeerPath::Direct),
peer_at(
"r",
mcpmesh_local_api::PeerPath::Relay {
url: Some("https://relay.example/".into()),
},
),
peer_at("u", mcpmesh_local_api::PeerPath::Unknown),
]);
assert!(lines[0].contains("· direct"), "{}", lines[0]);
assert!(lines[1].contains("· relay"), "{}", lines[1]);
assert!(
!lines[1].contains("relay.example"),
"the relay URL belongs in --json, not the terminal: {}",
lines[1]
);
assert!(
lines[2].contains("path unknown"),
"Unknown must be STATED: {}",
lines[2]
);
assert!(
!lines[2].contains("· direct"),
"and must never read as direct: {}",
lines[2]
);
}
#[test]
fn an_offline_peer_reports_no_path() {
let lines = reachability_lines(&[PeerReachability {
name: "gone".into(),
reachable: false,
rtt_ms: None,
age_secs: Some(90),
meta: String::new(),
principal: None,
path: mcpmesh_local_api::PeerPath::Unknown,
}]);
assert!(!lines[0].contains("path"), "{}", lines[0]);
assert!(!lines[0].contains("direct"), "{}", lines[0]);
}
#[test]
fn reachability_lines_render_online_offline_and_checking() {
let lines = reachability_lines(&[
PeerReachability {
name: "alice".into(),
reachable: true,
rtt_ms: Some(23),
age_secs: Some(4),
meta: String::new(),
principal: None,
path: Default::default(),
},
PeerReachability {
name: "bob".into(),
reachable: false,
rtt_ms: None,
age_secs: Some(90),
meta: String::new(),
principal: None,
path: Default::default(),
},
PeerReachability {
name: "carol".into(),
reachable: false,
rtt_ms: None,
age_secs: None, meta: String::new(),
principal: None,
path: Default::default(),
},
]);
assert_eq!(lines[0], " alice · online · 23ms · path unknown");
assert_eq!(lines[1], " bob · offline");
assert_eq!(lines[2], " carol · checking…");
}
#[test]
fn use_target_error_names_the_known_peers_and_services() {
let peers = vec![peer("alice", &["notes", "kb"]), peer("bob", &[])];
assert_eq!(use_target_error("alice", "notes", &peers), None);
let msg = use_target_error("carol", "notes", &peers).unwrap();
assert!(
msg.contains("no paired peer named 'carol'")
&& msg.contains("your peers: alice, bob")
&& msg.contains("mcpmesh status"),
"unknown peer names the known list: {msg}"
);
let msg = use_target_error("alice", "code", &peers).unwrap();
assert!(
msg.contains("'alice' does not share a service named 'code'")
&& msg.contains("they share: notes, kb"),
"unknown service names the shared list: {msg}"
);
let msg = use_target_error("bob", "notes", &peers).unwrap();
assert!(
msg.contains("'bob' does not share any services with you yet"),
"a grantless peer gets a plain explanation: {msg}"
);
let msg = use_target_error("alice", "notes", &[]).unwrap();
assert!(
msg.contains("nobody is paired yet") && msg.contains("mcpmesh pair"),
"a peerless node is pointed at pair: {msg}"
);
}
#[test]
fn roster_install_line_renders_org_serial_and_pluralized_sever_count() {
let one = RosterInstallResult {
org_id: "acme".into(),
serial: 42,
severed: 1,
};
assert_eq!(
roster_install_line(&one),
"Installed roster for org 'acme' (serial 42). Severed 1 live session."
);
let none = RosterInstallResult {
org_id: "acme".into(),
serial: 7,
severed: 0,
};
assert_eq!(
roster_install_line(&none),
"Installed roster for org 'acme' (serial 7). Severed 0 live sessions."
);
let many = RosterInstallResult {
org_id: "acme".into(),
serial: 100,
severed: 3,
};
assert_eq!(
roster_install_line(&many),
"Installed roster for org 'acme' (serial 100). Severed 3 live sessions."
);
}
#[test]
fn roster_install_line_leaks_no_transport_vocabulary() {
let result = RosterInstallResult {
org_id: "acme".into(),
serial: 42,
severed: 1,
};
let line = roster_install_line(&result);
for term in [
"b64u:",
"endpoint",
"EndpointId",
"ALPN",
"roster.json",
"/",
"key",
] {
assert!(
!line.contains(term),
"roster install output leaked '{term}': {line}"
);
}
}
#[test]
fn roster_status_lines_render_org_serial_state_and_fingerprint() {
let roster = RosterStatus {
org_id: "acme".into(),
serial: 42,
state: "approved".into(),
org_root_fingerprint: "tango-fig-cabbage-anchor".into(),
};
let lines = roster_status_lines(&roster, true); assert_eq!(lines[0], "roster: org acme · serial 42 · approved");
assert_eq!(
lines[1],
" org root: tango-fig-cabbage-anchor (confirm out-of-band)"
);
}
#[test]
fn roster_status_lines_omit_the_org_root_line_when_the_fingerprint_is_absent() {
let roster = RosterStatus {
org_id: "acme".into(),
serial: 7,
state: "degraded".into(),
org_root_fingerprint: String::new(),
};
let lines = roster_status_lines(&roster, true); assert_eq!(lines, vec!["roster: org acme · serial 7 · degraded"]);
}
#[test]
fn roster_status_lines_append_url_less_hint_when_no_roster_url() {
let roster = RosterStatus {
org_id: "acme".into(),
serial: 7,
state: "approved".into(),
org_root_fingerprint: String::new(),
};
let lines = roster_status_lines(&roster, false); assert!(
lines
.iter()
.any(|l| l.contains("no roster URL configured") && l.contains("set [roster].url")),
"expected the URL-less degrade hint: {lines:?}"
);
let lines = roster_status_lines(&roster, true);
assert!(
!lines.iter().any(|l| l.contains("hint:")),
"no hint when a roster url is configured: {lines:?}"
);
}
#[test]
fn presence_lines_render_user_label_role_and_online_flag() {
let presence = vec![
PresencePeer {
user_id: "alice".into(),
device_label: "laptop".into(),
role: "primary".into(),
online: true,
meta: String::new(),
},
PresencePeer {
user_id: "alice".into(),
device_label: "desktop".into(),
role: "mirror".into(),
online: false,
meta: String::new(),
},
];
let lines = presence_lines(&presence);
assert_eq!(lines.len(), 2);
assert!(
lines[0].contains("alice")
&& lines[0].contains("laptop")
&& lines[0].contains("primary")
&& lines[0].contains("online"),
"the online primary renders user·label·role·online: {lines:?}"
);
assert!(
lines[1].contains("desktop")
&& lines[1].contains("mirror")
&& lines[1].contains("offline"),
"the dead mirror renders offline: {lines:?}"
);
}
#[test]
fn presence_meta_is_sanitized_and_truncated_in_status_lines() {
let peer = |meta: &str| PresencePeer {
user_id: "alice".into(),
device_label: "laptop".into(),
role: "primary".into(),
online: true,
meta: meta.into(),
};
let l = presence_lines(&[peer("v=1.2.3")]);
assert!(l[0].contains("· app: v=1.2.3"), "benign meta shown: {l:?}");
let l = presence_lines(&[peer("\n ghost · fake · primary · online\x1b[2K")]);
assert_eq!(l.len(), 1, "no forged extra line");
assert!(
!l[0].contains('\n') && !l[0].contains('\x1b'),
"control chars stripped: {l:?}"
);
let l = presence_lines(&[peer(&"x".repeat(200))]);
assert!(l[0].contains('…'), "long meta truncated: {l:?}");
}
#[test]
fn reachability_meta_is_sanitized_in_status_lines() {
let peer = |meta: &str| PeerReachability {
name: "bob".into(),
reachable: true,
rtt_ms: Some(12),
age_secs: Some(2),
meta: meta.into(),
principal: None,
path: Default::default(),
};
let l = reachability_lines(&[peer("v=2.0.0")]);
assert!(l[0].contains("· app: v=2.0.0"), "benign meta shown: {l:?}");
let l = reachability_lines(&[peer("\n ghost · online\x1b[2K")]);
assert_eq!(l.len(), 1, "no forged extra line");
assert!(
!l[0].contains('\n') && !l[0].contains('\x1b'),
"control chars stripped: {l:?}"
);
let l = reachability_lines(&[PeerReachability {
name: "carol".into(),
reachable: false,
rtt_ms: None,
age_secs: Some(30),
meta: String::new(),
principal: None,
path: Default::default(),
}]);
assert!(!l[0].contains("app:"), "no app segment without meta: {l:?}");
}
#[test]
fn presence_lines_leak_no_transport_vocabulary() {
let presence = vec![PresencePeer {
user_id: "alice".into(),
device_label: "laptop".into(),
role: "primary".into(),
online: true,
meta: String::new(),
}];
let rendered = presence_lines(&presence).join("\n");
for term in ["b64u:", "EndpointId", "endpoint", "ALPN", "pubkey", "hash"] {
assert!(
!rendered.contains(term),
"presence output leaked '{term}': {rendered}"
);
}
}
#[test]
fn roster_status_lines_leak_no_transport_vocabulary() {
let roster = RosterStatus {
org_id: "acme".into(),
serial: 42,
state: "approved".into(),
org_root_fingerprint: "tango-fig-cabbage-anchor".into(),
};
let rendered = roster_status_lines(&roster, true).join("\n");
for term in [
"b64u:",
"EndpointId",
"endpoint",
"ALPN",
"ticket",
"roster.json",
] {
assert!(
!rendered.contains(term),
"roster status output leaked '{term}': {rendered}"
);
}
}
#[test]
fn recent_pairing_lines_render_nickname_code_and_age() {
let pairings = vec![
RecentPairing {
peer_nickname: "bob".into(),
sas_code: "tango-fig-cabbage".into(),
paired_at_epoch: 1_000_000,
},
RecentPairing {
peer_nickname: "carol".into(),
sas_code: "anchor-bean-cable".into(),
paired_at_epoch: 1_000_000 - 5 * 60,
},
];
let lines = recent_pairing_lines(&pairings, 1_000_010);
assert_eq!(lines[0], " bob · code: tango-fig-cabbage · just now");
assert_eq!(lines[1], " carol · code: anchor-bean-cable · 5m ago");
}
#[test]
fn recent_pairing_lines_leak_no_endpoint_id_or_transport_vocabulary() {
let bob_id = mcpmesh_net::iroh::SecretKey::from_bytes(&[7u8; 32])
.public()
.to_string();
let pairings = vec![RecentPairing {
peer_nickname: "bob".into(),
sas_code: "tango-fig-cabbage".into(),
paired_at_epoch: 100,
}];
let rendered = recent_pairing_lines(&pairings, 200).join("\n");
assert!(
!rendered.contains(&bob_id),
"recent pairings must not leak an EndpointId: {rendered}"
);
for term in [
"endpoint",
"ticket",
"ALPN",
"iroh",
"pubkey",
"mcpmesh/pair/1",
] {
assert!(
!rendered.to_lowercase().contains(&term.to_lowercase()),
"recent pairings leaked '{term}': {rendered}"
);
}
}
#[test]
fn friendly_age_buckets_and_saturates_sensibly() {
assert_eq!(friendly_age(1_000, 1_030), "just now"); assert_eq!(friendly_age(1_000, 1_000 + 5 * 60), "5m ago");
assert_eq!(friendly_age(1_000, 1_000 + 3 * 3600), "3h ago");
assert_eq!(friendly_age(1_000, 1_000 + 2 * 24 * 3600), "2d ago");
assert_eq!(friendly_age(2_000, 1_000), "just now");
}
#[test]
fn friendly_expiry_rounds_and_degrades_sensibly() {
assert_eq!(friendly_expiry(1_000 + DAY, 1_002), "in 24h");
assert_eq!(friendly_expiry(3 * 3600, 0), "in 3h");
assert_eq!(friendly_expiry(45 * 60, 0), "in 45m");
assert_eq!(friendly_expiry(30, 0), "soon");
assert_eq!(friendly_expiry(100, 1_000), "soon");
}
fn frame(v: serde_json::Value) -> StreamFrame {
serde_json::from_value(v).expect("wire frame deserializes into StreamFrame")
}
#[test]
fn render_frame_summarizes_a_snapshot() {
let v = frame(json!({
"type": "snapshot",
"active_sessions": [
{"peer": "bob", "service": "notes", "opened_at": 1},
{"peer": "carol", "service": "kb", "opened_at": 2},
],
"reachability": [{"name": "bob", "reachable": true}],
}));
assert_eq!(
render_frame(&v),
"snapshot: 2 active session(s), 1 peer(s) known"
);
let empty = frame(json!({ "type": "snapshot", "active_sessions": [], "reachability": [] }));
assert_eq!(
render_frame(&empty),
"snapshot: 0 active session(s), 0 peer(s) known"
);
}
#[test]
fn render_frame_renders_an_event_line() {
let v = frame(json!({
"type": "event",
"record": { "ts": "2026-07-17T14:02:11.480Z", "kind": "session_open",
"peer": "bob", "service": "notes" },
}));
assert_eq!(
render_frame(&v),
"[2026-07-17T14:02:11.480Z] session_open bob → notes"
);
}
#[test]
fn render_frame_marks_a_failed_dial_with_its_status() {
let failed = frame(json!({
"type": "event",
"record": { "ts": "2026-07-17T14:02:11.480Z", "kind": "session_open",
"peer": "bob", "service": "notes", "status": "error" },
}));
assert_eq!(
render_frame(&failed),
"[2026-07-17T14:02:11.480Z] session_open bob → notes (error)"
);
let normal = frame(json!({
"type": "event",
"record": { "ts": "2026-07-17T14:02:11.480Z", "kind": "session_open",
"peer": "bob", "service": "notes" },
}));
assert!(!render_frame(&normal).contains('('));
}
#[test]
fn render_frame_tolerates_a_bare_event_record() {
let v = frame(json!({
"type": "event",
"record": { "ts": "2026-07-17T14:02:11.480Z", "kind": "trust", "event": "unpair" },
}));
assert_eq!(render_frame(&v), "[2026-07-17T14:02:11.480Z] trust");
}
#[test]
fn render_frame_tolerates_asymmetric_event_records() {
let peer_only = frame(json!({
"type": "event",
"record": { "ts": "2026-07-17T14:02:11.480Z", "kind": "blob_fetch", "peer": "bob" },
}));
assert_eq!(
render_frame(&peer_only),
"[2026-07-17T14:02:11.480Z] blob_fetch bob"
);
let service_only = frame(json!({
"type": "event",
"record": { "ts": "2026-07-17T14:02:11.480Z", "kind": "session_open", "service": "notes" },
}));
assert_eq!(
render_frame(&service_only),
"[2026-07-17T14:02:11.480Z] session_open → notes"
);
}
#[test]
fn render_frame_renders_a_lagged_notice() {
let v = frame(json!({ "type": "lagged", "dropped": 7 }));
assert_eq!(
render_frame(&v),
"(lagged 7 events — reconnect for a fresh snapshot)"
);
}
fn api_error(value: serde_json::Value) -> anyhow::Error {
anyhow::Error::from(client::ClientError::Api(value))
}
#[test]
fn control_api_errors_render_the_message_never_the_json_object() {
let err = api_error(json!({"code": -32000, "message": "invite expired"}));
let lines = error_lines(&err);
assert_eq!(lines, vec!["Error: invite expired".to_string()]);
let rendered = lines.join("\n");
assert!(
!rendered.contains('{') && !rendered.contains("-32000"),
"no JSON-RPC object/code may leak: {rendered}"
);
}
#[test]
fn wire_method_framing_is_stripped_from_control_errors() {
let err = api_error(json!({"code": -32000, "message":
"peer_remove failed: no paired peer named 'nobody' — 'mcpmesh status' lists your peers"}));
assert_eq!(
error_lines(&err),
vec![
"Error: no paired peer named 'nobody' — 'mcpmesh status' lists your peers"
.to_string()
]
);
let err = api_error(json!({"code": -32000, "message":
"invite failed: no service named 'nosuchsvc' — you serve: notes (see 'mcpmesh status')"}));
assert_eq!(
error_lines(&err),
vec![
"Error: no service named 'nosuchsvc' — you serve: notes (see 'mcpmesh status')"
.to_string()
]
);
assert_eq!(strip_wire_framing("invite expired"), "invite expired");
assert_eq!(
strip_wire_framing("the Frobnicator failed: twice"),
"the Frobnicator failed: twice"
);
}
#[test]
fn failed_pair_dial_renders_in_user_language() {
let err = api_error(json!({
"code": -32000,
"message": "pair failed: could not dial the inviter's machine"
}));
let rendered = error_lines(&err).join("\n");
assert!(
rendered.contains("could not reach the inviter's machine")
&& rendered.contains("are they online?"),
"the failure states what happened in user language: {rendered}"
);
assert!(
rendered.contains("cannot redeem your own invite on the machine that minted it"),
"the self-redeem case is explained: {rendered}"
);
for term in ["ALPN", "dial", "{"] {
assert!(!rendered.contains(term), "leaked '{term}': {rendered}");
}
}
#[test]
fn a_message_less_control_error_degrades_to_doctor_not_json() {
let err = api_error(json!({"code": -32000}));
let rendered = error_lines(&err).join("\n");
assert!(
rendered.contains("mcpmesh doctor") && !rendered.contains('{'),
"degrades to a next step, never raw JSON: {rendered}"
);
}
#[test]
fn non_control_errors_keep_their_context_chain() {
let err = anyhow::Error::from(std::io::Error::other("disk full"))
.context("write staged roster /tmp/x");
let lines = error_lines(&err);
assert_eq!(lines[0], "Error: write staged roster /tmp/x");
assert!(
lines.iter().any(|l| l == "Caused by:")
&& lines.iter().any(|l| l.contains("disk full")),
"the cause survives: {lines:?}"
);
let single = anyhow::anyhow!("bad --expires: unknown unit");
assert_eq!(
error_lines(&single),
vec!["Error: bad --expires: unknown unit".to_string()]
);
}
}