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}.