# Robinhood Agentic MCP — Data Reference & Dashboard Mapping

This doc is a reference for the data available from the **Robinhood agentic MCP**
and how it maps onto the vibe-dashboard.

- **MCP endpoint:** `https://agent.robinhood.com/mcp/trading` (streamable HTTP)
- **Auth:** OAuth, scopes `["trading.read"]`, client name `Vibe-Trading`
- **Account:** `476549654` (owned by Raj; read-only)
- **OAuth cache dir:** `~/.vibe-trading/live/robinhood/oauth`
- **Config:** `/workspace/.vibe-trading/agent.json`

> **Read-only:** the account is wired read-only. Never place orders. Only the
> `get_*` (read) tools below are relevant to the dashboard; order/place tools are
> intentionally not enabled.

---

## The read tools the dashboard uses

Four tools drive the dashboard:

| Tool | What it returns | Used by |
|------|-----------------|---------|
| `get_equity_tax_lots` | Per-lot equity tax lots (cost basis, quantity, open date, term) for an account + symbol | `vibe-tax-lots` (PnL math) |
| `get_realized_pnl` | Realized PnL across a span | `PORTFOLIO_BRIEF.md` (historical realized gains) |
| `get_option_positions` | Option positions (long/short, quantity, avg premium, expiry, multiplier) | `PORTFOLIO_BRIEF.md` + `options_data.json` |
| `get_equity_quotes` | Live equity quotes (incl. `last_trade_price`) — no account number required | `vibe-tax-lots` (current price) |

### `get_equity_tax_lots`
- Args: `account_number` (e.g. `"476549654"`), `symbol`.
- Returns a `data.data.tax_lots[]` array; each lot's fields are **strings**:
  `open_lot_id`, `open_tran_type`, `order_id`, `quantity`, `quantity_available`,
  `is_selectable`, `cost_per_share`, `tax_cost_basis`, `open_date`, `term`.
- Raw capture: `/workspace/vibe-dashboard/data/equity_tax_lots.json`
- See `TAX_METHODOLOGY.md` for the field-level math.

### `get_realized_pnl`
- Args include a span (the brief used `span=all`).
- Yields total realized PnL and per-year breakdown. In the brief: total
  `$70,260.18` → 2024 `$67,782.77` | 2025 `$569.91` | 2026 `$1,907.50`.

### `get_option_positions`
- Returns `data.data.positions[]` with fields such as: `option_id`, `chain_id`,
  `chain_symbol`, `type` (`"long"`/`"short"`), `quantity`, `average_price`
  (entry premium per contract), `expiration_date`, `trade_value_multiplier`
  (100), plus pending quantities and `opened_at`.
- Raw capture: `/workspace/vibe-dashboard/data/options_data.json`

### `get_equity_quotes`
- Args: `symbols` (list). **Does not need `account_number`.**
- Returns quotes including `last_trade_price` (string); the tool regex-extracts
  that value for the current price.

---

## `agent.json` — enabledTools list

The config file lives at:

```
/workspace/.vibe-trading/agent.json
```

Inside `mcpServers.robinhood`, the `enabledTools` array lists every Robinhood MCP
tool the agent is permitted to use. It includes the read tools above plus many
others (`get_accounts`, `get_portfolio`, `get_equity_positions`,
`get_equity_orders`, `get_option_quotes`, `get_option_chains`, `get_financials`,
`get_indexes`, `get_scans`, `search`, and more).

To add/remove a tool, edit `enabledTools` in this file and re-run the affected
wrappers. **Order/place tools are not in this list** — keep it that way for the
read-only account.

---

## Wrapper-invocation pattern

The tax tool does **not** call the MCP HTTP endpoint directly. Instead it builds a
**tool wrapper** from the installed Vibe-Trading package, so all MCP plumbing,
OAuth, and serialization are handled for it:

```python
from src.tools.mcp import MCPServerConfig, build_mcp_tool_wrappers
from src.config.schema import MCPOAuthConfig

cfg = MCPServerConfig(
    type="streamableHttp",
    url="https://agent.robinhood.com/mcp/trading",
    enabled_tools=["get_equity_tax_lots"],            # one tool per wrapper
    auth=MCPOAuthConfig(
        type="oauth",
        scopes=["trading.read"],
        client_name="Vibe-Trading",
        cache_dir="~/.vibe-trading/live/robinhood/oauth",
    ),
)
wraps = build_mcp_tool_wrappers("robinhood", cfg, local_server_name="robinhood")
wrapper = next(w for w in wraps if getattr(w, "name", None) == "mcp_robinhood_get_equity_tax_lots")
```

Key details:

- The wrapper is named `mcp_robinhood_<toolName>` (prefix `mcp_robinhood_`).
- Each wrapper is built with **one** `enabled_tools` entry; build a separate
  wrapper per tool used.
- Invoke synchronously: `wrapper.execute(**kwargs)` — e.g.
  `wrapper.execute(account_number="476549654", symbol="TSLL")` for tax lots, or
  `wrapper.execute(symbols=["TSLL"])` for quotes.
- Results often arrive as JSON strings; the tool parses them with `json.loads`
  before reading the nested `data.data....` paths.

This is the same pattern used per-symbol in `vibe-tax-lots` (`fetch_lots` uses
`get_equity_tax_lots`, `fetch_quote` uses `get_equity_quotes`).

---

## Where the fetched data lands

| Raw tool output | Saved to | Consumed by |
|-----------------|----------|-------------|
| `get_equity_tax_lots` | `data/equity_tax_lots.json` | `vibe-tax-lots` PnL math |
| `get_option_positions` | `data/options_data.json` | brief / options analysis |
| `get_realized_pnl` + quotes + lots | `data/PORTFOLIO_BRIEF.md` | human brief |
| Table + TOTAL line | `data/snapshots/YYYY...md` + `data/snapshots/INDEX.md` | snapshot history |

All processing is local; nothing is sent off-box.
