Last updated 22 October 2026
Support and setup
brands.menu is a visual brand OS for Shopify and DTC brands. One canvas shows every touchpoint of your brand as it really looks, and your approved brand identity lets Claude, ChatGPT and Grok make ads, pages and emails that stay on brand. Questions? Email lauri.enckell@gmail.com.
Before you connect
- Sign in at brands.menu with Google.
- Create your brand, or accept an invite to one. You need to be an owner or editor of a brand to connect an AI app to it.
- Optional: connect Shopify, Klaviyo and Meta under Connected apps so your live pages, emails and ads appear on the canvas.
Connect Claude
- In Claude, open Customize, Connectors, and find brands.menu in the directory. Or add it as a custom connector with the URL
https://brands.menu/api/mcp. - Click Connect. A brands.menu window opens. Sign in with Google and pick the brand Claude may use, then Approve.
- In a chat, turn on brands.menu from the tools menu and ask, for example, "Show my live brand journey".
- Claude allows one connector per URL. For a second brand, add another custom connector with a different name and that brand's URL, for example
https://brands.menu/api/mcp/b/electroandhttps://brands.menu/api/mcp/b/electro-review. Open the brand and choose Connect your AI to copy it. The approve page selects that brand.https://brands.menu/api/mcpstill works for a single connector.
Connect ChatGPT
- In ChatGPT, open the Plugins directory and search for brands.menu, then click Connect.
- Sign in with Google in the brands.menu window, pick a brand and Approve.
- Ask, for example, "What are our brand colors, fonts and voice rules?"
Connect Grok
- In Grok, open Connectors and click New Connector, then Custom.
- Name it brands.menu and paste the URL
https://brands.menu/api/mcp, then add it. - Click Connect. Sign in with Google in the brands.menu window, pick the brand Grok may use and Approve.
- In a chat, turn on brands.menu and ask, for example, "Show my live brand journey".
What the connector can do
- Show brand journey: your live ads, website and Shopify pages and emails, or your drafts, shown inline as they really look.
- Get brand identity: your approved brand guidelines. Colors, fonts, logos, voice, product facts, claims rules and rules per channel, plus design tokens (W3C DTCG).
- Add item: puts an ad, page or email on the canvas as a draft or a new version for your team to review.
- List comments and projects: reads the feedback on the canvas and what is in progress.
- Set status: approves, rejects or moves an item between draft, review and live. For a website page with HTML, Live creates a published Shopify Online Store page. For an email with HTML, Live saves a Klaviyo template and does not send it. For an ad, Live only links a paused ad that was already created from the canvas. It never turns a Meta ad on.
- Propose brand identity change: saves a proposal. It only takes effect when you approve it on the Brand page.
- Create brand and create project: sets up a workspace or a project for a group of drafts.
The connector never sends a Klaviyo email and it never turns a Meta ad on, and it has no delete tool. Marking a website page Live can publish that page on the connected Shopify store. Marking an email Live can save a Klaviyo template. It only sees the brand you picked when you connected.
Example prompts
- Show my live brand journey.
- What are our brand colors, fonts and voice rules?
- Write a launch email in our brand voice and add it to the canvas as a draft.
- Check this ad against our brand guidelines.
- What open comments are there on our emails?
Publish a website page to Shopify
Open the page on the canvas and click Live, or ask your AI to set that item to live. A home or product card (Home A/B, Product page, or a theme template) does not create an Online Store page. Live duplicates the live theme, applies edits on that unpublished copy, and shows a preview URL with preview_theme_id. The copy is not published. If that cannot run, Live stays where it was and tells you to use create_experiment and start_experiment (theme). Any other website page is published on the connected store with a handle unique to that card, and the card shows the full page URL. A page this item already published is updated. A sibling page is not overwritten. A page synced from the store is not overwritten.
Publishing needs write access. The Shopify app has to include write_content and write_online_store_pages, and the store has to be reconnected after that version is released. Until then, Live stays where it was and the card explains how to reconnect.
- In the Shopify Dev Dashboard, open the brands.menu app (brands-menu-1).
- Add write_content and write_online_store_pages to the app version. Keep the existing read scopes (read_products, read_content, read_themes, read_online_store_pages, read_files).
- Release that version. If the server has SHOPIFY_SCOPES set, add the same two write scopes there, or leave SHOPIFY_SCOPES empty so the default list is used.
- On brands.menu, open Account, then Connected apps, pick the brand (Electro), and click Reconnect on the Shopify store. Approve the new access.
- Open the website page on the canvas and click Live again. The card should show the new page URL.
Post-purchase emails
The canvas has a Post-purchase view. It lists the standard Shopify notification emails (Order confirmation, Shipping confirmation, Shipping update, Out for delivery, Delivered, and Refund) next to the Klaviyo flows whose name or trigger matches Placed Order, Fulfilled Order, Ordered Product, Refund, Delivered, Out for delivery, Shipping confirmation, or Order confirmation.
Klaviyo flows sit in a project named Flows, as a tree: trigger, then waits, emails, and yes or no branches. Both branch emails stay visible. Campaigns sit in a project named Campaigns, including ones already sent. Saved templates stay in Email templates and in Drafts.
Shopify does not give apps the notification HTML. Each Shopify card starts as a stub and links to Admin, Settings, Notifications: https://admin.shopify.com/store/your-store/settings/notifications. Open that page, copy the email, and paste the HTML (or a subject and a body) onto the card. You can also upload an HTML file. A later sync does not replace what you pasted. brands.menu does not read the admin page.
Site tests
A site test splits new visitors and keeps that choice in a cookie. The theme embed stamps the order with control or challenger. Ask Claude to create_experiment, set_experiment_split, start_experiment, pause_experiment, or read_experiment. The canvas also has a Site tests view. This does not turn a Meta ad on.
A page test uses two Online Store page URLs, usually under /pages/. start_experiment publishes a website card that is not on the store yet, the same way Live does. A page already synced from the store is not overwritten. Use this when the challenger is a different page, not a different theme.
A theme test competes on the live theme for home, product, collection, cart, search, blog, or the theme page template. It does not create a new Online Store page. start_experiment duplicates the live theme, then applies color or section edits on that unpublished copy. Visitors who are assigned the challenger stay on the same path (for example / or /products/your-handle) and Shopify previews the copy with preview_theme_id. Visitors on control stay on the live theme. The copy is never published. Home, product, and similar cards use a theme test unless you ask for a page test. Pausing the test leaves the unpublished copy in the theme library.
Color edits set a hex on a color scheme in config/settings_data.json (for example scheme-1 background). If the theme has no color schemes, the edit sets that key on the current settings. Section edits merge settings on a section id in the template JSON for that area (templates/index.json for home, templates/product.json for product). Pass those edits to create_experiment or start_experiment.
The default split is 50, so half of new visitors see the challenger. People who already have a cookie stay on their variant when you change the split. Orders and revenue on the card are counted from Shopify orders that carry the stamp. Sessions show only when Shopify returns them, and that number is for the whole store, not by variant. Add to cart is not in the order data, so the card does not show an add to cart count.
If Shopify is not connected, or the grant does not include write_themes, the theme test does not start and the live theme is not changed. Shopify also has to allow this app to duplicate themes and write theme files (their theme exemption). A refusal stops the test and does not edit the live theme.
- In the Shopify Dev Dashboard, open the brands.menu app (brands-menu-1). Keep write_themes on the app version along with the existing scopes, including read_orders, write_content, and write_online_store_pages. Release that version. If SHOPIFY_SCOPES is set, add write_themes and read_orders there too, or leave it empty.
- From the repo, run shopify app deploy so the theme app extension Site split is on the app. The extension lives in extensions/ab-split. Theme tests need this version of the script, because it assigns preview_theme_id and not only page paths.
- On the live theme, open the theme editor, App embeds, and turn on Site split. Save the live theme before you start the test, so the duplicated theme copies the embed. Leave the embed on. Do not publish the challenger theme.
- On brands.menu, open Account, Connected apps, Electro, and Reconnect Shopify if the store was connected before write_themes was granted. Approve the access. Electro already reconnected with write_themes and write_files.
- Ask Claude for a theme test on the home or product card, with areas and color or section edits, then start it. Or ask for a page test from two /pages/ cards. Open Site tests and click Read results after a few stamped orders.
Save an email as a Klaviyo template
Open an email with HTML on the canvas and click Live, or ask your AI to set that item to live. brands.menu saves a CODE template in Klaviyo and shows the editor link on the card. The template name starts with brands.menu. A second Live updates that same template. It does not create a campaign, so it cannot schedule or send. Emails synced from Klaviyo are not overwritten.
Saving needs templates:write. A key or login connected before that scope was added stays read only until you reconnect. Until then, Live stays where it was and the card explains how to reconnect.
- In Klaviyo, open the brands.menu app and add the OAuth scope templates:write. Keep accounts:read, campaigns:read, flows:read, templates:read and lists:read. campaigns:write is not required, because no campaign is created.
- On brands.menu, open Account, then Connected apps, pick the brand (Electro), and click Reconnect on Klaviyo. Approve the new access.
- If you use a private key instead, click Create a private API key in Klaviyo on that same card (the link now asks for templates:write), create the key, and paste it in place of the old one.
- Open the email on the canvas and click Live again. The card should show the Klaviyo template editor link. In Klaviyo, the template is under Content, Templates. Nothing is sent.
Mark an ad Live as paused
Open an ad draft on the canvas and click Live. brands.menu asks for a Facebook Page, an https link, and an ad set or a new paused campaign, then creates the ad as paused. The card shows an Ads Manager link. A second Live uses that same paused ad and does not create another one. Nothing is turned on. Synced ads (already in Ads Manager) only change the stage label on the canvas.
This needs ads_management, which the Meta app already requests. If Electro connected before that permission was granted, click Reconnect on the Meta card and approve ads_management. If the server uses a Facebook Login for Business configuration (META_LOGIN_CONFIG_ID), add ads_management to that configuration as well, because the login dialog then sends the configuration instead of the scope list.
Replace worst 50% (PAUSED)
On Electro and Comfy Food, owners see Replace worst 50% (PAUSED) on the canvas. It reads ad insights for the last 30 days (spend, CTR, CPC, and purchases or purchase ROAS only when Meta sent them). It ranks each connected ad account by lowest CTR among ads with at least 1000 impressions. If an account has fewer than 2 such ads, that account uses highest CPC instead. brands.menu does not invent a score.
The preview lists the worse half, rounded down. Pick a staged draft for each row, then confirm. Each replacement is a new paused ad in the same ad set, using the draft's picture and the old ad's Page and link. The old ad is left as it is. Nothing is turned on. This is limited to Electro and Comfy Food for the first proof.
Page posts and Instagram
The same Meta connection can read Facebook Page posts and Instagram media onto the canvas, in a project named Organic. These cards are read only. They are not ads, and they cannot be turned on from brands.menu. Instagram tags are read when Meta allows them. If tags are refused, the rest of the Meta sync still runs.
Reconnect asks for ads_management, ads_read, business_management, pages_read_engagement and pages_show_list. Page posts are read from the Page feed with pages_read_engagement. The login does not ask for pages_read_user_content or instagram_basic. On this app those two names make the Facebook dialog return Invalid Scopes and skip the consent screen, so the ads reconnect fails as well.
Instagram media and tags on graph.facebook.com need instagram_basic from Instagram API with Facebook Login, together with the Page permissions above. instagram_business_basic belongs to Instagram Login (graph.instagram.com) and is not valid on the facebook.com dialog. Do not add it to the scope list or to a Login configuration.
Before instagram_basic can be requested again, open the Meta app and add the use case Instagram API with Facebook Login. Set instagram_basic to Ready for testing. Meta lists pages_read_user_content as a dependency of instagram_basic, so set that to Ready for testing on the Page use case too. If either stays off, the dialog rejects the grant. If META_LOGIN_CONFIG_ID is set, the Login configuration replaces the scope list: keep it to the five permissions above, and leave the two rejected permissions out until both are Ready for testing. App Review is still required before anyone who is not an app tester can grant instagram_basic. This app does not submit that review.
Until that use case is ready, reconnect and approve the five permissions. Page posts and ads sync. Instagram calls are skipped with a note. Nothing is turned on.
Disconnect or delete
Remove brands.menu in Claude, ChatGPT or Grok to disconnect it. To remove a team member's access, change or remove their role on the Team page; their AI connection stops working at once. To delete a brand or your account, use Settings or email lauri.enckell@gmail.com. See the privacy policy and terms.
Troubleshooting
- "This connection only has access to the brand ..." You picked another brand when you connected. Disconnect and connect again, then pick the brand you want.
- "Your access to this brand was removed" Ask the brand owner to make you an editor, then reconnect.
- No brands to pick Create a brand at brands.menu/start first.
- Live says Shopify is read only The store was connected before page publishing was allowed. Release the app version with write_content and write_online_store_pages, then Reconnect that store and click Live again. The stage stays put until the page is published.
- Live says Klaviyo needs templates:write Reconnect Klaviyo after the app allows templates:write, or paste a new private key from the Connected apps link. The email stays where it was until the template is saved. Nothing is sent.
- Live on an ad asks you to send it as paused The card has no paused ad yet. Complete the paused send. brands.menu will not turn it on.
Still stuck? Email lauri.enckell@gmail.com and Lauri Enckell will answer. brands.menu is operated by Almas Ousadas Unipessoal LDA, Lisbon, Portugal.