vesper
README.md
# vesper
A small Rust workspace that lets multiple coding agents work on the same
codebase without a human relaying every message between them. Built and
tested across the `vesper-core` and `vesper-registry` crates.
## Why it exists
When several agents share a workspace, three things go wrong repeatedly:
- two agents edit the same file at the same time
- an agent "remembers" a useful script/prompt/tool and the next agent
has to rediscover it
- a tool is shared before anyone has actually checked it works, so a
broken tool spreads silently
`vesper` addresses each with a dedicated MCP server:
| Problem | Server | Mechanism |
| --- | --- | --- |
| Clobbered files | `vesper-core-server` | file/task **claims** — exclusive, keyed by resource, not agent+resource |
| Hand-off / coordination | `vesper-core-server` | per-agent **inbox** (direct message + broadcast) |
| Tool re-discovery | `vesper-registry` | **versioned tool registry** (append-only, never overwrites) |
| Unverified tools spreading | `vesper-registry` | **multi-agent verification** — needs N distinct verifiers; a single failure flags and hides |
## Workspace layout
```
.
├── Cargo.toml # workspace root = vesper-core
├── src/
│ ├── lib.rs # AgentId, Message, Claim, CoordinationState
│ ├── model_router.rs # ModelClient trait + HttpModelClient (Phase 5)
│ ├── python.rs # PyO3 bindings (feature-gated, Phase 7)
│ ├── main.rs # `vesper-core-demo` binary
│ └── bin/
│ └── vesper-core-server.rs # coordination server (rmcp Streamable HTTP)
├── tests/
│ └── end_to_end.rs # integration: claim → handoff → register → verify
└── vesper-registry/
├── Cargo.toml
├── src/
│ ├── lib.rs # Registry, ToolId, ToolVersion, VerificationState
│ └── main.rs # registry server (rmcp Streamable HTTP)
└── tests/
└── live_roundtrip.rs # real MCP-client round-trip
```
## Crates
### `vesper-core`
The shared library. Defines:
- `AgentId`, `AgentStatus`, `Message`, `Claim`, `ClaimTarget`
- `CoordinationState` — DashMap-backed shared store for claims, inboxes,
and statuses. Cloning is cheap; the inner maps are wrapped in `Arc`,
so the same state can be shared across the coordination server,
integration tests, and (optionally) the Python bindings.
- `AgentState` — single-process per-agent loop (Phase 1).
- `model_router` — `ModelClient` trait plus an `HttpModelClient` that
talks to any OpenAI-compatible `/chat/completions` endpoint. API keys
resolve via a `secrets://ENV_VAR` reference, never embedded in config.
- `python` module — PyO3 bindings, compiled only when the
`python-bindings` feature is on. A plain `cargo build` / `cargo test`
never needs a Python toolchain or links against `libpython`.
### `vesper-registry`
A versioned, multi-agent-verified tool registry.
- `ToolId`, `ToolVersion` (monotonic, never overwrites)
- `VerificationState` — `Unverified` → `Verified` (after N distinct
verifiers) or `Flagged` (a flag hides it, but the `(flagger, reason,
when)` record is contestable: `unflag` or enough distinct re-verifiers
restores it)
- `Registry` — `register`, `verify`, `flag`, `unflag`, `fork`, `unregister`,
`list_tools`, `list_all_tools`, `get_tool`, `find_similar`
Exposed as an MCP server on `http://127.0.0.1:9899/mcp`.
## Servers (MCP Streamable HTTP)
Both servers use the official `rmcp` Streamable HTTP transport
(spec `2024-11-05`), not a hand-rolled JSON-RPC. Stateless requests
share one `Arc<CoordinationState>` / `Arc<Registry>` captured by the
service factory.
| Server | Port | Tools |
| --- | --- | --- |
| `vesper-core-server` | 9898 | `claim_file`, `release_file`, `claim_task`, `release_task`, `renew_file_claim`, `renew_task_claim`, `send_message`, `broadcast`, `get_inbox`, `drain_inbox`, `get_status`, `list_claims`, `expire_stale_claims`, `release_agent_claims` |
| `vesper-registry` | 9899 | `register_tool`, `list_tools`, `list_all_tools`, `get_tool`, `verify_tool`, `flag_tool`, `unflag_tool`, `fork_tool`, `unregister_tool` |
## Build, test, run
Requires a recent stable Rust toolchain.
```bash
# Build & test the whole workspace
cargo build --workspace
cargo test --workspace
# Run the servers (separate terminals)
cargo run --bin vesper-core-server
cargo run --bin vesper-registry-server
```
On Windows the dev workflow hits an `Access denied` if both server
binaries are still running while a rebuild tries to remove the `.exe`.
Stop the running server (or `Stop-Process` it) before `cargo build`.
## Python bindings (optional)
`vesper-core` is also a `cdylib` with PyO3 bindings, packaged via
Maturin. Built and tested against a real Python venv — claim/release,
send_message, broadcast, inbox, drain_inbox, and status all work from
Python the same way the Rust tests say they should.
```bash
# Requires the python-bindings feature + a Python toolchain on PATH
maturin build --release
pip install <generated wheel>
```
A plain `cargo build` / `cargo test` does **not** enable the feature
and does not need a Python toolchain.
## Phases (status)
| Phase | Content | Status |
| --- | --- | --- |
| 1 | Single-agent loop, `AgentState` | done |
| 2 | `CoordinationState` + `vesper-core-server` JSON-RPC | done |
| 3 | `vesper-registry` (versioning + multi-agent verification) | done |
| 4 | (planned) | — |
| 5 | `model_router` (trait + `HttpModelClient`) | done |
| 6 | Convert both servers to rmcp Streamable HTTP | done |
| 7 | PyO3 bindings + Maturin wheel | done |
| 8 | Closed SDK (deliberately last) | pending |
The remaining gap before any of this is useful day-to-day is the
**live wiring**: actually pointing real agents at the running servers
as MCP clients and running a full claim → handoff → register → verify
cycle. That's what the `live_roundtrip` integration test exercises.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing