| name | daily-briefing |
| description | Run a one-shot morning portfolio digest that ties together health, alerts, macro regime, crowding risk, concentration, and earnings calendar into a single decision-ready brief. Use when the user asks for "morning briefing", "daily digest", "what's happening today?", "what changed overnight?", or "give me the morning rundown". Composes existing MCP tools - no new data sources. |
Daily Briefing (morning digest)
Goal
One scroll-length brief surfacing what matters today. Composes the MCP tools listed below (8 core + BoC; crypto pair only if held). No new data fetches outside that list.
State check (BEFORE any tool calls)
Read .claude/context/STATE.md. If last_briefing_date equals today's date (YYYY-MM-DD), output:
"Daily briefing already ran today (last_briefing_date). Skipping re-fetch to save tokens. Re-run with /daily-briefing force to override."
Then stop - do not call any MCP tools.
If last_crowding_regime is set, use it as prior context when interpreting positioning signals (flag if regime changed).
Decision Memory Protocol (load first, log after)
Before forming any view, load prior decisions so verdicts stay consistent across sessions:
mcp__aifolimizer__get_cross_ticker_lessons (max_lessons=3) - portfolio-level win/loss patterns
- For any name you issue a per-ticker BUY/SELL/TRIM/HOLD/ADD on, also load
mcp__aifolimizer__get_ticker_decision_history (ticker=…, max_decisions=5) and mcp__aifolimizer__get_ticker_reflection (symbol=…, n=3). If a prior decision exists and this run flips it, state explicitly WHY (new data / catalyst / price); never silently contradict a logged decision.
After output, log every actionable verdict: for each BUY/SELL/TRIM/ADD/HOLD issued, call mcp__aifolimizer__log_recommendation (skill="daily-briefing", ticker, action, conviction, rationale, target_pct, stop_pct). Skipping breaks the cross-session feedback loop and causes drift.
How to run
Call in parallel (no inter-dependencies):
mcp__aifolimizer__get_profile
mcp__aifolimizer__get_portfolio
mcp__aifolimizer__get_personal_context - use derived (marginal_tax_rate_pct, account_waterfall, horizon) to sharpen the focus list and risk flags (e.g. tax-aware trim guidance, account-placement). If present == false, keep briefing generic and suggest running /profile-setup.
mcp__aifolimizer__get_macro_snapshot (FRED + market regime)
mcp__aifolimizer__get_concentration_warnings
mcp__aifolimizer__get_triggered_alerts (since_hours=24)
mcp__aifolimizer__get_earnings_calendar (next 14d)
mcp__aifolimizer__get_positioning_signals (top 15 holdings)
mcp__aifolimizer__get_technicals_intraday (top 5 holdings + any focus-list tickers - only if US market is open or pre-market)
mcp__aifolimizer__get_boc_snapshot (cheap, 12h cache) - Canadian rate/FX/curve context; surface curve_signal in section 4 if inverted
mcp__aifolimizer__get_crypto_fear_greed + mcp__aifolimizer__get_crypto_macro - ONLY if portfolio holds crypto; skip both otherwise (list in section 6)
Catalyst day check (FIRST - before anything else)
Catalysts drive intraday moves. Trading without knowing today's catalysts = trading blind.
Check macro snapshot for these scheduled events TODAY (US Eastern):
- FOMC decision / Fed minutes (8 per year, 2pm ET)
- CPI release (monthly, 8:30am ET)
- NFP / jobs report (first Friday monthly, 8:30am ET)
- PCE release (monthly, 8:30am ET)
- GDP advance (quarterly, 8:30am ET)
- VIX > 25 (elevated fear regime - wider stops, smaller size)
- Treasury auction (10Y/30Y reopening - bond-proxy stocks reactive)
- Turn-of-Month window (McConnell & Xu, 1897-2005): last trading day of month OR first 3 trading days of new month. Historically, essentially ALL positive equity returns are concentrated in this 4-day window. If today falls in this window, flag:
📅 TOTM WINDOW - bias long, avoid aggressive intraday shorts, favor momentum adds.
Cross-reference earnings calendar for next 24h (large-cap names only): MSFT/AAPL/NVDA/META/GOOGL/AMZN reporting tonight = next-day gap risk across whole portfolio if mega-cap.
If catalyst flagged, prefix section 1 headline with ⚠️ CATALYST: <event> @ <time> and add section 2 bullet: "Reduce intraday position sizes by 50% until event resolves. Wide stops or no trade."
Investor profile
- Canadian retail investor
- Philosophy: growth stocks, index ETFs, dividends, crypto
- Always pull capital + accounts from
get_profile - never hardcode
Output structure
Single-page brief, ≤ 450 words, this exact order:
1. Headline (one sentence)
Format: [Portfolio value CAD] · [Day Δ %] · [Regime label] · [N alerts last 24h]
Example: $182,300 CAD · -0.7% · bull_high_fear · 3 alerts last 24h
2. What changed (≤ 5 bullets)
Action-significant items only. No filler.
- New triggered alerts (price drop, RSI, earnings, concentration)
- Crowding score regime shifts (if positioning history available - flag consensus → contrarian or vice versa)
- Earnings within 3 days
- Macro regime change (e.g. bull_low_fear → bull_high_fear)
3. Today's focus list (≤ 3 tickers)
Pick from cross of: alerts triggered + earnings imminent + crowding flag. Format per ticker:
TICKER · weight X% · reason · suggested action
Suggested action is one of: review, trim, hedge, hold, add (small).
4. Risks on radar
- Single-position concentration > 10%
- Sector concentration > 35%
- Consensus-crowded names with negative day change > 3% (late-entry risk materializing)
- Yield curve / VIX / Fear-Greed extremes if macro snapshot flags; inverted
curve_signal from get_boc_snapshot is a Canadian recession flag
- Crypto sleeve (only if held):
get_crypto_fear_greed extreme (≤20 fear / ≥80 greed) + falling DefiLlama TVL = risk-off in crypto
5. Anti-FOMO traps (only surface real ones - else one line)
Behavioral guardrail. Built from data ALREADY fetched (crowding + day-change + earnings) - no new tool calls. List ≤ 3, each as TRAP · ticker · horizon · why · the disciplined move.
Horizon scope (READ FIRST - the logic inverts): the traps below are calibrated for swing / position / long-term entries. For intraday momentum trades the crowding + narrative-spike logic is REVERSED - riding the crowd is the edge, not the trap. Tag each trap with the horizon it bites. Never flag an intraday momentum scalp with a long-horizon crowding trap.
Swing / position / long-term traps:
- Chase-the-consensus:
crowding_label == consensus (score ≥ 70) on a name with a positive day → late-entry, negative expected alpha over weeks-months. Move: defer / size down, not add.
- Narrative spike:
headline_velocity_ratio > 1.5 (news surge) + crowding consensus → story-driven, not fundamental. Move: wait for velocity to cool before sizing.
- Green-day add urge: holding already > 8% weight up > 5% on the day → adding on strength concentrates risk at a local high. Move: hold, revisit on pullback to support.
- Pre-print gamble: earnings within 3 days + urge to add a position-trade → binary bet, not a thesis. Move: no new size until after the print.
Intraday traps (the discipline is exit-rules, NOT crowd-avoidance):
- No-stop scalp: intraday entry without a hard stop + time-stop. Move: define both before entry or no trade.
- Late chase: entering after price already ran > 2 ATR / RSI(2) extreme - the move is spent. Move: wait for VWAP reclaim or next setup.
- Overstay: intraday thesis but holding past your time-stop into close → it's now an unplanned swing. Move: flatten or consciously convert with a swing stop.
If none apply, write: No active FOMO traps - positioning disciplined.
6. Intraday addendum (only if US market open or pre-market)
From get_technicals_intraday on focus-list + top 5 by weight, surface:
- Names with
intraday_score >= 0.7 AND volume_spike >= 1.5 → "active setup"
- Names with
opening_range_break == "below" AND held weight > 3% → "intraday weakness on size"
- Gap names:
abs(gap_pct) >= 3 → "gap watch"
Format per line: TICKER · intraday_score · VWAP $X.XX (Δ Y.Y%) · OR break: <dir> · note
If no intraday signals worth surfacing, write: No notable intraday setups.
7. Skipped today
One line listing tools/checks that returned empty or stale data. Example: Skipped: crypto (no holdings), tax-loss (no underwater positions), intraday (market closed).
After output - write STATE.md
After completing the brief, update .claude/context/STATE.md:
last_briefing_date: today's date (YYYY-MM-DD)
last_crowding_regime: crowding_label from positioning signals (consensus/neutral/contrarian) - same vocabulary as get_positioning_signals so the next run's prior-context comparison is valid
active_alerts: count of triggered alerts from get_triggered_alerts
open_recs: count of open recommendations (from brief context if available)
Rules
- Direct. No hedging, no "you may want to consider".
- If tool errors or returns empty, list in section 7 - do NOT fabricate data.
- Currency: CAD aggregate unless user in specific account.
- Crowding rule (per CLAUDE.md): if
crowding_label == consensus AND ticker in focus list, default action skews toward trim or hold, NOT add.
- One-shot - do not chain into another skill unless user asks.
Gotchas
get_triggered_alerts read-only - does NOT re-evaluate rules. If user wants fresh evaluation, call run_alerts_now first (only if explicitly requested - adds 5-10s).
- TSX (.TO) tickers may have null crowding fields → label "neutral" by fallback. Don't treat as real signal.
- Macro regime label
bull_low_fear can co-exist with portfolio-level red day - regime is market-wide, day-change is portfolio-specific. Don't conflate.
- Earnings calendar is yfinance - sparse for non-US listings. Cross-check IR pages for TSX names if stake is large.
- "What changed" requires comparing to prior brief. If running fresh (no prior), say so in section 2 - don't invent comparisons.
get_technicals_intraday returns empty dict outside US market hours - that is correct, list "intraday (market closed)" in skipped section, do not error
- Catalyst check is REQUIRED - never skip it. If macro snapshot data is unavailable, default to assuming a quiet day BUT explicitly state "catalyst data unavailable - assume normal" in the headline. Better to be wrong about a quiet day than to miss a Fed day.
- Earnings catalyst list (mega-caps reporting in next 24h) only matters for big names - TSX small-caps reporting do not move SPY. Filter
get_earnings_calendar to weight > 2% of portfolio OR market_cap > $500B before flagging as portfolio-wide catalyst.