> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neuraldraft.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools, resources, and prompts

> Every primitive `@neuraldraft/mcp` exposes — what it returns, what it expects, and when the AI should call it.

This is the reference the AI sees through the MCP protocol. The exact same
information is included in the server's responses to `resources/list`,
`tools/list`, and `prompts/list`, so a curious model can rediscover all of
this at runtime.

## Resources

Resources are read-only context. The AI fetches them once per session — they
don't take parameters and they don't have side effects.

### `brand://current`

The single source of truth for your project's brand. The first thing the AI
should read in any UI generation session.

```json theme={null}
{
  "voice": "friendly_professional",
  "audience": "indie founders building with AI tools",
  "industry": "software",
  "colors": {
    "primary": "#7C3AED",
    "secondary": "#0F172A",
    "accent": "#A78BFA"
  },
  "fonts": {
    "heading": "Inter",
    "body": "Inter"
  },
  "default_language": "en",
  "target_languages": ["en", "fr", "de"]
}
```

Backed by [`GET /v1/brand`](/api-reference#tag/Brand). Refresh in a long
session by re-reading the resource.

### `schema://blog-post`

JSON Schema for `Post` and `PostTranslation`. The AI reads it before
generating a `/blog` page so the rendered markup matches what the API returns.

```json theme={null}
{
  "type": "object",
  "required": ["id", "slug", "status", "title"],
  "properties": {
    "id": { "type": "integer" },
    "slug": { "type": "string" },
    "status": { "enum": ["draft", "published", "scheduled", "archived"] },
    "featured_image": { "type": ["string", "null"], "format": "uri" },
    "published_at": { "type": ["string", "null"], "format": "date-time" },
    "title": { "type": "string" },
    "excerpt": { "type": ["string", "null"] },
    "content": { "type": "string", "description": "HTML body" },
    "language_code": { "type": "string" },
    "category": { "$ref": "#/definitions/Category" },
    "tags": { "type": "array", "items": { "$ref": "#/definitions/Tag" } }
  }
}
```

### `schema://product`

JSON Schema for `Product` and `ProductVariant`. Drives storefront page
generation and product-card components.

### `schema://booking`

JSON Schema for `BookableService`, `BookingAvailability`, and `Booking`.
Drives booking flow generation.

### `conventions://editable-html`

The most important resource. A short markdown doc describing the markup rules
the AI must follow to make generated sections editable in the project's
admin.

```markdown theme={null}
# Neural Draft editable-HTML conventions

Every generated section MUST follow these rules so the customer's admin can
edit it without touching code.

## Text
- Wrap any human-visible text node with data-translate="<key>":
  <h1 data-translate="hero.headline">Welcome</h1>
- Keys are dot-namespaced: section.field
  e.g. hero.headline, pricing.tiers.0.title

## Images
- <img data-image-key="hero.background" src="..." alt="...">
- The customer can swap in admin; the CDN URL resolves server-side.

## Calls to Neural Draft
- Read content: GET /v1/content/{key}?lang={locale}
- Bulk: GET /v1/content/bulk?keys=a,b,c&lang=en
- Use @neuraldraft/sdk for runtime fetches.
```

### `conventions://api-usage`

REST patterns: how auth headers work, error envelope shape, the async-job
contract, idempotency. The AI uses this when generating server-side code that
calls Neural Draft.

## Tools

Tools have side effects. Each one wraps a real call to the v1 Project API.

### `register_component`

The AI calls this for every section it generates. The component appears in
your admin as editable, with `data-translate` keys discovered automatically.

```json theme={null}
{
  "name": "register_component",
  "input": {
    "html": "<section data-component=\"hero\"><h1 data-translate=\"hero.headline\">Welcome</h1></section>",
    "intent": "marketing hero",
    "section_type": "hero"
  },
  "output": {
    "component_id": "cmp_2NgcaXxFqLPo",
    "editor_url": "https://app.neuraldraft.io/components/cmp_2NgcaXxFqLPo",
    "keys_created": ["hero.headline"]
  }
}
```

| Param          | Type                                                                                     | Required |
| -------------- | ---------------------------------------------------------------------------------------- | -------- |
| `html`         | string — full section markup with `data-translate` / `data-image-key` attrs              | Yes      |
| `intent`       | string — short description of the section's purpose                                      | Yes      |
| `section_type` | enum: `hero`, `features`, `pricing`, `cta`, `footer`, `testimonials`, `gallery`, `other` | No       |

Backs onto [`POST /v1/components/register`](/api-reference#tag/Components).

### `create_translation_keys`

Bulk-create translation key namespaces. Useful when the AI is about to emit a
component with many keys and wants to seed each with default per-language
values.

```json theme={null}
{
  "name": "create_translation_keys",
  "input": {
    "keys": [
      { "key": "hero.headline", "value": "Welcome", "lang": "en" },
      { "key": "hero.subhead", "value": "We build software that scales.", "lang": "en" }
    ]
  },
  "output": { "created": 2 }
}
```

### `generate_blog_post`

Kick off the full blog generation pipeline. Returns a job id; poll or stream.

```json theme={null}
{
  "name": "generate_blog_post",
  "input": {
    "topic": "How to choose a CMS for AI-built sites",
    "tone": "friendly_professional",
    "length": "medium",
    "translate_to_all_languages": true
  },
  "output": {
    "job_id": "job_2NgcaXxFqLPo",
    "status_url": "https://api.neuraldraft.io/v1/jobs/job_2NgcaXxFqLPo",
    "estimated_credits": 60
  }
}
```

### `generate_image`

Brand-consistent image generation. Returns a job id; poll for the URL.

```json theme={null}
{
  "name": "generate_image",
  "input": {
    "prompt": "A founder typing on a laptop in a sunlit cafe, soft focus",
    "aspect_ratio": "16:9",
    "key": "hero.background"
  },
  "output": {
    "job_id": "job_2Nh4PqRsTuVw",
    "status_url": "https://api.neuraldraft.io/v1/jobs/job_2Nh4PqRsTuVw"
  }
}
```

### `connect_social_account`

Returns the OAuth URL the AI surfaces to the user. They click, authorize,
return; the AI can then call `social_post.publish`.

```json theme={null}
{
  "name": "connect_social_account",
  "input": { "platform": "instagram" },
  "output": {
    "oauth_url": "https://app.neuraldraft.io/oauth/instagram?state=...",
    "expires_in": 600
  }
}
```

### `list_products` / `get_product`

Reads. The AI uses these when generating a product-grid or product-detail
page so the rendered fields match real data.

### `setup_booking_widget`

Returns the embed snippet for a service. The AI inserts it into the page.

```json theme={null}
{
  "name": "setup_booking_widget",
  "input": { "service_id": 42, "theme": "auto" },
  "output": {
    "snippet": "<div data-nd-widget=\"booking\" data-service-id=\"42\"></div>\n<script src=\"https://widgets.neuraldraft.io/v1/booking.js\" defer></script>",
    "embed_url": "https://embed.neuraldraft.io/booking/42"
  }
}
```

### `create_bookable_service`

Create a service customers can book. Two modes — both share the same tool;
pick `booking_type` to switch:

* `time_slot` (default) — meeting / appointment style with `duration_minutes`,
  `buffer_before_minutes`, `buffer_after_minutes`, `max_bookings_per_slot`.
* `date_range` — apartment / rental style with `min_nights`, `max_nights`.

```json theme={null}
{
  "name": "create_bookable_service",
  "input": {
    "name": "Cozy beach apartment",
    "booking_type": "date_range",
    "price": 15000,
    "currency": "eur",
    "min_nights": 2,
    "max_nights": 14
  }
}
```

After creation, call `setup_booking_widget` with the returned `service_id`.

### Pages — `create_page` / `list_pages` / `get_page` / `update_page`

Multi-page authoring with per-page SEO meta. Call `create_page` once per
page **before** registering its components if you want a real
`meta_title` / `meta_description`. If you skip it, `register_component`
auto-creates a stub page that you can backfill via `update_page`.

```json theme={null}
{
  "name": "create_page",
  "input": {
    "slug": "about",
    "title": "About us",
    "meta_title": "About — Acme",
    "meta_description": "Built for makers who hate boilerplate.",
    "og_image": "https://cdn.example.com/og.png"
  }
}
```

`update_page` uses **merge semantics** — only the fields you pass are
overwritten, the rest are preserved. Pass `null` to clear a meta field.

### Galleries — `list_galleries` / `get_gallery` / `create_gallery` / `update_gallery` / `delete_gallery`

Named, ordered image collections. One `slug` per gallery, an `items` array
of `{url, alt}` (max 200). Slugs auto-derive from `name` on create with
`-2`/`-3`/… suffixed on collision. **`items` updates are full-replace** —
read with `get_gallery`, mutate the array, send the complete new list back.

```json theme={null}
{
  "name": "create_gallery",
  "input": {
    "name": "Home carousel",
    "items": [
      { "url": "https://cdn.example.com/hero-1.jpg", "alt": "Studio entrance" },
      { "url": "https://cdn.example.com/hero-2.jpg", "alt": "Workshop" }
    ]
  }
}
```

```json theme={null}
{
  "name": "update_gallery",
  "input": {
    "slug": "home-carousel",
    "items": [
      { "url": "https://cdn.example.com/hero-2.jpg", "alt": "Workshop" },
      { "url": "https://cdn.example.com/hero-1.jpg", "alt": "Studio entrance" },
      { "url": "https://cdn.example.com/hero-3.jpg" }
    ]
  }
}
```

`delete_gallery` removes the gallery record only — underlying image URLs
stay in the images registry / media library.

### Destructive deletes — `delete_content` / `delete_page` / `delete_component` / `delete_image`

Fill the gap on the destructive side of the catalog. All four take the
identifier and return 204. **No undo.**

| Tool               | Identifier     | Notes                                                                                                  |
| ------------------ | -------------- | ------------------------------------------------------------------------------------------------------ |
| `delete_content`   | `key` (string) | Removes every locale's value for the key.                                                              |
| `delete_page`      | `id` (number)  | Soft-retires by default (`is_active=false`). `force: true` for a hard delete. Refuses on the homepage. |
| `delete_component` | `id` (number)  | Hard delete; the HTML chunk is gone. Re-register via `register_component`.                             |
| `delete_image`     | `key` (string) | Removes the key→URL binding only. CDN bytes are untouched.                                             |

### `generate_video`

Short-form clip generation. Returns a Job; poll `get_job` until complete.
Two tiers — pick `budget` (default, Wan 2.1) for **40 credits** or
`premium` (Kling v2.1 / Runway Gen4) for **300 credits**. Premium requires a
**Build** plan or higher; Free / Hobby calling with `tier=premium` get
`402 plan_required`.

```json theme={null}
{
  "name": "generate_video",
  "input": {
    "prompt": "slow-mo pour-over coffee, warm morning light, cinematic",
    "aspect_ratio": "9:16",
    "duration_seconds": 5,
    "tier": "budget"
  }
}
```

### `get_brand` / `update_brand`

Read or patch the project's brand context as a tool, for clients that don't
list MCP resources. `get_brand` is identical to the `brand://current`
resource — read-only, free. `update_brand` accepts a partial patch (pass
`null` on a field to clear it) and writes through `PATCH /v1/brand`.

```json theme={null}
{
  "name": "update_brand",
  "input": {
    "voice": "friendly_professional",
    "audience": "indie founders building with AI tools",
    "content_tone": "warm"
  }
}
```

Example prompt: *"Read the current brand context and tighten the voice to
something punchier — under 40 words."*

### `get_content` / `list_content`

Lookups for translation keys. `get_content(key, lang?)` returns one value plus
the full `all_locales` map; `list_content({ scope?, lang?, page_size? })`
paginates the project's keys. Read-only, free.

```json theme={null}
{ "name": "get_content", "input": { "key": "hero.headline", "lang": "en" } }
```

Example prompt: *"List the first 50 translation keys on this project, then
tell me which ones still have empty French values."*

### `get_usage`

Read the project's current credit balance and per-operation breakdown for
the active billing period. Wraps `GET /v1/projects/me/usage`. Read-only,
free.

```json theme={null}
{
  "name": "get_usage",
  "output": {
    "credits_balance": 8420,
    "credits_monthly_limit": 10000,
    "period_start": "2026-05-01T00:00:00Z",
    "period_end": "2026-05-31T23:59:59Z",
    "breakdown": [
      { "operation_type": "blog_post", "total_spent": 1200, "count": 20 },
      { "operation_type": "image", "total_spent": 384, "count": 12 }
    ]
  }
}
```

Example prompt: *"How much of my Neural Draft monthly budget have I burned
so far this period? Break it down by operation."*

### `list_blog_posts`

Paginated read of the project's posts. Filter by `status`, `lang`,
`category`, `tag`, plus `sort` (`created_at`, `published_at`, descending
with `-`). Read-only, free.

```json theme={null}
{
  "name": "list_blog_posts",
  "input": { "status": "draft", "page_size": 20, "sort": "-created_at" }
}
```

Example prompt: *"List my most-recent draft posts so I can decide which to
publish first."*

### `find_workspaces`

Look up the Neural Draft workspaces (tenants) registered against an email
address. Hits the **central** host (e.g. `https://app.neuraldraft.io`),
not the per-tenant API, and does NOT require an API key. Always returns
200 (empty list for unknown emails — defeats enumeration). Free.

```json theme={null}
{
  "name": "find_workspaces",
  "input": { "email": "ada@example.com" },
  "output": {
    "workspaces": [
      { "id": 12, "name": "Acme", "domain": "acme.neuraldraft.io" },
      { "id": 47, "name": "Acme staging", "domain": "acme-stg.neuraldraft.io" }
    ]
  }
}
```

Example prompt: *"Help me find all my Neural Draft workspaces for this
email address — I forgot which one I logged into last."*

### `list_newsletter_subscribers` / `list_contact_form_submissions`

Read-only listings of the project's captured leads. Both support `page`,
`page_size` (max 200) and `search` (substring match against email + subject

* message). The newsletter listing also accepts an `app_lead` boolean to
  filter trial leads from real subscribers.

```json theme={null}
{
  "name": "list_contact_form_submissions",
  "input": { "page": 1, "page_size": 50, "search": "demo" }
}
```

Submissions are written to the project from the **public** v1 endpoints
(`POST /v1/newsletters/subscribe`, `POST /v1/contact-forms`). Form-submit
topics are not currently in the outgoing-webhook event whitelist — poll
these list endpoints (or the matching v1 admin endpoints) to inspect what
came in. These tools are read-only.

## Prompts (slash commands)

Prompts are user-invoked. They expand into a long instruction the AI then
executes — like a parameterised macro.

### `/scaffold-marketing-site`

Generates a full Lovable/Next.js/Astro/Nuxt marketing site whose content lives
in Neural Draft.

| Argument    | Notes                                              |
| ----------- | -------------------------------------------------- |
| `framework` | `next` \| `astro` \| `sveltekit` \| `nuxt`         |
| `pages`     | Comma-separated, e.g. `home,about,pricing,contact` |

The expanded prompt instructs the AI to:

1. Read `brand://current` and apply colors/fonts/voice.
2. Read `conventions://editable-html` and follow the markup rules.
3. Read `schema://blog-post` if generating a `/blog` route.
4. Generate the requested pages.
5. For every section, call `register_component` so the customer admin shows
   them as editable.
6. Use `@neuraldraft/sdk` for runtime fetches; print the `editor_url` for each
   section.

### `/scaffold-blog-page`

Drops a blog index + dynamic post page into the current project. Reads
`schema://blog-post` and renders an SSG-friendly page that fetches via the
v1 API.

### `/connect-existing-site`

For static sites that already exist. Replaces hardcoded text with
`{{ __('key') }}`-style fetches and adds `data-translate` attributes so the
admin editor works.

### `/add-booking-widget`

Single-flow embed: AI calls `list_services`, asks the user to pick one, calls
`setup_booking_widget`, then drops the snippet into the right place in the
page.

## Annotations

Each tool advertises [MCP annotations](https://spec.modelcontextprotocol.io/specification/server/tools/#tool-annotations)
so smart clients can surface confirm-prompts before destructive ops:

| Tool                      | `readOnly` | `destructive` | `idempotent` |
| ------------------------- | :--------: | :-----------: | :----------: |
| `register_component`      |            |               |              |
| `create_translation_keys` |            |               |       ✓      |
| `generate_blog_post`      |            |               |              |
| `generate_image`          |            |               |              |
| `connect_social_account`  |      ✓     |               |       ✓      |
| `list_products`           |      ✓     |               |       ✓      |
| `get_product`             |      ✓     |               |       ✓      |
| `setup_booking_widget`    |      ✓     |               |       ✓      |
| `list_galleries`          |      ✓     |               |       ✓      |
| `get_gallery`             |      ✓     |               |       ✓      |
| `create_gallery`          |            |               |              |
| `update_gallery`          |            |               |       ✓      |
| `delete_gallery`          |            |       ✓       |       ✓      |
| `delete_content`          |            |       ✓       |       ✓      |
| `delete_page`             |            |       ✓       |       ✓      |
| `delete_component`        |            |       ✓       |       ✓      |
| `delete_image`            |            |       ✓       |       ✓      |

## Observability

Every tool call is logged in your project's audit log under the synthetic
agent `mcp:<machine-name>`. The dashboard's "MCP usage" pane shows the most
common tool/resource calls and tail latency, so you can spot a misbehaving
session.

## Source

The MCP server ships as the [`@neuraldraft/mcp`](https://www.npmjs.com/package/@neuraldraft/mcp)
npm package; source lives at
[github.com/vbalagovic/neuraldraft-mcp](https://github.com/vbalagovic/neuraldraft-mcp).
File issues there. We follow SemVer; non-breaking additions are normal.
