Plan overview
Weekly Market Intelligence Brief
Research a full week of debt-relief market signals — regulatory enforcement, competitor moves, consumer-lending news, macro developments, and a nine-metric economic dashboard — then render a branded HTML email and send it through Resend. Built to run on a schedule.
Best for
Sales leadership · Marketing · Industry analysts
Runs with
Internet search · Resend · HTML email
At a glance
04
Outputs
02
Capabilities
03
Teams
Core outputs
Leading-indicators dashboard
Regulatory & competitor roundup
Branded HTML email
Delivered via Resend
Capability requirements
What it solves
A weekly industry brief means one person manually scanning regulators, competitors, and economic data across a dozen sources, then hand-building an email — so it's late, inconsistent, and easy to skip on a busy week.
Turns a manual weekly research-and-build task into a hands-off scheduled run.
Keeps the brief compliance-first and consistent every single week.
Computes and delivers in one plan — no separate reporting or email pipeline.
Workflow
Search the week's regulatory, competitor, consumer-lending, marketing, and macro developments in parallel sessions.
Pull the latest nine leading economic indicators with prior-period comparisons for the dashboard.
Render a branded, mobile-safe HTML brief (with a plain-text fallback) in code and send it through the Resend MCP server.
Implementation
Review the underlying FML plan — the sessions, tools, and typed schemas that define this workflow — and see exactly how it is instructed for repeatable execution.
FML Plan
weekly-brief.fml
287 lines
system("You are an expert financial researcher and industry analyst for a major debt settlement company.") require mcp Resend parameter("timeframe", type=string, default="this past week") parameter("to_address", type=string, title="To Address") session("regulatory_news") { use search + Search for news from {{ .params.timeframe }} regarding the Debt Settlement Industry, focusing on FTC and CFPB regulatory or enforcement developments. - Extract the key regulatory updates and general debt settlement industry news. schema { updates: { category: string # e.g., "FTC Enforcement", "CFPB Rulemaking", "General Industry" headline: string summary: string # detailed summary of the news sourceUrl?: string }[] } } session("competitor_updates") { use search + Search for news and developments from {{ .params.timeframe }} for major debt settlement companies: Freedom Debt Relief (Achieve), National Debt Relief, Accredited Debt Relief, Beyond Finance, DebtBlue, Alleviate, ClearOne Advantage, and JG Wentworth. - Compile the most significant news, product launches, or leadership changes for these companies. schema { companyUpdates: { companyName: string newsSummary: string sourceUrl?: string }[] } } session("lending_and_marketing") { use search + Search for news from {{ .params.timeframe }} on the broader Consumer Lending market. + Search for recent marketing trends specific to consumer lending and debt relief, particularly around paid social (TikTok/Meta), lead generation, and marketing compliance. - Synthesize the consumer lending news and marketing trends into structured insights. schema { consumerLendingNews: { headline: string summary: string sourceUrl?: string }[] marketingTrends: { trend: string description: string complianceNotes: string # Any regulatory or compliance implications for marketing }[] } } session("macro_economics") { use search + Search for macroeconomic news from {{ .params.timeframe }} relevant to a debt relief marketing company. Focus heavily on Federal Reserve policy, the jobs market, and inflation reports. - Extract the top macroeconomic developments and their potential impact on debt relief demand. schema { developments: { topic: string # e.g., "Fed Policy", "Inflation", "Jobs" summary: string impactOnDebtRelief: string # How this specifically affects the debt relief sector }[] } } session("economic_dashboard") { use search + Find the most recently published data (from FRED or the Federal Reserve) for the following indicators: 1. Fed funds rate 2. Unemployment rate 3. Labor force participation 4. Personal savings rate 5. Total household debt 6. Credit card balances 7. Credit card delinquency rate 8. Credit card charge-off rate 9. Average credit card APR Look for current values and prior-period comparisons. - Extract the data to populate the Leading Indicators Dashboard. schema { metrics: { indicator: string # The name of the economic indicator currentValue: string # The most recent value (include date/period if known) priorPeriodValue: string # The value from the previous reporting period trend: string # "Up", "Down", or "Flat" source: string # Data source, e.g., "FRED", "Federal Reserve" }[] } } session("send_email", after="economic_dashboard") { use mcp Resend # ── Render the branded HTML (+ plain-text fallback) from all session # outputs. Resend cannot loop over arrays, so we build the rows here and hand # finished html/text to send-email. Result is routed to vars.email. call("render_email") -> vars:email { code( ( const esc = (s) => String(s == null ? '' : s) .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') .replace(/"/g, '"').replace(/'/g, '''); const NAVY = '#031D48', GOLD = '#D4A72C', GOLD_LT = '#F4C94E', INK = '#31384A', MUTE = '#6B7385', FAINT = '#9AA1B0', LINE = '#E3E7EF', ZEBRA = '#F7F9FC', BG = '#EEF1F6'; const FONT = "'Segoe UI',Arial,Helvetica,sans-serif"; const d = args.data || {}; const timeframe = args.timeframe || ''; const unsub = args.unsub || '#'; const recipient = 'the Sales Management Team'; const metrics = ((d.economic_dashboard || {}).metrics) || []; const devs = ((d.macro_economics || {}).developments) || []; const regs = ((d.regulatory_news || {}).updates) || []; const comps = ((d.competitor_updates || {}).companyUpdates) || []; const lend = ((d.lending_and_marketing || {}).consumerLendingNews) || []; const mkt = ((d.lending_and_marketing || {}).marketingTrends) || []; const intro = "This week's signals continue to favor the debt-relief category: household debt, " + "credit card balances, delinquency and charge-off rates are all rising while incomes stay " + "capped, even as the Fed holds a “higher for longer” stance. Regulatory enforcement " + "remains active, so compliance-first positioning stays essential. Details below."; const trend = (t) => { const k = String(t || '').toLowerCase(); if (k === 'up') return ['▲', 'Up', '#1E8E5A']; if (k === 'down') return ['▼', 'Down', '#C0392B']; return ['▬', 'Flat', MUTE]; }; const hdr = (title) => '<tr><td class="px" style="padding:30px 32px 0 32px;"><table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr>' + '<td style="border-left:4px solid ' + GOLD + ';padding:2px 0 2px 12px;"><h2 style="margin:0;font-family:' + FONT + ';font-size:16px;font-weight:700;letter-spacing:0.6px;color:' + NAVY + ';text-transform:uppercase;">' + esc(title) + '</h2></td>' + '</tr></table></td></tr>'; const dashRows = metrics.map((m, i) => { const bg = i % 2 ? ZEBRA : '#FFFFFF'; const tr = trend(m.trend); return '<tr>' + '<td style="padding:11px 14px;font-family:' + FONT + ';font-size:13px;color:' + INK + ';border-top:1px solid ' + LINE + ';background-color:' + bg + ';">' + esc(m.indicator) + '</td>' + '<td style="padding:11px 14px;font-family:' + FONT + ';font-size:13px;font-weight:700;color:' + NAVY + ';border-top:1px solid ' + LINE + ';background-color:' + bg + ';">' + esc(m.currentValue) + '</td>' + '<td style="padding:11px 14px;font-family:' + FONT + ';font-size:13px;color:' + MUTE + ';border-top:1px solid ' + LINE + ';background-color:' + bg + ';">' + esc(m.priorPeriodValue) + '</td>' + '<td align="center" style="padding:11px 14px;font-family:' + FONT + ';font-size:13px;font-weight:700;color:' + tr[2] + ';border-top:1px solid ' + LINE + ';background-color:' + bg + ';white-space:nowrap;">' + tr[0] + ' ' + tr[1] + '</td>' + '<td style="padding:11px 14px;font-family:' + FONT + ';font-size:11px;color:' + FAINT + ';border-top:1px solid ' + LINE + ';background-color:' + bg + ';">' + esc(m.source) + '</td>' + '</tr>'; }).join(''); const dashboard = '<tr><td class="px" style="padding:14px 32px 0 32px;"><table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border:1px solid ' + LINE + ';border-radius:8px;overflow:hidden;">' + '<tr>' + '<td style="background-color:' + NAVY + ';padding:11px 14px;font-family:' + FONT + ';font-size:11px;font-weight:700;letter-spacing:0.5px;color:#FFFFFF;text-transform:uppercase;">Indicator</td>' + '<td style="background-color:' + NAVY + ';padding:11px 14px;font-family:' + FONT + ';font-size:11px;font-weight:700;letter-spacing:0.5px;color:#FFFFFF;text-transform:uppercase;">Current</td>' + '<td style="background-color:' + NAVY + ';padding:11px 14px;font-family:' + FONT + ';font-size:11px;font-weight:700;letter-spacing:0.5px;color:#FFFFFF;text-transform:uppercase;">Prior</td>' + '<td align="center" style="background-color:' + NAVY + ';padding:11px 14px;font-family:' + FONT + ';font-size:11px;font-weight:700;letter-spacing:0.5px;color:' + GOLD_LT + ';text-transform:uppercase;">Trend</td>' + '<td style="background-color:' + NAVY + ';padding:11px 14px;font-family:' + FONT + ';font-size:11px;font-weight:700;letter-spacing:0.5px;color:#FFFFFF;text-transform:uppercase;">Source</td>' + '</tr>' + dashRows + '</table>' + '<p style="margin:8px 0 0 0;font-family:' + FONT + ';font-size:11px;color:' + FAINT + ';">Trend reflects directional change vs. the prior reporting period: ▲ Up ▼ Down ▬ Flat.</p></td></tr>'; const macro = devs.map((x) => '<tr><td class="px" style="padding:14px 32px 0 32px;"><table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border:1px solid ' + LINE + ';border-radius:8px;"><tr><td style="padding:14px 16px;">' + '<p style="margin:0 0 6px 0;font-family:' + FONT + ';font-size:12px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;color:' + GOLD + ';">' + esc(x.topic) + '</p>' + '<p style="margin:0 0 10px 0;font-family:' + FONT + ';font-size:14px;line-height:21px;color:' + INK + ';">' + esc(x.summary) + '</p>' + '<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:' + ZEBRA + ';border-radius:6px;"><tr><td style="padding:10px 12px;font-family:' + FONT + ';font-size:13px;line-height:20px;color:' + NAVY + ';"><span style="font-weight:700;color:' + GOLD + ';">Impact on debt relief:</span> ' + esc(x.impactOnDebtRelief) + '</td></tr></table>' + '</td></tr></table></td></tr>').join(''); const regulatory = regs.map((u) => { const link = u.sourceUrl ? ' <a href="' + esc(u.sourceUrl) + '" style="color:' + GOLD + ';text-decoration:underline;font-size:12px;">Source ↗</a>' : ''; return '<tr><td class="px" style="padding:14px 32px 0 32px;"><table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border:1px solid ' + LINE + ';border-left:4px solid ' + NAVY + ';border-radius:6px;"><tr><td style="padding:13px 16px;">' + '<span style="display:inline-block;background-color:' + NAVY + ';color:' + GOLD_LT + ';font-family:' + FONT + ';font-size:10px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;padding:3px 8px;border-radius:3px;">' + esc(u.category) + '</span>' + '<p style="margin:9px 0 5px 0;font-family:' + FONT + ';font-size:15px;font-weight:700;line-height:21px;color:' + NAVY + ';">' + esc(u.headline) + '</p>' + '<p style="margin:0;font-family:' + FONT + ';font-size:13px;line-height:20px;color:' + INK + ';">' + esc(u.summary) + link + '</p>' + '</td></tr></table></td></tr>'; }).join(''); const competitorRows = comps.map((c, i) => { const bg = i % 2 ? ZEBRA : '#FFFFFF'; return '<tr>' + '<td valign="top" width="34%" style="padding:12px 14px;font-family:' + FONT + ';font-size:14px;font-weight:700;color:' + NAVY + ';border-top:1px solid ' + LINE + ';background-color:' + bg + ';">' + esc(c.companyName) + '</td>' + '<td valign="top" style="padding:12px 14px;font-family:' + FONT + ';font-size:13px;line-height:20px;color:' + INK + ';border-top:1px solid ' + LINE + ';background-color:' + bg + ';">' + esc(c.newsSummary) + '</td>' + '</tr>'; }).join(''); const competitors = '<tr><td class="px" style="padding:14px 32px 0 32px;"><table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border:1px solid ' + LINE + ';border-radius:8px;overflow:hidden;">' + '<tr><td style="background-color:' + NAVY + ';padding:11px 14px;font-family:' + FONT + ';font-size:11px;font-weight:700;letter-spacing:0.5px;color:#FFFFFF;text-transform:uppercase;">Company</td>' + '<td style="background-color:' + NAVY + ';padding:11px 14px;font-family:' + FONT + ';font-size:11px;font-weight:700;letter-spacing:0.5px;color:' + GOLD_LT + ';text-transform:uppercase;">This Week</td></tr>' + competitorRows + '</table></td></tr>'; const lending = lend.map((it) => { const link = it.sourceUrl ? ' <a href="' + esc(it.sourceUrl) + '" style="color:' + GOLD + ';text-decoration:underline;font-size:12px;">Source ↗</a>' : ''; return '<tr><td class="px" style="padding:12px 32px 0 32px;"><table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr>' + '<td valign="top" width="10" style="padding-top:6px;"><div style="width:7px;height:7px;background-color:' + GOLD + ';border-radius:50%;"></div></td>' + '<td style="padding-left:10px;"><p style="margin:0 0 3px 0;font-family:' + FONT + ';font-size:14px;font-weight:700;color:' + NAVY + ';">' + esc(it.headline) + '</p>' + '<p style="margin:0;font-family:' + FONT + ';font-size:13px;line-height:20px;color:' + INK + ';">' + esc(it.summary) + link + '</p></td>' + '</tr></table></td></tr>'; }).join(''); const marketing = mkt.map((t) => '<tr><td class="px" style="padding:12px 32px 0 32px;"><table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border:1px solid ' + LINE + ';border-radius:8px;"><tr><td style="padding:13px 16px;">' + '<p style="margin:0 0 6px 0;font-family:' + FONT + ';font-size:14px;font-weight:700;color:' + NAVY + ';">' + esc(t.trend) + '</p>' + '<p style="margin:0 0 9px 0;font-family:' + FONT + ';font-size:13px;line-height:20px;color:' + INK + ';">' + esc(t.description) + '</p>' + '<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#FBF4DE;border-radius:6px;"><tr><td style="padding:9px 12px;font-family:' + FONT + ';font-size:12px;line-height:18px;color:#6A5410;"><span style="font-weight:700;">Compliance:</span> ' + esc(t.complianceNotes) + '</td></tr></table>' + '</td></tr></table></td></tr>').join(''); const html = '<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head>' + '<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="x-apple-disable-message-reformatting">' + '<title>Your Company — Weekly Intelligence Brief</title>' + '<!--[if mso]><noscript><xml><o:OfficeDocumentSettings><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml></noscript><![endif]-->' + '<style>body,table,td,a{-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}table,td{mso-table-lspace:0pt;mso-table-rspace:0pt;}img{-ms-interpolation-mode:bicubic;border:0;}table{border-collapse:collapse!important;}body{margin:0!important;padding:0!important;width:100%!important;background-color:' + BG + ';}@media screen and (max-width:600px){.container{width:100%!important;}.px{padding-left:18px!important;padding-right:18px!important;}.h1{font-size:22px!important;line-height:28px!important;}}</style></head>' + '<body style="margin:0;padding:0;background-color:' + BG + ';">' + '<div style="display:none;max-height:0;overflow:hidden;mso-hide:all;font-size:1px;line-height:1px;color:' + BG + ';">Weekly debt-relief market intelligence.</div>' + '<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:' + BG + ';"><tr><td align="center" style="padding:24px 12px;">' + '<table role="presentation" class="container" width="640" cellpadding="0" cellspacing="0" style="width:640px;max-width:640px;background-color:#FFFFFF;border-radius:10px;overflow:hidden;box-shadow:0 2px 8px rgba(3,29,72,0.08);">' + '<tr><td style="background-color:' + NAVY + ';padding:22px 32px;" class="px"><table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr>' + '<td align="left" style="font-family:' + FONT + ';font-size:24px;font-weight:800;letter-spacing:1.5px;color:#FFFFFF;">YOUR<span style="color:' + GOLD_LT + ';">BRAND</span></td>' + '<td align="right" style="font-family:' + FONT + ';font-size:11px;font-weight:600;letter-spacing:1px;color:' + GOLD + ';text-transform:uppercase;">Weekly Intelligence Brief</td>' + '</tr></table></td></tr>' + '<tr><td style="height:4px;background-color:' + GOLD + ';line-height:4px;font-size:0;"> </td></tr>' + '<tr><td class="px" style="padding:30px 32px 6px 32px;">' + '<p style="margin:0 0 6px 0;font-family:' + FONT + ';font-size:12px;font-weight:700;letter-spacing:1.5px;text-transform:uppercase;color:' + GOLD + ';">Debt Relief Market Intelligence</p>' + '<h1 class="h1" style="margin:0;font-family:' + FONT + ';font-size:26px;line-height:32px;font-weight:800;color:' + NAVY + ';">Weekly Sales Brief</h1>' + '<p style="margin:10px 0 0 0;font-family:' + FONT + ';font-size:13px;color:' + MUTE + ';">Week of ' + esc(timeframe) + ' • Prepared for ' + esc(recipient) + '</p></td></tr>' + '<tr><td class="px" style="padding:16px 32px 0 32px;"><p style="margin:0;font-family:' + FONT + ';font-size:14px;line-height:22px;color:' + INK + ';">' + esc(intro) + '</p></td></tr>' + hdr('Economic Dashboard — Leading Indicators') + dashboard + hdr('Macro-Economic Developments') + macro + hdr('Regulatory News') + regulatory + hdr('Competitor Updates') + competitors + hdr('Consumer Lending News') + lending + hdr('Marketing Trends') + marketing + '<tr><td style="height:12px;line-height:12px;font-size:0;"> </td></tr>' + '<tr><td style="background-color:' + NAVY + ';padding:26px 32px;" class="px">' + '<p style="margin:0 0 4px 0;font-family:' + FONT + ';font-size:16px;font-weight:800;letter-spacing:1px;color:#FFFFFF;">YOUR<span style="color:' + GOLD_LT + ';">BRAND</span></p>' + '<p style="margin:0 0 12px 0;font-family:' + FONT + ';font-size:12px;line-height:18px;color:#9FB0CC;">Your Company • Weekly Market Intelligence for the Sales Team</p>' + '<p style="margin:0;font-family:' + FONT + ';font-size:11px;line-height:18px;color:#6E82A6;">You\'re receiving this because you\'re part of your company\'s distribution list.<br>' + '<a href="' + esc(unsub) + '" style="color:' + GOLD + ';text-decoration:underline;">Unsubscribe</a></p></td></tr>' + '</table></td></tr></table></body></html>'; const L = (s) => String(s == null ? '' : s); let text = 'YOURBRAND — WEEKLY SALES BRIEF\nWeek of ' + timeframe + ' | Prepared for ' + recipient + '\n============================================================\n\n' + intro + '\n\nECONOMIC DASHBOARD — LEADING INDICATORS\n'; metrics.forEach((m) => { text += '* ' + L(m.indicator) + ': ' + L(m.currentValue) + ' (prior ' + L(m.priorPeriodValue) + '; ' + L(m.trend) + ') [' + L(m.source) + ']\n'; }); text += '\nMACRO-ECONOMIC DEVELOPMENTS\n'; devs.forEach((x) => { text += '# ' + L(x.topic) + '\n' + L(x.summary) + '\nImpact: ' + L(x.impactOnDebtRelief) + '\n\n'; }); text += 'REGULATORY NEWS\n'; regs.forEach((u) => { text += '[' + L(u.category) + '] ' + L(u.headline) + '\n' + L(u.summary) + '\n' + (u.sourceUrl ? 'Source: ' + L(u.sourceUrl) + '\n' : '') + '\n'; }); text += 'COMPETITOR UPDATES\n'; comps.forEach((c) => { text += '# ' + L(c.companyName) + '\n' + L(c.newsSummary) + '\n\n'; }); text += 'CONSUMER LENDING NEWS\n'; lend.forEach((it) => { text += '* ' + L(it.headline) + '\n' + L(it.summary) + '\n'; }); text += '\nMARKETING TRENDS\n'; mkt.forEach((t) => { text += '# ' + L(t.trend) + '\n' + L(t.description) + '\nCompliance: ' + L(t.complianceNotes) + '\n\n'; }); text += '============================================================\nUnsubscribe: ' + unsub + '\n'; ({ html: html, text: text }); ) ) data = $( context ) timeframe = "{{ .params.timeframe }}" unsub = "https://example.com/unsubscribe" } call("send-email") { to = $( [params.to_address] ) from = "notifications@ai.example.com" subject = "Weekly Industry Brief: {{ .params.timeframe }}" html = $( vars.email.html ) text = "{{ .context | json }}" } - Output true for sentSuccessfully to confirm the session ran. schema { sentSuccessfully: bool } }