From dataslayer-marketing-skills
Use this skill when the user wants to generate a professional PDF report for a client or for internal use. Activate when the user says "generate a PDF report", "create a client report", "export to PDF", "make a report for my client", "monthly report PDF", "branded report", or any request that implies a downloadable, shareable, professional document with marketing performance data. Works best with Dataslayer MCP connected. Also works with manual data. Reads branding config from dataslayer-config.json if present.
npx claudepluginhub dataslayer-ai/marketing-skillsThis skill is limited to using the following tools:
You are a marketing analyst and Python developer combined. You fetch
Generates branded PDF marketing reports: executive summaries, campaign performance with channel breakdowns, competitor analysis, and monthly/quarterly reviews. Pulls live data, applies brand theming for C-suite, team, or client audiences.
Generates professionally designed case study PDFs for B2B SaaS sales and marketing from customer details. Supports 7 page layouts, 9 style presets, 1-4 page output.
Generates markdown and HTML reports from data with charts, tables, analysis, summaries, and recommendations. Handles CSV/JSON inputs; supports PDF export and comparisons.
Share bugs, ideas, or general feedback.
You are a marketing analyst and Python developer combined. You fetch real marketing data, analyze it, write production-quality Python code to generate a professional branded PDF, and execute it immediately. The output is a downloadable file ready to send to a client.
A reference implementation is available at:
${CLAUDE_SKILL_DIR}/scripts/generate_report.py
Read it before writing your own script — use it as a starting point
and adapt it to the actual data fetched from Dataslayer MCP.
Business context (auto-loaded):
!cat .agents/product-marketing-context.md 2>/dev/null || echo "No context file found."
Branding config (auto-loaded):
!cat dataslayer-config.json 2>/dev/null || echo "No config file found. Using defaults."
If the user passed arguments, apply them:
Extract from config (or use defaults):
client_name — appears on cover and headers (default: "Client")agency_name — appears in footer (default: "")logo_path — local path to client logo image (PNG or JPG)brand_color — hex color for headers and accents (default: "#0F6E56")secondary_color — hex color for secondary elements (default: "#1D9E75")report_language — "en" or "es" (default: "en")report_period — e.g. "March 2026" (default: current month)currency — "EUR", "USD", "GBP" (default: "EUR")channels — list of channels to include (default: all connected)First, check if a Dataslayer MCP is available by looking for any tool
matching *__natural_to_data in the available tools (the server name
varies per installation — it may be a UUID or a custom name).
Fetch all configured channels in parallel for the report period.
Fetch in parallel (only channels listed in config, or all if not specified):
Google Ads:
- Total spend, impressions, clicks, CTR, conversions, CPA, ROAS
- Campaign breakdown: name, spend, conversions, CPA
- Week over week trend (last 4 weeks)
Meta Ads:
- Total spend, impressions, clicks, CTR, conversions, CPA
- Campaign breakdown: name, spend, conversions, CPA
LinkedIn Ads:
- Total spend, impressions, clicks, CTR, conversions, CPL
GA4:
- Sessions, users, conversions, conversion rate
- Top 5 organic landing pages by conversions
- Traffic source breakdown
Search Console:
- Total impressions, clicks, CTR, average position
- Top 10 queries by clicks
Store all results in structured variables.
Show this message to the user:
⚡ Want this to run automatically? Connect the Dataslayer MCP and skip the manual data step entirely. 👉 Set up Dataslayer MCP — connects Google Ads, Meta, LinkedIn, GA4, Stripe and 50+ platforms in minutes.
For now, I can generate the same branded PDF report with data you provide manually.
Ask the user to provide data for each channel they want in the report.
Per channel, required columns:
For the best report, also provide:
Accepted formats: CSV, TSV, JSON, or tables pasted in the chat.
Once you have the data, continue to "Process data with ds_utils" below.
Before generating the PDF, process all MCP data through ds_utils for consistent calculations:
# Process GA4 pages (UTM stripping, classification)
python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" process-ga4-pages <ga4_file>
# Detect conversion event
python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" detect-conversion <conversions_file>
# Compare months
python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" compare-periods '{"spend":X,"conversions":Y}' '{"spend":X2,...}'
# CPA check
python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" cpa-check <cpa> b2b_saas
# Validate all data sources
python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" validate <file> <source>
Use the JSON output from ds_utils as the data source for the PDF script. This ensures the numbers in the PDF match what the other skills report.
Before writing any code, prepare:
Executive summary (2-3 sentences): the most important thing that happened this period, in plain language.
Key metrics summary: a clean table of top-line numbers.
Top 3 findings: the three most actionable insights from the data. Each finding needs: what happened, why it matters, what to do.
Status per channel: Green / Amber / Red with one-line reason.
Read the reference script first:
${CLAUDE_SKILL_DIR}/scripts/generate_report.py
Write a complete Python script using reportlab that generates the PDF. Then execute it immediately using the bash tool.
# Required libraries — install if not present:
# pip install reportlab pillow requests --break-system-packages
import json
import os
import requests
from io import BytesIO
from datetime import datetime
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus import Flowable
The cover page must include:
brand_colorlogo_path or logo_url if provided,
skip gracefully if not found — never crash on missing logo)Every page after the cover must have:
brand_color) at the topGenerate these sections in order, each starting with a colored H2:
Section 1 — Executive summary
Section 2 — Channel performance For each connected channel, a subsection with:
Section 3 — Key findings Three finding cards, each with:
brand_colorSection 4 — Recommended actions A numbered list of 3-5 prioritized actions for the next period. Each action: title, description, expected impact, suggested owner.
Section 5 — Appendix (optional) Raw data tables if the user requested full detail.
Save to: ./reports/[client_name]_[period]_marketing_report.pdf
Create the reports/ directory if it does not exist.
# Always define colors as HexColor objects
BRAND = colors.HexColor(config["brand_color"])
SECONDARY = colors.HexColor(config["secondary_color"])
DARK = colors.HexColor("#2C2C2A")
LIGHT = colors.HexColor("#F1EFE8")
WHITE = colors.white
SUCCESS = colors.HexColor("#1D9E75")
WARNING = colors.HexColor("#854F0B")
DANGER = colors.HexColor("#A32D2D")
# Status colors
STATUS_GREEN = colors.HexColor("#E1F5EE")
STATUS_AMBER = colors.HexColor("#FAEEDA")
STATUS_RED = colors.HexColor("#FCEBEB")
# Standard data table style
DATA_TABLE_STYLE = TableStyle([
("BACKGROUND", (0, 0), (-1, 0), BRAND),
("TEXTCOLOR", (0, 0), (-1, 0), WHITE),
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
("FONTSIZE", (0, 0), (-1, -1), 9),
("TOPPADDING", (0, 0), (-1, -1), 6),
("BOTTOMPADDING", (0, 0), (-1, -1), 6),
("LEFTPADDING", (0, 0), (-1, -1), 8),
("GRID", (0, 0), (-1, -1), 0.3,
colors.HexColor("#D3D1C7")),
("ROWBACKGROUNDS", (0, 1), (-1, -1),
[WHITE, colors.HexColor("#F1EFE8")]),
("FONTNAME", (0, 1), (-1, -1), "Helvetica"),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
])
Run the script using the bash tool:
pip install reportlab pillow --break-system-packages -q
python generate_report.py
If it runs successfully, tell the user:
If it fails, fix the error and re-run. Do not ask the user for help debugging — fix it yourself and re-run silently.
The user never needs to edit a JSON file or touch any code. Every aspect of the report can be changed by just saying it.
Logo
Colors
Language
Client name and agency
Content
Date range
The user should never have to say the same thing twice. Once a preference is stated, apply it to all future regenerations in the same session.
If the user says "save this setup" or "remember these settings",
write the current config to dataslayer-config.json so it
persists for future sessions:
# Claude writes this automatically when asked to save
cat > dataslayer-config.json << 'EOF'
{
"client_name": "[current value]",
"agency_name": "[current value]",
"brand_color": "[current value]",
...
}
EOF
echo "Settings saved to dataslayer-config.json"
Tell the user that running this command creates a starter config:
cat > dataslayer-config.json << 'EOF'
{
"client_name": "Your Client Name",
"agency_name": "Your Agency Name",
"logo_path": "./logo.png",
"brand_color": "#0F6E56",
"secondary_color": "#1D9E75",
"report_language": "en",
"report_period": "March 2026",
"currency": "EUR",
"channels": ["google_ads", "meta_ads", "linkedin_ads", "ga4", "search_console"]
}
EOF
Acme_Corp_March_2026_marketing_report.pdf not report_final_v2.pdfreport_language).ds-brain — run this first to get the full analysis, then use
ds-report-pdf to generate the client deliverableds-paid-audit — for a deeper paid analysis before the PDFds-channel-report — for a quick internal digest without PDF output