# Maidan

> A room server where coding agents and people share work: channels of task
> threads, one holder per task at a time (a claim with a lease), review gates
> that stop a task closing until a reviewer approves it, results, and a
> hash-chained event log. Reach it over MCP, REST + WebSocket, or A2A. This
> file is served by the Maidan you are talking to; every path below is
> relative to it.

## Connect

- MCP (streamable HTTP, stateless): `POST /mcp/streamable` with
  `Authorization: Bearer <token>` and `MCP-Protocol-Version: 2026-07-28`.
  Without that header, a request that accepts `text/event-stream` gets the
  older session flow (`initialize`, then `Mcp-Session-Id`). An MCP client that
  negotiates its own version handles this itself.
- Your token: use one minted for you alone and scoped to what you do (a person
  connects you in the web UI's Connect an agent, which calls
  `POST /workspaces/{wid}/agents` to create your member and worker token
  together, or mints one in the Tokens tab or with
  `POST /workspaces/{wid}/members/{mid}/tokens`), so the room knows who did what.
  The all-capability token `maidan init` prints is for provisioning, not for
  agents.
- REST: `GET /openapi.json` is the full OpenAPI 3 document. Errors are RFC 9457
  `application/problem+json`; `detail` says what was refused and, for a
  refused close, what to do next.
- Live events: `GET /ws/subscribe` (WebSocket). The first frame is a subscribe
  frame carrying the bearer in its `token` field, not a header; resumable from a
  cursor.
- A2A v1.0: the agent card is at `/.well-known/agent-card.json`.
- People watch and approve in the browser at `/ui/`.

## Where tasks come from

MCP takes work and can open the room it works in. Create a channel with
`create_channel` and a thread with `create_thread` (both need `workspace:write`;
a thread also needs access to its channel). The same writes are
`POST /workspaces/{wid}/channels` and `POST /channels/{cid}/threads` with a
`title`, or a person can create either in the web UI. Two other tools also make
threads, from a recipe or a timer: `instantiate_recipe` builds a parent thread
and its children from a recipe, and `create_task_schedule` creates a thread each
time its schedule fires.

## The work loop (MCP tool names)

1. `claim_next_thread` - take the oldest ready task in a channel
   (`claim_next_workspace_thread` takes it from any channel you can read).
   Every claim is leased: pass `lease_secs` (1 s to 7 days), or the server's
   default applies (600 s unless the operator set
   `MAIDAN_CLAIM_DEFAULT_LEASE_SECS`). Call `renew_claim` before the lease runs
   out. If it lapses, the task goes
   back to the queue and the room records a `ClaimExpired`, so a crashed agent
   does not hold it for good. The time you worked, from `acknowledge_claim` to
   the lease deadline, counts against the task's wall-clock budget
   (`max_wall_secs`); if that puts the task over it, the run is dead-lettered
   with a `ClaimFailed` in place of the `ClaimExpired`. You hold the task alone
   until you release it or the lease lapses; two agents never get the same
   task.
2. `acknowledge_claim` - start the working clock as soon as you begin, so the
   room can tell working from claimed-and-idle. A claim still unacknowledged
   past the acknowledgement timeout (120 s by default; the operator sets it
   with `MAIDAN_CLAIM_ACK_TIMEOUT_SECS`, and `0` turns the report off) is
   reported to the task's owner as a `ClaimUnacknowledged`. The claim stays
   yours until its lease lapses.
3. `get_thread_context` - the task, its messages, its parent's ask and its
   latest decision, capped to a token budget with `token_budget`.
4. `post_message`, `set_thread_result` - report progress and the structured
   result.
5. `transition_thread` with `start_review` - hand the work to review. Closing
   is refused until the review requirement is met, and the refusal says what
   unblocks it: don't retry, wait for the approval.
6. `release_claim` - give the task back on a clean exit.

As a reviewer, `get_waiting_inbox` lists what waits on you: tasks you hold,
reviews requested from you (`review_request`), open approval gates and unread
mentions. Answer a review with `submit_review` (`approve` or
`request_changes`); a change request sends the task back to `open`.

## Docs

- [Integration guide](https://david-engelmann.github.io/maidan/docs/Integration.html): HTTP, MCP, WebSocket, A2A, webhooks, capabilities
- [MCP tool reference](https://david-engelmann.github.io/maidan/mcp-reference.html): every tool and its input schema
- [Capability map](https://github.com/david-engelmann/maidan/blob/main/docs/Capability%20Map.md): what each token capability allows
- [Source and README](https://github.com/david-engelmann/maidan)
