peers.list
List peers
What it is
Every worker of this repository: id, the client's own name and version from its initialize, transport, when it attached, when it was last seen, what it announced, and which checkout it is attached to. A server serves one checkout, so the board of a repository worked on through linked worktrees is gathered: this checkout's board out of memory, every other checkout's from the server its lease names, asked for its own board alone. 'boards' says which checkouts were covered and 'complete' whether every one of them could be read, so a short board is never mistaken for an empty repository. 'checkouts: this' reads one board and enumerates, probes and asks nothing else. In-memory on every server; gone with the processes.
Descriptor
- Canonical id
peers.list- Module
peers- Kind
- query
- Stability
- behaviorallyverified
- Provenance
- declared
- Source
apps/majordomus-cli/src/capability/builtin/peers.rs- Cache
disabled- Benchmark
required- Tags
- peerscoordination
Run
queryProjections
| Interface | As | Where |
|---|---|---|
| MCP tool | majordomus_peers | - |
| MCP resource | not exposed | - |
| HTTP | GET /api/v1/peers | Swagger |
| Command line | not exposed | - |
Schemas
Input · PeerListInput
{
"type": "object",
"properties": {
"checkouts": {
"$ref": "#/$defs/Checkouts",
"description": "Which checkouts the board covers. Absent means `repository`; `this` is the checkout the call reached and nothing else, and it is what a sibling server is asked so that a gather can never ask back.",
"default": "repository"
}
},
"description": "What to ask of `peers.list`: how wide the board is.\n\nThe same one field, the same word and the same default as\n`super::server::ServerStatusInput`, because it is the same question asked of the same\nset of checkouts, and a caller should not have to learn it twice.\n\nThe evidence for that is `the_default_board_is_the_repositorys` below rather than a doc\nexample here: this module is `pub(crate)`, so a doc test — which compiles as an external\ncrate — cannot name the type at all.",
"title": "PeerListInput",
"$defs": {
"Checkouts": {
"oneOf": [
{
"type": "string",
"const": "repository",
"description": "Every checkout git registers for the repository, the primary first — a lease read\nand a probe each. The default, because it is the answer this capability gave before\nthere was anything to ask."
},
{
"type": "string",
"const": "this",
"description": "This checkout alone. No other checkout is enumerated, no other lease is read and no\nother server is probed; `servers` holds the one entry, and it is this one."
}
],
"description": "Which checkouts a reading of the server status covers.\n\nThe two answers cost differently and that is the whole reason the choice exists: the\nrepository's checkouts are read from git's registry of them and each one costs a lease\nread and a probe, while this checkout alone costs one of each and enumerates nothing.\nThe word each variant serialises to is the word the query parameter, the tool input and\nthe command-line flag all take.\n\n```\nuse majordomus_cli::capability::builtin::server::Checkouts;\nassert_eq!(serde_json::to_value(Checkouts::This).unwrap(), \"this\");\nassert_eq!(serde_json::to_value(Checkouts::Repository).unwrap(), \"repository\");\nassert_eq!(Checkouts::default(), Checkouts::Repository, \"the wide answer is what a caller who says nothing has always got\");\n```"
}
}
}Output · PeerList
{
"type": "object",
"properties": {
"count": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "How many peers are attached across every board that was read, the caller included."
},
"caller": {
"anyOf": [
{
"$ref": "#/$defs/PeerId"
},
{
"type": "null"
}
],
"description": "The caller's own peer id, when the call came through an MCP session. A position on\nthis checkout's board, not a durable identity: it is handed out again after a\nreconnect, and `Peer::checkout` is the half of a worker's identity that is not."
},
"peers": {
"type": "array",
"items": {
"$ref": "#/$defs/Peer"
},
"description": "The peers, this checkout's board first and then the siblings in the order git\nregisters them, each in its own board's attachment order. Every one carries the\ncheckout it belongs to, because `p1` is the first session of every board. A peer\nthat announced something and then went away is still here, with `attached: false`."
},
"overlaps": {
"type": "array",
"items": {
"$ref": "#/$defs/Overlap"
},
"description": "Every pair of peers whose claimed scope meets, each pair once — now across\ncheckouts as well as within one. Empty is the ordinary case, and a reader who sees\nan entry here is looking at two workers about to do the same work."
},
"boards": {
"type": "array",
"items": {
"$ref": "#/$defs/BoardView"
},
"description": "One entry per checkout the answer covers, reached or not."
},
"complete": {
"type": "boolean",
"description": "Whether every board the answer covers was read. `false` when a checkout's server\ncould not be asked, and `BoardView::reason` says which and why — so that \"nobody\nelse is here\" is never reported when the truth is \"I could not ask\"."
}
},
"required": [
"count",
"peers",
"boards",
"complete"
],
"description": "The answer of `peers.list`: every worker of this repository, from every checkout's board.",
"title": "PeerList",
"$defs": {
"PeerId": {
"type": "string",
"description": "A peer's identity for the life of the server: `p1`, `p2`, ... in attachment order.\n`p1` is the session that started the server."
},
"Peer": {
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/PeerId",
"description": "`p1`, `p2`, ..."
},
"client": {
"$ref": "#/$defs/ClientInfo",
"description": "The client behind it."
},
"transport": {
"$ref": "#/$defs/Transport",
"description": "How it is attached."
},
"connected_at": {
"type": "string",
"description": "When it attached, RFC 3339, UTC."
},
"last_seen_seconds_ago": {
"type": "integer",
"format": "uint64",
"minimum": 0,
"description": "Seconds since its last message."
},
"attached": {
"type": "boolean",
"description": "Whether the session is still attached. A peer that announced something and then\nwent away is kept and listed with `attached: false`: what it said it was working on\noutlives the connection that said it, because the work does."
},
"claims": {
"type": "array",
"items": {
"$ref": "#/$defs/Announcement"
},
"description": "Every claim this peer holds, in name order, the unnamed one first. Empty for a peer\nthat has announced nothing.\n\nOne connection may be doing several things at once — a session that fans work out to\nsubagents shares its MCP session with all of them — and before this field the board\ncould hold only the last thing said, so each announcement silently erased the one\nbefore it and the other peers stopped seeing the rest of the scope."
},
"announcement": {
"anyOf": [
{
"$ref": "#/$defs/Announcement"
},
{
"type": "null"
}
],
"description": "The most recently made of `Peer::claims`, for a reader that wants one line rather\nthan all of them. Derived from `claims` and never a second account of it: a peer\nholding one claim reports the same thing in both, which is what every peer that does\nnot name its claims reports."
},
"checkout": {
"anyOf": [
{
"$ref": "#/$defs/PeerCheckout"
},
{
"type": "null"
}
],
"description": "Which checkout of the repository this peer is attached to; see `PeerCheckout`.\n\nThe board itself never sets it — a board does not know where it is — and it is\nstamped by the reader that gathered this peer, which is the one thing that knows\nwhich checkout's server it asked."
}
},
"required": [
"id",
"client",
"transport",
"connected_at",
"last_seen_seconds_ago",
"attached"
],
"description": "One peer as the board lists it."
},
"ClientInfo": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "`clientInfo.name`: `claude-code`, `codex`, `gemini-cli`, whatever the client sends."
},
"version": {
"type": "string",
"description": "`clientInfo.version`."
},
"title": {
"type": [
"string",
"null"
],
"description": "`clientInfo.title`, when the client sends one."
}
},
"required": [
"name",
"version"
],
"description": "What a client said about itself in `initialize`."
},
"Transport": {
"oneOf": [
{
"type": "string",
"const": "stdio",
"description": "The owner's own client, on the process's stdin and stdout."
},
{
"type": "string",
"const": "http",
"description": "MCP over HTTP at `/mcp`: a `majordomus mcp` bridge, or a client speaking it directly."
}
],
"description": "How a peer reached the server."
},
"Announcement": {
"type": "object",
"properties": {
"name": {
"type": [
"string",
"null"
],
"description": "What this claim is called, when the peer named it. Absent for a peer's unnamed claim."
},
"intent": {
"type": "string",
"description": "One line: the task or intent, in the peer's words."
},
"scope": {
"type": "array",
"items": {
"type": "string"
},
"description": "Repository-relative paths the peer expects to touch; informational, never enforced here."
},
"at": {
"type": "string",
"description": "When it was announced, RFC 3339, UTC."
}
},
"required": [
"intent",
"scope",
"at"
],
"description": "One claim a peer has made: what it is working on, and where.\n\nA peer may hold several. The `name` is what tells them apart and what makes announcing\nagain an update rather than a second claim: announce under the same name and the claim\nis replaced, announce under a new one and the peer now holds both. A peer that never\nnames anything holds exactly one claim, the unnamed one, which is what a single session\nannouncing about itself has always had."
},
"PeerCheckout": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The checkout's identity digest, the same value `server.status` reports as\n`checkout_id`. One per checkout, never a path, and stable across a restart."
},
"worktree": {
"type": "string",
"description": "Where the checkout is. The one thing on this board that a human can act on\ndirectly, and the one thing that survives a reconnect."
},
"branch": {
"type": [
"string",
"null"
],
"description": "The branch checked out there, when it could be read."
},
"this_checkout": {
"type": "boolean",
"description": "Whether this is the checkout of the server answering the call."
}
},
"required": [
"id",
"worktree",
"this_checkout"
],
"description": "Which checkout of the repository a peer is attached to.\n\nA board is one process's memory and a server serves one checkout, so a peer read from\na sibling checkout's server and a peer of this one are otherwise indistinguishable —\nand worse than indistinguishable, because the ids collide: `p1` is the first session\nof *every* board, so a repository-wide listing without this field would hold several\npeers called `p1` and no way to tell them apart. This is the qualification. The\nworktree path is the durable half of a worker's identity: the peer id is a position on\none board and is handed out again after a reconnect (`p3` this morning, `p1` after the\nbridge re-attached), while the checkout a worker is working in outlives its connection.\n\nAbsent on a peer a server reports about its own board without being asked which\ncheckout that is — `peers.announce` answers about the announcing session and the\nanswer is this server's by construction. The repository-wide listing stamps every\npeer it gathers, its own included, so that no entry of that answer is unqualified.\n\n```\nuse majordomus_cli::peers::PeerCheckout;\nlet c = PeerCheckout {\n id: \"b8293f11\".into(),\n worktree: \"/repo-wt/feature/x\".into(),\n branch: Some(\"feature/x\".into()),\n this_checkout: false,\n};\nlet v = serde_json::to_value(&c).unwrap();\nassert_eq!(v[\"branch\"], \"feature/x\");\nassert_eq!(v[\"this_checkout\"], false);\n```"
},
"Overlap": {
"type": "object",
"properties": {
"peer": {
"$ref": "#/$defs/PeerId",
"description": "The other peer."
},
"attached": {
"type": "boolean",
"description": "Whether that peer is still attached. An overlap with a departed peer is a weaker\nsignal than one with a live session, and the reader is told which it is."
},
"intent": {
"type": "string",
"description": "What it said it was doing."
},
"paths": {
"type": "array",
"items": {
"$ref": "#/$defs/OverlapPath"
},
"description": "The claims that meet: one line per pair, `yours` and `theirs`."
},
"checkout": {
"anyOf": [
{
"$ref": "#/$defs/PeerCheckout"
},
{
"type": "null"
}
],
"description": "Which checkout the other peer is attached to, when the reader knew.\n\nThe overlap that matters most is the one nobody could see before: two workers in\ntwo worktrees of one repository, each reading a board that held only itself, both\nclaiming `apps/majordomus-cli/src`. Naming the checkout is what turns \"p1 is on\nyour ground\" into something a reader can act on when `p1` is not on this board."
}
},
"required": [
"peer",
"attached",
"intent",
"paths"
],
"description": "Two peers that claimed the same ground.\n\nReported when the second of them announces, so that a collision is known at the moment\nit is created rather than discovered afterwards in the history of a branch."
},
"OverlapPath": {
"type": "object",
"properties": {
"yours": {
"type": "string",
"description": "The path the announcing peer claimed."
},
"theirs": {
"type": "string",
"description": "The path the other peer claimed."
}
},
"required": [
"yours",
"theirs"
],
"description": "One pair of claims that contain one another."
},
"BoardView": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The checkout's identity digest, the same value `server.status` reports as\n`checkout_id`. One per checkout, never a path, and stable across a restart."
},
"worktree": {
"type": "string",
"description": "Where the checkout is. The one thing on this board that a human can act on\ndirectly, and the one thing that survives a reconnect."
},
"branch": {
"type": [
"string",
"null"
],
"description": "The branch checked out there, when it could be read."
},
"this_checkout": {
"type": "boolean",
"description": "Whether this is the checkout of the server answering the call."
},
"standing": {
"$ref": "#/$defs/ServerStanding",
"description": "Where its server stands, by the same reading `server.status` reports."
},
"url": {
"type": [
"string",
"null"
],
"description": "The address its lease names, when it has one."
},
"attached": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "How many of this board's peers are attached."
},
"reason": {
"type": [
"string",
"null"
],
"description": "Why this board is not in the answer. `None` when it is."
}
},
"required": [
"id",
"worktree",
"this_checkout",
"standing",
"attached"
],
"description": "One checkout's board, as the gather found it.\n\nPresent for every checkout the answer covers, whether or not its board could be read,\nbecause a listing that silently drops the checkouts it could not reach is the shape of\nanswer that made this capability wrong in the first place: a reader would see a short\nboard and conclude nobody else is working here."
},
"ServerStanding": {
"oneOf": [
{
"type": "string",
"const": "absent",
"description": "No lease: nothing serves this checkout."
},
{
"type": "string",
"const": "starting",
"description": "A lease without an address, young enough that its owner is still binding."
},
{
"type": "string",
"const": "ready",
"description": "The server the lease names answers for this checkout, from the code on disk, at\nthis executable's version."
},
{
"type": "string",
"const": "outdated",
"description": "The server answers, but from older code than this executable, or from a file that\nhas been replaced since it started: everything it says is yesterday's."
},
{
"type": "string",
"const": "stale",
"description": "The lease names a server that does not answer, or is not a lease at all."
}
],
"description": "Where a checkout's server stands, decided from its lease, whether the server the lease\nnames answers for that checkout, and whether what answers is this executable's code.\n\n```\nuse majordomus_cli::capability::builtin::server::ServerStanding;\nlet all = [ServerStanding::Absent, ServerStanding::Starting, ServerStanding::Ready,\n ServerStanding::Outdated, ServerStanding::Stale];\nlet words: Vec<&str> = all.iter().map(|s| s.as_str()).collect();\nassert_eq!(words, [\"absent\", \"starting\", \"ready\", \"outdated\", \"stale\"]);\nassert_eq!(serde_json::from_str::<ServerStanding>(\"\\\"stale\\\"\").unwrap(), ServerStanding::Stale);\n```"
}
}
}Examples
These are the capability's own benchmark cases: the same inputs the benchmark runs and the OpenAPI document shows.
default
{
"checkouts": "this"
}