MCP Server
Ycode includes an embedded Model Context Protocol (MCP) server that lets AI tools build and edit your site. Connect Claude (Desktop, Claude.ai, or Claude Code), ChatGPT, Cursor, or VS Code to your Ycode project and use natural language to create pages, design layouts, manage CMS content, and publish changes.
For an AI that lives inside the Ycode editor — no external client to install — see the AI Agent. It uses the same tool registry as MCP (~130 tools), just wired into the builder’s Agent tab instead of an external client. The one difference: the in-app agent can’t publish (only you can), while MCP tools can.
How to Connect
AI tools connect over OAuth: you paste one URL into the client, sign in to Ycode, and approve access on a consent screen. Open Integrations → MCP in the builder to find your MCP server URL, per-client setup steps under How to connect, and your approved Connections.
Ycode supports both OAuth client registration methods clients use today — Dynamic Client Registration and Client ID Metadata Documents — so any client that speaks the MCP Streamable HTTP transport with OAuth can connect.
Ycode Cloud: one URL for all your sites
On Ycode Cloud, the MCP page leads with a single shared URL:
https://mcp.ycode.cloud/mcpSign in once with your Ycode Cloud account. The connection works on every site you have designer access to — including sites you get access to later. In the conversation, name the site you want to work on and the assistant switches to it with the list_sites and select_site tools. If you only have one site, it’s selected automatically.
In Claude, search the connector directory for Ycode and click Connect. If Ycode isn’t in your directory yet, add it as a custom connector with the URL above. Each site’s own URL (https://your-site.com/ycode/mcp) remains available on the same page as a secondary option.
If you start connecting while logged out, Ycode sends you back to the consent screen after you sign in, so the connection request isn’t lost.
Self-hosted: one URL per project
Self-hosted projects aren’t listed in the Claude or ChatGPT connector directories, because every project has its own URL. Add your project as a custom connector instead, using the MCP server URL from Integrations → MCP — it looks like https://your-site.com/ycode/mcp.
Clients like Claude.ai and ChatGPT connect from the vendor’s servers, so they need a public HTTPS URL and can’t reach localhost. For local development, use Cursor, Claude Code, or VS Code. If your project is served from several hostnames or behind a reverse proxy, set NEXT_PUBLIC_MCP_SERVER_URL to the public URL clients should use.
Client Setup
The How to connect tabs on the MCP page show these steps with your URL filled in.
Claude Desktop and Claude.ai — Open Settings → Connectors, scroll past the directory, and click Add custom connector. Name it “Ycode”, paste the MCP server URL into Remote MCP server URL, and leave the OAuth client ID and secret fields empty. Click Add, then Connect, and sign in to Ycode to approve access. Custom connectors require a paid Claude plan (Pro, Max, Team, or Enterprise); on Team and Enterprise an owner may need to add the connector for the organization.
Claude Code — Run the command below, then run /mcp in Claude Code and choose ycode to sign in:
claude mcp add --transport http ycode https://your-site.com/ycode/mcpCursor — Open Settings → MCP and click Add new MCP server, or edit .cursor/mcp.json directly:
{
"mcpServers": {
"ycode": { "url": "https://your-site.com/ycode/mcp" }
}
}ChatGPT — Open Settings → Connectors and enable Developer mode (under Advanced). Click Create, name it “Ycode”, and paste the MCP server URL. Choose OAuth authentication, then sign in to Ycode and approve access. Developer mode connectors are available on ChatGPT Plus, Pro, Business, Enterprise, and Edu plans.
VS Code — Run the command below, then open the Chat view, click the tools icon, and start the ycode server to sign in:
code --add-mcp '{"name":"ycode","type":"http","url":"https://your-site.com/ycode/mcp"}'Approving Access
Ycode shows a consent screen with your site name and the client requesting access. If the client redirects to an app on your own machine (Claude Code, Cursor), the screen warns you that the target is a local application. Approve to connect.
Access tokens last 1 hour. Refresh tokens last 30 days, rotate on every use, and are bound to the client that received them, so a connected client stays signed in until you revoke it.
Tool Permissions
The first time the assistant uses a tool, the client asks for your permission. Choose Always allow for the editing tools — every change is a draft until you publish — and keep Publish and the delete tools on ask. On the Cloud shared URL, one approval covers all your sites.
Every tool reports a title and a read-only or destructive hint, which clients use to decide which calls need confirmation. Editing tools batch a whole turn of changes into one batch_operations call, so a page edit usually needs one approval instead of one per layer.
Changes made through the MCP server appear in the browser editor in real time via Supabase Realtime. You can watch the AI build your site as it works.
Start Building
However you connected, ask the AI to create pages, add elements, style them, manage CMS content, and publish. Tool calls happen in your project; changes appear in the editor live.
What AI Agents Can Do
The MCP server is at version 1.0, with full feature parity with the Ycode editor. Tools are organized by area:
Pages
Create, update, duplicate, and delete pages. Manage page settings including SEO metadata, custom code injection, and password protection. Organize pages into folders. Mark pages as the homepage (is_index), as a dynamic page (is_dynamic), or as an error page (401, 404, 500). Bind dynamic pages to a CMS collection with a slug field and control how next-item / previous-item link keywords traverse the collection.
Pages also support draft state via is_publishable — set false on create_page / update_page to keep a page out of the live site while leaving it editable in the builder. Pages with is_publishable: false are skipped on publish.
Layers and Elements
Add any element type — including tables (table, thead, tbody, tr, td, th). Update design properties (layout, typography, spacing, sizing, backgrounds, borders, effects, position, transforms, transitions), text content, images, links, videos, and background images.
Design tools accept a ui_state argument (hover, focus, active, disabled, current) so the same property can take different values per state. The current state activates when a link points to the page being viewed, which is how you style the active item in a navigation menu.
Layer settings cover the full surface: sliders (pagination, easing, touch events, slides per group), CMS-bound lightboxes (multi-image fields, groups), maps (Mapbox / Google Maps with coordinates, zoom, marker color, navigation controls), CMS-bound select/radio/checkbox options, plus per-layer hidden, keepInHtml, filter_on_change, and placeholder flags.
The design schema reaches further than the visual controls in the editor sidebar. Agents can also set mixBlendMode (multiply, screen, overlay, and the rest), raw filter and backdropFilter values, and any CSS backgroundImage — including inline SVG data URIs for noise and texture overlays. For the rare property with no design field at all (such as pointer-events), agents can set a style custom attribute on the layer via update_layer_settings. Combined with absolute positioning and z-index, this is enough to build tinted scrims, film-grain overlays, and similar effects as native layers instead of HTML embeds.
Links support URLs, internal pages, email, phone, anchors (anchor_layer_id), specific dynamic items (collection_item_id), assets, plus rel and download attributes.
batch_operations covers the same edits as the single tools — including update_link, update_settings, and update_background_image ops — so an agent can apply a whole turn of changes in one call. update_component_layers accepts update_link and update_settings ops too, preserving any linked component variable.
Move, reorder, and delete layers.
get_layers returns the full page tree by default. On large pages, agents read it in pieces instead: fields: "summary" returns a compact tree (id, name, tag, html id, link, truncated text, classes, component), depth limits how many levels come back (deeper levels report a children_count), layer_id returns a single subtree, and search finds up to 50 layers by id, name, html id, class, or text, with each match’s parent and path.
Edit tools return design_warnings ranked by severity. An error renders wrong (content directly in a section, low contrast, a grid on a collection layer, nav links hidden on mobile without a toggle), a warning looks unfinished (missing container, missing typography, clickable layers with no hover state), and a hint is optional polish. Agents fix errors and warnings and may skip hints.
HTML Import
import_html turns HTML and Tailwind into native, editable layers in one call. It’s opt-in: agents use it when you ask for an HTML import or provide HTML, and keep building with layouts and layer tools otherwise. It uses the same converter as the builder’s Import HTML, so mobile-first breakpoints, gradients, nav rows, anchor links, and form attributes convert the same way.
- Section by section — Import into a page (defaults to the body) or a component, under any parent and position. The response returns
refsmapping each elementid,data-ref, and unnamed landmark (header,nav,main,section,section[2],footer…) to its new layer id, so the agent can target layers without reading the page. Passreplace_layer_idto swap an existing section in place, ordry_runto preview the layer count and warnings without saving. - Site links —
href="/pricing"becomes a page link, andhref="#id"orhref="/path#id"becomes a page + anchor link when the id lives on another page. Paths with no matching page stay URLs. - Warnings — Anything dropped or converted lossily (
<script>,<style>, relative media URLs, classes with no design control) is reported in groups ranked by severity.
Annotate the HTML with data-ycode-* attributes to wire up Ycode features during the import:
| Attribute | What it creates |
|---|---|
data-ycode-component="Name" | A component from the element, with an instance left in its place. Repeated names, or names matching an existing component, become more instances of it |
data-ycode-toggle="menu" + data-ycode-menu="menu" | A working mobile menu: the button toggles the panel with the same click interaction as the built-in navigation layouts, on the breakpoints where the panel is hidden |
data-ycode-collection="Name" | A Collection List from the marked card, with optional data-ycode-limit, data-ycode-sort="Field:desc", and data-ycode-filter="Field=value; Other!=value" |
data-ycode-field="Field" | A field binding on text, heading, image, video, audio, or link layers. data-ycode-field-alt binds image alt text and data-ycode-field-bg the background image. Outside a list, it binds the dynamic page’s own item |
data-ycode-link="item" | A link from the card to the item’s dynamic page |
data-ycode-preview-only | Nothing — drops static copies that only exist to preview the list |
Unknown collections, fields, sort or filter values are reported as warnings, and the markup stays static.
Layouts
Insert pre-built layout templates — hero sections, headers, feature grids, footers, and more. Layouts provide a quick starting point that the AI can then customize.
CMS
Create and manage collections, fields, items, and item values. Field types include text, rich text, number, boolean, date, asset (image / audio / video / document, with optional multiple), reference, option (with custom choices), and count (computed from a referenced collection).
Add per-field metadata (default, fillable, hidden, is_computed), set a default sorting on each collection (field, direction), reorder fields with reorder_collection_fields, and reposition manually-sorted items with set_collection_item_order.
create_collection_pages sets up a collection’s pages in one call: a folder, an index (listing) page, and a dynamic detail page bound to the collection’s slug field, with the SEO title and description bound to fields (name, plus description, excerpt, or summary when present, and an optional title suffix). It reuses an existing folder with the same slug and won’t create a second dynamic page for a collection.
Dynamic Content (Collection Lists, Bindings, Visibility)
Bind layers to CMS data without leaving the agent:
bind_collection_layerturns a layer into a Collection List bound to a collection (passconvertto turn a plain container into one), with sorting, limit, pagination (Pages or Load More), and nested-collection sourcing from a reference, multi-reference, multi-asset, or inverse-reference field — useful for “show this category’s products” or “show this post’s tags” patterns.set_collection_filterswrites filter rules as AND-of-OR condition groups. Conditions can compare a field to a static value, to a visitor-facing filter input (input_layer_id), or to the current page’s item on dynamic pages (the “Current Tag” / “Current Category” pattern). Item ID conditions support both selected items and the current page item.set_layer_visibilitywrites show/hide rules for any layer with the same condition model (field,item_id, andpage_collectioncount sources).bind_layer_fieldbinds dynamic content onto a layer: text and rich-text values (including headings), imagesrc/alt, videosrc/poster, audiosrc, background images, and link, email, or phone fields on buttons and links. Pass an optionalprefix/suffixfor inline formatting.set_dynamic_textcomposes one text node from an ordered list of literal strings and field references — useful for “Posted on{Date}by{Author}” patterns.batch_operationsacceptsbind_collectionandbind_fieldops, so a whole list can be bound in one call.update_rich_text_stylesstyles the elements insiderichTextlayers — h1–h6, paragraphs, links, lists, blockquotes, code, images, separators, and tables — with the same design schema asupdate_layer_design, plus hover styles, per-breakpoint values, and aresetlist. The styles also apply to CMS rich text bound to the layer, and work on component masters viacomponent_id.
The collection layer is the repeated item, not the list container: grid columns, gaps, and dividers belong on its parent.
Components
Create reusable components with variables, edit component layer trees, and manage the component library. Variables include rich_text, variant, visibility, and id types, plus placeholder and default_value fallbacks.
A visibility variable is a boolean ({ visible: true|false }) linked to a layer’s Settings Visibility. Instances override it with visible on set_component_instance. Nested pass-through works the same as other variable types. Deleting the variable unlinks layers and clears overrides.
An id variable is a string ({ id: "…" }) linked to a layer’s Settings ID. Instances override it with element_id on set_component_instance. Values are sanitized to a valid HTML id. Unlinking or deleting the variable falls back to the layer’s static id.
set_component_instance can also bind an instance’s variables to CMS data, so one generic component — a card, say — works in Collection Lists of different collections:
- Text and rich text —
segmentsmixes literal text with field references, likeset_dynamic_text - Image, video, audio, and link —
field_idbinds the variable to a CMS field (icons can’t be bound) - Links to items —
link_page_idwith a dynamic page links each item to its own page. Without acollection_item_id, it defaults to the current list item or the current page item, likeupdate_layer_link.anchor_layer_idandtargetwork too
Fields resolve from the enclosing Collection List or the dynamic page (source). An instance on a static page outside any list returns an error and saves nothing. Keep the component’s own defaults static and bind per instance.
Variants have full CRUD: list_component_variants, create_component_variant (optionally cloning an existing variant), update_component_variant, and delete_component_variant. update_component_layers accepts an optional variant_id so edits target a specific variant without clobbering the others.
list_components reports how many instances each component has and on which pages. replace_component_instances swaps every instance of one component for another across the site. get_component accepts variant_id, depth, and fields filters for a compact read of large components.
Animations and Interactions
Add animations from 18 curated presets — reveal, hover, click, parallax, stagger, and loop families — in a single tool call:
add_animation— apply a preset to one or moretargetslist_layer_animations,remove_layer_animation,clear_layer_animationsset_layer_interactions— raw escape hatch for custom GSAP timelines
All of these accept component_id (and an optional variant_id) to animate layers inside a component master, so every instance gets the animation.
A dedicated Animation Presets Reference resource documents every preset, trigger semantics, and the raw interaction shape.
Site Settings
Read and update project settings (site name, description, custom CSS, and more). Manage URL redirects with list_redirects, add_redirect, update_redirect, and delete_redirect — including regex patterns and 301 / 302 types.
Forms
View form submissions, update statuses, and manage form data. update_form_settings configures success behaviour (message or redirect to a URL) and email notifications (to, subject).
Analytics
On Ycode Cloud, get_analytics reads the published site’s visitor analytics: visitors, pageviews, bounce rate, visit length, live visitors, a traffic series, and top-10 lists of pages, sources, countries, devices, CMS items, and tracked clicks and form submissions. It’s read-only and takes a period or a from/to range, up to five breakdowns, and an optional page path. On the hub URL, pass site_id to pick the site. See Analytics.
Localization
Manage locales and translations for multilingual sites. Start with list_translatable_content to discover exactly what can be translated for a page, component, or CMS item — the response returns the precise source_type, source_id, content_key, and content_type for every translatable string, plus the current source value (and any existing translation when a locale is passed). Use set_translation for plain-text values, set_rich_text_translation for rich-text fields (it accepts structured blocks and writes a properly-formed translation — no need to hand-assemble the underlying document JSON), or batch_set_translations for bulk updates.
For large or multi-language jobs, keep discovery and writes lean. Pass untranslated_only: true (and a locale_id) to list_translatable_content so it returns only keys still missing a completed translation — the cheapest way to resume work or add a locale. Paginate big CMS collections with limit and offset instead of loading everything at once. list_translations accepts source_type and completed filters when you need a subset of existing rows.
batch_set_translations accepts up to 1000 items per call. Set a top-level locale_id once and omit it on each item — do not repeat the locale on every row. Prefer one large batch over many small set_translation calls. Rich text in a batch uses content_type richtext with a JSON-stringified Tiptap document; use set_rich_text_translation only when you are writing a single field.
Long rich text, such as a blog post body, translates in segments instead of as one huge document. get_rich_text_segments returns the field as numbered segments, one per paragraph or heading. Formatting and links appear as <mN>…</mN> tags and inline elements as <xN/> placeholders. set_rich_text_segments takes the translated text and rebuilds the document from the source, so links (including internal page links), images, tables, and lists can’t break. Send it in parts, in sequence or in parallel; segments you don’t send keep their previous translation. Pass locale_id to get_rich_text_segments to get each segment’s current translated_text and fix one segment at a time. Invalid input, like a dropped link tag, is rejected without saving anything. The translation is marked complete once every segment is translated. This works for CMS rich-text fields and for rich-text layers on pages and components.
Custom attributes that hold readable text (aria-label, title, alt, placeholder, and the other ARIA text attributes) are listed by list_translatable_content with the key layer:<layerId>:attribute:<name> and translate like any other value.
Page custom code (the head and body snippets) is translatable too: it comes back from list_translatable_content with content_type code, and set_translation and batch_set_translations accept the same type.
Translations default to completed so they appear on the live site after publishing — pass is_completed: false only for work-in-progress drafts. Rich-text payloads are validated against their declared content_type and rejected with an actionable error rather than silently stored as unrenderable data. get_unpublished_changes reports pending translation and locale counts alongside other unpublished changes, so agents know when there’s something to publish.
Styles
Create, apply, update, and delete reusable layer styles for consistent design across the site. Use set_layer_styles to stack multiple styles on a single layer in priority order — the same combo-class model the editor uses, where later styles in the stack win on conflicting properties.
Assets
Upload images and files (from URL or base64), list and organize assets in folders.
Color Variables
Create, update, delete, and reorder global color variables.
Fonts
List installed fonts, search Google Fonts, and add new fonts to the project.
Export
export_layer_html renders any layer subtree to a self-contained HTML string with Tailwind classes preserved — useful for handing a finished section off to another tool or saving it as a snippet.
Pass rendered: true to preview what the layer looks like once published, without publishing. It renders through the same pipeline as the live site: components are expanded, Collection Lists repeat with real draft items, CMS fields are filled in, visibility conditions apply, and links resolve to published URLs. On a dynamic page it renders the first item, or the one whose slug you pass as collection_item_slug.
Publishing
Check for unpublished changes and publish all drafts to make the site live.
MCP Resources
The MCP server also provides read-only resources that give AI agents context about your project:
| Resource | Description |
|---|---|
| Elements Reference | Available element types (including tables) and nesting rules |
| Design Reference | All design properties and valid values, across every category (including transforms and transitions) |
| Animation Presets Reference | The full preset catalog with trigger semantics, tween value formats, and a worked raw-interaction example |
| Prompts Reference | Example prompts and recommended workflows |
| Site Pages | Current pages and folder structure |
| Site Collections | CMS schema (collections, fields) |
| Site Design Tokens | Color variables, fonts, and locales |
Managing Connections
The Connections section on the Integrations → MCP page lists every approved AI tool. Each row shows Connected (or Expired once its refresh token lapses), the date it connected, and when it was last used. Open a row’s menu and choose Revoke connection to cut the client off — it has to reconnect and approve access again.
On Ycode Cloud, connections made through the shared URL are listed there too and can be revoked from any of your sites.
Legacy URL Tokens
For clients that don’t support OAuth, expand Legacy URL tokens at the bottom of the page and click Generate URL token. Give it a Connection name (for example Windsurf) and copy the URL shown in Your MCP URL — it embeds the token (https://your-site.com/ycode/mcp/ymc_...).
URL tokens never expire until you delete them, and anyone with the URL can access the project. Prefer the OAuth URL whenever your client supports it, and treat URL tokens like API keys.