lightbreak Sign in
  1. lightbreak
  2. Developers
  3. AI agents

Let your AI agent build the newsletter.

Claude, Codex, Grok, Meta Muse or any AI assistant can work inside lightbreak: fill an issue, have lightbreak write each section in your voice, fact-check everything against its sources, and hand a finished draft to Beehiiv. A person still decides when it sends.

Actions
35Every step of an issue
Connects over
MCP or HTTPSWorks with any agent
Access
A key per agentOne workspace, revocable
Notifications
5 eventsSigned webhooks
Sends email
NeverDrafts go to your ESP

The short version

Four steps

  1. 01

    Make a key in lightbreak under Settings, then AI agents & API.

  2. 02

    Give your agent the lightbreak address and that key.

  3. 03

    Ask it to build, review or finish an issue, in plain English.

  4. 04

    Nothing reaches readers until a person schedules the draft in your ESP.

Most newsletter work is repeatable: gather the week's stories and events, write them up in the publication's voice, check the facts, and get a clean draft into the email platform. lightbreak already does each of those steps for people. Now an AI agent can do them too, using the same rules, the same section instructions and the same fact-checking review.

What an agent can do

Newsletters and issues

  • See every newsletter, start or generate an issue, read it section by section, delete it.list_publications · list_issues · list_templates · create_issue · generate_issue · get_generation_status · get_issue · get_issue_tree · delete_issue

Finding content

  • Browse the stories, events, jobs and places lightbreak already collected, read any link, manage sources.browse_content · browse_places · read_link · list_sources · add_source

Writing and editing

  • Have lightbreak write in each section's voice, add your own stories, events and jobs, edit or remove anything.write_story_for_section · add_story · add_event · add_job · update_block_text · update_issue_details · remove_blocks · save_issue_tree · upload_image_from_url · suggest_subject_lines · write_intro

Checking and finishing

  • Fact-check every link, image, claim and sentence, then export or push a draft to the ESP.review_issue · get_review · export_issue_html · push_to_beehiiv · push_to_activecampaign · mark_issue_done

Notifications

  • Get told the moment a draft is ready, a review finishes, or a draft reaches the ESP.add_notification · list_notifications · test_notification · remove_notification
At a glance

Built for creating, not sending

Every action goes through the same checks a person's clicks do: workspace access, save conflicts and the AI spend limit.

35
ActionsFrom finding a story to pushing the draft
4
Review checksLinks, images, facts and copy
5
NotificationsSigned, retried, logged
0
Emails sentA person schedules every send

How a week's issue can run

  1. 01

    Build. The agent pulls this week's stories, events and restaurants that lightbreak already collected, or brings its own.

  2. 02

    Write. lightbreak writes each piece with that section's own instructions and voice, exactly as when a person drags a story in.

  3. 03

    Review. The reviewer opens every link and source and checks each claim. The agent fixes what it flags and runs it again.

  4. 04

    Draft. The finished issue goes to Beehiiv or ActiveCampaign as a draft, and your notification tells your team it's ready.

We build the issue. Your platform sends it.How lightbreak works, for people and agents alike

Connect your agent

  1. 01

    In lightbreak, open Settings, then AI agents & API, then New key. Name it after the agent. Copy it right away: it's shown once.

  2. 02

    Give the agent the address https://app.lightbreak.ai/api/mcp and the header Authorization: Bearer followed by the key.

  3. 03

    Ask it: "List my lightbreak newsletters." If it answers, you're connected.

Claude Code terminal, Claude desktop app, Conductor

Run once, with your key in place of the placeholder:

claude mcp add --scope user --transport http lightbreak https://app.lightbreak.ai/api/mcp --header "Authorization: Bearer lbk_YOUR_KEY"
Codex OpenAI

Add to ~/.codex/config.toml:

[mcp_servers.lightbreak]
url = "https://app.lightbreak.ai/api/mcp"
http_headers = { Authorization = "Bearer lbk_YOUR_KEY" }
OpenCode opencode.json

Keep the key in its own private file and point to it:

"mcp": {
  "lightbreak": {
    "type": "remote",
    "url": "https://app.lightbreak.ai/api/mcp",
    "headers": { "Authorization": "Bearer {file:~/.secrets/lightbreak.key}" }
  }
}
Cursor, Windsurf and other MCP apps remote MCP server

Add a remote (HTTP) MCP server with the address https://app.lightbreak.ai/api/mcp and the header Authorization: Bearer followed by your key.

Grok, Meta Muse, ChatGPT and custom agents MCP, actions or plain HTTPS

If it asks for an MCP server, use the address and header above. If it asks for an OpenAPI or "actions" link, use https://app.lightbreak.ai/api/agent/openapi with the same key. Anything that can send a web request can call an action directly with POST https://app.lightbreak.ai/api/agent/<action>.

What a key can and can't do

Can

  • Everything a newsletter manager does day to day, including deleting issues and pushing drafts, inside the one workspace the key belongs to (or only the newsletters you pick).

Can't

  • Manage people or other keys, open lightbreak's screens, reach another workspace, or send email.

Questions people ask

Is it safe to give an AI a key?
A key only works inside one workspace, can't manage people or other keys, and can be switched off in one click. lightbreak keeps a fingerprint of the key, never the key itself.
Can an agent send my newsletter?
No. lightbreak doesn't send email. The furthest an agent can go is putting a draft into Beehiiv or ActiveCampaign, where a person schedules it.
Will it overwrite what my team is editing?
No. If someone saved the issue in the meantime, the agent's save is refused with a clear conflict instead of replacing their work.
Does the AI make things up?
That's what the review is for. It opens every story's source, checks each claim, and only calls something wrong when it can quote the source that proves it.
What does it cost?
Connecting is free. Writing, generating and reviewing use AI the same way they do when a person clicks the button. A full review is a few cents per issue.
{ }

For AI agents

Reference · generated from the live API

This part is written for software. If you are an AI agent helping a person use lightbreak, everything you need is here, generated from the same catalog the API serves. The same reference as plain text: lightbreak.ai/agents.md.

AConnection

MCP endpoint
https://app.lightbreak.ai/api/mcp
Transport
Streamable HTTP, JSON responses. Protocol 2025-06-18 (also 2024-11-05, 2025-03-26)
Authentication
Authorization: Bearer lbk_... (workspace API key)
Plain HTTPS
POST https://app.lightbreak.ai/api/agent/<action> with the arguments as a JSON body
OpenAPI
https://app.lightbreak.ai/api/agent/openapi (send the key)
Scope
One workspace, newsletter-manager level, optionally limited to chosen publications
Errors
HTTP status with {"error": "plain-English sentence"}; over MCP the result has isError: true
Saving
save_issue_tree needs expected_updated_at; a newer save returns 409 conflict instead of overwriting
Email
Never sent. push_to_beehiiv and push_to_activecampaign create drafts only
Keys
Created by a workspace admin at Settings > AI agents & API; shown once; revocable

BRecommended workflow

  1. list_publications, then list_issues for one publication.
  2. Either generate_issue (lightbreak's own AI writes the whole issue; poll get_generation_status) or create_issue and fill it yourself.
  3. get_issue to read it as an outline with block ids and each section's writing instructions.
  4. Edit: update_block_text for a single block's words, update_issue_details for subject and preview text, or get_issue_tree + save_issue_tree for structural changes (always pass back the updatedAt you read).
  5. review_issue, then poll get_review. The reviewer checks every link, image, fact (against each story's source) and sentence. Findings marked "wrong" include the source's own words. Fix what it finds and review again.
  6. export_issue_html, or push_to_beehiiv / push_to_activecampaign when the issue is ready. mark_issue_done marks it finished in lightbreak.
  7. Instead of polling, add_notification to be told when a draft is generated, a review finishes, or a draft reaches the ESP.

CActions (35)

ActionWhat it doesInputs
Newsletters and issues
list_publicationsList the newsletters (publications) this key can work on: id, name, slug, locale and timezone.
none
list_issuesList recent issues, newest first. Optionally only one publication.
publication_id: string (optional)
limit: integer (optional)
list_templatesSaved issue templates for a publication (or the whole workspace with scope=workspace).
publication_id: string (optional)
scope: publication | workspace (optional)
create_issueCreate an empty issue for a date from the publication's template. Returns the issue id (or the existing one for that date).
publication_id: string
date: string
generate_issueHave lightbreak's own AI write a whole issue for a date using the publication's sources and section instructions. Runs in the background; poll get_generation_status with the run id.
publication_id: string
date: string (optional)
get_generation_statusCheck a generate_issue run. When finished it includes the issue id.
publication_id: string
run_id: string
get_issueRead an issue as an outline: subject, preview text, updatedAt, and each section's writing instructions and blocks (id, kind, text, url, image).
issue_id: string
get_issue_treeRead the full raw block tree of an issue, for structural edits with save_issue_tree.
issue_id: string
delete_issueDelete an issue.
issue_id: string
Finding content
browse_contentStories, events and other items lightbreak has already collected from a publication's sources, newest first. kind: news, events, pets, jobs, tools, youtube, business, restaurants.
publication_id: string
kind: string (optional)
limit: integer (optional)
events_from: string (optional)
events_before: string (optional)
cursor: string (optional)
browse_placesLocal restaurants and businesses from the publication's directory (Google listing details, photos). kind: restaurant or business.
publication_id: string
kind: restaurant | business (optional)
search: string (optional)
city: string (optional)
page: integer (optional)
read_linkRead any web page and have lightbreak write it up for a section, using that section's writing instructions. Returns the written headline and text (and event details for event sections). Does not add it; follow with add_story or add_event.
issue_id: string
section_id: string
url: string
list_sourcesThe websites, RSS feeds and calendars lightbreak collects content from for a publication.
publication_id: string
add_sourceAdd a website, RSS feed or calendar for lightbreak to collect content from. bucket: news, events, pets, jobs...
publication_id: string
url: string
name: string (optional)
bucket: string (optional)
Writing and editing
write_story_for_sectionHave lightbreak write one story in a section's own voice from a title, summary and source link (for example an item from browse_content), then add it to the section. mode keep adds it as written instead of rewriting.
issue_id: string
section_id: string
title: string
source_url: string
summary: string (optional)
content_item_id: string (optional)
image_url: string (optional)
mode: rewrite | keep (optional)
add_storyAdd a story you wrote to a section: headline, paragraphs (**bold** and *italic* work), optional photo and Read more link. Uses the same layout the builder uses.
issue_id: string
section_id: string
headline: string
paragraphs: string[]
source_url: string (optional)
button_label: string (optional)
image_url: string (optional)
image_alt: string (optional)
add_eventAdd an event card to a section. starts_at is ISO 8601 with offset. Event sections re-sort by date and drop events outside the issue window (you are told if that happens).
issue_id: string
section_id: string
title: string
starts_at: string
venue: string
url: string
blurb: string (optional)
time_label: string (optional)
type: string (optional)
city: string (optional)
image_url: string (optional)
add_jobAdd a job listing to a section.
issue_id: string
section_id: string
title: string
company: string
url: string
salary: string (optional)
job_type: string (optional)
city: string (optional)
apply_url: string (optional)
logo_url: string (optional)
update_block_textReplace the words of one text block (headline, paragraph, list) by block id. Keeps the block's link and formatting.
issue_id: string
block_id: string
text: string
update_issue_detailsSet the email subject line and/or preview text.
issue_id: string
subject: string (optional)
preview_text: string (optional)
remove_blocksRemove blocks from an issue by id (use get_issue for ids).
issue_id: string
block_ids: string[]
save_issue_treeSave a full block tree. expected_updated_at must be the updatedAt you read; a newer save by someone else returns a conflict instead of overwriting it.
issue_id: string
tree: object
expected_updated_at: string
upload_image_from_urlCopy an image from a public URL into lightbreak's storage and return a stable URL to use in stories. PNG, JPG, WEBP or GIF, under 8 MB.
image_url: string
suggest_subject_linesThree subject line and preview text options written from the issue's content.
issue_id: string
write_introWrite the issue's intro paragraph from its headlines, in the intro section's voice.
issue_id: string
section_id: string (optional)
Checking and finishing
review_issueStart the Review Issue agent on the saved issue: links, images, a fact check of every story against its source, and a copy read. Poll get_review.
issue_id: string
get_reviewThe latest review of an issue: status, summary, and findings (severity wrong/fix/check/unverified, block id, message, the source's own words, a suggested fix).
issue_id: string
export_issue_htmlThe finished email HTML. format: beehiiv (default, exactly what is pushed to Beehiiv), html (full designed email) or native.
issue_id: string
format: beehiiv | html | native (optional)
push_to_beehiivPut the finished issue into the publication's Beehiiv account as a DRAFT post. It is not sent or scheduled; a person does that in Beehiiv.
issue_id: string
push_to_activecampaignPut the finished issue into ActiveCampaign as a draft campaign. Not sent.
issue_id: string
list_ids: string[] (optional)
mark_issue_doneMark an issue finished (or not) in lightbreak.
issue_id: string
done: boolean (optional)
Notifications
add_notificationHave lightbreak POST a signed JSON message to your https address when something happens. events: issue.generated, issue.generation_failed, review.completed, issue.pushed_to_esp, issue.marked_done. Returns a signing secret once: verify the Lightbreak-Signature header (t=<unix>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">) with it.
url: string
events: [issue.generated | issue.generation_failed | review.completed | issue.pushed_to_esp | issue.marked_done]
description: string (optional)
list_notificationsNotification addresses (webhooks) for this workspace and the events each one receives.
none
test_notificationSend a sample message to one notification address and report what the receiver answered.
notification_id: string
remove_notificationStop sending notifications to an address.
notification_id: string

DNotifications

EventSent when
issue.generatedA draft finished generating
issue.generation_failedGenerating a draft failed
review.completedAn issue review finished
issue.pushed_to_espA draft was pushed to Beehiiv or ActiveCampaign
issue.marked_doneAn issue was marked done

Each message is a JSON POST with id, type, created_at, workspace_id, publication_id, issue_id, data and links. Headers: Lightbreak-Event, Lightbreak-Delivery, and Lightbreak-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">. Up to 3 attempts on timeout, 429 or 5xx. An address that fails 25 times in a row is switched off.

import { createHmac, timingSafeEqual } from "node:crypto";

// header = the Lightbreak-Signature request header, rawBody = the exact bytes received
export function isFromLightbreak(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((part) => part.split("=")));
  const expected = Buffer.from(createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex"));
  const given = Buffer.from(parts.v1 ?? "");
  return expected.length === given.length && timingSafeEqual(expected, given);
}

EExamples

POST https://app.lightbreak.ai/api/mcp
Authorization: Bearer lbk_YOUR_KEY
Content-Type: application/json

{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"review_issue","arguments":{"issue_id":"ISSUE_ID"}}}
curl -X POST https://app.lightbreak.ai/api/agent/list_issues \
  -H "Authorization: Bearer lbk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"limit": 5}'

FRules for agents

  1. Run review_issue before push_to_beehiiv or push_to_activecampaign, and fix every finding marked wrong.
  2. Never state that a business is new, opening or long-established unless the source says so. Copy phone numbers, emails and addresses exactly.
  3. Treat a 409 conflict as a person's edit: read the issue again, then reapply your change.
  4. Tell the person which drafts you pushed. Sending always happens in their ESP.
  5. Prefer notifications (add_notification) over polling for long jobs.

GMachine-readable files

/agents.md (this reference as markdown) · /llms.txt (site summary) · https://app.lightbreak.ai/api/agent/openapi (OpenAPI 3.1, needs a key)