Skip to main content
Glama
mothanaprime

Portfolio Rotation MCP Server

by mothanaprime

Portfolio Rotation MCP Server

PyPI Python

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%

Related MCP server: Sablier MCP Server

Quick Start

# 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 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

{
  "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)

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):

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

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

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

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:

{
  "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

# 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 for full details.

Agent Prompt

See 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. 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

Available Tools

11 tools
analyze_riskA

Analyze portfolio risk: concentration, correlation, volatility.

Checks position concentration (>10% single stock), sector concentration (>30% single sector), pairwise correlation, and portfolio volatility. Optionally includes candidate tickers in correlation matrix to see how they correlate with existing holdings before executing swaps.

Args: portfolio_json: JSON array of holdings, e.g. '[{"ticker": "AAPL", "weight": 0.20, "sector": "Technology"}, ...]'. period: History period for correlation/volatility calculation (default "1y"). Uses yfinance period format: "1y", "2y", "6mo", etc. corr_threshold: Flag pairs with correlation above this (default 0.85). candidates: Optional comma-separated candidate tickers to include in correlation analysis (e.g. "META,AVGO"). These are included in the correlation matrix but not in concentration/weight checks.

Returns: JSON with concentration analysis, correlation matrix (holdings only and with candidates if provided), portfolio volatility, risk flags, and overall risk level (LOW/MEDIUM/HIGH).

ParametersJSON Schema
NameRequiredDescriptionDefault
portfolio_jsonYes
periodNo1y
corr_thresholdNo
candidatesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description fully bears the transparency burden. It details what the tool checks (concentration, correlation, volatility) and the optional candidate inclusion. However, it does not disclose rate limits, auth requirements, or any side effects, though none seem needed for a read-only analysis tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a brief intro, bulleted details, and clear Args/Returns sections. It front-loads the purpose and every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description doesn't need to explain return values but does anyway, showing thoroughness. It covers all parameters, usage hints, and return structure completely for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description provides comprehensive parameter explanations, including examples for portfolio_json, valid values for period, default for corr_threshold, and format for candidates. This adds significant meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly defines the tool's purpose: analyzing portfolio risk through concentration, correlation, and volatility checks. It also distinguishes from sibling tools by listing specific risk checks and optional candidate inclusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for portfolio risk analysis before swaps but lacks explicit guidance on when to use this tool versus alternatives like compare_swaps or stress_test. No exclusions or when-not-to-use instructions are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_swapsA

Generate pairwise swap recommendations from scored tickers.

Compares each holding against each candidate. Recommends a swap when the candidate's composite score exceeds the holding's score by >= threshold.

Args: scores_json: JSON array of score dicts from score_tickers tool. holdings: Comma-separated current holding tickers. candidates: Comma-separated candidate tickers. threshold: Minimum score delta to recommend a swap (default 15).

Returns: JSON with swap recommendations and full scorecard ranking.

ParametersJSON Schema
NameRequiredDescriptionDefault
scores_jsonYes
holdingsYes
candidatesYes
thresholdNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description discloses the core behavior: pairwise comparison using composite scores and a threshold. It notes that scores_json is expected from score_tickers. It does not cover edge cases (e.g., missing tickers) or state side effects, but the main logic is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description starts with a clear one-line summary, followed by a brief algorithm explanation, then a well-formatted Args list. Every sentence adds necessary information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the algorithm, parameter semantics, output format (JSON with recommendations and scorecard), and ties to the preceding score_tickers tool. With output schema present, return details are optional. Minor gaps: no mention of error handling or behavior when no swaps meet threshold.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description fully compensates. The Args section explains the source of each parameter (scores_json from score_tickers), format (holdings/candidates as comma-separated), and default behavior (threshold default 15). This adds crucial meaning beyond the bare schema types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Generate pairwise swap recommendations from scored tickers,' which clearly identifies the verb (generate) and resource (swap recommendations). It distinguishes from siblings like score_tickers (which produces scores) and run_backtest (backtesting), making the purpose specific and non-overlapping.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use: after obtaining scores from score_tickers, to compare holdings vs candidates. It details the algorithm (threshold-based swap). However, it does not discuss when not to use it or mention alternative tools (e.g., analyze_risk for risk-only analysis), slightly limiting guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compute_attributionA

Analyze trade attribution and rotation effectiveness.

Matches BUY/SELL trades into round-trips, computes swap alpha (what the replaced stock did), benchmark-relative returns, and pattern analysis with calibration recommendations.

Args: trades_json: JSON array of trades, e.g. '[{"date": "2025-01-15", "action": "BUY", "ticker": "NVDA", "shares": 50, "price": 120.00, "score": 75, "replaced": "INTC"}, ...]'. prices_json: JSON of price data from fetch_prices (the "prices" array). benchmark: Benchmark ticker (default "SPY").

Returns: JSON with round_trips (per-trade attribution, swap alpha) and patterns (win rate, avg return, score-return correlation, recommendations).

ParametersJSON Schema
NameRequiredDescriptionDefault
trades_jsonYes
prices_jsonYes
benchmarkNoSPY

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden. It details the tool's behavior: matching trades into round-trips, computing swap alpha, benchmark-relative returns, and pattern analysis with recommendations. It does not mention side effects or permissions, but as a compute/analysis tool, this is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a brief intro, bulleted args, and returns. It is informative but slightly wordy, especially the trades example. Still, each sentence adds value and it is easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (3 params, no nested objects, output schema exists), the description covers input format, return structure, and provides an example. It is complete and leaves no major gaps for an AI agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description provides rich semantics: explains trades_json format with an example, references prices_json from fetch_prices, and notes benchmark default. This fully compensates for the schema's lack of descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool analyzes trade attribution and rotation effectiveness, with specific details on matching trades into round-trips, computing swap alpha, and benchmark-relative returns. It distinguishes itself from siblings like compare_swaps or analyze_risk through its focus on attribution and recommendations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains input requirements (trades_json from trades, prices_json from fetch_prices) but does not explicitly state when to use this tool versus alternatives like compare_swaps. It implies usage for attribution analysis but lacks exclusions or scenarios where other tools are more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_ff_factorsA

Download Fama-French 5-factor + momentum daily data.

Data is freely available from Kenneth French's Data Library. Used for factor decomposition in stress testing.

Args: start_date: Filter to dates on or after this date (default "2020-01-01").

Returns: JSON with factor records: [{date, MKT-RF, SMB, HML, RMW, CMA, MOM, RF}, ...]. All values are decimals (not percent).

ParametersJSON Schema
NameRequiredDescriptionDefault
start_dateNo2020-01-01

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden. It discloses that data is freely available from an external source, describes the return format, and notes decimal values. However, it does not explicitly state idempotency, latency, or any side effects, though the operation is clearly read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear title line, context paragraph, and explicit Args/Returns sections. Every sentence adds value, and there is no fluff or repetition. It is appropriately sized for a single-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has one optional parameter and a rich return format described in the description text, the description is largely complete. It provides source attribution and use case. The absence of a formal output schema in the provided definition is compensated by the textual description of return fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, start_date, has a default value. The description adds meaning beyond the schema by explaining it filters dates on or after the specified date. This clarifies the parameter's purpose effectively.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Download Fama-French 5-factor + momentum daily data.' It specifies the exact resource (Fama-French factors) and action (download), and the context of factor decomposition differentiates it from sibling tools like fetch_prices or fetch_financials.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions 'Used for factor decomposition in stress testing' which implies a use case but does not explicitly state when to use this tool versus alternatives, nor does it provide any when-not-to-use guidance. The usage context is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_financialsA

Fetch financial statements (income, balance sheet, cashflow) from the API.

Requires FINANCIAL_DATASETS_API_KEY env var.

Args: tickers: Comma-separated ticker symbols (e.g. "AAPL,MSFT"). stmt_type: Statement type -- "income", "balance", "cashflow", or "all". period: "annual" or "quarterly". limit: Number of periods per ticker (default 5).

Returns: JSON with financial statement records.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickersYes
stmt_typeNoall
periodNoannual
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions the API key requirement and return format, which is helpful, but it does not disclose potential errors, rate limits, or whether the operation is read-only. Behavioral transparency is adequate but not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with an Args section and a Returns line. It is concise, each sentence adds value, and there is no fluff. Slightly more conciseness could be achieved, but it is already efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema, the description does not need to detail return values. It covers all parameters, the environment variable requirement, and the return type. However, it could be more complete by mentioning error handling or rate limits. Overall, it is sufficient for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no descriptions, so the description fully compensates by explaining the format of 'tickers' (comma-separated), enumerating valid values for 'stmt_type' and 'period', and clarifying 'limit' as periods per ticker with a default. This adds substantial meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches financial statements (income, balance sheet, cashflow) from an API. The verb 'fetch' and resource 'financial statements' are specific, and the tool is distinct from siblings like fetch_prices which fetch price data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description specifies a required environment variable but does not explicitly state when to use this tool versus alternatives among the siblings. Usage is implied by the purpose, but there are no exclusion criteria or direct comparisons.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_pricesA

Fetch historical daily OHLCV prices for given tickers.

Uses financial-datasets API with automatic yfinance fallback. Set FINANCIAL_DATASETS_API_KEY env var for API access. Set PORTFOLIO_ROTATION_SOURCE env var to change the default source.

Args: tickers: Comma-separated ticker symbols (e.g. "AAPL,MSFT,NVDA,SPY"). start_date: Start date in YYYY-MM-DD format (e.g. "2023-01-01"). end_date: End date in YYYY-MM-DD format (e.g. "2026-03-05"). source: Data source -- "auto" (API first, yfinance fallback), "api", "financial-datasets" (same as "api"), or "yfinance". If empty, reads PORTFOLIO_ROTATION_SOURCE env var (default: "auto").

Returns: JSON with price records: [{date, ticker, open, high, low, close, volume}, ...].

ParametersJSON Schema
NameRequiredDescriptionDefault
tickersYes
start_dateYes
end_dateYes
sourceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses API with yfinance fallback, environment variable dependencies, and return format. No annotations provided, so description carries full burden; misses potential error scenarios.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured, front-loaded with purpose, then API details, environment variables, parameters, and return format. Every sentence is informative and concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Comprehensive coverage: purpose, configuration, parameters, return format. Given an output schema exists, the description is sufficient for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates fully by detailing each parameter's format, defaults, and source options, adding significant meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it fetches historical daily OHLCV prices for given tickers. Distinguishes from sibling tools like fetch_financials and fetch_ff_factors.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides context on when to use the tool for historical price data, explains fallback behavior and environment variable configuration. Lacks explicit when-not-to-use but is otherwise clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_skillA

Get domain knowledge for portfolio rotation analysis.

Returns detailed methodology, decision rules, scoring criteria, and interpretation guidelines. Call this BEFORE using other tools to understand how to interpret their outputs correctly.

Available skills:

  • "scoring-framework": 5-dimension scoring system (0-100), criteria matrices, decision thresholds, auto vs manual dimensions

  • "swap-methodology": Swap decision rules, delta thresholds, ranking logic, edge cases, post-swap monitoring

  • "risk-management": Concentration limits, correlation checks, volatility thresholds, risk level classification

  • "style-presets": GARP/value/growth/momentum/event-driven weight matrices and when to use each style

  • "rotation-pipeline": 6-stage pipeline orchestration, stage dependencies, partial run options

Args: name: Skill name to retrieve. Use "" or "all" to list available skills with brief descriptions.

Returns: Markdown content with the requested domain knowledge, or a list of available skills if no name is provided.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations, but description fully discloses behavior: read-only retrieval, return format, and effect of empty argument. No side effects or destructive actions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with bullet points and sections. Every sentence adds value, no redundancy. Front-loaded with purpose and usage guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a reference tool with multiple options. Explains input, output, usage context, and available skills. Output schema exists but description also clarifies return format.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has only 'name' with 0% description coverage. Description compensates fully by listing available skill values, explaining default behavior, and detailing what each skill contains.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'Get domain knowledge for portfolio rotation analysis'. Differentiates from sibling tools (computational financial analysis tools) by being an informational/reference tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Call this BEFORE using other tools to understand how to interpret their outputs correctly'. Also explains how to list and retrieve skills.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_backtestA

Backtest a rotation strategy on historical price data.

Uses price momentum ranking by default. Simulates monthly rebalancing with trailing stops and transaction costs.

Args: prices_json: JSON of price data from fetch_prices (the "prices" array). strategy_json: Optional JSON strategy config, e.g. '{"rebalance": "monthly", "max_positions": 5, "sizing": "equal_weight", "entry": {"min_score": 60}, "exit": {"trailing_stop": 0.15}}'. If empty, uses sensible defaults. benchmark: Benchmark ticker (default "SPY"). cost_bps: Transaction cost in basis points (default 10). scores_json: Optional JSON of score results from score_tickers tool. When provided with ranking_mode="score", uses composite scores for initial allocation instead of price momentum. ranking_mode: "momentum" (default, rank by 3M price return) or "score" (rank by composite scores for initial allocation). When "score", the entry.min_score threshold from strategy is honored. Note: subsequent rebalances use momentum since scores can't be recomputed mid-backtest without financials at each date.

Returns: JSON with metrics (total_return, CAGR, Sharpe, Sortino, max_drawdown, win_rate), equity_curve, trade_log, and monthly_returns.

ParametersJSON Schema
NameRequiredDescriptionDefault
prices_jsonYes
strategy_jsonNo
benchmarkNoSPY
cost_bpsNo
scores_jsonNo
ranking_modeNomomentum

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Given no annotations, the description discloses key behavioral traits: default momentum ranking, monthly rebalancing, trailing stops, transaction costs, and the interaction between ranking_mode and scores_json. It also notes that subsequent rebalances use momentum since scores aren't recomputed mid-backtest. While it doesn't explicitly state that the tool is read-only (non-destructive), the nature of a backtest implies no data mutation. This is adequate transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear overview, bullet-listed parameters, and a return value section. Every sentence adds necessary information without redundancy. It is concise yet comprehensive, avoiding unnecessary prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers all aspects needed for an agent: inputs (required and optional), behavior (momentum vs. score ranking, rebalancing), constraints (scores not recomputed mid-backtest), and outputs (metrics, equity curve, etc.). Despite no output schema, the return description is detailed. The tool is complex with 6 parameters, and the description leaves no gaps in understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description fully compensates by explaining all six parameters in detail. It provides examples, defaults, and links to other tools (e.g., fetch_prices, score_tickers). This adds significant meaning beyond the schema, enabling correct parameter usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Backtest a rotation strategy on historical price data.' It distinguishes itself from sibling tools by focusing on rotation strategies, simulations with monthly rebalancing, trailing stops, and transaction costs. This specificity helps an agent select the correct tool for backtesting scenarios.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear guidance on when to use the tool, including prerequisites (prices from fetch_prices) and optional inputs (strategy_json, scores_json, ranking_mode). It explains the default behavior and how different ranking modes affect the backtest. However, it does not explicitly mention when to use this tool over alternatives (e.g., stress_test vs. run_backtest), which would strengthen the guidelines.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_pipelineA

Run the full 6-stage rotation analysis pipeline.

Stages: refresh (fetch prices) -> score (5-dimension scoring) -> risk (concentration/correlation) -> compare (swap recommendations) -> backtest (historical simulation) -> report (markdown summary).

This is the main entry point for a complete rotation analysis.

Args: portfolio_json: JSON array of current holdings, e.g. '[{"ticker": "AAPL", "weight": 0.20, "sector": "Technology"}, {"ticker": "MSFT", "weight": 0.15, "sector": "Technology"}, ...]'. candidates: Comma-separated candidate tickers to evaluate (e.g. "META,AVGO,LLY"). style: Investment style -- "garp" (default), "value", "growth", "momentum", "event_driven". overrides_json: Optional JSON of manual score overrides, e.g. '{"AAPL": {"thesis": 75, "catalyst": 60}}'. benchmark: Benchmark ticker (default "SPY"). stages: Comma-separated stages or "all" (default "all"). skip_refresh: Skip data fetching, use cached data (default False). start_date: Price data start date YYYY-MM-DD (default: 3 years ago). end_date: Price data end date YYYY-MM-DD (default: today). source: Data source for price fetching -- "auto" (API first, yfinance fallback), "api", "financial-datasets" (same as "api"), or "yfinance". If empty, reads PORTFOLIO_ROTATION_SOURCE env var (default: "auto").

Returns: JSON with complete pipeline results: scores, swap recommendations, risk analysis, backtest metrics, and markdown report.

ParametersJSON Schema
NameRequiredDescriptionDefault
portfolio_jsonYes
candidatesYes
styleNogarp
overrides_jsonNo
benchmarkNoSPY
stagesNoall
skip_refreshNo
start_dateNo
end_dateNo
sourceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, description details the 6 stages and parameter behaviors (e.g., skip_refresh, source fallback). Discloses pipeline flow and data source selection. Lacks mention of potential side effects like API calls or caching, but overall sufficiently transparent for a complex tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is fairly long but well-structured with bullet points for stages and clear sections for args/returns. All content is relevant and adds value. Slightly verbose for a simple tool, but appropriate for the complexity of a 10-parameter pipeline.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 10 parameters, 0% schema coverage, no annotations, but with an output schema (return mentioned), the description covers all parameters, pipeline stages, and return format. Provides sufficient context for an agent to understand input, behavior, and output.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but description provides extensive parameter explanations with examples (portfolio_json format, candidates style, overrides_json structure, env var for source). Adds significant meaning beyond bare schema types and defaults, fully compensating for lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Run the full 6-stage rotation analysis pipeline' with specific stages enumerated. Distinguishes from sibling tools (individual stages like analyze_risk, compare_swaps) by positioning itself as the main entry point for a complete analysis.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States 'This is the main entry point for a complete rotation analysis,' implying use when full pipeline is needed. Does not explicitly mention when to use alternatives (individual stages) or exclusions, but context from sibling names makes this clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

score_tickersA

Score tickers across 5 dimensions for rotation analysis.

Dimensions (0-100 each):

  • Thesis Integrity (manual via overrides)

  • Valuation Attractiveness (auto with financials, or manual)

  • Fundamental Momentum (auto from prices + financials)

  • Catalyst Proximity (manual via overrides)

  • Technical Trend (auto from prices: MA crossovers, RSI, relative strength)

Args: tickers: Comma-separated tickers to score (e.g. "AAPL,MSFT,NVDA,META"). prices_json: JSON string of price data from fetch_prices (the "prices" array). benchmark: Benchmark ticker for relative strength (default "SPY"). financials_json: Optional JSON string of financials from fetch_financials. overrides_json: Optional JSON string of manual overrides, e.g. '{"AAPL": {"thesis": 75, "catalyst": 60}, "MSFT": {"thesis": 70}}'. holdings: Comma-separated current holding tickers for action labeling. style: Investment style -- "garp", "value", "growth", "momentum", or "event_driven".

Returns: JSON with scored tickers: [{ticker, thesis, valuation, momentum, catalyst, technical, composite, action, style, auto_dimensions, manual_dimensions}, ...].

ParametersJSON Schema
NameRequiredDescriptionDefault
tickersYes
prices_jsonYes
benchmarkNoSPY
financials_jsonNo
overrides_jsonNo
holdingsNo
styleNogarp

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility. It discloses that some scores are auto-calculated while others are manual via overrides, and describes the output format. It does not mention side effects or destructive actions, but it is safe and clear enough for an agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-organized with a clear purpose statement, dimension list, parameter explanations, and return structure. It is somewhat lengthy but every part adds value; could be slightly more concise but remains effective.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (7 parameters, output schema), the description covers purpose, dimensions, parameters, and output structure adequately. The existence of an output schema reduces the need to detail return values, but the description summarizes it well.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description provides detailed explanations for each parameter, including defaults, examples (e.g., overrides_json format), and allowed values for style. This fully compensates for the lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool scores tickers across 5 specific dimensions for rotation analysis. It uses a specific verb ('score') and resource ('tickers') with distinct dimensions, and differentiates from sibling tools like analyze_risk or fetch_prices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for rotation analysis but does not explicitly state when to use this tool versus alternatives, nor does it provide prerequisites or when-not-to-use guidance. It mentions parameters but lacks contextual usage advice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stress_testA

Run comprehensive portfolio stress tests.

Includes: historical scenario replay (GFC, COVID, etc.), hypothetical rate/equity/sector shocks, Fama-French factor decomposition, and Monte Carlo simulation.

Args: portfolio_json: JSON array of holdings, e.g. '[{"ticker": "AAPL", "weight": 0.20, "sector": "Technology"}, ...]'. prices_json: JSON of price data from fetch_prices (the "prices" array). factor_data_json: Optional JSON of Fama-French factors from fetch_ff_factors. benchmark: Benchmark ticker (default "SPY"). run_scenarios: Run historical scenario replay (default True). run_shocks: Run hypothetical shocks (default True). run_factors: Run Fama-French factor decomposition (default True). run_montecarlo: Run Monte Carlo simulation (default True). n_simulations: Number of Monte Carlo simulations (default 10000).

Returns: JSON with scenario results, shock estimates, factor betas/alpha, Monte Carlo VaR/CVaR, risk flags, and overall risk level.

ParametersJSON Schema
NameRequiredDescriptionDefault
portfolio_jsonYes
prices_jsonYes
factor_data_jsonNo
benchmarkNoSPY
run_scenariosNo
run_shocksNo
run_factorsNo
run_montecarloNo
n_simulationsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so the description carries full burden. It describes the computations performed but does not disclose any behavioral traits like side effects, safety, rate limits, or prerequisites beyond the parameter info. It is a compute-only tool, but the lack of explicit safety information is a gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-organized with a purpose statement, bulleted list of test types, a clear 'Args' section for parameters, and a 'Returns' section. It is front-loaded and every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 9 parameters, 2 required, and the presence of an output schema, the description is fairly complete. It explains inputs (including derivation like 'from fetch_prices') and return format. Could be improved by explicitly stating that fetch_prices must be called first, but it is implied.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description fully documents all 9 parameters. Each parameter has a clear explanation, example for portfolio_json, defaults, and types. This adds significant meaning beyond the schema, especially for required inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool runs comprehensive portfolio stress tests and lists specific test types (historical scenario replay, hypothetical shocks, Fama-French decomposition, Monte Carlo). This distinguishes it from sibling tools like analyze_risk (likely for single asset risk) and run_backtest (historical backtest).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for running stress tests on a portfolio but does not explicitly state when to use vs alternatives or when not to use. However, the tool's purpose is clear and the context of sibling tools makes usage context understandable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 11 tool updatesv0.2.0
    • First observedanalyze_risk
    • First observedcompare_swaps
    • First observedcompute_attribution
    • First observedfetch_ff_factors
    • First observedfetch_financials
    • First observedfetch_prices
    • First observedget_skill
    • First observedrun_backtest
    • First observedrun_pipeline
    • First observedscore_tickers
    • First observedstress_test

TDQS

A4.4/5.0

Scored across 11 tools

Disambiguation5/5

Each tool has a clearly distinct purpose, from data fetching (fetch_prices, fetch_financials, fetch_ff_factors) to analysis (analyze_risk, score_tickers, compare_swaps, compute_attribution, stress_test, run_backtest) and orchestration (run_pipeline, get_skill). No two tools overlap in functionality; the pipeline tool is explicitly a meta-orchestrator, avoiding confusion.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with lowercase and underscores: analyze_risk, compare_swaps, compute_attribution, fetch_ff_factors, fetch_financials, fetch_prices, get_skill, run_backtest, run_pipeline, score_tickers, stress_test. The naming is predictable and uniform.

Tool Count5/5

11 tools is well-scoped for a portfolio rotation analysis server. The count covers essential data retrieval, scoring, risk assessment, swap comparison, backtesting, attribution, stress testing, and a full pipeline orchestrator. No tools feel redundant or extraneous.

Completeness5/5

The tool surface covers the entire portfolio rotation workflow: data acquisition (prices, financials, factors), scoring, risk analysis, swap recommendations, backtesting, attribution, stress testing, and a knowledge skill. The pipeline tool ties everything together. No obvious gaps exist for the stated purpose.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Portfolio risk analytics MCP server — VaR, Monte Carlo simulation, stress testing, portfolio optimization, options Greeks, and correlation analysis. Real market data via Yahoo Finance. Free tier available, Pro at $29/mo.
    10
    73 npm
    2
    MIT
  • F
    license
    B
    quality
    B
    maintenance
    Enables unified access to portfolio management, market data, risk analysis, trade records, compliance checks, and Slack notifications through a single MCP server.
    18
    -
  • F
    license
    A
    quality
    B
    maintenance
    MCP server providing portfolio analytics tools: beta to a benchmark, sector correlation, and FIFO trade matching with realized/unrealized P&L using Yahoo Finance prices.
    3
    -