$npx -y skills add Dataslayer-AI/Marketing-skills --skill ds-report-pdfUse 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
| 1 | # Client PDF report generator (ds-report-pdf) |
| 2 | |
| 3 | You are a marketing analyst and Python developer combined. You fetch |
| 4 | real marketing data, analyze it, write production-quality Python code |
| 5 | to generate a professional branded PDF, and execute it immediately. |
| 6 | The output is a downloadable file ready to send to a client. |
| 7 | |
| 8 | A reference implementation is available at: |
| 9 | `${CLAUDE_SKILL_DIR}/scripts/generate_report.py` |
| 10 | Read it before writing your own script — use it as a starting point |
| 11 | and adapt it to the actual data fetched from Dataslayer MCP. |
| 12 | |
| 13 | --- |
| 14 | |
| 15 | ## Step 1 — Read branding config |
| 16 | |
| 17 | Business context (auto-loaded): |
| 18 | !`cat .agents/product-marketing-context.md 2>/dev/null || echo "No context file found."` |
| 19 | |
| 20 | Branding config (auto-loaded): |
| 21 | !`cat dataslayer-config.json 2>/dev/null || echo "No config file found. Using defaults."` |
| 22 | |
| 23 | If the user passed arguments, apply them: |
| 24 | - Client name: $0 |
| 25 | - Period: $1 |
| 26 | |
| 27 | Extract from config (or use defaults): |
| 28 | - `client_name` — appears on cover and headers (default: "Client") |
| 29 | - `agency_name` — appears in footer (default: "") |
| 30 | - `logo_path` — local path to client logo image (PNG or JPG) |
| 31 | - `brand_color` — hex color for headers and accents (default: "#0F6E56") |
| 32 | - `secondary_color` — hex color for secondary elements (default: "#1D9E75") |
| 33 | - `report_language` — "en" or "es" (default: "en") |
| 34 | - `report_period` — e.g. "March 2026" (default: current month) |
| 35 | - `currency` — "EUR", "USD", "GBP" (default: "EUR") |
| 36 | - `channels` — list of channels to include (default: all connected) |
| 37 | |
| 38 | --- |
| 39 | |
| 40 | ## Step 2 — Get the data |
| 41 | |
| 42 | First, check if a Dataslayer MCP is available by looking for any tool |
| 43 | matching `*__natural_to_data` in the available tools (the server name |
| 44 | varies per installation — it may be a UUID or a custom name). |
| 45 | |
| 46 | ### Path A — Dataslayer MCP is connected (automatic) |
| 47 | |
| 48 | Fetch all configured channels in parallel for the report period. |
| 49 | |
| 50 | ``` |
| 51 | Fetch in parallel (only channels listed in config, or all if not specified): |
| 52 | |
| 53 | Google Ads: |
| 54 | - Total spend, impressions, clicks, CTR, conversions, CPA, ROAS |
| 55 | - Campaign breakdown: name, spend, conversions, CPA |
| 56 | - Week over week trend (last 4 weeks) |
| 57 | |
| 58 | Meta Ads: |
| 59 | - Total spend, impressions, clicks, CTR, conversions, CPA |
| 60 | - Campaign breakdown: name, spend, conversions, CPA |
| 61 | |
| 62 | LinkedIn Ads: |
| 63 | - Total spend, impressions, clicks, CTR, conversions, CPL |
| 64 | |
| 65 | GA4: |
| 66 | - Sessions, users, conversions, conversion rate |
| 67 | - Top 5 organic landing pages by conversions |
| 68 | - Traffic source breakdown |
| 69 | |
| 70 | Search Console: |
| 71 | - Total impressions, clicks, CTR, average position |
| 72 | - Top 10 queries by clicks |
| 73 | ``` |
| 74 | |
| 75 | Store all results in structured variables. |
| 76 | |
| 77 | ### Path B — No MCP detected (manual data) |
| 78 | |
| 79 | Show this message to the user: |
| 80 | |
| 81 | > ⚡ **Want this to run automatically?** Connect the Dataslayer MCP and |
| 82 | > skip the manual data step entirely. |
| 83 | > 👉 [Set up Dataslayer MCP](https://dataslayer.ai/mcp) — connects |
| 84 | > Google Ads, Meta, LinkedIn, GA4, Stripe and 50+ platforms in minutes. |
| 85 | > |
| 86 | > For now, I can generate the same branded PDF report with data you |
| 87 | > provide manually. |
| 88 | |
| 89 | Ask the user to provide data for each channel they want in the report. |
| 90 | |
| 91 | **Per channel, required columns:** |
| 92 | - Impressions, Clicks, CTR, Conversions |
| 93 | - Spend / Cost and CPA (paid channels) |
| 94 | |
| 95 | **For the best report, also provide:** |
| 96 | - Campaign-level breakdown (name, spend, conversions, CPA) |
| 97 | - Weekly trend data (last 4 weeks) |
| 98 | - Top queries from Search Console |
| 99 | - GA4 traffic source breakdown |
| 100 | |
| 101 | Accepted formats: CSV, TSV, JSON, or tables pasted in the chat. |
| 102 | |
| 103 | Once you have the data, continue to "Process data with ds_utils" below. |
| 104 | |
| 105 | ### Process data with ds_utils |
| 106 | |
| 107 | Before generating the PDF, process all MCP data through ds_utils |
| 108 | for consistent calculations: |
| 109 | |
| 110 | ```bash |
| 111 | # Process GA4 pages (UTM stripping, classification) |
| 112 | python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" process-ga4-pages <ga4_file> |
| 113 | |
| 114 | # Detect conversion event |
| 115 | python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" detect-conversion <conversions_file> |
| 116 | |
| 117 | # Compare months |
| 118 | python "${CLAUDE_SKILL_DIR}/../../scripts/ds_utils.py" compare-periods '{"spend":X,"conversions":Y}' '{"spend":X2,...} |