← BrevoCONTENT HISTORY

Update to Brevo

Snapshot Oct 28, 2026 · 12:06 UTC · version 1.2.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Brevo and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Previews a Brevo draft email and sends a test of it. Use when the user wants to see how a draft campaign or a transactional template looks, or to receive a test email (for example \"send me a test of the VIP campaign\"). Gets a preview link or a server render with sample data, and sends a test only to the addresses the user names and confirms - never to an empty list, never to real recipients.",
  "included_files": [],
  "name": "email-test-preview",
  "skill_md_contents": "---\nname: email-test-preview\ndescription: \"Previews a Brevo draft email and sends a test of it. Use when the user wants to see how a draft campaign or a transactional template looks, or to receive a test email (for example \\\"send me a test of the VIP campaign\\\"). Gets a preview link or a server render with sample data, and sends a test only to the addresses the user names and confirms - never to an empty list, never to real recipients.\"\nmetadata:\n  version: 1.0.0\n  status: beta\n  author: brevo\n---\n# Preview and test-send an email\n\nShows the user how a draft campaign or a transactional template looks, and sends a test of it\nto addresses they name. A test send emails someone, so each one needs the user's explicit\nconfirmation of the addresses. It never sends a campaign to its recipients.\n\n| Step | Tool |\n|---|---|\n| Find the draft campaign | `email_campaign_management_get_email_campaign` |\n| Find the template, one at a time | `templates_get_smtp_template` |\n| Test-send a transactional template | `templates_send_test_template` |\n| Test-send a campaign | `email_campaign_management_send_test_email` |\n| Render a template with sample data | `templates_post_preview_smtp_email_templates` |\n| Check what happened to a template test send | `campaign_analytics_get_email_event_report` |\n| Check the sender's domain is authenticated | `domains_get_domains` |\n\nIf a tool a step needs isn't in your tool list, stop that step and tell the user their Brevo\nconnection doesn't offer it (connection rules below).\n\n## Brevo connection rules\n\n- Every Brevo call goes through the Brevo MCP server's tools. The user's connection carries\n  their authentication (OAuth). **Never ask for an API key, never ask the user to paste a key\n  into the chat, and never put a key in a file or command.**\n- If a tool returns 401, or 403 about the login or token, ask the user to reconnect Brevo in\n  their agent's settings.\n- A 403 \"required scope not present\" (`permission_denied`) means this connection doesn't\n  allow that action; reconnecting won't change it. Say so, skip that step, and carry on with\n  the fallback the skill gives (for a template render: the test send and its outcome check).\n  If the skill gives no fallback for that step, stop the step and tell the user.\n- If a tool a step needs is missing from your tool list, stop that step and say that the\n  user's Brevo connection doesn't offer it (connections can differ). Don't improvise with\n  other tools. Writing HTML never needs a tool; offer it, and the steps to finish in Brevo.\n- On a sub-account, pass `subaccount_id` on every call: every Brevo tool takes it per call,\n  and a call without it acts on the main account.\n- Show a tool's error message as returned, after a plain-language summary. Don't invent a\n  cause the tool didn't give.\n\n## Where this skill comes from\n\n- You already have this skill: it is in your context, whether installed, from the plugin, uploaded\n  or fetched with `get_brevo_guide`. Don't call `get_brevo_guide` for it again in this\n  conversation.\n- To have it without a tool call next time, install it once: the Brevo plugin from\n  `getbrevo/brevo-skills`, `npx skills add getbrevo/brevo-skills`, or, with a shell, the Brevo CLI\n  (`npm i -g @getbrevo/cli`, then `brevo skill install`). `brevo skill check` lists copies that are\n  behind.\n- Once per conversation, call `list_brevo_guides` with `installed` set to the version in the\n  `metadata` of each Brevo skill you have, if the tool accepts `installed`; otherwise call it\n  with no arguments and compare the versions yourself. For a `stale` one, follow its `update`\n  hint.\n- If you don't have the skill, call `get_brevo_guide` with its name: it returns the current text.\n\n## Working rules for every step\n\n- Follow the steps in order. Don't skip, merge or reorder them, and don't add steps this skill\n  doesn't have.\n- Use only the tools this skill names, with the arguments it describes. Never invent a tool, a\n  parameter, an ID or an email address; ask the user instead, one question at a time.\n- Before anything is created, changed or sent, say in plain words what will happen and wait for\n  the user's yes. A yes covers only what you described.\n- Read each Brevo object once per conversation and reuse it. Re-read only after something\n  changed it.\n- Report a result only from what the tool returned. If a call failed or returned nothing,\n  say so; never describe it as done.\n- Reply in the user's language, and keep names, IDs and addresses exactly as Brevo shows them.\n\n## Conversation cache (every email skill)\n\nKeep what you read from Brevo in this conversation and reuse it, instead of calling the same\ntool again. The cache is your own notes in the conversation, never a file. Key every entry by\naccount **and** sub-account ID (none for the main account), and note when you fetched it\n(`fetchedAt`). Never show or reuse an entry from another account or sub-account.\n\n| What | Keep it | Fetch again when |\n|---|---|---|\n| Account (company, address, own email), senders, contact attributes | About 10 minutes | Time is up. An attribute in the email isn't in the cached list and the cache is more than about a minute old: fetch the attributes once more before reporting it (the user may have just added it). The user switches account or sub-account, or says they changed it in Brevo |\n| Sender domains (whether each is authenticated) | Same as senders | Same as senders |\n| Brand kit | The whole conversation (one read) | The user says they changed it in Brevo, or switches account. After this conversation's own save, update the cache with the approved values; don't read it back |\n| Templates this conversation created or read | The whole conversation | The user says they edited it in Brevo's editor (fetch it before a preview or test). After this conversation's own update, apply the change to the cache |\n| Lists and segments | Not cached | Fetch when needed |\n\n- **A failed fetch never blocks.** Skip the check that needed it, say so in one line (\"I\n  couldn't read your contact attributes, so that check was skipped\"), and go on.\n- **Errors:** a 5xx is retried once, then the user is told it is on Brevo's side. A 404 on a\n  cached template: drop it from the cache and tell the user it no longer exists. A 429 on\n  the brand kit: keep the cached kit and say the hourly limit is reached.\n- **\"What do you have cached?\"** List each entry (what, account, when fetched) without\n  secrets. **\"Refresh\"** clears everything; fetch again as each step needs it.\n- If you can't tell how much time has passed, fetch the 10-minute items again when the user\n  starts a new email.\n- Never keep API keys, tokens or passwords in the cache or anywhere in the conversation.\n\n**Call budget** for a transactional template (write, check, save, preview, test): about 11\ncalls with the cache (account, senders, attributes, brand kit, save, 3 sample renders,\nsender domains, test send, outcome) against about 16 without it (the account read 3 times,\nattributes and senders twice, and the template read back). Each fix round that re-checks\nattributes would add one more call without it.\n\n## 1. Collect the inputs\n\n- **What to test:** a draft campaign or a transactional template, by ID or name. Read it with\n  `email_campaign_management_get_email_campaign` (pass `excludeHtmlContent: true`) or\n  `templates_get_smtp_template`, or use the cached copy (see the cache table). Fetch\n  templates one at a time by ID: a template list returns the full HTML of every template, so\n  never list many at once.\n- **Test addresses**, for a test send: the addresses the user names. If they say \"send me a\n  test\", ask for their address; don't assume it. Never add addresses of your own choosing.\n\n## 2. Preview\n\n**Campaign:** nothing to render through the connection; step 3 gives the link. Don't give\nthe \"shared template\" link as a preview: it is a link to import the email into another Brevo\naccount, and opens a sign-in page, not the email.\n\n**Template:** render it on Brevo's servers with\n`templates_post_preview_smtp_email_templates`:\n\n- Pass `templateId` and `email` of an **existing contact** (the account's own email works),\n  plus the sample `params` when the template uses `params.*`. With `params` alone (no\n  `email`) the render fails with 400 \"Contact not found\" whenever the template uses\n  `contact.*` tags.\n- The unsubscribe link renders with an empty `href` in the preview: expected, not a fault\n  (it is filled in for real sends).\n- Use invented sample data, never a real customer's.\n- Render three times: with the full sample; with empty lists and missing optional keys; and\n  with `params: {}`, which is what a test send uses (see step 4). A drag-and-drop copy of HTML\n  that already passed these three renders needs one render, with `params: {}`: each render\n  returns the whole HTML, so don't repeat what the HTML version proved.\n- Don't paste the rendered HTML into the chat: report the subject, whether it rendered, and\n  anything that looks wrong (an empty greeting, a missing item line, literal `{{ }}`).\n- 403 \"required scope not present\": the connection doesn't allow renders. Say so once, skip\n  the renders, and go on to step 3. Tell the user the test send's outcome check (step 4) is\n  then the only render check, and that it uses no `params`.\n\n## 3. Share the preview link, then stop\n\nBefore any test send, give the user a link to look at the email themselves, and wait:\n\n- **Template** (drag-and-drop or HTML): `https://app.brevo.com/templates/email/edit/<id>`.\n  The user signs in to Brevo and uses Preview there.\n- **Campaign:** `https://app.brevo.com/marketing-campaign/edit/<id>`.\n\nSay that the link shows the saved email without the sample data (no `params`, no sample\ncontact). Ask: \"Open it and tell me if it looks right. Shall I send a test, and to which\naddress?\" Send nothing until the user answers yes in this conversation. If they ask for\nchanges, go back to `email-template-write`; after the update, the cached template carries\nthe change. Then render once with `params: {}`, give the link again, and wait for a new yes:\nan earlier yes doesn't cover the changed template.\n\n## 4. Send a test (confirm every time)\n\n**A template test send carries no `params`.** Every `{{ params.* }}`, in the body and in the\nsubject, renders blank, and a filter that needs a value (for example `time_parse` on an empty\ndate) fails the whole email, so nothing arrives. Tell the user before sending that the test\nshows the layout and contact data only, not their sample order; the `params: {}` render in\nstep 2 shows what the test will look like. A test works on an inactive template.\n\n**Check the sender's domain first.** Read the sender (template or campaign) and look for the sender's email domain in the\naccount's domains (cached with the senders). When the domain isn't there or isn't\nauthenticated, or it is a free or shared mailbox domain (gmail.com, yahoo.com and the\nlike), warn: Gmail and Yahoo reject or bounce mail from unauthenticated domains (DMARC),\nso the test may never arrive. Suggest authenticating the domain in Brevo (Senders,\nDomains) or using a sender on an authenticated domain. Let the user decide; don't block the\ntest.\n\nShow, and ask \"Send it?\":\n\n```\nSend a test:\n- Email: <campaign or template name> (ID <id>)\n- From: <sender email> (domain authenticated: yes | no | not checked)\n- To: <address 1>, <address 2>\nTest sends carry no params and are limited to 50 a day.\n```\n\nOn a yes in this conversation:\n\n- **Template:** `templates_send_test_template` with `templateId` and `emailTo` = exactly the\n  confirmed addresses.\n- **Campaign:** `email_campaign_management_send_test_email` with `campaignId` and `emailTo` =\n  exactly the confirmed addresses.\n\n**Never call a test send with an empty or missing `emailTo`:** Brevo then sends the test to\nthe account's whole test list. A new address, or a second test, needs a new confirmation.\n\n### Check the outcome\n\nA success response (204) only means Brevo **queued** the test. The send can still fail\nafterwards (a render error, a missing sender, a bounce). Never say \"sent\" or \"delivered\" on\nthe response alone.\n\n- **Template:** say the test was **queued**, and offer to check what happened to it. Events\n  take a minute or more to appear, so don't wait or poll. When the user asks, call\n  `campaign_analytics_get_email_event_report` with `templateId`, `email` = one test address\n  and `days: 1`. Report the newest events for this send: `delivered` means it reached the\n  mail server; `error`, `softBounces`, `hardBounces`, `blocked` or `invalid` mean it didn't.\n  Quote the `reason` and explain it in plain words (\"the date filter got an empty value\", \"the\n  sender email is missing\", \"Gmail refused the unauthenticated sender domain\"). An empty\n  report, or only `requests`: not logged yet; say it is still queued and offer to check again.\n  Never read either as success or failure.\n- **Campaign:** say the test was **queued**, not that it arrived. Ask the user to check\n  their inbox and spam folder. When the domain check said \"no\", say it will very likely not\n  arrive.\n\nThen say to whom it went and that test sends are limited to 50 a day.\n\n## Refusals and errors\n\n| Response | Meaning | Tell the user |\n|---|---|---|\n| 400 listing addresses not found, blocked, or in no list | The test address must exist as a contact, not be blocked, and belong to a list | Which address and why; they can add it as a contact in Brevo |\n| 400 \"Contact not found\" on a preview | The `email` passed isn't a contact, or `params` were sent alone for a template with contact attributes | Pass an existing contact's email plus the params |\n| A cached template returns 404 | It was deleted in Brevo | Drop it from the cache; tell the user it no longer exists |\n| Daily limit reached | 50 test sends a day | Try again tomorrow, or preview instead |\n| Event `error` with a template error (for example `time_parse`) | The template failed to render without params | Guard the line with `{% if params.x %}` (`email-template-check`), save, test again |\n| Event `error` \"From field is missing\" | The template has a sender ID but no sender email | Set the sender on the template (`email-template-to-dnd` step 4), or in Brevo |\n| Soft or hard bounce mentioning DMARC or authentication | The sender's domain isn't authenticated | Authenticate the domain in Brevo, or use a sender on an authenticated domain |\n| 403 \"required scope not present\" on a render | The connection doesn't allow template renders | Skip the renders (step 2); the test send's outcome check stands in |\n\nDon't retry a refused call in a loop: one retry at most, after the user fixed the cause.\n\n## Requirements\n\n- `email_campaign_management_send_test_email`: campaign test send.\n- `templates_post_preview_smtp_email_templates`: render a template with an existing\n  contact's email and sample params.\n- `campaign_analytics_get_email_event_report`: events of a template test send, with the\n  error or bounce reason.\n- `domains_get_domains`: the account's domains and whether each is authenticated.\n- On a sub-account, every call passes `subaccount_id`.\n\nNo tool reads the outcome of a campaign test send: the user checks their inbox.\n\nNo browser or screenshot step: the preview is a link the user opens, or a server render.\nThe shared template link (`email_campaign_management_get_shared_template_url`) isn't used:\nit is an import link for another account, not a preview.\n\n## Output rules\n\n- Do one thing per request: create one template, one campaign, one list. Never create a\n  second object to \"fix\" the first without the user's go-ahead.\n- Don't paste large inputs or outputs (HTML, design JSON, full reports) into the chat\n  unless the user asks. Summarize them.\n- Describe problems by what the user sees (\"the 'Shop the sale' button\"), never by\n  selectors, block types or internal field names.\n- Always end with the object's name, its ID, a link to it in Brevo, and what the user\n  still has to do there.\n"
}

SHA-256 of public snapshot: d23de4bfbf295c7e0b2d5d1fbdc551885fb598597936ad6fc3de1f49f0af99b4