Skip to main content
Glama
Luissalet

Midas Hoard MCP Server

by Luissalet

Absorbed by Coase's Hoard. This project's capabilities are maintained in the merged Hoard, with independent modules initially disabled. The code and instructions below remain as historical reference; use the linked repository for the current installation.

Midas's Hoard

A local market-research lab for one person. It freezes market data into snapshots with provenance, keeps falsifiable investment theses with rules that invalidate them, runs an honest strategy backtester with a sealed holdout and overfitting checks, and audits every model-written number against the evidence. Assistants reach it over MCP; you reach it in the browser.

Research, not trading. There is no broker, no order, no buy or sell advice. Results are historical analyses, not advice; past performance does not guarantee future results.

What it does

  • Market - search symbols, fetch a series and freeze it as a snapshot (canonical CSV, sha256, provider, fetch time, currency, adjustment flag). Compare series with correlation and relative performance; mixed currency, adjustment or frequency is refused unless you allow it, and an exchange-rate conversion is recorded step by step. Charts are hand-drawn SVG.

  • Theses - a claim, a forced rival hypothesis, a knowledge cutoff (as_of), a horizon, evidence for and against, and invalidation rules written in a small language with no eval (close(AAPL) < 150, yoy(CPIAUCSL) > 4, drawdown(^GSPC) < -20, sma(x,50) < sma(x,200)). A true rule means the thesis is invalidated. Evidence metrics never use data after the cutoff. Checks are idempotent and an invalidation emits one event.

  • Lab - declarative strategy specs (JSON, no code). A signal on bar t only affects the position earning bar t+1 (a test proves it). Costs, sizing, rebalancing, long/short, benchmark, sealed holdout, anchored walk-forward with an optional parameter grid, block-permutation test, block-bootstrap Sharpe interval, Bonferroni haircut and deflated Sharpe. Every variant is logged, failures included, with a multiple-testing warning.

  • Committee - two advocates, an independent risk reviewer and an arbiter over a fixed evidence pack. Citations are validated and every number goes through the number ledger (observed, derived, cited, proposed or unmatched). Without a model it returns the evidence pack and deterministic metrics.

  • Portfolio - holdings from a table or CSV, valuation at a date, allocation, currency exposure, concentration, volatility, drawdown, correlation, with every FX conversion recorded.

  • Reports - Markdown or JSON for a thesis, a run or a portfolio, with provenance for every number. A run's report follows the lab report contract (below) and also exports as HTML.

  • Data health - nulls, zeros, coverage by date, 3-sigma outliers and long gaps per series, computed before any metric is read.

  • Duplicates - the same idea under another name is found by mechanism, not only by spec hash, and counts as a trial.

Related MCP server: Polyrama MCP Server

Lab report contract

The report of a backtest (report_export with kind: "run", GET /api/lab/backtests/{run_id}/report, the Lab screen) always has the same eight sections, in this order:

  1. Identity and scope - strategy, universe, window, which part is in-sample and which out-of-sample (sealed or opened holdout; walk-forward windows), and a rule-based evidence-quality label.

  2. Summary.

  3. Health gates - data health, sample size, permutation, walk-forward, bootstrap, multiple testing, holdout and duplicate risk, each pass, warn, fail or not_run.

  4. Metrics - one table per window (development, walk-forward out-of-sample, opened holdout); windows are never mixed in a table.

  5. Mechanism with alternatives.

  6. Risks and evidence gaps.

  7. Next experiments, prioritised.

  8. Decision: reject, investigate, review or adopt, with the reasons.

Every statement carries a tag: Observed (read from, or computed on, the stored artifacts), Inference, Alternative or Experiment. In JSON each claim has kind; in Markdown the tag is bold (**[Observed]**); in HTML and in the UI it is a coloured label. The committee's arguments, risks and reasons carry kind: "inference".

The decision is computed by fixed rules from the validations that exist (walk-forward windows that were positive, permutation p-value, bootstrap interval, multiple-testing correction, holdout), the data health and the variants tried, including near-duplicates under other names. A model never writes or changes it. Missing evidence only lowers it: without validations, with a failing data-health gate or coverage under 90 %, with too few bars or trades, or with a window under a year, the most it can be is investigate; adopt also needs an opened holdout that held up and no high duplicate risk. A negative net Sharpe over at least 120 bars, a walk-forward with no positive window, or a failed holdout gives reject. The thresholds are returned with the decision.

Rules against invented metrics, enforced in code: a null stays null and reads no data (never 0); each table states its window; there is no composite score (the evidence-quality grade labels how much was tested and is not a verdict); the report states its conventions: drawdown is a negative fraction of the previous peak, and turnover is the sum of |change in weight| per year, not halved.

Data health

data_health (tool, GET /api/lab/data-health) measures, per series and window: share of null price cells, share of exact zeros, coverage (valid dates over expected dates), returns beyond 3 standard deviations and long gaps. It runs on the raw frozen series before any metric, is stored with each run and shows as a gate in the report. The thresholds used travel with the result. A missing close is never filled; the backtest warns where it had to treat one as no move.

Duplicates

At registration each experiment is compared with those of other families: Jaccard overlap of the indicator kinds, of the rule leaves (indicators compared by kind, so renaming fast to ma_short changes nothing) and of the universe symbols, plus the similarity of name and note (embeddings through Hoard Link when available, otherwise TF-IDF). duplicate_risk is low, medium or high with the similar experiments and why. It never blocks. Variants of another family at high mechanism overlap count in effective_variants, which drives the warning level and the multiple-testing correction (experiments_duplicates, GET /api/lab/duplicates).

Data providers

Provider

Data

Notes

Yahoo Finance (default)

daily prices for equities, ETFs, indices, FX and crypto: AAPL, ^GSPC, ^IBEX, SAN.MC, EURUSD=X, BTC-EUR

no key; unofficial public chart endpoint, personal and research use only; closes adjusted for splits and dividends, events recorded; may change or throttle without notice

FRED

macro series

Source: Federal Reserve Bank of St. Louis; values are as last revised, not vintages

European Central Bank

euro reference rates and statistics (SDMX)

Source: ECB Data Portal

CoinGecko

crypto prices, up to 365 days on the free tier

data provided by CoinGecko; throttled

Alpha Vantage

daily prices

optional, off until you add a free key (MIDAS_ALPHAVANTAGE_KEY or Settings); raw bars, small daily allowance

Tiingo

daily adjusted prices, mostly US

optional, off until you add a free key (MIDAS_TIINGO_KEY or Settings)

Stooq

end-of-day prices

currently blocked: it answers scripts with a JavaScript browser check, which Midas does not try to get around; fetches fail with provider_unavailable and the source is marked blocked

CSV

your own files

you declare currency or unit; nothing is guessed

fake

deterministic synthetic series

for tests, demos and offline use

API keys entered in Settings are write-only: they are stored locally and the API only reports configured and the last four characters. Providers show as ok, needs_key or blocked in the Sources page and in market_providers.

Responses are cached on disk by the shared Hoard Link JSON API client (identifying User-Agent, one retry on network errors and server errors, a stale copy when the provider is down, Retry-After on rate limits, public addresses only); MIDAS_OFFLINE=1 (or the Settings switch) answers only from the cache. Read each provider's terms, shown with every snapshot.

Run it

pip install -r requirements.txt
python -m midas_hoard            # http://127.0.0.1:5192

The client is built and committed under midas_hoard/static; rebuild it with npm install && npm run build. python scripts/launch.py picks a free port and opens the browser; python scripts/dev.py runs the API with reload plus the Vite dev server.

Settings come from the environment: MIDAS_DATA_DIR (default ./data), MIDAS_PORT (5192), PORT_STRICT, MIDAS_ALLOWED_HOSTS, MIDAS_HTTP_TIMEOUT_S, MIDAS_CACHE_TTL_S, MIDAS_OFFLINE. Data lives in data/midas.db (SQLite, WAL) plus data/snapshots, data/runs and data/reports; files are written atomically. The launcher, request guard, error envelope, stable mcp-token, SQLite layer, agent catalogue (20 KB result cap) and MCP bridge are the shared commons of Hoard Link (midas_hoard/hoard_link/); a second python -m midas_hoard on the same port exits instead of starting another copy.

Faustus assistant

Once the shared Hoard Link launcher is installed, the app shows the family's Faustus panel (a floating button). The conversation, the model and the tools live in Faustus; this app only tells the panel what is open.

  • Context per view. The panel receives the objects open in the view, with real ids read through the app's own API: thesis (title, status, as-of date, reference), portfolio (name, currency, number of holdings), experiment (run id, strategy or family), strategy and snapshot (symbol, provider; the snapshots selected in Market). The view also gives the page and tab. Creation views (a new thesis, portfolio or strategy) report new and give no object. No holdings, evidence text or keys are sent.

  • Unsaved fields. The panel asks for them with the midas:context-request window event. The forms thesis-form, evidence-form, portfolio-form, strategy-form (spec text cut to 20,000 characters when it does not parse) and snapshot-fetch-form answer with their typed fields and dirty.

  • Refresh. When the assistant finishes a turn the open view reloads in place (hoard:copilot-turn-end / window.hoardCopilot.onTurnEnd) without remounting or resetting forms.

  • Saving. Forms send only what changed. New: PATCH /api/portfolios/{name} and portfolio_set with action: "patch" (upsert holdings matched by symbol, remove symbols, currency; one transaction); PATCH /api/lab/strategies/{id} and strategy_save with id + spec_patch (objects merge, arrays replace, null removes a key; it cannot rename). Portfolios with repeated symbols are still replaced whole. See docs/API.md.

  • Tests. node --test client/copilot-context.test.mjs and python -m pytest -q tests/test_partial_update.py tests/test_manifest.py.

Assistant tools (MCP)

mcp_server.py is the shared Hoard Link stdio bridge. It never opens the database: it proxies every call to POST /api/agent/call with the token in data/mcp-token, reads the tool list from GET /api/agent/tools, and starts the app if nothing answers (MIDAS_BRIDGE_AUTOSTART=0 disables that). Variables: MIDAS_URL, MIDAS_TOKEN_FILE, MIDAS_DATA_DIR. Errors keep their code and hint. Deletes need confirm: true on the owning tool. The 29 tools:

Market data

Tool

What it does

midas_status

Health: providers, data counts, models, disk

market_providers

List data providers with terms, delay and licence

market_search

Search symbols (indices, FX, stocks, macro series, crypto)

market_fetch

Fetch a series and freeze it as a provenance-tagged snapshot

market_series

View a snapshot: points, returns, volatility, drawdown, resample, rebase

market_compare

Compare 2-12 snapshots: correlation, relative performance, aligned dates

snapshots_list

List stored snapshots with provenance

Theses

Tool

What it does

thesis_create

Create an investment thesis with a rival hypothesis and rules

thesis_get

Get a thesis with evidence, rules and last check state

thesis_list

List theses by status or text

thesis_update

Edit a thesis (claim, rules, status...) or delete it (action=delete, confirm=true)

thesis_evidence_add

Add evidence for/against a thesis (metric, url, note, hoard:// ref) or delete one

thesis_check

Check a thesis's invalidation rules on fresh data; may set it invalidated

committee_run

Run the committee on a thesis: advocates, risk reviewer, arbiter, number ledger

Strategy lab

Tool

What it does

strategy_validate

Validate a strategy spec (JSON, no code) with fixable errors

strategy_save

Save a validated strategy by name, or delete one (action=delete, confirm=true)

strategies_list

List saved strategies with the variants tried, or fetch one spec

backtest_run

Backtest a strategy: metrics, equity, trades, benchmark, variants tried

backtest_validate

Stress a backtest: walk-forward, permutation test, bootstrap Sharpe CI, multiple testing

experiments_list

List every backtest variant ever run, failures included, or one run in detail

data_health

Data health of series: % nulls, % zeros, coverage by date, 3-sigma outliers, long gaps

experiments_duplicates

Find the same idea under another name: shared indicators, rules, universe, description

Portfolio and reports

Tool

What it does

portfolio_set

Set a portfolio's holdings (list or CSV) or delete it (action=delete, confirm=true)

portfolio_analyze

Value and analyse a portfolio: allocation, currency exposure, vol, drawdown, correlation

report_export

Export a thesis, run or portfolio as Markdown/JSON with provenance for every number

Full reference: docs/API.md.

Method and limits

  • Snapshots are immutable and verified by hash on load; identical bytes reuse the snapshot.

  • as_of makes analyses point-in-time for the data you hold. FRED and some other providers publish revised values, so revisions can still leak into past dates; this is stated in each snapshot.

  • Variant counts are per strategy family (distinct spec hashes) plus the variants of other families that are the same idea (high mechanism overlap). The deflated Sharpe needs at least 3 variants.

  • Backtests are daily-bar simulations with proportional costs: no intraday fills, no liquidity model, no taxes, no survivorship correction for delisted names.

  • The committee can only be as good as the evidence you give it; unmatched numbers are flagged, not removed.

  • CoinGecko history is limited to 365 days on the free tier.

Tests

python -m pytest -q (offline: a fake provider, mocked HTTP transports and a scripted model). CI runs on Ubuntu and Windows.

Licence

MIT (c) Luis María Salete Cuartero. Data remains subject to each provider's terms.

Saved watchlists / Listas de seguimiento

Market now keeps named sets of pinned snapshots. Create a list from the selected series, rename it, add selections or remove individual entries without deleting snapshot files. Open each series in the existing chart. Filter by symbol/currency, percentage change and drawdown, with dated windows and source SHA. The date cutoff affects observations; it does not reconstruct provider vintages. Refresh fetches new snapshots per asset, keeps imported CSV data, reports partial failures and preserves concurrent edits.

Four native tools use the same API: watchlists_list, watchlist_save, watchlist_view, watchlist_refresh. The assistant receives the saved list identity and unsaved watchlist editor fields. No additional model or external application is required. API and verified behavior.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables quantitative trading research by providing tools to backtest strategies, list market datasets, review forward-test logs, and search previously rejected hypotheses, all through an MCP interface.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables MCP-compatible assistants to research prediction markets on Polymarket and Kalshi, analyze public wallets, read market signals, and run paper-only trading simulations.
    10
    16 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to run a full quant research workflow over MCP: pulling data, authoring and backtesting strategies, running statistical validation and risk checks, and recording findings for future sessions.
    1
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Provides a suite of MCP tools for evidence-grounded investment research, including time-bounded search of reports and news, thesis verification against subsequent events, market response calculations, and generation of validated research briefs.
    9
    MIT