The famous Rostra in the Roman Forum, decorated with the bronze beaks of captured enemy ships, where public speakers would stand
Rostra is an MCP server for durable, evidence-backed deliberation and decision making harnessing the power of multiple LLM models/harnesses.
Rostra includes six protocol presets. Each preset defines a sequence of model stages and a structured result contract.
Stage names guide the models, but Rostra does not inject full facilitator scripts or fixed attacker and defender personas.
| Protocol | Stages | Use it for | Model rounds |
|---|---|---|---|
quick |
Independent analysis → ballot | Low-cost decisions that need independent views and a final vote | 2 |
conference |
Independent analysis → critique → revision → ballot | General decisions that benefit from peer critique and revision | 4 |
red_team |
Proposal → adversarial attack → defense → ballot | Stress-testing proposals against counterarguments and failure modes | 4 |
delphi |
Independent analysis → anonymous aggregate → revision → ballot | Reducing identity and authority effects before revision | 3, plus local aggregation |
premortem |
Premortem → revision → ballot | Surfacing execution risks before a final decision | 3 |
evidence_tribunal |
Proposal → evidence → cross-examination → adjudication → ballot | Repository decisions that require inspectable evidence | 5, plus evidence continuations |
One model round runs all committee participants concurrently. Later preset stages receive prior responses without participant identities.
The delphi aggregate is deterministic and local. It counts exact recommendation strings without a model or semantic clustering.
The evidence_tribunal protocol permits bounded file, search, tree, Git status, and Git diff operations. Rostra validates cited evidence IDs.
The premortem preset supplies a stage label and an analysis contract. It does not run a separate failure simulation.
Choose one committee mode for any protocol:
explicit: Supply all participants.adaptive: Supply committee size and routing limits. Rostra selects configured models from calibrated metrics.
Every model response has a stage-specific schema. Rostra permits one structural repair attempt when a response does not match that schema.
The final ballot requires a two-thirds quorum. Rostra reports ballot consensus separately from semantic convergence and preserves minority rationales.
Custom protocols can change stage order, visibility, minimum completions, evidence permissions, and stopping policies. They can also add experiment-proposal stages.
- Node.js 24 or newer
- One configured model adapter
CLI adapters also require their matching executable. HTTP adapters require access to their configured endpoint.
Git and pnpm 10.11.0 are only required for a source install.
Install the exact beta version, then create the user configuration and data directory:
npm install --global @engineereddev/rostra@0.1.0-beta.2
rostra initgit clone https://github.com/EngineeredDev/rostra.git
cd rostra
pnpm install --frozen-lockfile
pnpm build
node dist/cli/main.js initThe init command creates the user configuration and data directory. It also downloads and verifies the pinned MiniLM model when required.
Edit ~/.config/rostra/config.yaml. Enable only the adapters and models that you use.
The same command is safe to run after an upgrade. It never replaces an existing configuration.
Rostra reads configuration from the first available path:
ROSTRA_CONFIG$XDG_CONFIG_HOME/rostra/config.yaml~/.config/rostra/config.yaml- The packaged
config.example.yaml
Rostra writes rostra.sqlite, transcripts, and model files to the data directory. It selects this directory in the following order:
ROSTRA_DATA_HOME$XDG_DATA_HOME/rostra~/.local/share/rostra
Use config.example.yaml as a starter configuration.
Supported CLI adapters are claude, codex, droid, gemini, llamacpp, and omp. Supported HTTP adapters are ollama, lmstudio, openrouter, nebius, and openai.
The model registry controls the model IDs, reasoning efforts, capabilities, provider families, costs, and latency estimates available for routing.
The default local_minilm similarity provider uses a pinned MiniLM model. The openai_compatible provider supports a remote embedding endpoint instead.
Pin the package version so a client restart cannot install a different release:
{
"mcpServers": {
"rostra": {
"command": "npx",
"args": ["--yes", "@engineereddev/rostra@0.1.0-beta.2"]
}
}
}The server uses stdio transport by default. It writes protocol messages only to standard output.
rostra serve --http serves the same tool surface over Streamable HTTP at /mcp:
node dist/cli/main.js serve --http --port 8787Point a client at http://127.0.0.1:8787/mcp. One HTTP process serves every client, so the
embedding model is loaded once instead of once per stdio client.
The endpoint has no authentication. It binds 127.0.0.1 and rejects any request whose Host
or Origin header is not loopback. Do not expose it to a network you do not control. Configure
the bind address, port, subscription cap, and keep-alive interval under http: in config.yaml;
--host and --port override them.
--host 0.0.0.0 prints a warning and is only meant for containers, where the loopback bind is
unreachable through -p. Publish it on the host's loopback address:
docker run -p 127.0.0.1:8787:8787 rostra serve --http --host 0.0.0.0rostra serve --stdio is the explicit form of the default; bare rostra still means
stdio.
Both transports keep the build identity captured at startup. Rebuilding or editing the
configuration underneath a running server makes the next dispatch fail with
stale_server_build; restart the server.
Submit a durable job with start_deliberation. Only valid ballots from the final completed ballot stage affect consensus.
Use these tools to manage jobs:
start_deliberationlist_deliberationsget_deliberationtail_deliberationcancel_deliberationresume_deliberation
A recovered job can enter recovery_required after an uncertain external attempt. Call resume_deliberation with retry or cancel to resolve it.
Every job is also readable as a resource. Clients do not have to poll a tool:
rostra://deliberations/{job_id}returns whatget_deliberationreturns.rostra://deliberations/{job_id}/eventsreturns the first 500 events and anext_seqcursor.
Use tail_deliberation when you need a custom cursor, limit, or blocking wait.
Both are URI templates, so they appear under resources/templates/list rather than
resources/list. The server advertises resources.subscribe, and a client on the 2026-07-28
protocol can subscribe to a job's URIs and receive notifications/resources/updated as the job
moves. Job transitions happen in detached worker processes, so the server discovers them by
polling the database every jobs.poll_interval_ms; a subscriber sees a change one interval late.
Blocking calls also report progress. When get_deliberation(wait_for_terminal) or
tail_deliberation(wait_for_change) is called with a progress token, each newly recorded job
event is sent as notifications/progress, keyed by the event sequence number.
Each completed job publishes an immutable decision packet. The packet includes claims, evidence provenance, predictions, ballots, minority reports, and experiment proposals.
Experiment proposals are inert records. Rostra does not run their commands.
Decision data is scoped to the canonical Git workspace. Use these MCP tools:
query_decisionslist_stale_decisionsrecord_decision_outcomereview_decision_change
record_decision_outcome appends an observed outcome. It never changes an earlier outcome. Resolved prediction labels update model calibration metrics.
Review a Git range from the command line:
node dist/cli/main.js decision review \
--working-directory /path/to/repository \
--base origin/main \
--head HEAD \
--format json \
--fail-on warning--format accepts text, json, or sarif. --fail-on accepts error, warning, or none.
The command returns these exit codes:
0: no finding meets the threshold.1: invalid input or runtime failure.2: at least one finding meets the threshold.
Decision CI reports stale evidence, changed assumptions, conflicting decisions, superseded precedents, and outcome regressions. It does not modify the repository.
The CLI also initializes user files and manages jobs and model files:
node dist/cli/main.js init
node dist/cli/main.js jobs list
node dist/cli/main.js jobs cancel <job-id>
node dist/cli/main.js models fetchjobs list returns the 100 most recent jobs as JSON. jobs cancel requests idempotent cancellation for one job.
list_modelslists enabled configured models.set_session_modelschanges adapter defaults for the whole server process. Over HTTP one process serves every client, so these overrides are shared rather than per-client.get_quality_metricsreturns attempts, ballots, failures, latency, cost, and prediction calibration.
Adaptive routing uses Laplace-smoothed success rates and Brier calibration. It also enforces provider-family, cost, and latency constraints.
Built-in evidence tools confine file and Git access to the canonical workspace. They reject traversal, symlink escapes, and unsupported Git arguments.
CLI model adapters run as unrestricted host processes. Their decision packets use host_unrestricted as the execution isolation value. Set execution.allow_host_tools: true to permit them.
Build the image:
docker build -t rostra .Run the MCP server with a mounted configuration and data directory:
docker run --rm -i \
-e ROSTRA_CONFIG=/config/config.yaml \
-v "$PWD/config.yaml:/config/config.yaml:ro" \
-v rostra-data:/home/node/.local/share/rostra \
rostraRun the HTTP transport instead, published on the host's loopback address:
docker run --rm -p 127.0.0.1:8787:8787 \
-e ROSTRA_CONFIG=/config/config.yaml \
-v "$PWD/config.yaml:/config/config.yaml:ro" \
-v rostra-data:/home/node/.local/share/rostra \
rostra serve --http --host 0.0.0.0The container must bind 0.0.0.0 to be reachable through -p, which is why the published port
is pinned to 127.0.0.1. The endpoint is unauthenticated.
The image includes Git. It does not include third-party model CLIs.
pnpm build
pnpm typecheck
pnpm lint
pnpm format:check
pnpm test
pnpm generate:schemasGenerated MCP input and output schemas are in docs/generated/tool-schemas.json.
MIT
