# Editing a bernard website over MCP — connect & instructions

> **This is the live connect reference** for editing a bernard site over MCP, served at `/agent`. Connect an assistant to `https://mcp.bernardmoves.com/mcp` (bearer auth) and it can read and edit your sites — every change lands on a draft you approve. (This replaces the retired feat-011 REST API.) See [docs/prd/feat-023-mcp-edit-server.md](prd/feat-023-mcp-edit-server.md).

bernard hosts your website. An AI assistant can edit it **through bernard's MCP server** — it calls tools that read and change your real site files, and every change lands on a **draft** you approve before anything goes live. (MCP = Model Context Protocol, the standard way assistants connect to tools.)

---

## Part A — For the site owner: connect your assistant

You don't need to be technical, and you never edit a config file. One connection covers **all your bernard sites**, and only yours.

1. **Get your setup prompt.** Log in to bernard → **Account → Your AI**. bernard hands you a ready-to-paste **setup prompt** — it carries a secure key scoped to **your own sites**, which you can replace any time (replacing it revokes the old key instantly).
2. **Connect your assistant** (one-time):
   - **Claude on the web (claude.ai)** — no key to paste: press **Connect to Claude** in Account → Your AI, sign in, press **Allow**. Disconnect any time from the same place.
   - **Claude Desktop / Cursor** — paste the setup prompt, or add the config by hand:
     ```json
     {
       "mcpServers": {
         "bernard": {
           "url": "https://mcp.bernardmoves.com/mcp",
           "headers": { "Authorization": "Bearer bnt_your_key_here" }
         }
       }
     }
     ```
   - **Claude Code** — one command: `claude mcp add bernard --transport http https://mcp.bernardmoves.com/mcp --header "Authorization: Bearer bnt_your_key_here"`.
   - **ChatGPT** — Settings → Connectors (developer mode) → add a custom MCP connector with that URL and the `Authorization: Bearer …` header. (Business/Enterprise plans may also offer a sign-in flow.)
   - **Other MCP clients** — any client that speaks Streamable HTTP MCP works: same URL, same header.
3. **Ask in plain English.** *"What's worth improving on my site?", "Fix the broken Instagram link", "freshen the copyright year", "make the buttons navy."* Your assistant makes the changes on a **draft**. If your assistant shows bernard's **prompts** (some clients list them as slash-commands or a task picker), each one is a ready-made job — health check, freshen, SEO audit, open a shop — you can run with one click; if it doesn't show them, just ask in your own words — the same jobs run either way.
4. **Review & publish.** It hands you a **preview link**. Look it over; if you're happy, press **Approve** in bernard and it goes live. **Nothing is live until you approve it.**

**What it costs:** bernard doesn't charge for editing over MCP — your assistant's own plan or API key pays for the AI's thinking; bernard just serves the tools.

Lost or worried about a key? **Account → Your AI → "Want to change your connection key?" → Replace key** — the old key stops working that instant, and your drafts stay safe. If the connection won't work at all, see [Help: my assistant won't connect](https://bernardmoves.com/help/assistant-wont-connect).

---

## Part B — For the assistant (agent instructions)

### 1. What bernard is (relay this confidence)
Every bernard site was moved off a platform like Squarespace, WordPress, Wix or Webflow and is now hosted by bernard as plain static files — there is no old CMS, dashboard or page builder behind it any more, and bernard is where it is edited. *(Canonical — kept byte-identical with the REST doc + the in-app system prompt.)* You are the one who edits it here; never tell the owner to "go and change it in Wix/Squarespace" — that platform no longer hosts the site.

### 2. Connect
- **Transport:** Streamable HTTP MCP at `https://mcp.bernardmoves.com/mcp`.
- **Auth:** `Authorization: Bearer <token>` on **every** request. The token is **scoped to the owner's account** — it covers all of their sites (call `listMySites` to see them) and nothing else; a slug outside that set is refused (`site_forbidden`). Older per-site keys still work and cover just their one site. If the token is missing/expired/revoked you'll get a 401 — ask the owner for a fresh setup prompt from **Account → Your AI** (Replace key).

### 3. The surface (tools, prompts, resources)
- **Tools** (`tools/list`) — 90+ tools. **Call `getDocs` first**: it returns the guide to how bernard works (the draft model, CSS handles, the no-scripts rule, pure-CSS interactivity, limits) as a short table of contents, then one section per call; `getDocs('tool-map')` is the canonical map of every tool by job. The guide is also on the open web at [`/agent/docs`](https://bernardmoves.com/agent/docs).
- **Prompts** (`prompts/list`) — every ready-made job (health check, freshen, SEO audit, design polish, open a shop, start a course, …) is an MCP prompt; `prompts/get` returns the full engineered protocol for that task, tuned for these tools. Offer them to the owner as things bernard can do; `getDocs('what-bernard-can-do')` lists the same menu if your client doesn't surface prompts.
- **Resources** (`resources/list`) — the agent guide (`bernard://docs/{section}`) and the whole help library (`bernard://help/{slug}`: 120+ owner problems, each with a paste-ready ask).
- **No specific ask? Call `suggestImprovements(slug)`** — one read-only call runs bernard's deterministic checks and returns a ranked, evidence-backed list of what's worth doing on the owner's actual site, each item naming the prompt that does the job.

The everyday core, in one table (the tool-map section has the rest — audit packs, shop, courses, images, verify/render):

| Tool | Use |
|---|---|
| `getDocs` | **READ FIRST** — how bernard works; TOC then sections on demand |
| `suggestImprovements` | ranked "what's worth doing" for this site, with evidence |
| `searchSite` | **CHEAP grep** over HTML+CSS — use FIRST to locate anything |
| `getSeoFacts` / `getDesignFacts` / `freshenScan` / `contactFacts` / `linkCheck` | **audit packs** — one call replaces a whole discovery loop; call the relevant pack FIRST for its task family |
| `getLinks` / `findElements` / `readCssRule` | locate a link / element / CSS rule → a **stable handle** |
| `readSiteFileRange` / `readSiteFile` | the lines around a hit / a whole file (EXPENSIVE — locate first) |
| `editDraftFile` | exact-string replacement(s) on the draft (`expectedDraftHead` for safe concurrency) |
| `setElementText` / `setAttribute` / `setCssDeclaration` / `patchCss` | targeted element / CSS edits by handle (or site-wide by selector) |
| `updateCopyrightYear` | **codified transform** — set the year everywhere in one deterministic call |
| `screenshotPage` / `getRenderedLayout` / `interactElement` | see / measure / operate a real render of the draft to verify your work |
| `getDraftPreview` | what's staged: preview URL, pending commits, and the files they change |
| `publishDraft` | make the draft live — **only on the owner's explicit instruction** (see below) |

### 4. The workflow contract
1. **No specific ask → `suggestImprovements` first**, and offer the top items in plain language.
2. **Find before you read** (audit packs / `searchSite` first; whole-file reads are a last resort).
3. **Edit** with the targeted tools — every write lands on the **draft** and needs a short, plain-English **reason** (it becomes the owner's version history; end it with which assistant you are, e.g. `(by Claude)`).
4. **Check your work** — `getDraftPreview` gives the preview URL; verify a changed page with `screenshotPage`/`getRenderedLayout`/`interactElement` (or fetch it back) to confirm.
5. **Hand over** — give the owner the preview URL: *"Have a look — if you're happy, say so (or press Approve in bernard) and it goes live."* The preview is a normal web page the owner can open in a browser.
6. **Publish only when told.** `publishDraft` performs the owner's Approve from here — call it ONLY when the owner has explicitly asked, in this conversation, to make it live; review `getDraftPreview` with them first. Never publish on your own initiative, and never claim a change is live unless a publish actually ran.

### 5. Rules of the road
- **No `<script>` / tracking / third-party embeds** (enforced server-side).
- **Follow the site's existing markup + classes**; make the smallest change that satisfies the request.
- **Don't invent content** (no made-up prices, dates, reviews). Ask if you need a fact.
- **You're responsible for SEO** — preserve/improve `<title>`, meta, headings, image `alt`.
- **Site-wide changes: be consistent, and verify at scale.** Make the same change the same way on every affected page; on a large site, fetch a **representative sample** of changed pages from the draft preview — **each distinct template** — and confirm it landed and nothing else moved. A blind find-and-replace silently corrupts real markup. Tell the owner roughly how many pages you changed.

### 6. Limits (the short version — `getDocs('limits')` has the full list)
- **Rate:** 60 requests/minute and 1,000 writes/day per key — generous for real editing; there to stop loops, not enthusiasm.
- **Sampling:** on large sites the audit packs and site-wide reads work over a capped page sample and say so (`capped: true`) — tell the owner when a result is sampled.
- **Handles go stale:** `cref`s (CSS) after any write; page/screenshot views after any edit. Re-read before reusing.
- **Renders cost real work:** the screenshot/layout/interact tools run a real browser render — verify once per change; don't re-shoot what hasn't changed.

### 7. Troubleshooting
- **401 / "unauthorized"** → the key is missing, revoked or replaced. Ask the owner for a fresh setup prompt (**Account → Your AI → Replace key**).
- **`site_forbidden`** → that slug isn't in this key's account. `listMySites` shows what is.
- **Connected but no tools listed** → the client added the server without the `Authorization` header, or against the wrong URL — it must be exactly `https://mcp.bernardmoves.com/mcp` over Streamable HTTP.
- **Tool errors teach** — every refusal names what to call or do instead; relay it plainly to the owner rather than retrying blind.
- Owner-facing walkthrough: [help/assistant-wont-connect](https://bernardmoves.com/help/assistant-wont-connect).

### 8. Acceptable use
Do not help make a site that deceives (fake scarcity, impersonation, fabricated reviews/credentials, deceptive pricing). If a request would mislead visitors, decline and say why.

---

## Migration note (for bernard maintainers)
This replaced the feat-011 REST API (now removed). The canonical migrated-site sentence in §1 must stay byte-identical with the in-app system prompt (the `tests/ai-migrated-site-context.test.ts` guard). The rate/write limits in §6 mirror `content/help/_facts.json` (`requests_per_minute`, `writes_per_day`) — update both together.
