Every Core dna site answers three kinds of API request under /cdna-api: REST for everything, GraphQL for reads that span several entity types, and web events for endpoints you define yourself as jobs. Which fits which task, one worked request for each, and what is true of all three. Jobs were called hooks until the module was renamed Orchestration; the API's routes still use the old name.
L1–L3
Unit 07 · AI assistants and the MCP server
MCP, for editors and agents
AI assistants and the MCP serverPage 25 of 25Updated
Every site runs an MCP server that lets an AI assistant read and change its records and configuration, as the person who connected it. What it exposes, a configuration to copy, how it authenticates, where production belongs, and three questions to ask a site you have just inherited.
Who this is for. Any developer with an AI coding assistant, and the editors who work alongside them. Afterwards you can connect an assistant to a development site, know what it can do there and as whom, and keep production out of a shared configuration. It is not an integration surface: nothing in production should depend on it; integrations use the REST API.
The per-site MCP server
MCP, the Model Context Protocol, is a standard way for an AI assistant (Claude Code, Cursor, an editor plugin) to call tools that another system provides. The assistant is told what tools exist and what they take, and calls them as it works. Every Core dna site has an MCP server at /cdna-mcp on its own hostname, beside /cdna-api. Connect an assistant to it and the assistant can read the site's content model and records, and change them, in the conversation you are already having about your templates.
It is served by a separate service in front of the site, not by the site's pages, and speaks MCP's streamable HTTP transport. Called without credentials it answers the way an OAuth-protected MCP server should, as this documentation site does:
That header is how an MCP client finds out where to sign in: the metadata it points to names the site itself as the authorization server. You do not need to follow it by hand.
What it exposes
The tools a connection offers, grouped, with their names shortened from coredna_…. Each works on the site the URL names; list tools accept the same filters and field selection as REST.
list_layouts and mutate_layout, list_input_types and mutate_input_type, list_site_data and mutate_site_data, get_menus, mutate_menu and mutate_menu_element, list_rewrites and mutate_rewrite, mutate_taxonomy for categories and tags, list_dictionary for translations
Content
list and mutate tools for pages, blogs and posts, books and book pages, FAQ pages and questions, global components, and custom entity definitions and records; edit_content for partial edits of versioned records; duplicate_record; delete_record
products and product categories (list and mutate), product variants (mutate); orders, invoices, quotes and inventory (list)
People
users, people and groups (list and mutate)
Automation
list_jobs, mutate_job and mutate_job_action; list_job_runs, whose explain mode walks one run action by action; run_job
Feedback
submit_feedback, which reports a problem with the tools themselves
It covers records and configuration. It does not touch your repository: templates, styles and scripts are still deployed the usual way. A layout record can be created over MCP; its template file cannot.
Wiring it into an editor
For Claude Code, the configuration a whole team shares goes in .mcp.json at the root of the theme repository. Put the development site there and nothing else:
The production entry, for the people who need it, goes in their own user configuration instead, where it is not committed and not picked up by everyone who clones the repository:
Shell
claude mcp add --transport http --scope user example-production https://www.example.com/cdna-mcp
The first time the assistant calls a tool, the client opens a browser to the site's sign-in page and stores the token it gets back. There is no key to paste into the file. Other MCP clients take the same two values, a name and the URL, in their own configuration file.
The first useful request, once connected:
Use example-dev. Describe the Page entity, then list the layouts, and for each layout say how many published pages use it.
Authentication and scoping
The connection signs in with OAuth, as the person who approves it in the browser, and asks for the mcp scope. Only a backend user can approve that scope: the sign-in goes through the admin's login, and a site member is refused. The tools call the site's API with that person's token, so the assistant can do exactly what that person can do through the API, it appears as them in revision histories, and its deletes are theirs. A read-only connection is one approved by a user whose permissions are read-only.
A production endpoint does not belong in a development configuration. An assistant that is told to “tidy up the test pages” does not know which of its two servers is the test site, and a shared .mcp.json hands production to everyone who opens the repository, including their assistants. If one is already there:
Remove the entry from .mcp.json and commit that.
Ask everyone who had it to sign out of that server in their client, so the stored token is dropped.
Check production's recent revision history and job runs for changes nobody meant to make.
Add production back only in the user scope, for the people who need it, signed in as a user with the least access that does the job.
Exploring an unfamiliar site
The practical use for a site builder is exploration. When you inherit a site, reading its templates tells you what it renders; asking its MCP server tells you what it holds, which is faster and closer to the truth. Three questions worth asking in the first hour:
“Which layouts exist, which templates do they point at, and how many records use each?” Layouts that nothing uses can be retired; templates with no layout are dead code; a layout used by one page is a special case to know about.
“What custom entities are defined, with their fields and record counts?” The content model that is not in the templates' variable names, and the first thing a migration or a new feature must fit.
“Which jobs are published, what starts each, and which runs failed in the last week?” Jobs are behaviour that lives outside the repository: emails, CRM pushes, custom endpoints. They are the part of an inherited site most likely to surprise you.
Keep exploring on the development site. When the answer has to come from production, ask for lists and descriptions, and read what the assistant proposes to change before it changes anything.