KB / mcp
MCP tool: read_report
Last verified
read_report returns the platform’s flagship Markdown research report — the same report.md the engine writes after every cycle and the dashboard renders on the home page. Call this when market_pulse isn’t enough and you need the full narrative across equity markets, macro, volatility, credit, energy, sectors, gamma walls, Fed Watch, correlations, and “what changed” since the last cycle.
Signature
read_report(
filename: str | None = None, # specific archive name; omit for latest
) -> str # JSON-serialised dict
The tool wraps GET /api/v1/reports/latest when no filename is given, or GET /api/v1/reports/{filename} for a specific archive (report-YYYYMMDD-HHMMSS.md shape).
Returns
{
"filename": "report-20260526-094500.md",
"date": "2026-05-26",
"time": "09:45:00",
"generated_at": "2026-05-26T09:45:00-04:00",
"content": "# Market Report — 2026-05-26 09:45 ET\n\n## Market Overview\n...",
"previous_filename": "report-20260526-080000.md",
"next_filename": null
}
contentis the full Markdown body — sections in fixed order: Market Overview, Sector Breadth, Gamma Call/Put Wall, Fed Watch, Correlations, Macro Fundamentals, Energy, What Changed.previous_filename/next_filenamelet the agent walk the archive without a separate listing call. The latest report hasnext_filename: null.generated_atis ET ISO 8601 with offset (Law 1).
Behaviour
- Cache TTL.
CACHE_TTL_REPORT = 30s(mcp/mcp_server/config.py). Reports are written once per cycle (cadence depends on profile —hotevery 5 min,marketevery 15 min during RTH,full4×/day); a 30s cache deduplicates burst reads cheaply. - Source path. The latest report is
/app/data/report.mdinside the backend container; archives arereport-YYYYMMDD-HHMMSS.mdin the same directory. The route reads from disk — no DB round-trip — so this tool stays fast even when the signals DB is hot. - Read-only, no auth. The route is public.
- Rendered via Jinja2 with the
numfilter. Per Law 6, missing numeric inputs render as"N/A"rather than leaking$0.00or0.00%. An agent reading"N/A"should treat the field as unavailable, not zero.
Examples
Latest report
Operator: "Read me the latest market report."
Agent: read_report()
Returns the most recent cycle’s full Markdown.
Specific archive
Operator: "What did the report say at the open today?"
Agent: read_report(filename="report-20260526-093100.md")
Walk the archive
Agent: read_report()
-> previous_filename = "report-20260526-080000.md"
Agent: read_report(filename="report-20260526-080000.md")
-> previous_filename = "report-20260526-063000.md"
The previous_filename / next_filename chain lets an agent reconstruct a session timeline without a separate listing endpoint.
When to use
- Building a thesis — read the full narrative across all sections at once.
- Following up on a
market_pulseheadline that needs more context. - Reviewing prior cycles when the operator asks “what was the report saying at noon?”
When NOT to use
- You just need the regime + score + alerts (use
market_pulse). - You need structured data, not narrative — use
analyze_signalsfor typed JSON. - You need a specific signal value — go straight to the matching
analyze_signalsaspect.
See also
market_pulse— short summary surface backed by the same source helpers.analyze_signals— typed JSON for individual signal aspects.- Implementation:
mcp/mcp_server/tools/public.py:read_report, backend routesGET /api/v1/reports/latestandGET /api/v1/reports/{filename}.