# Pagelive agent setup

> Pagelive publishes an HTML page as a private, branded, tracked link. This file tells a coding
> agent (Claude Code, Cursor, Codex, or any MCP client) how to connect, which tools exist, and the
> three-step flow for publishing and updating a page. Follow it top to bottom.

## 1. The server

- Remote MCP server: `https://app.pagelive.io/api/mcp`
- Transport: Streamable HTTP (JSON-RPC 2.0), MCP protocol `2025-06-18`
- Auth, one of:
  - **OAuth** in Claude.ai and Claude Code. Add the URL, then sign in to Pagelive in the browser window that opens.
  - **API key** in Cursor, Codex, Claude Code, or any HTTP client. Create one at
    `https://app.pagelive.io/dashboard/keys` (dashboard, "API & MCP"). It is shown once. Send it as
    `Authorization: Bearer pl_...`. Treat it like a password: anyone holding it can publish to the account.

## 2. Connect your client

### Claude.ai

Customize, Connectors, +, Add custom connector. Paste `https://app.pagelive.io/api/mcp`, then sign in to
Pagelive when asked.

### Claude Code

OAuth:

```sh
claude mcp add --transport http pagelive https://app.pagelive.io/api/mcp
```

Then run `/mcp` inside Claude Code and sign in to Pagelive.

API key instead of OAuth:

```sh
claude mcp add --transport http pagelive https://app.pagelive.io/api/mcp \
  --header "Authorization: Bearer pl_your_key"
```

### Cursor

Add this to `~/.cursor/mcp.json` (every project) or `.cursor/mcp.json` (one project):

```json
{
  "mcpServers": {
    "pagelive": {
      "url": "https://app.pagelive.io/api/mcp",
      "headers": {
        "Authorization": "Bearer ${env:PAGELIVE_API_KEY}"
      }
    }
  }
}
```

Set `PAGELIVE_API_KEY` to your `pl_` key in the environment Cursor starts from.

### Codex

Add this to `~/.codex/config.toml` (or a trusted project's `.codex/config.toml`):

```toml
[mcp_servers.pagelive]
url = "https://app.pagelive.io/api/mcp"
bearer_token_env_var = "PAGELIVE_API_KEY"
```

Then, in the shell that starts Codex:

```sh
export PAGELIVE_API_KEY="pl_your_key"
```

The Codex CLI and the IDE extension read the same file.

### Any other MCP client, or plain HTTP

Add `https://app.pagelive.io/api/mcp` as a remote (Streamable HTTP) MCP server and send the header
`Authorization: Bearer pl_your_key`. Without an MCP client, POST JSON-RPC directly:

```sh
curl -s https://app.pagelive.io/api/mcp \
  -H "Authorization: Bearer pl_your_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

Methods: `initialize`, `tools/list`, `tools/call`. Use any HTTP client with its normal User-Agent.

## 3. Tools

- `publish_page`: publish an HTML document and get its link. Required: `html`. Optional: `title`, `password`, `view_once`, `slug` (replace a page you own instead of creating a new one), `workspace`, `domain`, `folder`, `comments` (a review bar above the page where viewers comment on text, elements or areas), `private_reviewers` (each reader sees only their own comment threads), `pdf` (Print or save as PDF in that bar), `show_version` (the version number in the bar), `decisions` (Approve and Request changes in that bar). `comments`, `pdf`, `show_version` and `decisions` are paid and off unless set. So is `private_reviewers`. Returns `slug`, `url`, `workspace`.
- `update_page`: change a page at the same URL. Required: `slug`. Send `edits` (a list of `{ "old_str", "new_str" }`, each `old_str` found exactly once) or a full `html` rewrite. Saves a version. Optional: `comments`, `private_reviewers`, `pdf`, `show_version`, `decisions` (true or false; only the ones you send change, and sent alone they change the setting without a new version), `resolves` (the ids of the comment threads this update fixes, at most 50).
- `list_pages`: the pages you can access, newest first, with URL, workspace, folder and view count. Optional: `limit`, `offset`, `folder`.
- `get_page_stats`: views, unique viewers and top countries for one page. Required: `slug`.
- `list_form_submissions`: replies sent through a `<form data-pagelive>` on a page. Required: `slug`.
- `create_recipient_link`: a personal link to a page for one person; their opens and reading time show under their name, with no email gate. Required: `page` (slug, URL or id), `email`. Optional: `label`. Paid plans.
- `list_recipient_links`: the recipient links on a page, each with its URL, opens, reading time and last open. Required: `page`.
- `list_comments`: comment threads on a page, each with its quote, anchor, body, author email, status, `written_on` (the version, "v3"), `state` (`same`, `changed` or `gone`, with `before` and `after` when changed) and replies. A pin or a box carries a CSS selector and the element's text (plus a one-line `where`), so you can find the spot in your own HTML. Required: `page` (slug, URL or id). Optional: `status` (`open`, `resolved`, `all`; default `open`).
- `create_comment`: start a comment thread as the page owner. Required: `page`, `body`. Optional: `anchor` (a quote `{ "kind": "quote", "text": "..." }`, or a pin or a box as `list_comments` returns it), `internal` (true: only the owner, the team and you see it). Paid plans.
- `reply_comment`: reply to a comment thread as the page owner; the commenter is emailed. Required: `comment_id`, `body`.
- `resolve_comment`: mark a comment thread resolved. Required: `comment_id`.
- `apply_suggestion`: apply a suggested edit (a thread with a `suggestion`): the quoted text is replaced on the page as a new version, and the thread is resolved with the reply "Applied in v5". Required: `comment_id`. Paid plans.
- `reopen_comment`: reopen a resolved comment thread. Required: `comment_id`.
- `list_decisions`: who approved a page and who requested changes, one decision per reader, each with its note, the version it was made on (`version`, "v3") and `on_current_version`. Required: `page` (slug, URL or id).
- `list_workspaces`: your personal workspace and any teams, with their plan. Use an id as `workspace`.
- `list_domains`: your connected custom domains. Use a hostname as `domain`.
- `list_folders`: the folders in a workspace, with page counts.
- `create_folder`: create a folder in a workspace.
- `move_page`: file a page into a folder, or back to the workspace root.

`update_page`, `get_page_stats`, `list_form_submissions` and `move_page` also accept `domain` when the
same slug exists on more than one of your hosts.

## 4. The flow: publish, get the link, update at the same URL

1. **Publish.** Call `publish_page` with `{ "html": "<!doctype html>...", "title": "Q3 report for Acme" }`.
   Send one self-contained document: inline CSS and scripts, images as data URLs or absolute URLs,
   25 MB at most.
2. **Get the link.** The result holds `url` and `slug`. Give the user the `url`; that is the link they
   send. Keep the `slug`; you need it for every later call.
3. **Update at the same URL.** When the page changes, call `update_page` with `{ "slug": "...", "edits": [...] }`
   for small changes or `{ "slug": "...", "html": "..." }` for a rewrite. The URL stays the same, so
   nobody needs a new link. Calling `publish_page` again with the same `slug` also replaces the page.

Later, `get_page_stats` tells you whether it was read and `list_form_submissions` returns any replies.

**Review loop.** On paid plans, with `comments` on for the page, people you share it with can comment on it. Call `list_comments`
with the page, fix what they raise with `update_page`, then `reply_comment` to say what changed or
`resolve_comment` to close the thread. Read a thread's `after` to see what the page says there now,
and republish with `resolves` to close the threads you fixed. A thread with a `suggestion` is a suggested edit: when its `applicable` is true, `apply_suggestion` makes the change as a new version and closes the thread. To leave a note for the owner and the team that no reader ever sees, call `create_comment` with `internal: true`.
With `decisions` on, each reader approves the page or requests changes (one decision per reader, not a signature): `list_decisions` returns them, and a request for changes carries a note that says what to fix.

## 5. Rules

- Pages are noindex by default: search engines are told not to list them.
- Passwords, email gates, view-once links, custom domains and custom slugs need a paid plan. On the
  free plan, `password`, `view_once`, `domain`, `comments`, `private_reviewers`, `pdf`, `show_version` and `decisions` come back as an error that says so; pass it on to
  the user rather than retrying. Plans: https://pagelive.io/pricing
- Report only the numbers and replies the tools return. Never estimate or invent analytics.
- Published HTML is scanned, and obvious phishing is rejected.
- To collect replies, include a plain `<form data-pagelive>` in the HTML. No action URL, endpoint or key.

## 6. More

- Full tool reference with schemas: https://pagelive.io/llms-full.txt
- Setup pages: https://pagelive.io/claude-code, https://pagelive.io/cursor, https://pagelive.io/codex
- Claude connector: https://pagelive.io/mcp
- Reply forms: https://pagelive.io/docs/forms
