Read, edit, publish, and preview your pepita websites from Claude.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
Snapshot. Factored out of the private pepita monorepo, built and released from there, and not standalone-buildable. PRs are applied in the monorepo. https://pepita.dev
Local MCP server (stdio) for pepita sites. Lets a local Claude (Claude Code / Desktop / the MCP Inspector) read and edit your sites, publish them, and manage shareable preview links β the same things you can do in the editor. Edits show up live in the pepita editor too, so you can move between the chat and the visual editor mid-task.
Prefer the hosted connector? There's a remote, OAuth-authenticated connector at
https://mcp.pepita.dev/mcpβ nothing to install, just sign in with your pepita account:(or add it as a custom connector in Claude Desktop / claude.ai). This package is the local alternative β it runs on your machine and works with any MCP client.
Authentication reuses the pepita CLI: run pepita login first (writes
~/.pepita/config.json), or set PEPITA_TOKEN. No separate OAuth.
Also listed in the MCP Registry as
dev.pepita.mcp/mcp. If your MCP client can browse the registry, find pepita
there and add it in one step; otherwise use the npx / claude mcp add setup above
(the registry entry points at the same @pepitahq/mcp package).
Forty-three tools β six that read your sites, seven that write, publish, or manage previews, three for video, one that teaches the model pepita's platform contracts, five that manage confirmation-email templates, two for the images inside one, three that read or export what visitors submitted through your forms, and fifteen for repeating content collections:
Read β list_sites, get_site_status (what a site IS: how much of it there
is, which platform features it already uses, what is pending β one cheap call,
and the one to make first), list_site_files, read_site_file, list_previews,
read_served_page (what a VISITOR gets for an address β the response, not the
file, and the only way to tell whether an item's own page serves anything),
list_videos
Write β create_site (a brand-new site, live immediately with starter content),
write_site_file (into the working copy), delete_site_file (out of it β a file
written by mistake could only be overwritten before), publish_site (β live), and preview
links: create_preview, update_preview (push the current site onto an existing
link), delete_preview
Video β rename_video (display label only β the id and URLs never change, so
pages referencing the video keep working), get_video_original_url (an
expiring download link for the uploaded original), delete_video (removes
the video and stops its streams)
Guide β get_building_guide (the platform contract for a topic β overview,
forms, confirmation-emails, video, headers-and-csp, dynamic-content β
read before writing any of them)
Email templates β list_email_templates, read_email_template (envelope +
body), write_email_template (upsert by form name; updating an existing
template changes the WORKING COPY only, a brand-new one is saved as it is
created), save_email_template (makes the working copy the version people
receive β the same act as the editor's Save button on the template's row),
delete_email_template (confirmation emails for that form stop immediately)
Template images β list_email_template_images (what a template holds, each
with the public URL to reference in an <img src>), delete_email_template_image
(by that name β if the body still references it, the picture breaks in the next
email that goes out). There is no upload tool: an assistant has no practical
way to hand over image bytes, so uploading is yours to do with the CLI
(pepita email template image add) or in the editor's Forms tab
Form submissions β get_form_records_count (every form that has received a
submission, with how many it holds β counts cover every source together),
list_form_records (one form's submissions, newest first; reads the editor
preview's own test submissions by default, live: true for the published
site, preview: "<name>" for one preview link. Over 100 matching records it
returns the COUNT instead, so the assistant can ask before filling your screen
β confirm_large: true then returns them all. A form holds at most 1000
entries in total, and one whose entries carry more than 50 different field
names can only be read as a file), get_form_export_url (a link to download
one form's submissions as xlsx, csv or json β same source selection and
the same editor-preview default as list_form_records, so the two tools never
disagree about which rows they mean; the link expires in 15 minutes)
Content collections β repeating structured content: a blog, a menu, a team
page. Two halves, and they are separate tools. The SHAPE:
list_content_templates, read_content_template (the complete HTML document for
ONE item β markup only: every <style>, <script> and <link> in it is
dropped, silently), write_content_template (a brand-new one is saved as it is
created; changing an existing one writes the working copy until
save_content_template), save_content_template, delete_content_template (the
items survive β writing a template with the same name again brings them back).
A collection's LOOK and BEHAVIOUR are two files it owns, not part of any
template: read_content_file and write_content_file, addressed by the name
the owner sees β style.css or script.js. One of each per collection,
applying to every layout, because two layouts start life as copies of each
other and two stylesheets defining the same class names would fight over which
wins. Write the script as if it runs ONCE for the whole page: loop over the
items, and get per-item values from data attributes in the template.
The ITEMS: list_content_records, add_content_records (an ARRAY, so many in one
call β all of them land or none do, and a refusal names every bad item by its
position), update_content_record (the WHOLE item, not a patch),
delete_content_record, publish_content_record, unpublish_content_record.
And a record's PICTURES: add_content_image (fetch one from a public web
address) and get_content_image_upload_url (a short-lived link to send a file
from this machine). Both answer with a pepita address, which is the only thing an
{{image:}} field accepts.
A collection can have several layouts β a card for a list page where the
default is a full article. Each of the four content-template tools that act on a
template takes an optional layout β list_content_templates reports them
instead. Leaving it out addresses the default one, which is the template itself.
A page picks a named one with variant="β¦" on the tag. Deleting WITH a layout
removes only that shape; without one it removes the template and every layout
with it.
Everything a collection owns waits together, and ONE save promotes it. A
layout's markup, style.css and script.js are all working copies until
save_content_template is called with no layout β that promotes the whole
collection at once. With a layout it promotes just that one. This is not
ceremony: a collection's parts are edited together, so promoting them one at a
time leaves the live site rendering a layout against a stylesheet that does not
match it. The save is not atomic, so it reports what landed and what did not β
a partial result is a real answer, never rolled back.
Three things to know. The name is the pairing β a page shows a collection
through <pepita-content mode="list" name="blog">, which is an ordinary site
file you write with write_site_file, and the name must match the template's or
the page renders the static markup inside the tag and nothing else, with no error
anywhere. Every item needs a title β it is what the item's web address is
made from, and pepita mints the last few characters itself, so never invent an
address. And a new item is a draft: it shows in the editor and on preview links, and reaches the live site only when published. There is no site-wide publish
step, unlike every other write here.
list_site_files / read_site_file read the working copy by default, the live
site (state: "live"), or a specific preview link (preview: "<name>").
Destructive / account-level actions (custom domains, team, billing, deleting a site) are deliberately not exposed β those stay in the editor UI, where their confirmations live. Creating a site IS exposed (it destroys nothing); deleting one is not. (Deleting a preview link is exposed: it only stops serving, and the version stays restorable from History.)
pepita sites come with forms, confirmation emails, video and analytics built
in β the server's instructions tell the model to offer them and to call
get_building_guide before writing any of their file contracts.
If the server has moved past this package's version, every tool result carries one extra line naming the newer minimum and the command to update. The CLI prints its equivalent on stderr once the command finishes; a server is long-lived and has no "after the run" moment, so the notice rides inside each result instead. It is a notice, never a block β nothing stops working because of it. The hosted connector never shows it: it ships with its own deploy, so it cannot be behind.
PEPITA_TOKEN β bearer token (overrides the config file).PEPITA_API_BASE β API host (default https://app.pepita.dev).PEPITA_CONFIG_DIR β config dir (default ~/.pepita).Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/pepita)<a href="https://allmcps.com/mcp/pepita"><img src="https://allmcps.com/api/badge/pepita?style=directory" alt="Pepita on AllMCPs" /></a>