Report Generation¶
Cerebro MCP can produce interactive, self-contained HTML reports with ECharts visualizations, narrative markdown, and a polished UI. Reports are rendered as native UI elements in Claude Desktop and VS Code, or opened in the default browser from Claude Code.
Picking a report tool¶
All four report generators share the chart pipeline and enforcement gates. Pick the one that matches the deliverable:
| Generator | When to use | Required extras |
|---|---|---|
generate_report | Analytical dashboard. Default. Dense charts, KPIs, short commentary. | — |
generate_research_report | Long-form research essay (Anthropic-style). Whitepapers, narrative analyses, thesis pieces. | deck (≤240 chars), key_takeaways (3–6) |
generate_case_study_report | Scrollytelling layout — marketing case study, customer story, growth pitch, narrative-first investor update. | deck, key_points (3–6), optional hero_image, cta |
storyteller_generate_story_report | Final step of the storyteller pipeline (memos, decision briefs, pitches). Routes to one of the three layouts above via style="research" \| "scrollytelling" \| "dashboard". | n/a — storyteller drives args |
The research and case-study generators support extra markdown directives:
{{figure:CHART_ID caption="..." source="..."}},{{pullquote}},{{callout kind=...}},{{sidebar}}, footnotes (research){{scene chart="..." side="left|right"}},{{step chart="..." state="..."}},{{reveal}},{{image full_bleed=true}},{{cta}}(case study)
Standard {{chart:ID}} and {{grid:N}} work in all layouts.
Batch-first chart generation¶
Always call generate_charts(specs=[...]) with all charts in a single batch — multiple generate_chart calls slow the run and break gate counting. Minimum 3 charts.
generate_charts(specs=[
{"sql": "...", "chart_type": "line", "title": "...", "x_field": "dt", "y_field": "txs"},
{"sql": "...", "chart_type": "scatter", "title": "...", "x_field": "fees", "y_field": "tps", "series_field": "protocol"},
{"sql": "...", "chart_type": "bar", "title": "...", "x_field": "label", "y_field": "share"},
])
Enforcement gates¶
generate_report will REJECT a report that fails any of the following. The full ruleset (with rationale and mitigations) is on the Quality Gates page.
| Gate | What it checks |
|---|---|
| Dimensional breakdown | At least one chart with series_field, or a pie / treemap / heatmap / sankey. |
| Relational analysis | At least one scatter / heatmap chart, OR a correlation query. |
| Statistical query | At least one quantile, stddev, or corr query. |
| Exploratory queries | At least 2 EDA queries during the run. |
| Stock-flow discipline | Rejects SUM(tvl_usd \| balance \| supply) over a date range without a point-in-time constraint. |
| Residual-bucket disclosure | Rejects WHERE col != '' filters without acknowledging exclusion in chart title / subtitle. |
| Stationarity on correlations | Rejects corr(x, y) over a series with date / month / week unless first-differenced (or ADF / Spearman / cointegration / lagInFrame mentioned). |
| Aggregator volume dedup | Rejects SUM(volume_usd) over fct_execution_pools_daily etc. without dedup CTE. |
| Discovered-model coverage | Every model returned by search_models must be queried, explored, OR explicitly excluded with record_model_exclusion(name, reason). |
Telemetry: gate evaluations and discovered-model coverage are exported as Prometheus counters (cerebro_quality_gate_evaluations_total, cerebro_quality_report_generations_total, cerebro_discovered_model_coverage_total).
Key takeaways formatting¶
Key takeaways / summary sections in reports MUST use a 3-column markdown table:
| Takeaway | Evidence | Why it matters |
|---|---|---|
| Q3 retention up 8% MoM | chart_4 + corr(cohort_size, retention)=0.71 | Concentrates risk in a single onboarding cohort |
Do not use bullet lists for key takeaways. The renderer styles the table specifically.
After generate_report succeeds¶
- Always include the
file://link from the tool response in your reply. - Do NOT repeat the markdown content or
{{chart:ID}}placeholders as text — the renderer handles them. - Summarize key insights and ask whether to convert to docx / pdf / pptx (use
export_report). - SQL queries are embedded in the report UI — click
</>on each chart card.
list_reports() and open_report(id) reopen past reports. The list includes both dashboard and research-essay kinds.
Workflow Overview¶
Report generation follows a structured pipeline with three phases:
Phase 1: Analytics Reporter
search_models --> describe_table --> execute_query --> generate_chart
(discover) (verify) (sample) (visualize)
| |
+--- Repeat for each metric <-----------------------------+
|
Phase 2: UI Designer v
Assemble markdown with {{chart:CHART_ID}} placeholders
generate_report(title="...", content_markdown="...")
|
Phase 3: Reality Checker v
Validate column names, date ranges, chart types, data integrity
Step-by-Step Guide¶
Step 1: Discover Relevant Models¶
Use search_models to find dbt models relevant to your report topic.
search_models("transactions daily")
search_models("validator active", module="consensus")
search_models("bridge netflow")
Step 2: Verify Table Schemas¶
Before writing any SQL, always call describe_table to confirm exact column names. Column names in the dbt models are non-obvious and guessing will produce errors.
Step 3: Sample Data¶
Optionally use get_sample_data to preview what the data looks like.
Step 4: Generate Charts¶
Call generate_chart for each metric. The tool executes the SQL query, builds an ECharts specification, and registers the chart in an in-memory registry (2-hour TTL). It returns a chart_id (e.g., chart_1, chart_2) used as a placeholder in the report.
generate_chart(
sql="SELECT dt, txs FROM dbt.api_execution_transactions_daily WHERE dt >= today() - 30 ORDER BY dt",
chart_type="line",
x_field="dt",
y_field="txs",
title="Daily Transactions (30d)"
)
# Returns: chart_1
generate_chart(
sql="SELECT dt, active_validators FROM dbt.api_consensus_validators_active_daily WHERE dt >= today() - 30 ORDER BY dt",
chart_type="area",
x_field="dt",
y_field="active_validators",
title="Active Validators (30d)"
)
# Returns: chart_2
Step 5: Assemble the Report¶
Call generate_report with a title and markdown content. Use {{chart:CHART_ID}} placeholders where charts should appear. The markdown supports standard formatting: headings, lists, bold, italic, tables, and code blocks.
generate_report(
title="Weekly Gnosis Chain Report",
content_markdown="""
## Network Activity
Transaction volume over the past 30 days shows consistent growth.
{{chart:chart_1}}
Key observations:
- Average daily transactions: 145,000
- Peak day: March 7 with 182,000 transactions
## Validator Set
The validator set continues to grow with strong attestation participation.
{{chart:chart_2}}
- Active validators: 150,234
- Net new validators this week: +312
"""
)
Step 6: Output¶
The report is saved as a standalone HTML file at ~/.cerebro/reports/ and rendered according to the client:
| Client | Rendering |
|---|---|
| Claude Desktop | Native MCP App iframe embedded in the conversation |
| VS Code | MCP App rendered in the chat panel |
| Claude Code | Summary text with a file:// link; opens in default browser |
Chart Types¶
Line Chart¶
Best for time series trends and continuous data.
generate_chart(
sql="SELECT dt, txs FROM ...",
chart_type="line",
x_field="dt",
y_field="txs",
title="Daily Transactions"
)
Area Chart¶
Similar to line charts but with filled area beneath, emphasizing volume.
generate_chart(
sql="SELECT dt, active_validators FROM ...",
chart_type="area",
x_field="dt",
y_field="active_validators",
title="Validator Growth"
)
Bar Chart¶
Best for categorical comparisons and rankings.
generate_chart(
sql="SELECT client_name, node_count FROM ...",
chart_type="bar",
x_field="client_name",
y_field="node_count",
title="Client Distribution"
)
Pie Chart¶
Best for proportional distribution of a single dimension.
generate_chart(
sql="SELECT cloud_provider, node_count FROM ...",
chart_type="pie",
x_field="cloud_provider",
y_field="node_count",
title="Cloud Provider Share"
)
Number Display¶
Single KPI or headline metric, rendered as a large number with optional delta.
generate_chart(
sql="SELECT count() as total_txs FROM ...",
chart_type="numberDisplay",
y_field="total_txs",
title="Total Transactions"
)
Multi-Series Charts¶
Use the series_field parameter to split data into multiple series on the same chart. This works with line, area, and bar chart types.
generate_chart(
sql="SELECT dt, client_name, node_count FROM dbt.api_p2p_nodes_by_client_daily WHERE dt >= today() - 30 ORDER BY dt",
chart_type="line",
x_field="dt",
y_field="node_count",
series_field="client_name",
title="Node Count by Client"
)
Report UI Features¶
Generated reports include a React-based UI with the following features:
- Collapsible sidebar (224px expanded / 56px collapsed) with section navigation derived from markdown
##headings - Light/dark theme toggle (light by default), syncs with the MCP host preference
- Gnosis owl watermark on every chart (theme-aware SVG)
- Chart toolbar: save chart as PNG image (2x resolution), view raw data as a table
- Value coloring: positive values (
+) rendered in green, negative values (-) in red - Responsive layout that adapts to viewport width
- Print-friendly rendering with sidebar hidden when printing
Managing Reports¶
List Saved Reports¶
Returns a table of saved reports with IDs, dates, file sizes, and file:// links.
Reopen a Report¶
Accepts the full UUID or the 8-character short ID shown in report summaries.
Report Storage¶
Reports are saved as self-contained HTML files at ~/.cerebro/reports/ (configurable via CEREBRO_REPORT_DIR). Each file embeds all chart data as JSON, so reports can be shared and opened in any browser without a server.
Agent Personas¶
For complex reports, Cerebro MCP provides three agent personas that define strict operational rules and success metrics:
| Persona | Role | Loaded via |
|---|---|---|
| Analytics Reporter | Data discovery, schema verification, query writing, chart generation | get_agent_persona("analytics_reporter") |
| UI Designer | Chart type selection, markdown layout, report structure | get_agent_persona("ui_designer") |
| Reality Checker | SQL validation, data integrity, chart spec review, formatting QA | get_agent_persona("reality_checker") |
Each persona provides specific formatting rules, example patterns, and zero-tolerance constraints (e.g., no guessed column names, no charts without titles, minimum two ## sections per report).