agent-rehearsal
by ganeshbehera
README.md
# Agent Rehearsal
**Rehearse before reality.** A local flight simulator for tool-using AI agents.
Give an agent a scheduling task, introduce a failure, and inspect what actually happened to the calendar. Agent Rehearsal keeps the tool trace, resulting state, and outcome checks together in a local dashboard.
The first question it helps answer: **if a write succeeds but its response is lost, does your agent recover—or perform the action twice?**

```text
Scripted demo policy Your MCP-compatible agent
│ │
└──────────────┬──────────────┘
▼
Simulated calendar tools
│
Failure injection
│
▼
Isolated run + SQLite trace
│
▼
Calendar · Tool timeline · Outcome checks
```
## Try it locally
Requires **Node.js 24 or newer** and npm. The simulator needs no API key or cloud account.
```bash
git clone https://github.com/ganeshbehera/agent-rehearsal.git
cd agent-rehearsal
npm ci
npm run dev
```
Open [localhost:5173](http://localhost:5173). The development API runs on port `4173`.
1. Select **The missing confirmation** (`timeout-after-write`).
2. Compare the **blind retry** and **verify before retry** demo policies.
3. Inspect the tool calls and calendar changes. The first create commits an event but returns an error. Retrying without reconciliation creates a duplicate; reading the calendar first reveals the successful write.
The built-in policies are **scripted demonstrations, not LLM agents**. They make the failure case reproducible without model credentials. Connect your own agent over MCP to evaluate its behavior.
For a production build served by one local process:
```bash
npm run build
npm start
```
Open [localhost:4173](http://localhost:4173).
## What is included
- Four calendar scenarios with an isolated state for every run.
- A visual calendar and expandable tool-call timeline, including evidence of committed writes.
- Outcome checks against resulting calendar state, rather than an agent's success claim.
- Side-by-side comparison of the two demo policies.
- Persistent run history and JSON report export.
- A stdio MCP server for compatible external agents.
| Scenario ID | Behavior |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clean` | Calendar tools work normally. |
| `timeout-after-write` | The first successful create commits the event, then returns a timeout. The fixture permits exact repeats of that write to demonstrate duplication; unrelated overlaps are rejected. |
| `permission-denied` | Calendar reads work; writes return a permission error. |
| `slot-conflict` | An existing event occupies the initially requested slot. |
All scenarios use a fixed **22 October 2026, UTC** fixture. This is simulated time, independent of the machine's current date. The scheduling task concerns a 30-minute Design review with `sarah@example.test` during the configured afternoon window.
## Connect an agent
Build the project first. Open **Connect agent** in the dashboard to copy a configuration containing your actual local paths. A typical host configuration looks like this:
```json
{
"mcpServers": {
"agent-rehearsal": {
"command": "node",
"args": ["/absolute/path/agent-rehearsal/dist/server/mcp.js"],
"env": {
"REHEARSAL_DB": "/absolute/path/agent-rehearsal/data/rehearsal.sqlite"
}
}
}
}
```
Adapt the surrounding configuration format to your MCP host. It must support **stdio MCP** and have Node.js 24 available. The simulator does not manage model credentials; your agent host supplies its own model connection.
You can also start the MCP process directly with `npm run mcp` after building, or `npm run mcp:dev` during development. MCP uses stdin/stdout for protocol messages. Diagnostic output belongs on stderr.
To try the complete SDK connection without an agent host:
```bash
npm run build
node examples/mcp-client.mjs
```
This executable, scripted MCP client starts the timeout scenario, attempts a write, reads the calendar after the error, and prints the final checks. It does not call an LLM. Its run is saved to the same database and appears in the dashboard.
### Agent workflow
1. Call `rehearsal_list_scenarios` to inspect available scenarios.
2. Call `rehearsal_start_run` with a `scenarioId`. It returns the `runId`, task, fixture date, and timezone.
3. Use the calendar tools with that `runId` to attempt the task.
4. Call `rehearsal_finish_run` to evaluate and close the run.
5. Inspect the report in the dashboard or the finish tool's response.
| Tool | Inputs |
| -------------------------- | ------------------------------------------------------------------------ |
| `rehearsal_list_scenarios` | None |
| `rehearsal_start_run` | `scenarioId` |
| `calendar_list_events` | `runId`, optional `start` and `end` |
| `calendar_create_event` | `runId`, `title`, `start`, `end`, `attendees`, optional `idempotencyKey` |
| `rehearsal_finish_run` | `runId` |
Event timestamps use UTC ISO strings, such as `2026-10-22T14:00:00Z`. Finishing a run is terminal: subsequent calendar mutations are rejected. Start a new run to retry a task.
The agent sees tool responses, not the developer dashboard's hidden write evidence. There is no live MCP run-inspection tool that would reveal whether a timed-out write committed; the agent must reconcile through the simulated calendar tools.
Optional idempotency keys let agents exercise another recovery strategy. Repeating the same key and event reuses the original write; reusing a key with a different event is rejected.
Example prompt for your agent:
> Use Agent Rehearsal to start a `timeout-after-write` run. Read the returned task and complete it using the calendar tools. Handle tool errors as you would in a real integration. Finish the run when done and report the checks.
## Data and local operation
Runs live in `data/rehearsal.sqlite` under the project directory by default. The path is resolved from the application location, so launching the MCP server from another working directory does not create a separate database. Set `REHEARSAL_DB` to an absolute path to override it.
Use the **same database path** for the dashboard and MCP process to see external agent runs. SQLite data, local environment files, build output, and dependencies are excluded from Git.
If the dashboard server stops during a demo, restarting it marks the unfinished demo as interrupted and preserves its trace. External MCP sessions stay open until their agent calls `rehearsal_finish_run`.
This release is a **single-user local tool with no application authentication**. The server binds to loopback by default. Do not expose it to an untrusted network without adding access controls.
### Docker
```bash
docker compose up --build
```
The dashboard is available at [localhost:4173](http://localhost:4173), and a named volume preserves run data. Compose publishes only to the host's loopback interface.
To connect an agent to that same container and database, leave Compose running and use:
```json
{
"mcpServers": {
"agent-rehearsal": {
"command": "docker",
"args": [
"compose",
"-f",
"/absolute/path/agent-rehearsal/compose.yaml",
"exec",
"-T",
"rehearsal",
"node",
"/app/dist/server/mcp.js"
]
}
}
}
```
Paths shown in a container's **Connect agent** page refer to the container, not your host. Use the Docker configuration above instead of launching a separate local Node process with those paths.
## Development
```bash
npm run typecheck
npm test
npm run build
```
The automated suite covers simulation behavior and its API/MCP integration. CI runs the tests and production build on Node.js 24. Browser interaction and layout can be checked against the local dashboard.
```text
server/ Simulation, SQLite persistence, HTTP API, MCP tools
shared/ Shared TypeScript types
src/ React dashboard
tests/ Automated behavioral and integration tests
```
## Scope
This is an early calendar simulator, not a proxy to a real calendar service. It sends no email, books no real meetings, and needs no production credentials. It currently tests the included state-based calendar constraints; passing them is not a general guarantee of agent reliability.
The scripted policies and fixtures are reproducible. An external model may behave differently between runs; this project does not promise deterministic replay of LLM reasoning. A timeout is represented by a tool error after the write, rather than by intentionally hanging a network connection.
Contributions are welcome: new failure scenarios, clearer outcome checks, and additional simulated tools. See [CONTRIBUTING.md](CONTRIBUTING.md). Scenario definitions currently live in TypeScript.
## License
[MIT](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues