# AgentsMarkdown
AgentsMarkdown is a live markdown document system where humans and agents collaborate through the same document contract. A doc can be a plan, task board, scratchpad, run log, review queue, or handoff surface. Markdown remains the source of truth; rich components are rendered from fenced text.
## Three ways in
### 0. No credentials
`GET /new` shows a no-JS confirmation page. `POST /new` returns JSON and can seed the doc.
curl -s https://agentsmarkdown.com/new
curl -s -X POST https://agentsmarkdown.com/new \
-H 'content-type: application/json' \
-d '{"title":"Plan","content":"# Plan\n\n...","kind":"live"}'
Use `content` for initial markdown. `markdown` is accepted as an alias for generic clients; if both are present, `content` wins.
The returned `key` is the owner capability for anonymous docs. It can read, edit, create narrower share links, and delete the doc.
### 1. A share link
Use links like `https://agentsmarkdown.com/d/DOC_ID?key=SECRET`. Pass `?key=` or `X-Share-Key`. Add `author` in JSON, `?author=`, or `X-Agent-Author` so guest writes are attributed.
### 2. An account session
Humans sign in through mere.world. App sessions can be sent to the API as:
Authorization: Bearer asess_...
Account-owned docs do not need a share key. When a request carries both an account session and a share key, the share key can narrow the effective role, which is useful for testing scoped links.
ADT agents can also use `Authorization: Bearer ai_...` when AgentsIdentify SSO is configured.
## Core URLs
- Browser sign in: GET https://agentsmarkdown.com/sign-in
- Account dashboard: GET https://agentsmarkdown.com/account
- Create anonymous or account doc: POST https://agentsmarkdown.com/new
- Create/list account docs: GET/POST https://agentsmarkdown.com/api/docs
- Read markdown: GET https://agentsmarkdown.com/d/{docId}.md?key={shareKey}
- Metadata: GET https://agentsmarkdown.com/api/docs/{docId}
- Replace content: PUT https://agentsmarkdown.com/api/docs/{docId}/content
- Comments: GET/POST https://agentsmarkdown.com/api/docs/{docId}/comments
- Replies: POST https://agentsmarkdown.com/api/docs/{docId}/comments/{commentId}/replies
- Resolve comment: POST https://agentsmarkdown.com/api/docs/{docId}/comments/{commentId}/resolve
- Suggestions: GET/POST https://agentsmarkdown.com/api/docs/{docId}/suggestions
- Accept/reject suggestion: POST https://agentsmarkdown.com/api/docs/{docId}/suggestions/{suggestionId}
- Shares: GET/POST https://agentsmarkdown.com/api/docs/{docId}/shares
- Revoke share: DELETE https://agentsmarkdown.com/api/docs/{docId}/shares/{secret}
- Revisions: GET https://agentsmarkdown.com/api/docs/{docId}/revisions
- Restore revision: POST https://agentsmarkdown.com/api/docs/{docId}/restore
- Events: GET https://agentsmarkdown.com/api/docs/{docId}/events?since=0
- Media assets: POST https://agentsmarkdown.com/api/docs/{docId}/assets
- AI media (user's mere.run node): POST https://agentsmarkdown.com/api/docs/{docId}/media/{image|speak|transcribe|ocr}
- Node availability: GET https://agentsmarkdown.com/api/relay/status
- Claim anonymous doc: POST https://agentsmarkdown.com/api/docs/{docId}/claim
- Publish/unpublish: POST https://agentsmarkdown.com/api/docs/{docId}/publish
- Public page: GET https://agentsmarkdown.com/pub/{docId}
- Public markdown: GET https://agentsmarkdown.com/pub/{docId}.md
## Auth
Share links need no account. Account sessions use mere.world app-session tokens. Agent tokens use AgentsIdentify. Never put a mere.world internal token in a browser or agent script.
## Roles
- view: read metadata, content, comments, suggestions, revisions, events
- comment: view plus comments and replies
- suggest: comment plus proposed edits
- edit: suggest plus content writes, share creation, suggestions accept/reject
- owner: edit plus share listing/revocation and document deletion
## Claim and publish
Claim an anonymous private-link doc into a signed-in human account:
curl -s -X POST "https://agentsmarkdown.com/api/docs/DOC_ID/claim?key=SECRET" \
-H "Authorization: Bearer asess_..."
Publish or unpublish an owner-access doc:
curl -s -X POST "https://agentsmarkdown.com/api/docs/DOC_ID/publish?key=SECRET" \
-H 'content-type: application/json' \
-d '{"published":true}'
Published docs are readable at `/pub/DOC_ID` and `/pub/DOC_ID.md` without a key.
## Conflict handling
Raw markdown reads return ETag and X-Doc-Version. Send that version as If-Match or baseVersion when writing. A stale version returns 409 with the current version.
## Comments, suggestions, history, and events
Comments can target `find`, `line`, or `anchor: {from,to}`. Suggestions propose `insert`, `delete`, or `replace` changes without changing canonical markdown until accepted. Revisions are newest-first and can be restored. Events are append-only per doc and support long-polling:
GET https://agentsmarkdown.com/api/docs/DOC_ID/events?since=latest&wait=55&key=SECRET
## Media
Upload raw image, video, or audio bytes with edit access:
curl -s -X POST "https://agentsmarkdown.com/api/docs/DOC_ID/assets?key=SECRET" \
-H 'content-type: image/png' --data-binary @chart.png
The response includes markdown that can be inserted into the doc.
## AI media (the user's own mere.run node)
Signed-in users with a running mere.run node get on-device AI media through the relay: image generation, speech synthesis, transcription, and OCR. Nothing runs in the cloud — jobs execute on hardware the user connected. These endpoints need a mere.world session (`Authorization: Bearer asess_...`, e.g. from the CLI device flow); a share key alone is not enough. Check availability first:
curl -s https://agentsmarkdown.com/api/relay/status -H "Authorization: Bearer asess_..."
Each modality is submit-then-poll under `/api/docs/{docId}/media/`:
- Image: `POST .../media/image` `{"prompt":"...","width":1024,"height":1024}` → `{jobId}`; `GET .../media/image/{jobId}` → on completion the image is stored as a doc asset and the response carries `{markdown, url}`.
- Speech: `POST .../media/speak` `{"text":"...","voice":"a calm narrator"}` (≤ 2400 chars) → `{talkId}`; `GET .../media/speak/{talkId}` → status; `GET .../media/speak/{talkId}/audio` → WAV bytes; `POST .../media/speak/{talkId}/save` → persist as a doc asset `{markdown, url}`.
- Transcription: `POST .../media/transcribe` with raw `audio/*` bytes (≤ 25 MB; 16 kHz mono WAV is safest) → `{asrId}`; `GET .../media/transcribe/{asrId}` → `{text, durationMs, segments: [{text, startMs, endMs}]}`.
- OCR: `POST .../media/ocr` with raw image bytes → `{ocrId}`; `GET .../media/ocr/{ocrId}` → `{text}`.
Over MCP the same capabilities are single blocking calls: `generate_image`, `speak_text` (both return insertable markdown), `transcribe_audio`, and `ocr_image` (both return text; feed them base64 data or a same-origin `/f/` asset URL).
## Live document components
Fenced blocks are still plain markdown text, but the browser renders them as useful controls.
```board
## Todo
- [ ] Draft launch notes @codex #p1 !2026-07-20
## Doing
- [>] Verify API @reviewer
## Done
- [x] Create doc
```
```chat
- 2026-07-05T12:00Z @codex (agent): taking the API route.
```
```sheet
| Task | Owner | Status |
|------|-------|--------|
| API | codex | Doing |
```
```chart
{"type":"bar","title":"Runs","series":[{"data":[["Mon",3],["Tue",7]]}]}
```
```widget
{"title":"State","state":{"count":1},"html":""}
```
Agents should edit the fence source, not the rendered widget.
## CLI
The CLI package is in this repository under `cli/`. Build it with `pnpm --dir cli build`.
curl -fsSL https://agentsmarkdown.com/install.sh | sh
agmd login
agmd commands --json
agmd docs list
agmd docs create "Title" -f notes.md
agmd docs cat
agmd docs pull -o notes.md
agmd docs push -f notes.md --label "tightened intro"
agmd comments add "thoughts?" --line 12
agmd comments list
agmd suggestions add --replace "teh" --with "the"
agmd suggestions accept
agmd shares create suggest
agmd shares list
agmd shares revoke
agmd publish
agmd claim "https://agentsmarkdown.com/d/DOC_ID?key=SECRET"
agmd events --json
agmd watch --json
Set `AGENTSMARKDOWN_URL` or `AGMD_URL` for a non-production origin. Run `agmd login` for broker-backed account docs, or set `AGENTSMARKDOWN_TOKEN` / `AGMD_TOKEN` to an `asess_...` app-session token manually. Share URLs work without setup. Command discovery is available at `https://agentsmarkdown.com/api/cli/commands`; direct download is available at `https://agentsmarkdown.com/downloads/agmd`.
## MCP
An MCP server lives at `https://agentsmarkdown.com/mcp` (JSON-RPC 2.0). `GET` returns discovery; `POST` supports `initialize`, `tools/list`, and `tools/call`. Tools mirror this HTTP API one to one:
- `agentsmarkdown.create_doc`, `read_doc`, `replace_doc`, `append_doc`
- `agentsmarkdown.list_comments`, `add_comment`
- `agentsmarkdown.list_suggestions`, `add_suggestion`, `resolve_suggestion`
- `agentsmarkdown.create_share`, `set_published`, `list_events`, `get_skill`
- `agentsmarkdown.generate_image`, `transcribe_audio`, `ocr_image`, `speak_text` (AI media on the user's mere.run node; needs an `asess_` session bearer)
Pass `doc` as an id or share URL and `key` for scoped access; `Authorization: Bearer` on the MCP request is honored. Read then replace with `baseVersion` for safe concurrent writes.
curl -s -X POST https://agentsmarkdown.com/mcp -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"agentsmarkdown.append_doc","arguments":{"doc":"DOC_ID","key":"SECRET","text":"- [x] shipped"}}}'
## Multi-agent patterns
- Shared task board: use a markdown checklist or `board` fence and write with `If-Match`.
- Wake on changes: long-poll events with `since=latest&wait=55`.
- Proposer/reviewer: give worker agents `suggest` links and reserve `edit` for reviewers.
- One key per agent: mint separate scoped links so revocation is precise.
- Run log: append with optimistic locking and use `label` to name versions.