Skip to main content
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.
{
  "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. 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.
{
  "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.
# 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.
{
  "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"]
  }
}
ParamTypeRequired
htmlstring — full section markup with data-translate / data-image-key attrsYes
intentstring — short description of the section’s purposeYes
section_typeenum: hero, features, pricing, cta, footer, testimonials, gallery, otherNo
Backs onto POST /v1/components/register.

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.
{
  "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.
{
  "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.
{
  "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.
{
  "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.
{
  "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.
{
  "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.
{
  "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. 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.
{
  "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" }
    ]
  }
}
{
  "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.
ToolIdentifierNotes
delete_contentkey (string)Removes every locale’s value for the key.
delete_pageid (number)Soft-retires by default (is_active=false). force: true for a hard delete. Refuses on the homepage.
delete_componentid (number)Hard delete; the HTML chunk is gone. Re-register via register_component.
delete_imagekey (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.
{
  "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.
{
  "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.
{ "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.
{
  "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.
{
  "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.
{
  "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.
{
  "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.
ArgumentNotes
frameworknext | astro | sveltekit | nuxt
pagesComma-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 so smart clients can surface confirm-prompts before destructive ops:
ToolreadOnlydestructiveidempotent
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 npm package; source lives at github.com/vbalagovic/neuraldraft-mcp. File issues there. We follow SemVer; non-breaking additions are normal.