- Add the server.
https://yeja-ai.com/mcp. Add no key and no header. You do this once, and it works for any profile. - Give your agent your profile and a key. In the chat, paste your profile link and a key from Developer Access, for example "Connect to my Yeja profile https://yeja-ai.com/atelier/<your-username> with key yeja_atl_…". The agent connects with
connect_profile, and every result names the profile it is working on. - Ask for something. "Show me my Atelier and suggest three improvements."
Changes wait for you. An agent stages a draft; you preview it and press Publish. Two kinds of change are live the moment they run: the curation tools, which need the separately ticked atelier:curate permission, and the two undo tools (restore_snapshot, rollback_freeform),
reset_atelier_theme, unpublish_freeform and unpublish_atelier. Every live tool is marked in the tool list.
Prefer signing in to pasting a key? Use https://yeja-ai.com/mcp/oauth and approve in the browser. See Keys and Sign-In.
Install
Your Atelier is your public artist page at https://yeja-ai.com/atelier/<your-username>. The server is https://yeja-ai.com/mcp, and it speaks MCP over POST only (streamable HTTP, no SSE stream).
Every client gets the same entry: the address and nothing else. No key goes in the settings, so one install serves every profile, and the agent connects a profile at the start of each chat. Every client wants a slightly different shape, and four of them fail silently when given the wrong one. Use your own client's section, not the nearest-looking one.
Claude Code
claude mcp add --transport http yeja-atelier https://yeja-ai.com/mcpThen start a chat and give the agent your profile link and key.
Do not add --header "Authorization: …". A key in the settings ties the server to that one account in every chat. Any Authorization header also turns off OAuth fallback in Claude Code, and the header is read once when the process starts, so changing it later means restarting Claude Code. To sign in instead of using a key, add https://yeja-ai.com/mcp/oauth, then run
/mcp, pick the server and choose Authenticate.
Claude Desktop and Claude.ai
Add it as a custom connector: open Connectors in Claude's settings, press +, choose Add custom connector, paste https://yeja-ai.com/mcp and press Add. Then start a chat and give Claude your profile link and key. The same connector is available in Claude Desktop and on claude.ai, and it works for any profile.
If an older Yeja connector is signed in, it can only ever work on the account it signed in as. Check the account on the dashboard's Connected Agents list, and remove the connector if it is not yours.
Custom connectors are available on every Claude plan; the Free plan allows one. On Team and Enterprise, an organization Owner adds the connector first and members then press Connect.
Advanced: A Key In The Settings
Claude Desktop's config file cannot send a custom header to a remote server, so a key needs the mcp-remote bridge:
{
"mcpServers": {
"yeja-atelier": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://yeja-ai.com/mcp",
"--header", "Authorization: Bearer yeja_atl_YOUR_KEY_HERE"
]
}
}
}Cursor
{
"mcpServers": {
"yeja-atelier": {
"url": "https://yeja-ai.com/mcp"
}
}
}In ~/.cursor/mcp.json, or .cursor/mcp.json inside a project. Remote entries need no type field. Then give the agent your profile link and key in the chat.
Advanced: A Key In The Settings
{
"mcpServers": {
"yeja-atelier": {
"url": "https://yeja-ai.com/mcp",
"headers": { "Authorization": "Bearer yeja_atl_YOUR_KEY_HERE" }
}
}
}The dashboard's Developer Access card also has a one-click install link for Cursor, which is easier than editing this file.
VS Code and GitHub Copilot
{
"servers": {
"yeja-atelier": {
"type": "http",
"url": "https://yeja-ai.com/mcp"
}
}
}In .vscode/mcp.json, or in your user configuration (MCP: Open User Configuration). Note this client uses servers, not mcpServers. Then give the agent your profile link and key in the chat.
Advanced: A Key In The Settings
{
"inputs": [
{
"type": "promptString",
"id": "yeja-key",
"description": "Yeja Atelier API Key",
"password": true
}
],
"servers": {
"yeja-atelier": {
"type": "http",
"url": "https://yeja-ai.com/mcp",
"headers": { "Authorization": "Bearer YEJA_KEY_PLACEHOLDER" }
}
}
}Replace YEJA_KEY_PLACEHOLDER with an input reference so VS Code prompts for the key rather than storing it in the file: a dollar sign, then
{input:yeja-key}. The dashboard's Developer Access card also has a one-click install link for VS Code.
Codex CLI
codex mcp add yeja-atelier --url https://yeja-ai.com/mcpThen give the agent your profile link and key in the chat.
Advanced: A Key In The Settings
codex mcp add yeja-atelier --url https://yeja-ai.com/mcp \
--bearer-token-env-var YEJA_API_KEYCodex takes the NAME of an environment variable, not the key itself. Set
YEJA_API_KEY in your shell to the key, and pass the name here. Pasting the key where the name belongs fails in a way that does not say so. A bearer token takes precedence over sign-in when both are set. The file form, in
~/.codex/config.toml:
[mcp_servers.yeja-atelier]
url = "https://yeja-ai.com/mcp"
bearer_token_env_var = "YEJA_API_KEY"Antigravity and Windsurf
{
"mcpServers": {
"yeja-atelier": {
"serverUrl": "https://yeja-ai.com/mcp"
}
}
}Use serverUrl, not url. serverUrl works in both clients, while some versions ignore a plain url for a remote server, and an ignored entry looks exactly like a server that is not responding.
Antigravity reads ~/.gemini/config/mcp_config.json. Windsurf is now Devin Desktop, which reads ~/.config/devin/mcp_config.json. Then give the agent your profile link and key in the chat.
Advanced: A Key In The Settings
Add "headers": { "Authorization": "Bearer yeja_atl_YOUR_KEY_HERE" } beside
serverUrl.
Zed
{
"context_servers": {
"yeja-atelier": {
"url": "https://yeja-ai.com/mcp"
}
}
}Zed calls them context_servers, not mcpServers. Open the file with zed: open settings file. Then give the agent your profile link and key in the chat.
Advanced: A Key In The Settings
Add "headers": { "Authorization": "Bearer yeja_atl_YOUR_KEY_HERE" } beside
url.
Cline
{
"mcpServers": {
"yeja-atelier": {
"type": "streamableHttp",
"url": "https://yeja-ai.com/mcp"
}
}
}Then give the agent your profile link and key in the chat.
streamableHttp is case-sensitive. Writing streamable-http, or leaving
type out, makes Cline fall back to SSE, and this server answers SSE with a 405 that does not explain itself.
Check It Works
curl -s -X POST https://yeja-ai.com/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'A list of tools coming back means the server is reachable. The agent then connects a profile in the chat; until it does, every tool except the connection tools answers not_connected. A 401 means a key in your client's settings is wrong or revoked.
Keys and Sign-In
One profile per chat, named every time. At the start of each chat the agent passes your profile and a key to connect_profile. The server checks that the key belongs to that profile and refuses anything else, and every result carries
acting_as, the profile it is working on. If it is not the profile you meant, stop the agent. One chat works on one profile: to work on another, start a new chat.
To create a key:
- Open https://yeja-ai.com/dashboard/?app=profile&view=portfolio
- Scroll to Developer Access
- Name the key after the agent or computer that will use it.
- Both boxes start ticked: Allow This Key To Propose Changes and Allow This Key To Change Pinned Works Immediately. Untick what you do not want; with both unticked the key is read-only.
- Press Create API Key and copy the key immediately. It is shown once.
A key does not expire, and you can hold up to 10. Creating a key never touches the others. Revoke one on its own from the same card, and every chat it connected stops at once. Connected Agents, on the same page, lists every chat and signed-in app using your Atelier, with Disconnect for each.
Signing in instead (OAuth 2.1). A client that supports it can use
https://yeja-ai.com/mcp/oauth. You approve on a consent screen that shows the account you are signing in as, with Switch Account if it is the wrong one. That connection belongs to that account: the agent still connects the profile, and any other profile is refused. Access renews itself every hour; if the client goes unused for 30 days, you sign in again.
A key in the client's settings (Authorization: Bearer yeja_atl_…, under Advanced in each client's section) still works, and ties that entry to one account in the same way. Name such an entry after the profile, for example
yeja-atelier-<username>.
| Permission | What it lets an agent do | Sign-in starts | Key starts |
|---|---|---|---|
Read (atelier:read) | See your Atelier, works, drafts and measurements. Changes nothing. | Always on | Always on |
Propose (atelier:write) | Stage drafts, build Freeform pages, import an image with your permission, and restore or roll back your live page | Ticked | Ticked |
Curate (atelier:curate) | Change pins, hero, timeline, custom sections, products and theme listings, most of them live | Unticked | Ticked |
What an Agent Can Change
An agent cannot publish. It stages; you press Publish in your dashboard. The only way anything reaches your public page without that is a tool marked Live below.
| Staged: waits for Publish | Live: changes your public page immediately |
|---|---|
Headline, bio, layout, palette, banner and SEO fields (propose_atelier) | Pins and hero (pin_artwork, reorder_pins, set_hero…) |
Custom CSS (propose_custom_css) | Timeline entries and custom sections, edited one row at a time |
| Freeform pages, including clones | Products and theme listings, once set to available |
Whole collections through stage_collection | restore_snapshot, rollback_freeform, reset_atelier_theme, unpublish_freeform and unpublish_atelier |
Pins, timeline, sections and products can be changed two ways. The staged way,
stage_collection, sends the whole intended list and waits for Publish;
get_staged_collection reads back what to edit. The older per-row tools take effect at once. Prefer the staged way, and ask for it by name: "stage this, don't publish it."
Undo
A snapshot is taken automatically before every publish. restore_snapshot rolls your live page back to one, takes a snapshot of the current state first so the restore can itself be undone, and clears any pending draft. A good agent confirms with you before calling it.
For a Freeform page, rollback_freeform re-publishes an earlier version through the full publish gate. An artwork you have deleted since does not come back.
Staged work you no longer want: discard_staged_rows and
discard_freeform_draft. Your live page is untouched by both.
To start the theme over, reset_atelier_theme puts your Atelier back on the default Yeja theme: palette, type, corner radius, background and custom CSS are cleared, and an installed or agent-built Freeform page is taken down and its draft discarded. Your works, statement, timeline, sections and widgets stay. Called without confirm: true it only lists what would change. It snapshots first, so restore_snapshot undoes it, except a discarded Freeform draft.
To take only the Freeform page down, unpublish_freeform puts visitors back on the classic Atelier and keeps the draft and every version; rollback_freeform brings it back. To take the whole Atelier offline, unpublish_atelier does what Unpublish Atelier in the dashboard does: nothing is deleted, and only you can publish it again. Both are dry runs until called with confirm: true.
What Curation Refuses
- Pinning a work with no published image. It would render as a blank card. Publish the image in My Studio first.
- Pinning a trashed work.
- A partial reorder.
reorder_pinsneeds every pin named, in order. - Deleting a product with orders. Archive it instead.
remove_timeline_entry cannot be undone; remove_section can, with
restore_section.
What to Ask For
Once connected, talk to your agent normally:
- "Build out my whole Atelier. Ask me for anything you need."
- "Read my Atelier and tell me what a first-time visitor sees."
- "My work is quiet and monochrome. Propose a palette and layout that match."
- "Rewrite my headline to be less generic. Keep it under 80 characters."
- "Make my Atelier look like this site: <address>. Take the layout, not the art."
Many clients also list this server's six ready-made prompts, such as interview_artist and rebuild_from_reference, in their prompt or slash-command menu.
It Should Interview You First
A good agent starts with six questions: what the page is for, who lands on it, what a visitor should do, how it should feel, what must appear, and which sites you want it to resemble. About two minutes. An agent can see your artworks but none of that, and that is what decides the layout.
draft_from_reference refuses to build until the six are answered. Say plainly that you want to skip the questions and the agent can proceed; that it did is recorded. replicate_site does not wait: it fills only the answers you have not given with provisional ones, marked in your dashboard as the agent's and not yours, so check and correct them. Your answers are saved, so the interview happens once; say "start over" to rethink the page. None of this is public.
Filling the Whole Atelier
Ask for everything and a good agent fills every surface, not just the banner and a grid:
| Surface | What goes there |
|---|---|
| Banner + headline | An image of yours, or a Yeja pattern, with the line that sits over it |
| Pinned Showcase | The works you want seen first, in order |
| Artist Statement | The writing, plus an image beside it |
| Medium & Process | Up to three images, each with a note on how you work |
| Professional Timeline | Exhibitions, residencies, study, commissions |
| Skills & Technical Stack | Tools, mediums and specialized capabilities |
| Verifiable Collaborations | Projects with another artist, shown once both confirm |
| Get In Touch | The contact panel and its actions: Create An RFP, Share Profile, Export CV As PDF, Send A Quick Inquiry |
| Social Links | Where else your work lives |
| Support | Monthly pledges from people who follow your work |
| Atelier Style | Palette, type, corner radius and background pattern |
A section you fill but never switch on stays invisible, so an agent should turn on whatever it populates. And it should ask you for anything it does not have (dates, collaborators, a statement) rather than writing something plausible. A made-up exhibition history is worse than an empty one.
Custom Sections
| Type | For |
|---|---|
rich_text | An about section, a teaching philosophy, a positioning statement |
announcement | One upcoming thing, with an image: a workshop, a launch, an opening |
event_list | Several dates: a workshop calendar, a tour, a run of classes |
offer_list | Classes, courses, prints, books: a name, a description and a price |
testimonials | Quotes from people you have actually taught or worked with |
faq | Questions you answer often: what to bring, who it is for |
image_row | Process shots, a lookbook, a gallery |
Your agent is instructed by the server never to invent a testimonial, a price, a class date, a venue or a credential. Without the real thing from you, it leaves the section out and says so. Still read anything an agent writes about facts before you keep it.
Products and Themes
Selling through Yeja is coming soon. The Yeja Wallet is under development; once it is live, you will be able to sell your work and your themes directly through Yeja. Until then, point visitors at wherever you already sell.
Products (a class, a course, a workshop seat, a book, a print, a download) can be created, priced and shown on your page. Put an outside shop link in
external_url. New products start as drafts, invisible until set to available.
Atelier Themes: package_current_freeform_as_theme turns your published Freeform design into a listing with your artworks, bio and products replaced by marked placeholders. It starts as a draft; show_theme_listing puts it on Art Board, where other artists can browse it. Visitors who want it can reach you through your Atelier's "Request a Theme" link.
install_theme writes a purchased theme into the buyer's own Freeform draft, never their live page.
Seeing and Measuring the Page
inspect_atelier_renderscreenshots your page at desktop, tablet and mobile, in light or dark. It shows the published page by default, whether that is your standard Atelier or a published Freeform page, and says which inlive_mode. Passpreview: trueto screenshot your unpublished standard draft, orfreeform: truefor your Freeform draft.inspect_layout_metricsfinds sideways scrolling, failed images and heading skips.inspect_accessibilitymeasures contrast on the colors that actually painted; run it in both themes.create_preview_linkmakes a link to your staged standard-Atelier draft, rendered exactly as visitors would see it, with a banner across the top. It refuses when nothing is staged, and it does not show staged collections (compare_public_and_draftlists those). It lasts 24 hours by default, 7 days at most, and is revoked the moment you publish or discard that draft.atelier_auditranks what to fix. When your live page is a Freeform page, it also checks that page for unfilled placeholder text.analyze_artworksreports pixel size, 300dpi print size and dominant color for your images; videos are listed as skipped, not as failures. The centimeters on an artwork are what you entered; they are never derived from the file.get_atelier_viewsreports visits, sources and countries. It says "no data yet" rather than zero for pages older than 2026-08-26, has no per-artwork numbers, and stores no raw IP address or browser string.
Search and Sharing (SEO)
inspect_seo reports what a crawler and a link preview receive, including a missing share image and any drift between your saved SEO fields and the page.
propose_seo suggests values from your own bio, skills and pinned works and writes nothing; an agent stages them with propose_atelier, and nothing reaches a crawler until you press Save SEO yourself.
Writing Copy
There is no language model behind this server; your agent writes, and the server checks. check_copy says whether a line survives the save unchanged: a headline is at most 80 characters of plain text, a bio at most 600 characters with simple formatting. review_alt_text reports what each work announces to a screen reader. That text is the artwork's title, so a weak title should be raised with you, not renamed.
Rebuilding a Page Like Another Site
Take inspiration, not artwork. The MCP rebuilds a site's presentation: its layout, section rhythm, grid, type scale, palette and navigation. It fills that shape with your works and your words. It is not for reproducing another artist's work or another brand's identity:
- Measuring a reference downloads no images, fonts or copy from it.
import_artwork_from_urlbrings in an image only when it is yours or licensed to you. The agent must ask you first and record where it came from.- A reference's logo and brand name are left out, and the "Artist Name" placeholder is yours to replace.
How to Do It
- Tell your agent the address and what you like about it. "Make my Atelier look like <address>. I like the big image grid and the quiet navigation. Use my own works."
- It checks the site first with
classify_reference_site: supported, supported with fallbacks (with the exact fallback for each feature), or unsupported. - It builds a first draft with
replicate_site. That is the starting point, not the result. A run can take a few minutes; the agent checks back withcheck_replication_job. - It compares and corrects. Each
compare_roundputs the reference and your draft side by side at desktop and mobile and scores them on a nine-point visual rubric. The agent fixes the biggest difference and repeats, stopping at 80% on both with no serious finding and no dead links or menus. It changes the look for two rounds at most (round 2 is the last appearance round, and it stops sooner when a round makes no visible difference), then only repairs anything still broken, up to round 4, and it should tell you honestly if it stopped short. - You open the preview link, touch up, and publish.
The scores in the examples below are the agent's own screenshot rubric, reviewed by eye. The structural measurements beside them are diagnostic, not a pass or fail. Treat any number as a prompt to look, never as a guarantee.
Example: An Awards Landing Page
Deep-color field, logo pill with a menu button, a staggered wall of tiles. Classed supported (97% predicted).
- First draft 17%. Plain white instead of the deep field, no logo pill, tiles overlapping on mobile.
- Round 2: 50%, held down by one real defect: platform text at 1.12:1 contrast on the colored field. Fixed.
- Round 3: 94% (0.938 desktop, 0.944 mobile). Column stagger within a few pixels of the reference, 11 working links, the menu opens, nothing dead.
- Touch-ups left: the catalog has no stencil typeface, so a monospace stands in, and the wordmark is one line where the reference stacks two. The artist had 5 works, so they repeat across 24 tiles.
Takeaway: a well-supported page type gets close in three rounds. Upload enough works to fill a big grid; the tool will not invent more.
Example: A Design Studio's Project Grid
Wordmark and navigation, a large title, an asymmetric grid of narrow and wide project tiles. Classed supported with fallbacks (83% predicted).
- The loop reached 100% desktop, 94% mobile in 2 rounds. Grid, captions and title matched; the only mark lost was a slightly larger mobile title.
- The first draft now scores 94% on its own, after the 2026-09-30 generator improvement. Before it, the first draft scored 0.
- The cost of making every link work: navigation dropped to 2 links where the reference has 6, because pages the artist does not have were left out rather than linked nowhere. That, plus a plain-list mobile menu, gives a final 94% on both.
Takeaway: grids, spacing and type carry over best. Count the navigation links yourself and ask for any you want back.
Example: An Event Listings Page
A search bar, a filter column, category chips and rows of events with share and save icons. Classed supported with fallbacks (62% predicted); booking cannot be rebuilt.
- First draft 56% (0.625 desktop, 0.556 mobile).
- After 4 rounds: 100% desktop, 94% mobile. Header, breadcrumb, filter column, chips and event rows all in place.
- Behavior repair: 94% on both. Search, filters, chips and share/save are static look-alikes: they look right and do nothing, because a published Atelier runs no custom script. "Updates" and "Help Center" were dropped, and on mobile the icons sit below the image instead of over it.
Takeaway: interactive features come across as appearance only. For anything a visitor must do, like buy a ticket or get in touch, use a real link.
Which Sites Work
classify_reference_site recognizes eight kinds of page: exhibition or gallery, photography portfolio, architecture studio, editorial lookbook, design agency, artist portfolio, event landing page, and professional profile. Pages built around a WebGL scene, or behind a password, are unsupported. Forms, sign-in, booking, carts, file uploads and cross-origin embeds come back with a named fallback.
What Doesn't Carry Over
- Anything that needs script: a reference's own forms are replaced by the platform contact form, which sends to your inquiries; search, filters, carts and booking become static; a self-advancing carousel and WebGL do not work.
- Fixed bars:
position: fixedis not allowed, so a newsletter or cookie bar is dropped. - Typefaces map to the six in the catalog.
- Some images are missed: slides in a clipped carousel, and some lazy-loaded hero photographs.
- Brand marks can land in the wrong place, and a reference's own poor contrast can be copied faithfully.
- Some sites refuse to be measured (a 403), and nothing can be built from them.
Touch-Ups to Expect
- Navigation: count the links against the reference.
- Placeholders: replace "Artist Name" and any marked placeholder text.
- Enough works to fill the grid without repeats.
- The mobile menu: open it on a phone.
- Contrast in both themes.
- The hero image is actually there.
- Contact: every "Contact" or "Commissions" link points at the page's contact form.
- Then ask for
atelier_auditand fix what it ranks first.
Adding Your Widgets After a Clone
A clone copies a layout; it does not know about your Yeja widgets. Ask for them explicitly: "After the clone, add every widget I can support." The agent calls get_widget_inventory, which reports each one as present, empty, supportable or not supportable:
| Widget | What it shows | Who fills it |
|---|---|---|
| Get In Touch (Inquiry) | The platform's contact form | Always available; the agent only switches it on or off |
| Verifiable Collaborations | Projects with another artist | Read-only: both artists confirm |
| Social Links | Where else your work lives | The agent, up to 8 |
| Classes & Products | Your catalog | The agent, once you opt in |
| At Auction, Live Campaign, Next Drop | Auctions, fundraisers and drops | Other Yeja apps: the agent must ask you |
| Search & Sharing | Your title and share preview | The agent proposes; you save |
| Support | Monthly pledges | Only once Stripe is connected |
An agent should place every widget with real content and never fabricate one.
How a Match Is Scored
The rubric has nine criteria, each scored 0, 0.5 or 1: opening composition, navigation, section order, proportions, image treatment, type scale, whitespace rhythm, color, and on mobile, responsive behavior. A round's similarity is the lower of desktop and mobile. compare_round also counts dead links and menus that do not open, and will not call a round passed while any remain.
The structural checks (compare_to_reference,
check_replication_fidelity) measure section rhythm, grid shape, type scale, palette and navigation. A page can score well there and still look wrong, so if an agent quotes you a percentage, ask to see the screenshots beside the reference.
Motion and Interaction
Almost everything that makes a page feel alive is CSS, and CSS is allowed: hover states, transitions, transforms, keyframe animation and blend modes. Menus, in-page anchors and disclosure panels work on published pages. Fifteen named effects can be attached to an element. Ten compile to CSS:
| Effect | What it does |
|---|---|
reveal_on_scroll | Fades and slides content in as it enters the viewport |
scroll_progress | A thin bar showing how far down the page you are |
hover_lift | Lifts and slightly scales a card under the pointer |
parallax_background | Background drifts slower than the page |
glitch_bands | Bands of the element shift sideways in a loop |
cursor_lens | A grid lens that follows the pointer over the element |
scroll_scrub | Ties opacity, movement, scale or rotation to scroll position |
pin_section | Holds a section in place while the page scrolls past it |
sticky_heading | A heading that pins while its section scrolls past |
disclosure | A menu that opens on hover, focus or tap |
Five run one of the platform's own signed scripts, which a published page is allowed to load: cursor_follower, smooth_scroll, ambient_audio,
scroll_linked_columns and scroll_linked_columns_endless. Check
get_freeform_runtime_capabilities before using one: it says which are deployed.
A page may carry up to 30 effects, and up to 3 on any one element. Out-of-range values are refused rather than clamped, and every effect stops under reduced motion.
Contact and Support Blocks
Both work on a published page. A contact_form renders a real form (name, email, message) that sends straight to your inquiries; the page allows that one destination and no other. A support block renders one link per amount, and the pledge completes in the signed-in Yeja app, once Stripe payouts are connected.
Freeform: Building the Page Yourself
The tools above edit a page Yeja lays out for you. Freeform is the other option: your agent writes the structure and the stylesheet, and Yeja renders exactly that. A clone is a Freeform page.
A published page runs no script except the platform's own signed bundles, such as the artwork viewer. Interactions compile to CSS. That is what keeps a page safe on the same domain as your dashboard.
Start With the Schema and the Runtime
get_freeform_schema lists every node type, the nesting limits and what the stylesheet may contain. Then call get_freeform_runtime_capabilities before designing: the schema says what validates, the runtime report says what actually renders in this deployment, and they differ. Before handing over a preview, validate_freeform_draft checks a tree or the saved draft without writing anything, and flags embeds of artwork you do not own.
create_freeform_draft validates before storing. update_freeform_draft patches only what it is sent. patch_freeform_css adds a rule or two without rewriting the stylesheet.
A version holds a site, not a page: extra pages go under a __pages key and publish together. Components let one card be defined once and placed forty times, styled by one rule.
Galleries
build_artwork_gallery writes a whole wall of your works: columns, embeds, grid CSS and mobile breakpoints, generated from the same numbers so they cannot disagree. It returns the tree by default. With apply: true it adds the gallery to your existing draft; only mode: "replace_page" replaces the whole page. A gallery card is an image, so video works are refused: place each one with a video node (list_artworks lists them as usable_video_ids).
motion: "scroll_linked_columns" makes alternating columns drift as the page scrolls, without capturing the wheel. scroll_linked_columns_endless loops the columns and does read the wheel, but only while the gallery fills most of the screen, and it gives the wheel back after about 900px. Neither runs under reduced motion.
Fonts
Inter, Playfair Display, JetBrains Mono, Plus Jakarta Sans, Yuyu and Geist Pixel are self-hosted. Naming any other family is a rejection, not a silent fallback. Generic families (serif, sans-serif,
monospace, system-ui…) are always fine. Yuyu (handwriting) and Geist Pixel (pixel display) each have one weight, 400; use Geist Pixel for headings, not body text.
There is no font upload and no Google Fonts import; both are refused with
FONT_UPLOAD_UNAVAILABLE. Adding a family is a request to the Yeja team.
Artworks Open in the Native Viewer
Use embed_artwork for a work a visitor should be able to open. It renders the real image server-side, and the platform's viewer opens it in place, over the page you built: zoom, drag to pan, previous and next across every embed, Escape to close. A detail panel shows the work's own title, artist, availability, medium, year and provenance, and leaves out anything you never filled in. It has no comments, share or report controls, because a published page cannot make requests.
It degrades to the image, never to a blank space. artworkId must be a work you own (list_artworks); any other id renders nothing at all. It is for images: a video in embed_artwork or an image node shows as a broken image, and validate_freeform_draft warns about it.
One Node Type Renders Nothing
A generic embed (a third-party page in a frame) publishes as an empty space, because a published page cannot load outside content. Leave it out, or use a labelled static section instead. The other widget nodes work:
contact_form is a real form, and embed_product renders a card for one of your products (title, price or "Enquire", and a link to where you sell it) with no buy button.
Previews, Publishing and Versions
preview_freeform renders the draft, reports whether it would pass the publish gate, and returns a fingerprint. Publishing without a fingerprint is refused, and any edit changes it, so an approval cannot carry over to a changed draft. get_go_live_link gives you the dashboard link where you publish.
A Freeform preview link keeps working until it expires, and always shows what the draft holds now. After the Freeform draft is published or discarded, the link shows your published page, with a banner saying so. Publishing or discarding your standard draft revokes every preview link. refresh_preview_link mints a new one. snapshot_round pins a link to one round of a clone, so it keeps showing that round after the draft moves on.
list_freeform_versions shows every version, get_freeform_history every publish, rollback and unpublish, and rollback_freeform puts an earlier version live again.
Tools
95 tools. Needs is the permission it requires. Effect is what it does to your page: Read changes nothing, Staged waits for Publish, and Live changes your public page the moment it runs. On a deployment with Freeform switched off, the 23 Freeform-only tools are hidden.
Start Here
| Tool | What it does | Needs | Effect |
|---|---|---|---|
connect_profile | Connects this chat to the profile you named. Called first; every other tool waits for it. | None | Read |
get_connection | Which profile this chat is connected to, and how. | None | Read |
disconnect_profile | Ends this chat's connection to its profile. | None | Read |
atelier_audit | One prioritized list of what to fix, including placeholder text left on a live Freeform page. | Read | Read |
get_atelier | Your current Atelier, including any unpublished draft. | Read | Read |
get_atelier_schema | The document schema plus the constraints that are not obvious. | Read | Read |
get_operating_instructions | How this server expects an agent to work, for clients that do not surface it. | Read | Read |
list_artworks | Your artworks and the image ids an agent may use. | Read | Read |
get_widget_inventory | Which priority widgets you can support, with a count and visibility for each. | Read | Read |
compare_public_and_draft | Exactly what publishing would change: each staged field before and after, staged collections, and any Freeform draft. | Read | Read |
get_go_live_link | The dashboard link where you publish. No tool can publish for you. | Propose | Read |
Seeing and Measuring
| Tool | What it does | Needs | Effect |
|---|---|---|---|
inspect_atelier_render | Screenshots of your live page (standard or Freeform) at desktop, tablet and mobile, light or dark; preview or freeform shows a draft. | Read | Read |
inspect_layout_metrics | Overflow, broken images, missing alt text, heading order. | Read | Read |
inspect_accessibility | Contrast, landmarks, headings, unnamed controls and skip link, on the rendered page. | Read | Read |
inspect_seo | What search engines and link previews see, and drift from your saved SEO fields. | Read | Read |
propose_seo | Suggested title, description, job title and share image from your own content. | Read | Read |
analyze_artworks | Pixel size, print guidance and dominant color for your images. | Read | Read |
get_atelier_views | Visitor numbers, sources and countries for your published page. | Read | Read |
review_alt_text | What each work's image announces to a screen reader. | Read | Read |
check_copy | Whether a headline or bio survives the save unchanged. | Read | Read |
Drafts, Previews and Undo
| Tool | What it does | Needs | Effect |
|---|---|---|---|
propose_atelier | Stages a change to your Atelier as a draft. dryRun: true checks without saving. | Propose | Staged |
create_preview_link | A temporary link showing your staged standard draft as a real page. Refuses when nothing is staged. | Propose | Staged |
list_snapshots | Point-in-time copies of your Atelier, newest first. | Read | Read |
restore_snapshot | Rolls your page back to a snapshot and clears any pending draft. | Propose | Live immediately |
Pins and Hero
| Tool | What it does | Needs | Effect |
|---|---|---|---|
list_pins | Your Pinned Showcase, in order, with ids. | Read | Read |
pin_artwork | Adds a work to your Pinned Showcase. | Curate | Live immediately |
unpin_artwork | Removes a work from your Pinned Showcase. | Curate | Live immediately |
reorder_pins | Sets the order of your Pinned Showcase. | Curate | Live immediately |
set_hero | Chooses what leads the page: top pin, a specific work, or nothing. | Curate | Live immediately |
Timeline
| Tool | What it does | Needs | Effect |
|---|---|---|---|
list_timeline | Your exhibitions, shows, residencies and education, in order. | Read | Read |
add_timeline_entry | Adds an exhibition, show, residency or milestone. | Curate | Live immediately |
update_timeline_entry | Changes one timeline entry. | Curate | Live immediately |
remove_timeline_entry | Deletes a timeline entry. Not recoverable. | Curate | Live immediately |
reorder_timeline | Sets the order your timeline is displayed in. | Curate | Live immediately |
Custom Sections
| Tool | What it does | Needs | Effect |
|---|---|---|---|
get_section_schema | Every section type you can add, with its fields and limits. | Read | Read |
list_sections | Your custom sections, in order, with ids. | Read | Read |
add_section | Adds a workshop, class list, events, testimonials, an FAQ… | Curate | Live immediately |
update_section | Rewrites a custom section, or hides it. | Curate | Live immediately |
remove_section | Takes a custom section off. restore_section undoes it. | Curate | Live immediately |
restore_section | Puts back a section remove_section took off. | Curate | Live immediately |
reorder_sections | Sets the order of your custom sections. | Curate | Live immediately |
Staging Collections
| Tool | What it does | Needs | Effect |
|---|---|---|---|
get_staged_collection | The list to edit: your staged draft if you have one, otherwise your live rows. | Read | Read |
stage_collection | Stages the complete list for sections, timeline, products or pins. The one to prefer. | Curate | Staged |
discard_staged_rows | Throws away staged collection changes. | Curate | Staged |
Custom CSS
| Tool | What it does | Needs | Effect |
|---|---|---|---|
get_custom_css | Your Atelier's custom CSS, and which properties survive sanitizing. | Read | Read |
validate_custom_css | Checks standard-Atelier CSS without applying it. Not the Freeform validator. | Read | Read |
propose_custom_css | Stages custom CSS onto your Atelier. | Curate | Staged |
validate_freeform_css | Checks Freeform page CSS, with a line number for every rejection. | Read | Read |
Products
| Tool | What it does | Needs | Effect |
|---|---|---|---|
list_products | Your catalog with prices, seats and status. | Read | Read |
add_product | Adds a class, course, book or print. Starts as a draft. | Curate | Live once available |
update_product | Changes a product, or makes it available. | Curate | Live immediately when available |
remove_product | Deletes a product. Refused if it has orders. | Curate | Live immediately |
Themes
| Tool | What it does | Needs | Effect |
|---|---|---|---|
list_my_theme_listings | Your own Atelier Theme listings, any status. | Read | Read |
package_current_freeform_as_theme | Packages your published Freeform design as a listing, content replaced by placeholders. | Curate | Draft listing |
update_theme_listing | Changes a listing's title, price or status. | Curate | Live on Art Board once available |
show_theme_listing | Puts a listing on Art Board for other artists to browse. | Curate | Live immediately |
hide_theme_listing | Takes a listing off Art Board without deleting it. | Curate | Live immediately |
browse_atelier_themes | Theme listings on Art Board, for a buyer's agent. | Read | Read |
install_theme | Installs a theme you bought into your Freeform draft. Requires a completed purchase. | Propose | Staged |
reset_atelier_theme | Reset To Factory: back to the default Yeja theme, removing every theme adjustment and any installed page. Dry run unless confirmed. | Propose | Live immediately |
unpublish_atelier | Takes the whole Atelier offline. Nothing is deleted; only you can publish it again. Dry run unless confirmed. | Propose | Live immediately |
Freeform Pages
| Tool | What it does | Needs | Effect |
|---|---|---|---|
get_freeform_schema | Node types, nesting limits, what the stylesheet may contain. | Read | Read |
get_freeform_runtime_capabilities | What the deployed runtime actually renders, and why some nodes do not. | Read | Read |
validate_freeform_draft | Checks a tree and stylesheet without saving. | Read | Read |
get_freeform_draft | Your Freeform draft: tree, stylesheet and version. | Read | Read |
create_freeform_draft | Starts a Freeform page from a page tree. | Propose | Staged |
update_freeform_draft | Patches the draft; omitted fields are left alone. | Propose | Staged |
patch_freeform_css | Adds a rule or two without rewriting the stylesheet. | Propose | Staged |
build_artwork_gallery | A multi-column gallery of your images (videos are refused). Returns it; with apply, adds it to the draft. | Read (Propose to apply) | Read or Staged |
preview_freeform | Renders the draft, reports the publish gate, returns a preview link and the fingerprint. | Propose | Staged |
refresh_preview_link | A fresh preview link when one stopped working. | Propose | Staged |
discard_freeform_draft | Throws away the unpublished draft. | Propose | Staged |
list_freeform_versions | Every version, and which can be rolled back to. | Read | Read |
get_freeform_history | Every publish, rollback and unpublish, with evidence. | Read | Read |
rollback_freeform | Puts an earlier version's content live again. | Propose | Live immediately |
unpublish_freeform | Turns the live Freeform page off; visitors get the classic Atelier. Dry run unless confirmed. | Propose | Live immediately |
Images and Content Fields
| Tool | What it does | Needs | Effect |
|---|---|---|---|
list_freeform_image_slots | The picture spaces in your draft, filled and empty. | Read | Read |
fill_freeform_image_slot | Puts one of your works (image, video or audio) into a field, or empties it. | Propose | Staged |
fill_dynamic_content_text_field | Writes text into a text field, or clears it. | Propose | Staged |
add_dynamic_content_field | Adds a text, image, video or audio field. | Propose | Staged |
remove_dynamic_content_field | Deletes a field. | Propose | Staged |
set_dynamic_content_field_kind | Changes what a field holds, and empties it. | Propose | Staged |
import_artwork_from_url | Brings an image you may use into My Studio as a work you own, with its source recorded. | Propose | Adds to your account |
Rebuilding From a Reference
| Tool | What it does | Needs | Effect |
|---|---|---|---|
classify_reference_site | Whether a site can be rebuilt, before building. Call it first. | Read | Read |
ingest_reference_site | Measures a site's structure. Copies no images, fonts or text. | Read | Read |
describe_reference_design | Records a design you showed as a screenshot, to build from. | Propose | Staged |
replicate_site | Builds the first draft from a site's address and returns preview and publish links. | Propose | Staged |
check_replication_job | Checks on a rebuild that is still running. | Read | Read |
compare_round | One screenshot round: reference and draft side by side, the rubric, a pinned snapshot. | Propose | Staged |
snapshot_round | Freezes the draft as a round and pins a preview link to it. | Propose | Staged |
draft_from_reference | Builds a complete draft from an already measured reference. | Propose | Staged |
compare_to_reference | Structural comparison against a reference, with what to change next. | Read | Read |
check_replication_fidelity | How close the draft is to its reference, structurally. | Read | Read |
record_clone_result | Records the agent's own rubric scores for a clone; other kinds are for the platform's bench account only. | Propose | Platform record |
The Brief
| Tool | What it does | Needs | Effect |
|---|---|---|---|
start_brief | Begins the interview and returns the next question. | Read | Read |
answer_brief | Records one answer. Private; never public. | Propose | Private |
get_brief | Every answer so far, and what is missing. | Read | Read |
reset_brief | Clears the brief and starts again. | Propose | Private |
FAQ
Does My API Key Expire?
No. A key lasts until you revoke it, and you can hold up to 10. Sign-in renews itself hourly; if a client goes unused for 30 days, you sign in again.
Can an Agent Work on the Wrong Account?
Not without saying so. Each chat names its profile with connect_profile. The server checks the key belongs to that profile, and a connection signed in as one account refuses every other profile. Every result names the profile it acted on in acting_as.
Can an Agent Publish My Page?
No. It stages a draft and gives you a preview and a publish link; you press Publish. The exceptions are the tools marked Live: curation (pins, hero, timeline, sections, products, theme listings) and the two undo tools.
What Can Change My Live Page Without Me?
With Curate: the per-row curation tools. With Propose: only
restore_snapshot, rollback_freeform, reset_atelier_theme,
unpublish_freeform and unpublish_atelier, which a good agent confirms with you first. With Read alone: nothing.
My Agent Lost Its Connection. Why?
If it signed in, let it retry; it refreshes itself. If it connected with a key, the key was revoked, or the chat's connection ended: a chat stays connected for up to 7 days, or a day without use. Give the agent the profile and key again. A key in a client's settings is read once at start-up, so restart the client after changing it.
Will It Copy Someone Else's Art or Words?
No. Rebuilding measures a site's layout and style and downloads none of its images, fonts or text. Your page shows your works and words in a similar shape. An outside image comes in only through import_artwork_from_url, when it is yours or licensed to you, with its source recorded.
Can It Use an Image That Is Not in My Account Yet?
Yes, with your permission: import_artwork_from_url adds it to My Studio as a work you own, and records where it came from. A public-domain painting does not make a museum's photograph of it free to use; say which source is yours to use.
Why Doesn't My Clone Look Exactly the Same?
Because it uses your art, your words and the catalog's typefaces, and because anything that needs script becomes static. In the recorded examples, three or four correction rounds took a first draft to about 94%, and a few touch-ups remained every time.
How Long Does a Clone Take?
The first draft takes a few minutes. The agent then runs comparison rounds, correcting in between: the look changes through round 2, and any further round, up to round 4, only repairs something still broken. Expect one session, plus your own touch-ups.
Does a Contact Form Work on a Freeform Page?
Yes. A contact_form node renders a real form that sends to your inquiries, with no custom script involved. A clone puts one on the page even when the reference had none, and points its "Contact" links at it.
Can I Clone a Site With a Shop or Booking?
The look, yes; the checkout or booking, no. Those parts become static or a link. Point a button at wherever you already sell.
Can People Buy My Products or My Theme?
Soon. The Yeja Wallet is under development, and once it is live you will be able to sell your work and your themes directly through Yeja. Until then, link to wherever you already sell.
What Is My Interview, and Who Sees It?
Before building a full page, your agent asks you six short questions: what the page is for, who visits it, what you want a visitor to do, how it should feel, what must appear on it, and which sites you would like it to resemble. It takes about two minutes. Your answers are saved as a brief, so the agent only asks once and every later session starts from them. Say "start over" to answer again.
The brief is private. It shapes the layout your agent builds, and no visitor ever sees it.
Which Agents Work?
Any client that speaks MCP over streamable HTTP. The Install section covers Claude Code, Claude Desktop and claude.ai, Cursor, VS Code, Codex, Antigravity, Windsurf, Zed and Cline.
Troubleshooting
| What you see | What it means |
|---|---|
not_connected | The agent has not connected a profile in this chat. Give it your profile link and key. |
connect_failed | The profile and key do not match, or the key was revoked. Check both on the Developer Access card. |
identity_mismatch | The connection is signed in as a different account from the profile you named. Nothing was changed. Use a connection without sign-in and that profile's key, or sign in as that profile. |
profile_not_declared | A signed-in connection has not named its profile yet. The agent should call connect_profile. |
session_missing | Your client did not keep the session the server gave it. Restart the client. |
| Claude Code says the server needs authentication, with no key in its settings | An old sign-in is stored under that server name from before. Run /mcp, pick the server and clear its authentication, or remove it with claude mcp remove yeja-atelier and add it again. |
401 from /mcp/oauth with a www-authenticate header | Normal. The server is asking your client to sign in. |
401 "A valid Atelier credential is required" | A wrong or revoked key, or a yeja_live_ partner key, which belongs to a different system. |
401 "has expired" | Only a key deliberately given a short lifetime through the API, or a sign-in mid-refresh. Create a new key, or let the client retry. |
| "This key is read-only" | For a key: create one with Allow This Key To Propose Changes ticked. For sign-in: sign in again and tick Propose. |
| "must reference an image already in this artist's account" | The agent used an outside image address. Import it with import_artwork_from_url, with your permission, or upload it. |
405 when connecting | The client tried SSE. Set its transport to HTTP (Cline: streamableHttp). |
| Nothing changed on your public page | Correct. Proposals are drafts; press Publish in the dashboard. |
| A preview link stopped working | It expired, or your standard draft was published or discarded. Ask for refresh_preview_link. |
| A preview link shows the live page | The Freeform draft it showed was published or discarded. The banner says so. |
Rules an Agent Must Follow
These are enforced server-side, not merely requested. A proposal that breaks them is rejected or corrected, and the reason is returned to the agent.
- Connect the profile the user named, before anything else.
connect_profilewith the profile exactly as the user gave it. Every other tool refuses until it succeeds, and a signed-in connection refuses any profile but its own. Onidentity_mismatch, stop and tell the user; never work on the signed-in account instead. portfolio_process_scaleandportfolio_statement_scaleare the image's share of the row, not a zoom level. Values near 100 make the image take the whole row and push the page past the viewport. Keep them between 40 and 70.- An agent cannot introduce a new image URL. A page may only reference media already in your account. An outside image must first be imported with
import_artwork_from_url, with your permission and its source recorded. portfolio_headlineis at most 80 characters; the bio is at most 600 characters of text.portfolio_grid_columnsis 2 to 5. At most 3 process images and 8 social links.portfolio_sectionsstores only the OFF flag. An absent key means the section is visible; set a key tofalseto hide it.portfolio_section_ordersets the order, top to bottom, fromworks,exhibitions,statement,about,skills,collaborations,inquire,socialLinks,products,auctions,campaign,drop,supportandcustom. A section left out keeps its default place at the end; leaving it out never hides it.- Never invent a fact about an artwork. No dimension, price, material, date, exhibition or provenance detail that was not supplied.
Reference
- Endpoint:
https://yeja-ai.com/mcp(POST, JSON-RPC 2.0) - Protocol: MCP specification revision 2025-06-18, streamable HTTP, single JSON response, no SSE. Older revisions are negotiated.
- Auth: none to connect to
/mcp. Each chat callsconnect_profilewith a profile and itsyeja_atl_…key; the binding lives with theMcp-Session-Idthe server issued, for up to 7 days or 24 hours idle, and ends when the key is revoked. OAuth 2.1 on/mcp/oauth: PKCE S256, dynamic client registration, discovery at/.well-known/oauth-protected-resource/mcp/oauth, revocation at/oauth/revoke; access tokens last 1 hour, refresh tokens 30 days, rotating. A staticAuthorization: Bearer yeja_atl_…header still works. A signed-in connection must still callconnect_profile, and only for its own profile. Up to 10 keys per artist; they do not expire by default. - Permissions:
atelier:read,atelier:write(Propose),atelier:curate(Curate). - Prompts:
interview_artist,rebuild_from_reference,complete_my_atelier,audit_and_fix,add_background_image,verify_before_handoff. - Dashboard: https://yeja-ai.com/dashboard/?app=profile&view=portfolio
- This guide as Markdown: https://yeja-ai.com/mcp?format=md
- This guide last updated: 2026-10-19