v0.2.0
madari v0.2.0 — Rings
Rings are named capability sets of MCP servers: bundle the servers a task needs, attach the bundle to a client, and detach it cleanly when you're done. Ownership is reference-counted, so overlapping rings, standalone entries, and any attach/detach order all resolve to exactly the config you'd expect — and nothing madari doesn't own is ever touched.
The ring lifecycle
madari ring create research --member stewreads --member arxiv
madari ring attach research claude-code # or --scope user
madari ring status # who owns what, everywhere
claude --mcp-config <(madari ring render research --client claude-code)
madari ring detach research claude-code
madari ring delete researchring create/list/show— rings live asrings/<name>.toml; members reference registry servers by name, so the server manifest stays the single source of truth for command, args, and env.ring attach/detach— attach records aring:<name>ownership source for every member and materializes the eligible ones; detach releases it, and an entry leaves the client config only when nothing owns it anymore. Attaching onto an entry madari doesn't manage is refused, even when values match. Disabled or secret-refused members stay owned but absent until they become eligible.ring render— a self-contained MCP config on stdout for ephemeral sessions, mutating nothing; secret env values are never emitted.ring status— attached rings and per-server ownership for every client and scope, including pending/stale reconciliation work (--jsonsupported).ring delete— refuses while any client scope still records the ring's ownership, with scoped detach guidance; deletion never edits client configs or managed state.
Ownership, formally
An entry is present in a client config iff it is owned (any source) and eligible (enabled, targets the client, command-valid, not secret-refused for the scope). Ownership persists through ineligibility — disable a member and it leaves the config but stays owned; re-enable it and it comes back. Plain madari sync never promotes ring-owned entries to standalone and never adopts hand-managed entries. Ring membership edits — including snapshot imports — reconcile automatically on the next sync, attach, or detach.
Snapshots learn rings (v2)
export now writes servers and rings (and refuses to write a snapshot that wouldn't round-trip); import validates everything before writing anything, adds/updates only, and never attaches or syncs imported rings. v1 server-only snapshots still import cleanly.
Diagnostics
doctor flags attached rings whose file went missing (with the detach command that releases them) and rings referencing deleted servers; drift detection understands ring ownership and owned-but-ineligible entries.
Migration
Automatic — no action needed. Existing manifests, managed state, and JSON consumers are unaffected (schema_version stays 1; ring payloads and doctor's ring_issues are additive). Rings are entirely opt-in.
Assets
Prebuilt binaries for linux/darwin/windows on amd64/arm64. Verify with:
shasum -a 256 -c SHA256SUMS --ignore-missing