Architecture
How the system works under the hood.
System Overview
┌─────────────────────────────────────────────────────────────────┐
│ MAKORA HARNESS (Durable Object) │
├─────────────────────────────────────────────────────────────────┤
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌─────────────────┐ │
│ │ StockTwits│ │ Reddit │ │ Twitter │ │ Crypto Momentum │ │
│ │ Sentiment │ │ (4 subs) │ │ Confirm │ │ (24/7) │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └────────┬────────┘ │
│ └─────────────┴─────────────┴────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Signal Cache │ │
│ │ (Persistent) │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ LLM Research │ │
│ │ (OpenAI) │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Trading Logic │ │
│ │ + Staleness │ │
│ │ + Options │ │
│ └────────┬────────┘ │
└─────────────────────────────┼───────────────────────────────────┘
│
▼
┌─────────────┐
│ eToro │
│ Broker │
└─────────────┘
The Harness runs entirely on Cloudflare Workers with persistent state stored in Durable Object storage. It executes via an alarm every 30 seconds and survives restarts.
The MCP server provides tools for external integrations if needed.
Agent Loop
The agent runs continuously with two main phases:
Data Gathering (24/7)
- Fetch trending stocks from StockTwits API
- Calculate sentiment scores (bullish vs bearish messages)
- Filter by minimum sentiment and volume thresholds
- Send top signals to LLM for research
Trading (Market Hours Only)
- Check existing positions for stop-loss/take-profit
- Ask LLM to analyze each position (HOLD/SELL)
- Look for buy opportunities from researched signals
- Execute trades via MCP server
LLM Decision Making
Signal Research
For each trending stock, the LLM receives:
- Symbol and current price
- Sentiment score and volume
- Source breakdown (bullish/bearish counts)
It returns:
{
"verdict": "BUY" | "SKIP" | "WAIT",
"confidence": 0.0-1.0,
"reasoning": "explanation",
"red_flags": ["concerns"],
"catalysts": ["positive factors"]
}
Position Analysis
For each held position, the LLM receives:
- Symbol, shares, P&L percentage
- Current sentiment (if still trending)
- Take profit/stop loss targets
It returns:
{
"action": "HOLD" | "SELL",
"confidence": 0.0-1.0,
"reasoning": "explanation"
}
Order Flow
All orders go through a two-step process for safety:
1. Preview
Call orders-preview with order details. The policy engine validates:
- Kill switch not active
- Not in cooldown period
- Within position limits
- Within daily loss limits
- Sufficient buying power
Returns an approval token (valid 5 minutes).
2. Submit
Call orders-submit with the approval token. The order is executed through eToro.
MCP Tools
The MCP server at /mcp exposes tools for external integrations (e.g., Claude Desktop). Key tools:
| Category | Tools |
|---|---|
| Account | accounts-get, portfolio-get |
| Positions | positions-list, positions-close |
| Orders | orders-preview, orders-submit, orders-list, orders-cancel |
| Market Data | market-clock, market-quote, market-movers |
| Technicals | technicals-get, signals-get |
| Risk | risk-status, killswitch-enable, killswitch-disable |
For daily operation, use the /agent/* HTTP endpoints instead (see Configuration).
Project Structure
makora/
├── wrangler.jsonc # Cloudflare config
├── .dev.vars # Local secrets (gitignored)
├── src/
│ ├── index.ts # Entry point & routing
│ ├── durable-objects/
│ │ └── makora-harness.ts # Trading agent (customize this!)
│ ├── mcp/
│ │ └── agent.ts # MCP tool definitions
│ ├── policy/ # Trade validation & risk
│ ├── providers/
│ │ ├── etoro/ # eToro broker client
│ │ ├── llm/ # LLM providers (OpenAI, AI SDK)
│ │ └── social/ # StockTwits, Reddit scrapers
│ ├── storage/ # D1 and KV storage
│ └── schemas/ # Config schemas
├── dashboard/ # React dashboard
├── docs/ # This documentation
└── migrations/ # D1 database migrations