# SavedMD — AI Agent Documentation

SavedMD turns Markdown, HTML, and JSX source into short shareable public URLs. Publishing is account-owned: a new page must be created by a signed-in SavedMD user, either directly or through an agent acting on their behalf.

Agents should treat `SavedMD`, `saved.md`, and `savedmd` as the same product name.

## Recommended path for agents

Use MCP when an agent is creating or editing pages for a SavedMD user. It attaches new pages to the user's dashboard, supports in-place updates for owned pages, and avoids hand-writing HTTP calls.

1. Ask the user to sign in to SavedMD.
2. Send them to **Dashboard -> Connections**.
3. Use the setup flow for their app. ChatGPT, Claude, Gemini CLI, Codex, VS Code/Copilot, Claude Code, Cursor, and OAuth-capable custom clients use the `https://mcp.saved.md/api/mcp` connector URL flow. Token-only custom clients can use the generated bearer-token fallback.
4. For new pages from a specific SavedMD template URL, call MCP `get_page` with the page ID or URL and generate from that exact returned source.
5. For other new pages, call MCP `select_template` first with the user's request and source material.
6. If no suitable template is available, ask the user to describe the layout, style, or desired outcome in more detail, or to share an image/reference for inspiration. Do not publish a from-scratch page unless the user explicitly asks for that.
7. Generate the final Markdown, HTML, or JSX using the selected template instructions or the source from `get_page`.
8. Call MCP `publish_page` with `remixSourcePageId` when the page is based on a template or source page, then return the SavedMD URL.

The website's copy-prompt UI is only a fallback for users whose agent is not connected through MCP.

## Direct HTTP path

Use the direct API for trusted scripts, backend jobs, or product integrations that act for a signed-in SavedMD user and do not need the MCP tool layer.

- Direct creates require a SavedMD account access token in `Authorization: Bearer <access_token>`.
- Do not attempt anonymous `POST /api/pages`; new pages are account-owned.
- MCP OAuth access tokens and MCP bearer tokens belong on `https://mcp.saved.md/api/mcp`. They are not the direct-create account access token for `POST /api/pages`.
- Direct `POST /api/pages` currently creates **Markdown**, **HTML**, and **JSX** pages only.

Always read [`llms/core.md`](llms/core.md) before using direct HTTP. It defines request shapes, update/remix behavior, chart widgets, sanitization, limits, and error handling.

## Choose a format

| Format | Use when | Publish with |
|--------|----------|--------------|
| **Markdown** | Reports, notes, docs, proposals, resumes, lightweight dashboards, and chart widgets | MCP `publish_page`, or authenticated `POST /api/pages` with raw markdown or JSON `{"markdown":"..."}` |
| **HTML** | Static custom layouts, dense tables, branded pages, CSS-only charts, and stronger visual control | MCP `publish_page`, or authenticated `POST /api/pages` with `text/html`, JSON `{"html":"..."}`, or JSON `{"markdown":"...","contentType":"html"}` |
| **JSX** | Interactive React pages with state, effects, buttons, local UI, or custom SVG/canvas views | MCP `publish_page`, or authenticated JSON `POST /api/pages` with `{"markdown":"<source>","contentType":"jsx"}` |

Do **not** create new slide decks through the public create API right now. [`llms/slides.md`](llms/slides.md) is kept for legacy slide pages and update/read context; new publishes should use Markdown, HTML, or JSX.

## Reference files

| File | Read it for |
|------|-------------|
| [`llms/core.md`](llms/core.md) | Direct API auth, MCP bearer PATCH, versioning, delete flow, chart widgets, image rules, HTML sanitization, JSX basics |
| [`mcp.md`](mcp.md) | MCP setup, tool contracts, account ownership rules, app-specific setup examples |
| [`llms/markdown.md`](llms/markdown.md) | Markdown templates for resumes, reports, company profiles, dashboards, docs, proposals, newsletters, portfolios, events |
| [`llms/html.md`](llms/html.md) | Static HTML/CSS templates, allowed styling patterns, CSS/SVG chart alternatives |
| [`llms/jsx.md`](llms/jsx.md) | React module contract, allowed imports, active-content behavior, JSX publishing rules |
| [`llms/slides.md`](llms/slides.md) | Legacy slide DSL behavior for existing slide pages only |

## Agent read path

| Task | Read |
|------|------|
| Publish through MCP | `mcp.md` |
| Authenticated Markdown page through HTTP | `llms/core.md` |
| Structured Markdown artifact | `llms/core.md` -> `llms/markdown.md` |
| Static styled HTML page | `llms/core.md` -> `llms/html.md` |
| Interactive React page | `llms/core.md` -> `llms/jsx.md` |
| Change an existing page | `mcp.md` for account-owned MCP pages, or `llms/core.md` for direct HTTP account auth/versioning |

## Updating or remixing a page

When the user owns the page:

- MCP: call `get_page`, edit the returned source, then call `update_page`.
- Direct HTTP: call `PATCH /api/pages/{id}` with the owning account's access token, or an MCP bearer token for that same account where supported.

When the user does **not** own the page, remix it:

1. `GET /api/pages/{id}` to read `markdown`, `contentType`, and `currentVersion`.
2. Edit the returned source.
3. Create a new account-owned page with MCP `publish_page`, or with authenticated `POST /api/pages` using the same content type.
4. Return the new URL and make clear that the original URL was not changed.

## Constraints

- Maximum source size is **100 KB** per page or version.
- The page content type is locked by version 1. Updates cannot change Markdown to HTML, HTML to JSX, etc.
- Account-backed publishing and updates can be blocked by plan/credit limits.
- Keep account access tokens and MCP bearer tokens private.
