Skip to content

KB / mcp

MCP tool: portfolio_status

Last verified

portfolio_status is the one-call “show me everything” tool for an authenticated trading agent. It fans out five concurrent backend calls — account, stock positions, option positions, pending trades, recent history — and returns the combined view. Each leg is real Schwab pricing tracked against the platform’s paper-trading database (/app/data/trading.db, WAL mode).

Signature

portfolio_status() -> str   # JSON-serialised dict

No parameters. The tool fans out concurrent asyncio.gather() calls to the five backend routes and assembles them into a single response.

Returns

{
  "account": {
    "account_id": "paper-001",
    "balance": 99_840.12,
    "starting_balance": 100_000.00,
    "buying_power": 99_840.12,
    "as_of": "2026-05-26T10:14:33-04:00"
  },
  "stock_positions": [
    {
      "symbol": "SPY",
      "quantity": 10,
      "avg_price": 535.80,
      "current_price": 538.20,
      "market_value": 5_382.00,
      "unrealized_pl": 24.00,
      "unrealized_pl_pct": 0.45
    },
    ...
  ],
  "option_positions": [
    {
      "symbol": "SPY",
      "option_type": "call",
      "strike": 540.0,
      "expiration": "2026-06-20",
      "quantity": 2,
      "avg_price": 4.10,
      "current_price": 4.25,
      "market_value": 850.00,
      "unrealized_pl": 30.00,
      "delta": 0.48, "gamma": 0.012, "theta": -0.18, "vega": 0.42
    },
    ...
  ],
  "pending_trades": [
    {
      "trade_id": "trd-abc123",
      "symbol": "AAPL",
      "side": "buy",
      "quantity": 5,
      "price": 215.40,
      "expires_at": "2026-05-26T10:15:33+00:00",
      "status": "pending"
    }
  ],
  "recent_trades": [
    { "trade_id": "trd-xyz789", "symbol": "SPY", "side": "buy", "quantity": 10, "price": 535.80, "executed_at": "2026-05-23T14:02:11-04:00" },
    ...
  ]
}

Behaviour

Examples

Session opener for a trading agent

Agent: market_pulse()          -> regime + alerts
Agent: portfolio_status()      -> current positions + cash + P&L

The pair gives an agent everything it needs to reason about adjustments without further calls.

Pre-trade sanity check

Operator: "Add 10 more SPY shares."
Agent: portfolio_status()
  -> read account.buying_power, existing SPY quantity in stock_positions
Agent: get_quote(symbols="SPY")
Agent: plan_trade(symbol="SPY", side="buy", quantity=10)
Agent: execute_trade(trade_id="...", action="confirm")

P&L review

Operator: "How am I doing today?"
Agent: portfolio_status()
  -> sum unrealized_pl across stock_positions + option_positions.
  -> compare account.balance to account.starting_balance.

When to use

When NOT to use

See also