Metadata-Version: 2.4
Name: portfolio-rotation-mcp
Version: 0.2.0
Summary: MCP server for portfolio rotation analysis -- works with Claude, ChatGPT, Gemini, and any MCP client
Project-URL: Homepage, https://github.com/mothanaprime/Rebalance-MCP
Project-URL: Repository, https://github.com/mothanaprime/Rebalance-MCP
Project-URL: Issues, https://github.com/mothanaprime/Rebalance-MCP/issues
License-Expression: MIT
Keywords: backtest,investing,mcp,portfolio,risk,rotation,scoring
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp[cli]>=1.2.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: pandas>=2.0.0
Requires-Dist: scipy>=1.10.0
Requires-Dist: yfinance>=0.2.30
Description-Content-Type: text/markdown

# Portfolio Rotation MCP Server

[![PyPI](https://img.shields.io/pypi/v/portfolio-rotation-mcp)](https://pypi.org/project/portfolio-rotation-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/portfolio-rotation-mcp)](https://pypi.org/project/portfolio-rotation-mcp/)

MCP server for portfolio rotation analysis. Score holdings and candidates across 5 dimensions, identify optimal swaps, validate with risk checks and backtests.

**Works with any MCP client**: Claude Desktop, ChatGPT, Gemini, LangChain, Cursor, Windsurf, VS Code, Ollama clients, and more.

## What It Does

You give it a portfolio and candidate tickers. It returns:

```
ROTATION SCORECARD (GARP Style)
Ticker | Thesis | Valuation | Momentum | Catalyst | Technical | Composite | Action
META   |   75   |    80     |    78    |    85    |    74     |   78.4    | Strong Buy
AVGO   |   70   |    72     |    75    |    70    |    80     |   73.1    | Buy
AAPL   |   70   |    65     |    62    |    60    |    68     |   65.5    | Hold
MSFT   |   65   |    60     |    58    |    55    |    62     |   60.2    | Hold
JPM    |   50   |    55     |    45    |    40    |    42     |   47.4    | Watch

SWAP RECOMMENDATIONS
Sell JPM (47.4) → Buy META (78.4) | Delta: +31.0 | Strong Swap
Sell JPM (47.4) → Buy AVGO (73.1) | Delta: +25.7 | Strong Swap

RISK FLAGS
⚠️ Technology sector: 35% (>30% limit)

BACKTEST (2y)
Strategy: +42.3% | Benchmark (SPY): +28.1% | Sharpe: 1.24 | Max Drawdown: -14.2%
```

## Quick Start

```bash
# Install from PyPI
pip install portfolio-rotation-mcp

# Or run directly (no install needed)
uvx portfolio-rotation-mcp

# Set API key (optional -- falls back to yfinance without it)
export FINANCIAL_DATASETS_API_KEY=your-key
```

### Prerequisites

- Python >= 3.10
- Optional: [financial-datasets.ai](https://financial-datasets.ai) API key for premium data (without it, prices come from yfinance and financial statements are unavailable)

## 11 Tools

| Tool | Description |
|------|-------------|
| `fetch_prices` | Historical OHLCV prices (API + yfinance fallback) |
| `fetch_financials` | Income/balance/cashflow statements |
| `fetch_ff_factors` | Fama-French 5-factor + momentum data |
| `score_tickers` | 5-dimension scoring (auto + manual) |
| `analyze_risk` | Concentration, correlation, volatility |
| `compare_swaps` | Pairwise swap recommendations (delta >= 15) |
| `run_backtest` | Historical strategy simulation |
| `stress_test` | Scenario replay, Monte Carlo, factor decomposition |
| `compute_attribution` | Trade attribution and swap alpha |
| `run_pipeline` | Full 6-stage rotation analysis |
| `get_skill` | Retrieve domain knowledge (scoring rules, swap logic, risk thresholds) |

## Platform Setup

### Claude Desktop

Add to your config file:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "portfolio-rotation": {
      "command": "uvx",
      "args": ["portfolio-rotation-mcp"],
      "env": {
        "FINANCIAL_DATASETS_API_KEY": "your-key"
      }
    }
  }
}
```

Then in Claude Desktop, just say:

> My portfolio is AAPL 20%, MSFT 15%, JPM 10%. Evaluate META and AVGO as swap candidates.

Claude will automatically call the MCP tools.

### Claude Code (CLI)

```bash
claude mcp add portfolio-rotation -- uvx portfolio-rotation-mcp
```

### Cursor / Windsurf / VS Code

Add to your MCP settings (`.cursor/mcp.json`, `.windsurf/mcp.json`, or VS Code MCP config):

```json
{
  "mcpServers": {
    "portfolio-rotation": {
      "command": "uvx",
      "args": ["portfolio-rotation-mcp"],
      "env": {
        "FINANCIAL_DATASETS_API_KEY": "your-key"
      }
    }
  }
}
```

### LangChain (any model: DeepSeek, GPT, Llama, etc.)

```python
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_openai import ChatOpenAI

# Use any model -- DeepSeek, GPT, Llama, etc.
llm = ChatOpenAI(
    model="deepseek-chat",  # or "gpt-4o", etc.
    base_url="https://api.deepseek.com/v1",
    api_key="sk-...",
)

async with MultiServerMCPClient({
    "portfolio-rotation": {
        "command": "uvx",
        "args": ["portfolio-rotation-mcp"],
        "env": {"FINANCIAL_DATASETS_API_KEY": "your-key"},
    }
}) as client:
    tools = client.get_tools()
    # Create agent with tools and invoke
```

### OpenAI Agents SDK

```python
from agents import Agent
from agents.mcp import MCPServerStdio

async with MCPServerStdio(
    command="uvx",
    args=["portfolio-rotation-mcp"],
) as server:
    tools = await server.list_tools()
    agent = Agent(name="Rotation Analyst", tools=tools)
```

### Ollama + Continue / LibreChat

Configure in the MCP settings of your Ollama frontend:

```json
{
  "command": "uvx",
  "args": ["portfolio-rotation-mcp"],
  "env": {
    "FINANCIAL_DATASETS_API_KEY": "your-key"
  }
}
```

## Usage Examples

### Quick: Full Pipeline (one tool call)

Ask your AI agent:

> Analyze my portfolio: AAPL 20% (Technology), MSFT 15% (Technology), JPM 10% (Financials). Candidates: META, AVGO. Use GARP style.

The agent will call `run_pipeline` which runs all 6 stages automatically: data fetch -> scoring -> risk check -> swap comparison -> backtest -> report.

### Targeted: Score Specific Tickers

> Score AAPL, META, and AVGO. My thesis score for META is 80 and catalyst is 85.

The agent will call `fetch_prices`, then `score_tickers` with your manual overrides.

### Deep Dive: Stress Test

> Stress test my portfolio under a 2008-style crash scenario. Include Monte Carlo simulation.

The agent will call `fetch_prices`, `fetch_ff_factors`, then `stress_test`.

### Post-Trade: Attribution

> I sold INTC and bought NVDA on Jan 15 at $120. How did that swap perform?

The agent will call `fetch_prices`, then `compute_attribution` to measure swap alpha.

## Development

```bash
# Clone and install in development mode
git clone git@github.com:mothanaprime/Rebalance-MCP.git
cd Rebalance-MCP
pip install -e .

# Run the server
portfolio-rotation-mcp

# Test with MCP inspector
mcp dev src/portfolio_rotation/server.py
```

## Scoring Framework

5 dimensions, 0-100 each, weighted by investment style:

| Dimension | GARP Weight | Auto? |
|-----------|------------|-------|
| Thesis Integrity | 25% | Manual (via overrides) |
| Valuation Attractiveness | 25% | Auto (needs financials) |
| Fundamental Momentum | 20% | Auto (from prices) |
| Catalyst Proximity | 15% | Manual (via overrides) |
| Technical Trend | 15% | Auto (MA/RSI/relative strength) |

**Swap threshold**: Buy Score - Hold Score >= 15

**Style presets**: `garp` (default), `value`, `growth`, `momentum`, `event_driven` -- each has different dimension weights.

See [docs/scoring-framework.md](docs/scoring-framework.md) for full details.

## Agent Prompt

See [docs/agent-prompt.md](docs/agent-prompt.md) for a model-agnostic system prompt you can use to configure any AI agent for rotation analysis.

## Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `FINANCIAL_DATASETS_API_KEY` | No | -- | API key for [financial-datasets.ai](https://financial-datasets.ai). Without it, prices fall back to yfinance and financials are unavailable. |
| `PORTFOLIO_ROTATION_SOURCE` | No | `auto` | Data source: `auto` (API first, yfinance fallback), `api`, `financial-datasets`, or `yfinance`. Can be overridden per-call. |

## License

MIT
