Skip to content

HTTP API: server

The shared server of this checkout and of every other checkout of the same git repository: what each lease says, whether the server it names answers, whether what answers is the code on disk at this executable's version, and how many peers each one holds.

Rendered from docs/generated/openapi.json, which the executable generates from its capability registry and CI refuses stale. The raw document is at /openapi.json; a running server serves the same document at its own /openapi.json and Swagger UI at /swagger.

server

The shared server of this checkout and of every other checkout of the same git repository: what each lease says, whether the server it names answers, whether what answers is the code on disk at this executable's version, and how many peers each one holds.

GET /api/v1/server server.status

The shared server, and every server of the repository

Where this checkout's server stands — absent, starting, ready, outdated or stale — measured against what this executable would serve; the lease this process holds when it is the server; and, unless `checkouts` narrows it to this one, every checkout git registers for the repository, the primary first, each with its lease, its standing and the reason, and the peers its server reports. `checkouts: this` reads one lease and probes one server and enumerates no other checkout, which is what a caller asking only about the checkout it is in should pay. Read from the lease files and the servers on every call; nothing is cached, because the leases are written by other processes.

  • query
  • behaviorally_verified
  • benchmark required
  • cache disabled
  • MCP tool majordomus_server
  • MCP resource {"name": "server", "uri": "majordomus://server"}
  • $ serve status

Query parameters

nametyperequireddescriptionexamples
checkouts Checkouts no Which checkouts the answer covers. Absent means `repository`. repository: "repository"this-checkout: "this"

Try it

The port is whatever the server logged; 8741 is the one it asks for first. The values are the operation's first example.

curl -s "http://127.0.0.1:8741/api/v1/server?checkouts=repository"

Tested by apps/majordomus-cli/tests/http_serve.rs, which replays the route with these values against a server on a real socket.

Responses

statusbodymeaning
200 ServerStatus The shared server, and every server of the repository: the result.
400 ErrorBody invalid_input: The input does not fit the schema: a parameter of the wrong type, an unknown one, or a value the capability rejects.
404 ErrorBody not_found: The input names something the repository does not hold.
500 ErrorBody internal: The capability failed for a reason of its own; the message names it.
default ErrorBody Any other failure the transport reports: 405 method_not_allowed for another method on this path, 400 invalid_input for a body that is not a JSON object.

Schemas

The components only this tag's operations use. Each row is the type's own field, its doc comment the description; a type another page owns links there.

ConnectionCounts

object
What this process's HTTP server has done to clients that held a connection without using it: the deadline it applies and what that deadline cost, since the process started. Absent while this process serves no HTTP.

use majordomus_cli::http::deadline::{counts, ConnectionCounts};
// a process that has started no server reports nothing, rather than zeroes that would
// read as "no slow client was seen"
assert_eq!(counts(), None);
let c = ConnectionCounts { read_deadline_seconds: 30, closed_by_deadline: 4, refused_busy: 0 };
let text = serde_json::to_string(&c).unwrap();
assert_eq!(serde_json::from_str::<ConnectionCounts>(&text).unwrap(), c);
propertytyperequireddescription
read_deadline_seconds integer (uint64) yes server.read_deadline_seconds: as this process applies it.
closed_by_deadline integer (uint64) yes Connections closed because no request was read in full on them within the deadline.
refused_busy integer (uint64) yes Requests answered 503 because every request handler was busy.

Used by ServerStatus

Desired

object
What this executable would want a server of this checkout to be: the address it would bind, the version and the executable it would serve from. What standing is measured against.

use majordomus_cli::capability::builtin::server::Desired;
let d = Desired { host: "127.0.0.1".into(), port: 8741, version: "1.0.0".into(), executable: None };
let v = serde_json::to_value(&d).unwrap();
assert_eq!(v["port"], 8741);
assert!(v.get("executable").is_none(), "an executable that cannot be located is not written as null");
propertytyperequireddescription
host string yes The interface a server started here would bind: what MAJORDOMUS_HTTP_HOST names in this process's environment, and loopback when it names nothing.
port integer (uint16) yes The port it asks for first.
version string yes This executable's version.
executable ExecutableIdentity | null → ExecutableIdentity no This executable, when it can be located.

Used by ServerStatus

ExecutableIdentity

object
The identity of the file an executable was started from: where it is, and the mtime and size of the file at that path. A server outlives its own binary — a rebuild replaces the file under a process that keeps serving the code it loaded hours ago — and nothing about the process itself says so. This is what makes that visible.

use majordomus_cli::lease::ExecutableIdentity;
let recorded = ExecutableIdentity { path: "/opt/majordomus".into(), mtime: 1_700_000_000, size: 42 };
let text = serde_json::to_string(&recorded).unwrap();
assert_eq!(serde_json::from_str::<ExecutableIdentity>(&text).unwrap(), recorded);
propertytyperequireddescription
path string yes The path the process was started from.
mtime integer (uint64) yes The file's modification time, seconds since the epoch.
size integer (uint64) yes The file's size in bytes.

Used by Desired LeaseView

GitIdentity

object
The git repository a checkout belongs to, as distinct from the checkout itself.

identity names a checkout: one server, one lease, one index per checkout root. Every linked worktree of one git repository is a checkout of its own by that measure, and nothing in it said that they belong together. This does: the git directory every work tree shares (git rev-parse --git-common-dir) is the repository's identity, its digest is one value for every checkout of that repository, and linked says whether this checkout is the primary one or a work tree hanging off it. None where git cannot be asked: a repository of the layer does not have to be version controlled.

use majordomus_cli::repository::{git_identity, identity, GitIdentity};
use std::process::Command;
let dir = tempfile::tempdir().unwrap();
let root = dir.path().join("repo");
std::fs::create_dir_all(&root).unwrap();
let git = |args: &[&str]| assert!(Command::new("git").arg("-C").arg(&root).args(args).status().unwrap().success());
git(&["init", "-q", "."]);
git(&["-c", "user.email=t@example.com", "-c", "user.name=t", "commit", "-q", "--allow-empty", "-m", "init"]);
let wt = dir.path().join("repo-wt");
git(&["worktree", "add", "-q", "-b", "feature/x", wt.to_str().unwrap()]);

let primary: GitIdentity = git_identity(&root).expect("a work tree");
let linked: GitIdentity = git_identity(&wt).expect("a linked work tree");
assert_eq!(primary.id, linked.id, "one repository");
assert_ne!(identity(&root), identity(&wt), "two checkouts");
assert!(!primary.linked && linked.linked);
assert!(!primary.id.contains('/'), "a digest, never a path");
propertytyperequireddescription
common_dir string yes The git directory every work tree of the repository shares, canonical.
id string yes Its digest: the same for every checkout of one repository, different across repositories, and never a path.
linked boolean yes Whether this checkout is a linked work tree rather than the primary one.

Used by ServerStatus

LeaseView

object
A lease as a reader sees it: what the server wrote about itself, without the token that makes the file the server's own.

use majordomus_cli::capability::builtin::server::LeaseView;
let view = LeaseView { pid: 7, url: Some("http://127.0.0.1:8741".into()),
    started_at: "2026-09-10T00:00:00Z".into(), executable: None, version: Some("1.0.0".into()) };
let v = serde_json::to_value(&view).unwrap();
assert_eq!(v["pid"], 7);
assert!(v.get("token").is_none() && v.get("root").is_none());
propertytyperequireddescription
pid integer (uint32) yes The server's process id. Not proof of a live server — only a probe that is answered is — but decisions are made from it: a live pid earns a server that does not answer the election's busy wait before its lease is taken over, and serve ensure's patience before it starts another; serve stop sends its SIGTERM to this pid.
url string | null no The address, once bound.
started_at string yes When the server took the lease, RFC 3339.
executable ExecutableIdentity | null → ExecutableIdentity no The executable the server was started from, when it could be located.
version string | null no The executable's version; absent for a server too old to have written one.

Used by ServerStatus ServerView

ServerStatus

object
The shared server of this checkout and of every other checkout of the repository.

use majordomus_cli::capability::builtin::server::{Desired, ServerStanding, ServerStatus};
let status = ServerStatus { checkout_id: "c".into(), git: None,
    desired: Desired { host: "127.0.0.1".into(), port: 8741, version: "1.0.0".into(), executable: None },
    this_process: None, standing: ServerStanding::Absent, servers: Vec::new(),
    connections: None };
let text = serde_json::to_string(&status).unwrap();
assert_eq!(serde_json::from_str::<ServerStatus>(&text).unwrap(), status);
propertytyperequireddescription
checkout_id string yes This checkout's identity: what this process answers as repository_id.
git GitIdentity | null → GitIdentity no The git repository this checkout belongs to; absent where git cannot be asked.
desired Desired → Desired yes What this executable would serve, and what standing is measured against.
this_process LeaseView | null → LeaseView no The lease this process holds, when it is the server; absent when the question was answered by a process that serves nothing.
standing ServerStanding → ServerStanding yes Where this checkout's server stands.
servers array of ServerView → ServerView yes Every checkout of the repository, the primary first, each with its server. One entry — this checkout — where git cannot be asked.
connections ConnectionCounts | null → ConnectionCounts no What this process's HTTP server did to connections that held it without a request: the read deadline it applies, the connections that deadline closed, and the requests refused because every handler was busy. Absent when this process serves no HTTP.

Used by server.status

ServerView

object
One checkout of the repository, and the server its lease names.

use majordomus_cli::capability::builtin::server::{ServerStanding, ServerView};
let view = ServerView { worktree: "/r".into(), branch: Some("master".into()), checkout_id: "c".into(),
    primary: true, this_checkout: true, standing: ServerStanding::Absent, reason: None, lease: None, peers: None };
let v = serde_json::to_value(&view).unwrap();
assert_eq!(v["standing"], "absent");
assert!(v.get("lease").is_none() && v.get("peers").is_none(), "what there is not is not written");
propertytyperequireddescription
worktree string yes The checkout, absolute and canonical.
branch string | null no The branch checked out there, when git names one.
checkout_id string yes The checkout's identity: what its server answers as repository_id.
primary boolean yes Whether this is the primary checkout rather than a linked worktree.
this_checkout boolean yes Whether this is the checkout the answering process serves.
standing ServerStanding → ServerStanding yes Where its server stands.
reason string | null no Why, when the standing is not ready: what the lease held, or what answered.
lease LeaseView | null → LeaseView no The lease, when the file holds one.
peers integer | null no How many peers the server reports attached, when it answers.

Used by ServerStatus

Searches the titles and descriptions of every page this site publishes.