mcpmesh 0.26.1

Share MCP servers with people you trust — peer to peer, default-deny, no accounts
Documentation
[package]
name = "mcpmesh"
version.workspace = true
edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
readme = "../README.md"
description = "Share MCP servers with people you trust — peer to peer, default-deny, no accounts"
# The spawn-backend test stub is a test-only helper the integration tests reach via
# `CARGO_BIN_EXE_echo_mcp_stub`; excluding it from the package keeps `cargo install
# mcpmesh` shipping exactly one binary. The local tree (and CI) still build it for tests.
exclude = ["src/bin/echo_mcp_stub.rs"]

[lints]
workspace = true

[[bin]]
name = "mcpmesh"
path = "src/main.rs"

[features]
# TEST-ONLY (#116): forwards to mcpmesh-node so `doctor` can report whether THIS binary can
# honour `[network] relay_only`. Default off — see node/Cargo.toml for the semver rationale.
unstable-relay-only = ["mcpmesh-node/unstable-relay-only"]

[dependencies]
anyhow.workspace = true
clap.workspace = true
clap_complete.workspace = true
clap_mangen.workspace = true
serde.workspace = true
serde_json.workspace = true
thiserror.workspace = true
# `process` is added cli-local (the workspace tokio omits it — Task 3 detaches the
# daemon via std::process): the `run` backend (Task 7) spawns a child MCP server per
# session via tokio::process::Command with async stdin/stdout handles. No new crate.
tokio = { workspace = true, features = ["process"] }
tracing.workspace = true
mcpmesh-trust.workspace = true
mcpmesh-net.workspace = true
# `service` (implies `client`): the daemon consumes the seam's ONE hardened UDS rule
# (`ensure_private_dir`/`bind_uds` — symlink-refused 0700 owned dir, 0600 socket) for its own
# control socket, and the porcelain client wraps the seam's no-iroh ControlClient (D5) —
# adding daemon auto-start on top rather than re-implementing the wire.
mcpmesh-local-api = { workspace = true, features = ["service"] }
# The daemon core: the cli's daemon subcommand is the process shell (flock, env paths,
# runtime, control socket) around this crate's Node; porcelain + tests reach the moved
# modules through cli/src/lib.rs re-exports.
mcpmesh-node.workspace = true
# Our own uid for the runtime-dir ownership + peer-uid checks (spec §11.2/§13), plus the
# `fs::flock` single-daemon lock (Task 3). Already in the tree via iroh; SAFE wrappers (no
# inline unsafe → satisfies forbid(unsafe)). Peer uid itself comes from tokio's
# UnixStream::peer_cred() — no `nix` crate needed.
rustix = { version = "1", features = ["process", "fs"] }

[dev-dependencies]
tempfile.workspace = true
assert_cmd.workspace = true
# Log-capture for the pairing-rendezvous surface-discipline test (Task 5): assert no peer
# EndpointId leaks into a refusal's logs. Already in the lock via iroh (0.3.x) → a dev-only
# dependency edge, NO new crate version, no deny.toml change.
tracing-subscriber = "0.3"
# The `tests/*.rs` integration crate is separate from the package: it sees the `mcpmesh` lib
# + dev-deps only, so tokio (for `#[tokio::test]`) and serde_json must be listed here too.
tokio.workspace = true
serde_json.workspace = true
# Test-side only: the integration suites assemble hermetic meshes (endpoints, address
# lookups) and forge roster signatures directly. The SHIPPED binary reaches iroh through
# mcpmesh-net's pinned re-export and dalek through mcpmesh-trust's — no runtime dep here.
# `test-utils` (dev-only) brings `iroh::test_utils::run_relay_server`, which lets the #64 path
# test drive a REAL relay in-process. Without it the suite can only ever produce a direct path —
# and it was exactly that blind spot that let a wrong direct-vs-relay derivation pass review-free.
iroh = { workspace = true, features = ["test-utils"] }
# The in-process relay serves a self-signed cert; the #64 path test trusts it explicitly.
# Dev-only, and already in the lock via iroh.
iroh-relay = { version = "1", features = ["test-utils"] }
ed25519-dalek.workspace = true
# The distribute tests install the ring provider themselves (they build reqwest clients
# without booting a daemon). Same ring-only posture as mcpmesh-node's runtime dep.
rustls = { version = "0.23", default-features = false, features = ["ring", "std"] }
# The blob AC/gate tests hash fixture bytes and drive raw iroh-blobs requests at the gate.
blake3 = "1"
iroh-blobs = { workspace = true }

# Debian packaging (spec §16 M4). `cargo-deb` reads this declarative table — no debian/{control,rules}
# shell. Build with `cargo install cargo-deb && cargo deb -p mcpmesh` (a runbook step; cargo-deb is NOT a
# CI dependency, so this is validated only for TOML/parse correctness via `cargo metadata`). The
# operator runbook (docs/operator.md) is shipped separately; keep assets to the binary here to
# avoid a build-order dependency on files generated elsewhere.
[package.metadata.deb]
maintainer = "mcpmesh <knotanotsea@protonmail.com>"
copyright = "2026, mcpmesh contributors"
extended-description = """\
Peer-to-peer MCP transport: serve local MCP servers to allowlisted peers and mount remote peers' \
services through a local stdio proxy, over an end-to-end-encrypted iroh mesh. See `mcpmesh doctor` for \
a local health check and docs/operator.md for the operator runbook."""
section = "net"
priority = "optional"
depends = "$auto"
assets = [
    ["target/release/mcpmesh", "usr/bin/", "755"],
]