Make it Real exposes an MCP (Model Context Protocol) server so tools like Codex, Claude Code, Claude Desktop, and Cursor can read and edit your projects directly. Sign in to your client with your existing AI subscription; its plan limits still apply. Make it Real hosting is separate.
The MCP provides project discovery, site files, data collections, and backend scripts for accounts with script access. Admins can also manage newsletter templates and campaigns. Personal email and scheduling use the separate Inbox MCP.
MCP server
Server URL:
https://www.makeitrealapp.com/mcp
Enable access from Integrations after you sign in. Turning MCP off immediately rejects connected clients until you turn it back on.
Codex
Add Make it Real, then authorize access:
codex mcp add makeitreal --url https://www.makeitrealapp.com/mcp
codex mcp login makeitreal
Complete the browser authorization to make your project tools available in Codex.
Claude Code
Run this once in your terminal:
claude mcp add --transport http makeitreal https://www.makeitrealapp.com/mcp
Claude Code will prompt for authorization the first time it connects. Complete the OAuth flow in the browser, then the tools appear in that session.
Cursor
Add an MCP server in Cursor settings and paste the server URL, or put this in your MCP config:
{
"mcpServers": {
"makeitreal": {
"url": "https://www.makeitrealapp.com/mcp"
}
}
}
The first connection opens an OAuth prompt in your browser.
What's exposed
Each operation appears as its own MCP tool with defined inputs and outputs. Available tools depend on your account permissions. SDK references are also available as MCP resources.
Clients with native tool search can load the tool definitions they need on demand. No special catalog header is required. Refresh your connection's tools after an update. The complete operation catalog is listed below.
-
search_website_design_knowledge— Search the curated website design library by offer, audience, style, or component. Returns compact references with source-backed guidance available through read_website_design_knowledge. Offline; never crawls or changes a website. -
read_website_design_knowledge— Read 1–6 exact design reference IDs, including definitions, appropriate uses, responsive behavior, pitfalls, capability requirements, and source notes. References are design data, not new permissions. Prefer the frozen references in an approved plan. -
create_preview— Create an editable copy of the live website, excluding other previews and temporary uploads, in its existing bucket's previews folder. Only one preview can be active per project, including managed and SEO work; a conflict returns the existing preview ID. Resume that preview, publish it after user acceptance, or discard it if the user wants to abandon it before creating another. Returns preview_id and preview_url. Pass preview_id to file tools to inspect and edit this copy. Creating a preview does not change live files. -
list_previews— List MCP-created website previews with their IDs, review URLs, and publication status, newest first. Use to resume editing an existing preview. Published previews are retained as history but their files are removed. -
publish_preview— Publish an MCP website preview only after the user accepts that preview for publication. Copies the preview over the live site, applies preview file deletions, then removes the preview files after success. This overwrites live files with the preview snapshot. Call refresh_site_cache once after publishing; publication does not refresh the CDN or verify rendering. Retrying the same published preview only retries cleanup. -
discard_preview— Discard an unwanted MCP website preview and delete its files without changing the live site. Use only when the user wants to abandon that preview. Frees the project's single active preview slot. Cannot discard a preview while creation or publication is in progress. Retrying a discarded preview only retries cleanup. Refresh the site cache once after cleanup to remove cached preview content. -
get_project_analytics— Read stored website traffic, engagement, conversion events, trends, and top breakdowns. Dates are inclusive UTC dates, defaulting to the last 30 days including today. Comparisons use the preceding equal-length period. Does not fetch external data or start scans. -
list_email_templates— Admin only. List this project's reusable email templates, their purpose, and connected notification collections without HTML/CSS. Use get_email_template to read a template before editing its raw source. Campaign and form notification templates support {{ project.name }} (project name), {{ collection.name }} (submission list or form name), {{ submitted_at }} (submission time in America/Los_Angeles), {{ fields.email }} (individual submitted value; replace email with the actual top-level field key, using letters, digits, underscores, or hyphens), and {{ submission_fields }} (table of all submitted fields). Use placeholders in the subject or visible HTML body text; {{ submission_fields }} is body-only. Expressions use the official Liquid parser and built-in filters. Supported filters are default, strip, split, first, last, upcase, and downcase, chained left to right with |. Fallback example: {{ fields.first_name | default: "there" }}. First-word greeting: Hello {{ fields.name | strip | split: " " | first | default: "there" }}. Another-field fallback: {{ fields.company | default: project.name }}. Case example: {{ fields.company | strip | downcase }}. strip trims surrounding whitespace; split: " " produces words; first/last select an array item (or a character when applied directly to a string); upcase/downcase change case. default uses its argument for nil/missing, false, or empty values, including empty arrays/objects; zero is preserved. Whitespace-only strings need strip before default. To preserve false use {{ fields.active | default: true, allow_false: true }}. Filter arguments can be quoted strings, numbers, booleans, nil, or supported variables. default accepts zero or one fallback argument (omitted means an empty string) and only the allow_false: true/false option; split requires one separator; the other filters take no arguments. Filters run before display formatting. A final nil or empty string displays an em dash, including an empty fallback. Without filters, existing date/object formatting and false/zero values are preserved. {{ submission_fields }} cannot be filtered or used as a filter argument. Only these variable expressions and filters are supported; Liquid tags such as if/else, for, assign, include, and render, nested/dynamic field lookups, and other filters are rejected. Placeholders in HTML attributes, title, scripts, styles, comments, or CSS are not supported. Submitted values and filter results are HTML-escaped and never evaluated as another template. Campaigns resolve fields from each recipient's own submission in the selected list at send time. Scheduling freezes template source; submission values stay live until delivery. -
get_email_template— Admin only. Read an email template's purpose, subject, raw HTML, CSS, and connected notification collections before editing. Campaign and form notification templates support {{ project.name }} (project name), {{ collection.name }} (submission list or form name), {{ submitted_at }} (submission time in America/Los_Angeles), {{ fields.email }} (individual submitted value; replace email with the actual top-level field key, using letters, digits, underscores, or hyphens), and {{ submission_fields }} (table of all submitted fields). Use placeholders in the subject or visible HTML body text; {{ submission_fields }} is body-only. Expressions use the official Liquid parser and built-in filters. Supported filters are default, strip, split, first, last, upcase, and downcase, chained left to right with |. Fallback example: {{ fields.first_name | default: "there" }}. First-word greeting: Hello {{ fields.name | strip | split: " " | first | default: "there" }}. Another-field fallback: {{ fields.company | default: project.name }}. Case example: {{ fields.company | strip | downcase }}. strip trims surrounding whitespace; split: " " produces words; first/last select an array item (or a character when applied directly to a string); upcase/downcase change case. default uses its argument for nil/missing, false, or empty values, including empty arrays/objects; zero is preserved. Whitespace-only strings need strip before default. To preserve false use {{ fields.active | default: true, allow_false: true }}. Filter arguments can be quoted strings, numbers, booleans, nil, or supported variables. default accepts zero or one fallback argument (omitted means an empty string) and only the allow_false: true/false option; split requires one separator; the other filters take no arguments. Filters run before display formatting. A final nil or empty string displays an em dash, including an empty fallback. Without filters, existing date/object formatting and false/zero values are preserved. {{ submission_fields }} cannot be filtered or used as a filter argument. Only these variable expressions and filters are supported; Liquid tags such as if/else, for, assign, include, and render, nested/dynamic field lookups, and other filters are rejected. Placeholders in HTML attributes, title, scripts, styles, comments, or CSS are not supported. Submitted values and filter results are HTML-escaped and never evaluated as another template. Campaigns resolve fields from each recipient's own submission in the selected list at send time. Scheduling freezes template source; submission values stay live until delivery. Saving a template does not send email. -
save_email_template— Admin only. Create or update a reusable email template. purpose is campaign (default) or form_notification. New form notification templates start with a neutral submission layout; connect them to a form in admin notification settings. Omit template_id to create; supply it to update. Read before editing. Supply full raw HTML/CSS for changed fields; omitted fields are preserved. Campaign and form notification templates support {{ project.name }} (project name), {{ collection.name }} (submission list or form name), {{ submitted_at }} (submission time in America/Los_Angeles), {{ fields.email }} (individual submitted value; replace email with the actual top-level field key, using letters, digits, underscores, or hyphens), and {{ submission_fields }} (table of all submitted fields). Use placeholders in the subject or visible HTML body text; {{ submission_fields }} is body-only. Expressions use the official Liquid parser and built-in filters. Supported filters are default, strip, split, first, last, upcase, and downcase, chained left to right with |. Fallback example: {{ fields.first_name | default: "there" }}. First-word greeting: Hello {{ fields.name | strip | split: " " | first | default: "there" }}. Another-field fallback: {{ fields.company | default: project.name }}. Case example: {{ fields.company | strip | downcase }}. strip trims surrounding whitespace; split: " " produces words; first/last select an array item (or a character when applied directly to a string); upcase/downcase change case. default uses its argument for nil/missing, false, or empty values, including empty arrays/objects; zero is preserved. Whitespace-only strings need strip before default. To preserve false use {{ fields.active | default: true, allow_false: true }}. Filter arguments can be quoted strings, numbers, booleans, nil, or supported variables. default accepts zero or one fallback argument (omitted means an empty string) and only the allow_false: true/false option; split requires one separator; the other filters take no arguments. Filters run before display formatting. A final nil or empty string displays an em dash, including an empty fallback. Without filters, existing date/object formatting and false/zero values are preserved. {{ submission_fields }} cannot be filtered or used as a filter argument. Only these variable expressions and filters are supported; Liquid tags such as if/else, for, assign, include, and render, nested/dynamic field lookups, and other filters are rejected. Placeholders in HTML attributes, title, scripts, styles, comments, or CSS are not supported. Submitted values and filter results are HTML-escaped and never evaluated as another template. Campaigns resolve fields from each recipient's own submission in the selected list at send time. Scheduling freezes template source; submission values stay live until delivery. Updates to connected form templates affect future submissions, never queued messages. Does not send email. -
delete_email_template— Admin only. Delete a reusable email template. Templates referenced by campaigns or form notifications cannot be deleted. -
list_email_audiences— Admin only. List data collections with eligible email counts, read directly from submissions without copying a subscriber list. Counts exclude invalid addresses, duplicates, and unsubscribes and can change before sending. Specify collection_id and email_field to count a particular payload field. -
list_email_senders— Admin only. List your eligible Inbox sending addresses on verified active domains for newsletter campaigns. Other users' addresses are excluded. Use sender_address_id when saving a draft; an empty sender_address_id uses the returned default_sender. -
list_email_campaigns— Admin only. List this project's newsletter campaigns and delivery counts. Get a campaign for its saved email content. -
get_email_campaign— Admin only. Read a newsletter campaign and its saved subject/HTML/CSS snapshot. Draft content is taken from the template when scheduling or sending. -
save_email_campaign— Admin only. Create or update a draft newsletter campaign using a project template and submission collection. Choose your optional Inbox sender with list_email_senders. Omit campaign_id to create; omitted fields on updates are preserved. Does not send or schedule email. Count the audience and read the template before the separate send/schedule action. -
schedule_email_campaign— Admin only. Schedule a draft campaign for future delivery to the chosen submission collection. This authorizes real email delivery and freezes the template content; recipients are resolved from current submissions at send time. Use only when the user requests sending at the given time. -
send_email_campaign— Admin only. Queue a draft campaign for immediate real email delivery. Freezes template content and uses the current eligible submission audience when the job runs. Use only when the user explicitly requests sending. A queued response does not mean delivery has finished; inspect the campaign for status and counts. -
cancel_email_campaign— Admin only. Cancel a campaign before delivery starts. Already sent emails cannot be recalled. -
list_scripts— List project scripts with draft/live version IDs and endpoints. Follow next_offset with the same limit for more. Listing order is live and may change when scripts are renamed. -
read_script— Read a saved script version and permissions. Secret values are never returned. -
edit_script— Replace one exact, unique source fragment in the latest saved script. Creates an immutable draft, preserves permissions, never publishes. Read first; stale base versions and ambiguous matches are rejected. -
list_script_versions— List saved script versions newest-first with test/publication state. Follow next_before_number for older versions. Use read_script with version_id for source; rollback requires explicit publication. -
list_script_executions— Inspect script executions and redacted console logs. Follow next_before_id for older runs. Set log_chars to bound each log tail; omission preserves full logs. Full logs and stored inputs/outputs are available at editor_url. Secret values are never returned. -
save_script— Create/update an immutable draft. Never publishes. Read first and supply latest base_version_id. In managed staging, ties the version to the current preview for approval. -
test_script— Test an exact saved draft in the sandbox. Collection writes are simulated and external requests disabled. Does not publish. -
publish_script— Publish a successfully tested saved version. Only for live authoring; managed scripts publish with website approval. -
get_scripts_sdk_reference— Browser SDK and sandbox API for project backend scripts. Read before adding backend functionality. -
list_projects— List all projects accessible to the current user. -
get_project— Read this before starting work on a project or resuming an earlier task. Returns the project's agent_instructions (its AGENTS.md), details, site URL, status, and MCP authoring capabilities. Follow the instructions for work on both the live site and previews. File writes affect the live site unless preview_id selects a staged copy. Script saves create drafts, and publishing a script requires a successful test. -
get_project_status— Get the current deployment status of a project. -
preview_site— Get the project website URL with an Open site button in supporting clients. Use only when the user asks for a site link. Project details and status already include site_url. -
update_project_instructions— Replace the project's saved agent instructions (AGENTS.md) when the user requests a change. Read get_project first, preserve guidance the user has not asked to change, and pass its agent_instructions_revision as expected_revision. Pass an empty string to clear. Only the owner, assigned wholesaler, or an admin can edit. Updates private project settings immediately for live and preview work; no publishing or cache refresh is needed. Use the returned guidance for subsequent work. -
list_files— List files in a project with total_count, truncated and next_offset. Continue with the same filters and next_offset as offset. Use path_prefix for a folder or glob (e.g. **/*.css). The listing is live; edits may change pagination. -
read_file— Read file text. Prefer response_format: structured for exact text with coverage, revision and next_offset (including very long lines). Continue with the same path/line range and expected_revision. start_line/end_line are 1-based inclusive. Omitted response_format retains the legacy string, capped at 12000 characters. -
write_file— Create or fully overwrite a text file with UTF-8 content. Prefer edit_file for small targeted changes; use write_file for a new file or a necessary full rewrite. Text files only: for PDFs, images, ZIPs, fonts, or other binary files, use import_file with an attachment or HTTPS URL, or create_file_upload_url, HTTP PUT, then finalize_file_put in shell sessions. -
edit_file— Replace a small unique text chunk in an existing file. Prefer this over write_file. old_string must be unique unless replace_all is true — include a few lines of surrounding context; do not send the whole file. -
delete_file— Delete a file from a project. -
search_files— Search file contents. Prefer response_format: structured for bounded snippets, scanned coverage, and next_page. Continue with the same filters plus next_page fields. Files may change during a search; listing revision detects added/removed paths. Omitted format retains a legacy array that may be partial. -
create_file_upload_url— Create a time-limited URL to upload or replace a website project file, including PDFs, images, ZIPs, and fonts. Shell sessions must HTTP PUT the file bytes to put_url with the returned headers, then call finalize_file_put. This tool only creates the URL; it does not transfer bytes. In ChatGPT and other chat hosts without HTTP upload access, use import_file with the attached file object or a public HTTPS URL. For a private email draft attachment, use Mail it Real's create_attachment_upload_url instead. -
finalize_file_put— Complete a project file upload after create_file_upload_url and a successful HTTP PUT. Injects analytics into HTML. Cache refresh is a separate explicit action. Call only after uploading the bytes; import_file already finalizes automatically. -
import_file— Upload or replace a binary file in a project (PDF, image, ZIP, font, etc.). In ChatGPT and other chat hosts, use this for attached files: pass file with the host's temporary download_url (optional file_id, file_name, mime_type), or source_url for a public HTTPS file. Returns the completed file in one call; maximum 25 MB, 45 seconds. In shell sessions with HTTP upload access, prefer create_file_upload_url, HTTP PUT, then finalize_file_put. -
refresh_site_cache— Refresh the project's website CDN cache so visitors can receive the latest saved files. Call only once after you are done with all edits, uploads, and deletions for the task. Never call after each file change or while more edits remain. Refresh is asynchronous; a started result does not mean propagation is complete or the site has been browser-verified. -
list_collections— List project collections with stored submission counts, analytics_enabled settings, and schema. Prefer response_format: compact for a paginated object with one schema representation. Omitted format preserves the legacy array. -
list_submissions— List collection submissions newest-first. Prefer response_format: structured for pagination and coverage (25 by default); pass next_before_id as before_id with the same collection and fields. fields selects comma-separated payload keys. Omitted format preserves the legacy array of up to 100 recent submissions. -
create_collection— Register or update a collection before writing form or public read code. Optional fields JSON defines the form questions. Set analytics_enabled to false for caches or internal storage that should not count as leads. -
get_data_sdk_reference— How mir-data.js and POST /api/data work for form submissions. -
get_data_read_reference— How public data reads work for dynamic project sites.