`https://leancrawl.com/mcp` is a stateless Streamable HTTP MCP server that
exposes the whole API as tools — backed by the public API itself.

## Setup

```bash
claude mcp add --transport http leancrawl https://leancrawl.com/mcp \
  -H "Authorization: Bearer ac-…"
```

Other clients (Cursor, Windsurf, …) accept the equivalent JSON config:

```json
{ "leancrawl": { "url": "https://leancrawl.com/mcp",
    "headers": { "Authorization": "Bearer ac-…" } } }
```

## Tools (26)

Every response reports its `credit_cost`; rates are listed in
[Credits](https://leancrawl.com/docs/credits). Check `account_usage` for balance before large crawls.

### Capture

| Tool | Use |
|---|---|
| `markdown` | Read a page as clean Markdown — default for LLM content |
| `html` | Fully rendered HTML after JS — only when you need raw markup |
| `links` | All links on one page (url + anchor text) |
| `map` | Discover site URLs without fetching — for URL discovery, never `crawl_start` |
| `extract` | AI structured extraction → JSON (schema or prompt) |
| `screenshot` | Page screenshot, returned inline as an image block |
| `pdf` | Page rendered to PDF, returned inline as a resource block |

### Crawl

| Tool | Use |
|---|---|
| `crawl_start` | Async multi-page crawl → `job_id`; `webhook` pushes `crawl.*` events once to a user-provided URL |
| `crawl_status` | Poll status/progress; `include_pages` returns fetched pages on terminal states |
| `crawl_cancel` | Stop a running crawl — billed only for pages already fetched |
| `crawl_list` | List jobs — recover a lost `job_id` |

### Monitor

| Tool | Use |
|---|---|
| `monitor_create` | Watch a URL for changes every `interval_minutes` — recurring, NOT for one-off reads |
| `monitor_list` | List monitors; find a `monitor_id` |
| `monitor_get` | Detail + `include_checks` history; changed rows inline a diff excerpt |
| `monitor_update` | Pause/resume, retune cadence, rename, ignore_patterns, webhook_id, wait_for |
| `monitor_run` | Trigger one check now — result lands in check history |
| `monitor_snapshot` | Full normalized markdown of one snapshot (latest ~10 kept) |
| `monitor_delete` | Delete monitor + check history + snapshots — irreversible |

### Notification channels

| Tool | Use |
|---|---|
| `channel_list` | List notification channels — secrets are never shown |
| `channel_create` | Create a channel (slack/discord/telegram/feishu/wecom/dingtalk/email/custom) — custom returns `signing_secret` exactly once |
| `channel_update` | Change url/events/status/config/secrets — id and channel_type are kept |
| `channel_rotate` | New `signing_secret` in place (custom only) — shown once; old one dies immediately |
| `channel_deliveries` | Latest 50 delivery attempts — debug missing events |
| `channel_resend` | Re-post a failed/dead delivery |
| `channel_delete` | Delete a channel — deliveries kept, monitors auto-detached |
| `channel_test` | Send a `notification.test` event — verify wiring (10/hour per team) |

### Account

| Tool | Use |
|---|---|
| `account_usage` | Balance, quota, in-flight reservations, this key's 30-day spend |

`screenshot`/`pdf` artifacts are fetched server-side with your key and returned as
`image`/`resource` blocks — agents never need to handle Bearer-auth URLs.

## Failure semantics

- `initialize`/`tools/list` work without a key; a missing/invalid key surfaces as
  an `isError` tool result with actionable text — never an HTTP 401, so MCP clients
  do not fall into OAuth discovery.
- Every error message says whether the call was billed.

OAuth-based auth is not supported in this iteration.

`monitor_create` is the only recurring-spend tool: every check bills 1 credit
forever until you `monitor_update status="paused"` or `monitor_delete`. It is
not for one-off reads — use `markdown` for that. Agents cannot receive webhooks,
so results arrive by polling `monitor_get` with `include_checks=true`; the first
check runs at creation. `monitor_run` forces an immediate check (1 credit) and
does not shift the schedule.