Portfolio Copilot
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PORTFOLIO_COPILOT_SEC_USER_AGENT | No | User-Agent string with contact information for SEC EDGAR requests. Optional; a default works, but set this if SEC blocks requests, e.g. 'your-app your@contact'. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| parse_portfolio_exportA | Parse and normalize a local broker portfolio export. Never accesses any broker online. |
| get_portfolio_configA | Load targets, fees, risk_limits and rebalancing rules from config/portfolio.yaml.
Falls back to the tracked config/portfolio.example.yaml when the user has not created
their own file yet (flagged via |
| analyze_stockA | Deterministic stock score (0-100) + confidence from free public data. Yahoo (tier B) provides the snapshot; audited SEC 10-K facts (tier A) override revenue growth and free cash flow when the company files with the SEC. Every override is listed in provenance. A metric where sources disagree without an official (tier A) tiebreaker is excluded from the score entirely; the full reconciliation is returned under "evidence". |
| screen_stocksA | Analyze an explicit ticker universe and rank it. Every ticker is scored, including
revisions/catalysts when free data (yfinance analyst estimates/rating events, Yahoo
earnings-surprise history, SEC Form 4/8-K counts) covers it -- see
|
| portfolio_riskB | Summarize weights, concentration and leveraged exposure from a local export. |
| allocate_cashA | Allocate new cash toward target weights without selling, while considering fees. |
| rebalance_portfolioA | Cash-flow-first rebalancer. New cash buys the most underweight buckets first (BUY orders only, via allocate_cash) -- CLAUDE.md's preferred order: use new cash, suspend buys on overweights, buy underweights, and sell only as a last resort. Set allow_sells=True to also see SELL orders for buckets still beyond the rebalance band after cash is deployed, listed separately under "sell_proposals"; the BUY-only orders key is unchanged either way. Nothing here executes a trade. |
| generate_order_planB | Return suggested manual orders. This tool cannot send orders to any broker. |
| build_investment_planA | Turn four rookie answers into a deterministic plan: profile, targets, example instruments to verify, initial manual orders, fee-aware contribution cadence, 12-month calendar and review rules. No return forecast. Nothing is executed. |
| backtest_planB | Replay the plan rules on past monthly prices (free provider): fees paid, drift, drawdown, final weights. Buckets without price data are reported, never invented. This is a replay of the past, not a forecast. |
| discover_stocksA | Discovery step for "I have no idea what to buy" (public pages, tier C, no account). Nothing is excluded here: mode='universe' (default) samples the WHOLE market across
every size bucket and style -- huge and small companies in the same net, no filter by
index membership or overlap; mode='preset' runs one narrower Finviz preset screen
instead (original behaviour, |
| log_decisionC | Append a suggested decision to the local decision ledger (data/private, git-ignored). Records what was decided and the shadow alternative so it can be measured later. |
| review_decisionsA | Shadow portfolio: for every logged decision older than min_days, compare what was chosen with the recorded alternative at today's prices (free provider). Reports mean decision alpha and hit rate, and refuses to draw conclusions on fewer than 10 decisions. Also includes an 'opportunity' section (portfolio.opportunity): regret against the full ranking shown at decision time, when decisions were logged with 'candidates'. |
| fx_ratesA | Official ECB euro reference rates (free): units of currency per 1 EUR, with as_of. |
| convert_amount_to_eurA | Convert an amount to EUR with the ECB reference rate. Unknown currency => value null. |
| company_factsA | Audited annual fundamentals from SEC EDGAR 10-K XBRL facts (US filers only, free): revenue and growth, net income/margin, free cash flow, equity, debt, with fiscal year and filing date. Foreign ADRs usually have no us-gaap facts: the result says so. |
| save_thesisA | Persist (create or update) a symbol's investment thesis: the claims made at BUY time plus concrete, checkable falsifiers (see check_thesis). Upserts by uppercased symbol; call this right after log_decision on a BUY so the thesis can later be checked against fresh data instead of re-litigated from memory. |
| check_thesisA | Evaluate a stored thesis's falsifiers against a fresh market snapshot (Yahoo, plus audited SEC facts when available -- see analyze_stock). Never invents a thesis: raises if none was saved for this symbol via save_thesis. Returns the new check plus the previous status and a qualitative delta (new/unchanged/improved/worsened). |
| propose_replacementA | Is |
| portfolio_exposureA | Hidden-exposure theme/driver rollup for a local export (config/exposure_graph.yaml): a small-cap ETF and an "AI software" fund can lean on the same driver despite unrelated sector labels. For each single-stock equity holding, fetches sector/industry from the market-data provider (a failed lookup is recorded under 'provider_errors', never guessed) so it can be classified; ETFs/certificates/bonds use only the fields already in the export. Includes a separate leverage-adjusted 'equivalent' view -- an intuitive metric only, never a VaR substitute (CLAUDE.md). |
| capital_auctionA | Rank every use of new cash -- underweight target buckets, screened candidate stocks and holding cash itself -- by marginal utility (portfolio.auction) and allocate cash_eur to the winners, one economic order at a time. Bucket current values come from the local export mapped via portfolio.mapping against config/model_portfolios.yaml's example instruments; targets come from get_portfolio_config(). Candidate stocks are scored via analyze_stock; a stock below 0.5 confidence can never win. Each candidate's fit is its hidden-exposure overlap against the portfolio's own exposure (portfolio.exposure) -- a candidate that piles onto an already-large driver scores lower fit than one that diversifies. A stored thesis (check_thesis) discounts a candidate's utility if it is WEAKENING or BROKEN. Suggestions only -- never sends an order. |
| personal_edgeB | This user's own track record, not a market study: mean decision alpha and hit rate by category/theme (see log_decision's category/theme fields), from the decision ledger's measured rows. Refuses to call a group's evidence threshold raise/lower until it has at least min_sample measured decisions in it (default 10, CLAUDE.md-aligned). |
| decision_qualityA | Process-quality rubric (0-100) for one logged decision (see log_decision): did it have sources, adequate confidence, a red-team pass, a documented reason, a recorded alternative, a recorded price/amount and a non-deteriorating thesis? Never looks at the outcome. Paired here with the decision/outcome matrix using today's measured alpha, when the decision is already priceable. |
| macro_snapshotA | Deterministic macro regime read: HICP (Eurostat, tier A), unemployment (Eurostat, tier A; EU27_2020 by default because the euro-area aggregate is not published for une_rt_m) plus the ECB deposit facility rate (tier A). regime is restrictive/neutral/accommodative only when both HICP and the deposit rate are available; either missing makes it 'unknown' -- never guessed. |
| filing_sectionsA | Item-section text from the most recent SEC filing of |
| insider_activityA | Form 4 / 4-A filing counts in the trailing |
| investor_relations_linksA | Find and classify a company's investor-relations page (annual/quarterly reports,
earnings releases, guidance, presentations, press releases) from its public website
(yfinance's |
| map_holdings_to_targetsA | Map every holding in a local export to a target allocation bucket (portfolio.mapping) by ISIN then by name keywords, using get_portfolio_config()'s targets and config/model_portfolios.yaml's example instruments. Certificates, leveraged instruments and single stocks are reported as satellite positions outside the bucket system -- never silently dropped from coverage. The result's 'current_values' plugs directly into rebalance_portfolio/allocate_cash's current_values parameter. |
| save_portfolio_snapshotA | Freeze the local export as one dated monthly snapshot (portfolio.snapshots, data/private/snapshots, git-ignored) so a later check-in can measure what actually changed instead of re-deriving history that was never recorded. Holdings are mapped to target buckets the same way map_holdings_to_targets does; the stored plan_targets prefer data/private/investment_plan.json's own targets over get_portfolio_config()'s. Refuses to overwrite an existing date unless force=True. |
| list_portfolio_snapshotsA | Every stored monthly snapshot date (portfolio.snapshots, data/private/snapshots, git-ignored, local-only), oldest first. |
| compare_snapshotsA | Diff two stored monthly snapshots (portfolio.snapshots.diff_snapshots): total and per-holding/per-bucket value change since 'older'. Cannot separate contributions from market move on its own -- always read the returned 'note' before calling a number 'gain' or 'loss'. |
| resolve_isinsA | Map ISINs to tickers via the free, keyless OpenFIGI mapping API (tier A, no signup):
useful when a broker export identifies a holding only by ISIN and another tool
(analyze_stock, map_holdings_to_targets) needs a yfinance-style ticker instead. A miss
or an exchange OpenFIGI doesn't map to a known Yahoo suffix comes back as |
| rank_candidatesA | Score every ticker in |
| backtest_pickerA | Disclosed PROXY backtest of the picker's ranking logic (portfolio.picker_backtest) on
live free data: for each ticker, fetches price history (yfinance, tier B), earnings-
surprise history (yfinance, tier B, see providers.yfinance_surprises), analyst rating-
change events (yfinance, tier B, US-listed/ADR only) and as-filed annual fundamentals
(SEC EDGAR XBRL, tier A, US filers only), then replays a quarterly-rebalance top-quintile
strategy against |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| portfolio_review | Orchestrate a complete portfolio review. |
| stock_picker | Rank a comma-separated candidate universe. |
| rebalance | Guide a fee-aware portfolio rebalance. |
| deploy_cash | Decide how to deploy new cash across existing targets and new ideas. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/lodetomasi/portfolio-copilot'
If you have feedback or need assistance with the MCP directory API, please join our Discord server