---
name: nexdoc-mcp
description: >-
  Generate, iterate, preview, and export production-ready designs (landing
  pages, slide decks, reports, invoices, resumes, business cards, social cards,
  email newsletters, and 30+ formats) through the NexDoc Design MCP tools
  (create_design, update_design, wait_for_run, notify_run_email, export_design).
  Use whenever the user asks to design, lay out, make a deck, PDF, page, or
  card, or to edit an existing NexDoc design, and MCP tools are available.
  Never publish unless asked.
compatibility: NexDoc MCP tools (create_design, wait_for_run, export_design). Connect https://mcp.nexdoc.design/mcp (OAuth) or run npx -y @nexdoc/mcp-server with NXD_API_KEY. Pass only arguments listed on the connected tool schema.
metadata:
  homepage: https://www.nexdoc.design
  docs: https://www.nexdoc.design/docs/agents/mcp
  canonical: https://www.nexdoc.design/skills/nexdoc-mcp/SKILL.md
---

# NexDoc Design via MCP

Canonical: `https://www.nexdoc.design/skills/nexdoc-mcp/SKILL.md`

You are a client of the NexDoc Design engine. Write clean source copy and a clear design brief; NexDoc generates the HTML/CSS, validates it, and returns a preview URL. **Do not hand-write the final HTML.**

If NexDoc MCP tools are not connected, use the [REST API skill](https://www.nexdoc.design/skills/nexdoc-api/SKILL.md) instead (local: [../nexdoc-api/SKILL.md](../nexdoc-api/SKILL.md)).

## Connect (once)

If NexDoc tools (`create_design`, `export_design`, and related tools) are already available, skip this section.

**Remote MCP (recommended for Claude, ChatGPT, Cursor, and other remote-MCP clients).** Add a remote MCP server named `nexdoc` at:

```
https://mcp.nexdoc.design/mcp
```

The client opens a browser for OAuth. No API key is stored in the client.

**stdio MCP (desktop clients with an API key).** Cursor, Claude Desktop, and Claude Code can run the published server as a process:

```json
{
  "mcpServers": {
    "nexdoc": {
      "command": "npx",
      "args": ["-y", "@nexdoc/mcp-server"],
      "env": {
        "NXD_API_KEY": "nxd_live_..."
      }
    }
  }
}
```

Create a key at `https://app.nexdoc.design/keys`. Never print or echo a key.

## Tools

Pass **only** properties listed on the connected tool schema. If a field or tool below is missing, skip it — schemas with `additionalProperties: false` reject unknown keys.

| Tool | When to use |
|------|-------------|
| `create_design` | First design for a request. Creates a job and starts a run. Pass `wait: true` to block until done. Pass `notify_email: true` only if that property exists on the schema. |
| `update_design` | Any change to an existing design (`job_id`). Instructions are a **diff**. |
| `wait_for_run` | You started a run without `wait`, or the client timed out. Polls every 5 s (default timeout 900 s). |
| `notify_run_email` | If present: request an email when an in-progress run finishes. If already terminal, returns a warning — then call `check_run`. |
| `check_run` | One-shot status; also mints a fresh `viewer_url`. |
| `refresh_preview` | The preview link expired or returns 401. |
| `export_design` | The user wants a file: `pdf` or `html` (ZIP). Returns `download_url` (valid ~1 hour). |
| `publish_design` | **Only** when the user explicitly says publish, make public, or live link. |
| `unpublish_design` | The user asks to take a published design down. |
| `list_runs` | Compare versions of a job. |
| `list_formats` | You are unsure which format slug fits. |
| `get_balance` | A tool failed with `API 402`, or the user asks about cost or balance. |

## Persist IDs

**Save `job_id` and `run_id` as soon as a run is created** — before waiting, before timeouts, before talking to the user. Store them in conversation state and **repeat both IDs** after create and after every later step. They are the only way to resume, edit, export, or request email later.

- `job_id` — the design. Reuse it for all edits. Never create a second job for the same request.
- `run_id` — this generation. Required for `wait_for_run`, `check_run`, `notify_run_email`, and a specific export or publish.
- If a tool times out, call `wait_for_run` or `notify_run_email` (if present) with the **same** pair. Never start a duplicate run.

## How long generation takes

Tell the user the wait up front so they do not think the tool hung.

| Kind of work | Typical wait |
|--------------|--------------|
| Simple card, one-page layout, short landing page | **1–5 minutes** |
| Pitch deck, multi-page report, image-heavy or tightly branded work | **10–20 minutes**, sometimes longer |

Complex formats (`report`, `proposal`, `whitepaper`, `slide-deck`, `pitch-deck`, `lookbook`) take the longest. `wait: true` returns when the run is `completed`, `failed`, or `cancelled`. If the client enforces a shorter tool timeout, call `create_design` with `wait: false` and, **if the schema includes it**, `notify_email: true`. Tell the user they will be emailed at their account address, and **keep `job_id` / `run_id`**. You can also call `notify_run_email` after a run has started when that tool exists. If it returns a `warning`, the run is already terminal — call `check_run` and report the result (no email is sent). For long jobs, pass `timeout_sec: 1200` on `wait` / `wait_for_run` when the schema allows it.

## Workflow

```
1. Pick a format slug            → table below (call list_formats only if unsure)
2. Write content + instructions  → guidance below
3. create_design { format, instructions, content, name, wait: true }
   (if the client will time out: wait: false, plus notify_email: true if listed)
4. Immediately save and tell the user job_id + run_id
5. If not terminal: wait_for_run { job_id, run_id }
6. Report viewer_url, job_id, run_id, charge_usd
7. Offer export_design (pdf | html). Publish ONLY on explicit request.
8. Edits: update_design { job_id, format, instructions } — same job, same format
```

### Assets (logos, photos, PDFs)

**Accepted types only:** `.png` (`image/png`), `.jpg`/`.jpeg` (`image/jpeg`), `.gif` (`image/gif`), `.pdf` (`application/pdf`). Anything else (SVG, WebP, JSON, `brand-kit.json`, …) is rejected with `400`. Put brand colors and fonts in `instructions`.

- **stdio MCP:** pass `asset_paths` (for example `["./logo.png"]`) and `content_path` for a markdown file **when those properties exist on the schema**. Reference images in content by filename (`![Logo](logo.png)`); NexDoc rewrites them to `assets/`.
- **Remote MCP (OAuth):** the server cannot read the user's disk. Put copy inline in `content`. For image uploads, have the user attach files in the [NexDoc dashboard](https://app.nexdoc.design) or use the [REST API skill](https://www.nexdoc.design/skills/nexdoc-api/SKILL.md).
- New assets on an **update** usually require the REST API (`files` / `file_ids`) unless `update_design` lists an asset field.
- Do not paste base64 images into `content`.

## Writing `content` and `instructions`

**`content`** — the facts, in clean markdown. Headings, lists, tables, real names, numbers, dates, prices. Preserve everything factual from the user; invent nothing. NexDoc re-authors for the medium (condenses prose into slides, expands bullets into landing-page sections, maps prose into invoice fields), so give substance, not layout.

**`instructions`** — the design brief. Cover, in one short paragraph or bullets:

- **Audience and purpose** — “Series A investors”, “restaurant walk-in menu”, “internal Q3 review”
- **Aesthetic direction** — mood, palette, typography (“dark editorial, warm serif headlines, generous whitespace”). Be specific; avoid “modern and professional”.
- **Brand tokens** — write them inline: `Brand: primary #2563EB, accent #F59E0B, fonts Inter; use logo.png in the nav.` Stated colors and fonts are authoritative.
- **Structure** — “one idea per slide, ≤ 12 slides”, “hero + 3 features + pricing + FAQ + footer”, “single page A4”
- **Must-haves** — CTA text, contact block, legal line, page numbers
- **Slide decks** (`slide-deck` / `pitch-deck` / `presentation`) — the downloadable PDF is the native print export, not the browser view. Require: 1280×720 stages sized with `%` (never `vw`/`vh`); readable content ≥48px from all edges; inspect the exported PDF for clipped labels and footers.

**Update instructions are a diff.** “Make the hero darker and swap the CTA to *Start free trial*; keep everything else.” Do not resend the whole brief. Omit `content` unless copy actually changes. Keep the same `format` unless the user wants a different medium.

### Example

User: *“Make me a pitch deck for Loop, a B2B returns-logistics startup. Here are our notes…”*

```json
create_design {
  "name": "Loop pitch deck",
  "format": "pitch-deck",
  "instructions": "Seed-round pitch for logistics and e-commerce investors. 10–12 slides, one idea per slide, terse headlines, big numbers as callouts. Dark navy background, electric-green accent (#22C55E), Inter. Closing slide with contact: hello@loop.example.",
  "content": "# Loop\n\n## Problem\nReturns cost US retailers $743B in 2023...\n\n## Traction\n- 42 merchants\n- $1.2M ARR, +18% MoM\n...",
  "wait": true
}
```

Then report `viewer_url`, `job_id`, and `run_id`; offer `export_design { format: "pdf" }`. Expect several minutes (a deck like this often takes 10–20).

## Format selection

| Need | Slug |
|------|------|
| Marketing / product page | `landing-page` |
| Personal site, links hub | `portfolio`, `link-in-bio` |
| Visual collection | `lookbook` |
| Slides | `pitch-deck` (investor/sales), `slide-deck` (general; `presentation` is an alias) |
| Long print document | `report`, `proposal`, `whitepaper`, `case-study` |
| Business paperwork | `invoice`, `receipt`, `contract`, `nda` |
| Career | `resume` / `cv`, `cover-letter` |
| Print collateral | `brochure`, `menu` |
| Single image / card | `business-card`, `social-card`, `og-image`, `banner`, `poster` |
| Events | `invitation`, `ticket`, `certificate` |
| Passes / promos | `boarding-pass`, `coupon`, `voucher` |
| Email | `email-newsletter` |
| Data / structure | `infographic`, `dashboard`, `timeline`, `roadmap`, `org-chart` |

Export: `pdf` for print, slides, cards, certificates, resumes, invoices. `html` for `landing-page`, `portfolio`, `link-in-bio`, `email-newsletter`, `dashboard`.

## Errors

| Signal | Action |
|--------|--------|
| `API 402` | Call `get_balance`, then send the user to `https://app.nexdoc.design` (minimum $10). Do not retry in a loop. |
| `API 401` | Reconnect the MCP server (OAuth) or replace `NXD_API_KEY`. |
| Run `failed` | Read `error` and `log_tail`; fix the input; retry **once**. Failed runs are not charged. |
| `API 409` on cancel | The run already finished. |
| Preview link expired | `check_run` or `refresh_preview`; the design is not gone. |
| Timeout | Use the saved `job_id` / `run_id`. Call `wait_for_run` again, or `notify_run_email` if that tool exists. Never start a duplicate run. |

## Report to the user

After every run (and again after export or publish): **`viewer_url`** (click-to-edit text), **`job_id`**, **`run_id`**, `status`, `charge_usd`. After export: `download_url`. After a *requested* publish: `public_url`. Never invent URLs. Always persist and restate `job_id` and `run_id` — previews expire, IDs do not.
