Skip to main content
Glama

cigar-butt

An MCP server that screens stocks against Benjamin Graham and Walter Schloss deep-value criteria, computing every figure from primary filings rather than from a commercial screener or from a language model's memory.

It reads SEC EDGAR XBRL to build tangible book value, NCAV, NNWC and net cash; scans the filing index for restatements, bankruptcies and delistings before doing any valuation work; and turns whatever survives into equal-weight whole-share allocations and rebalance orders.

The distinguishing claim is provenance. Every figure carries the filing it came from, the accession number and the date it was filed. A figure that could not be retrieved is reported as missing, never estimated. The failure mode this exists to prevent is the obvious one: a plausible list of tickers with plausible-looking ratios attached, assembled from training data rather than from current filings. Valuations move — a name that traded at 0.7× tangible book six months ago may trade at 2× today — and a list built from memory is confidently wrong in exactly the way that costs money.

This is not investment advice, and no advisory relationship is created by using it. The software is provided as is, without warranty, and the author accepts no liability for any loss arising from its use. Data comes from third-party sources and may be inaccurate, delayed or incomplete. Past performance does not indicate future results. You are solely responsible for your own investment decisions; consult a licensed professional. Read the full disclaimer →

Contents

Related MCP server: Financial Signals MCP

Why "cigar-butt"

The name is Warren Buffett's, for the style of investing he learned from Benjamin Graham. From the 1989 Berkshire Hathaway shareholder letter:

If you buy a stock at a sufficiently low price, there will usually be some hiccup in the fortunes of the business that gives you a chance to unload at a decent profit, even though the long-term performance of the business may be terrible. I call this the "cigar butt" approach to investing. A cigar butt found on the street that has only one puff left in it may not offer much of a smoke, but the "bargain purchase" will make that puff all profit.

That is the strategy this server implements: buy the discarded business nobody wants, below what its assets alone are worth, for the one puff left in it.

Buffett wrote that passage to explain why he had moved away from it. In the same letter, under the heading Mistakes of the First Twenty-Five Years, he calls the approach foolish "unless you are a liquidator", notes that "the original 'bargain' price probably will not turn out to be such a steal after all", and concludes:

Time is the friend of the wonderful business, the enemy of the mediocre.

Both halves are true and the second one is the important one here. The objections are real: at Berkshire's size the strategy stopped scaling, cheap businesses are usually cheap for a reason, and a mediocre business gets worse while you wait. Schloss ran it successfully for decades on a small book and extreme diversification — his record is commonly cited as roughly 15% a year over 45 years against about 10% for the index — which is the honest evidence for the method, and it is evidence about one manager, not a promise about yours.

A tool whose entire discipline is refusing to overstate a number should not open by overstating its strategy.

The method, honestly

The whole thesis is that the reported balance sheet is true. Everything follows from that, including the order the tools run in.

Schloss's rules, as filters:

Criterion

Filter

Note

Below tangible book

P/TBV < 1.0

Schloss wanted 0.6–0.8. Goodwill and intangibles are stripped out; most screeners offer plain P/B

No real debt

Debt/Equity < 0.2

Or long-term debt near zero

Solvency

Current ratio > 2

Graham's own threshold

Diversify

15–20 positions, equal weight

Schloss ran 60 to 100. The method distrusts per-name conviction by design

Graham's stricter net-net variant:

  • NCAV = current assets − total liabilities − preferred stock. Buy below two-thirds of NCAV.

  • NNWC = cash + 75% of receivables + 50% of inventory − total liabilities.

Six things this does that a stock screener will not.

1. Disqualifiers run before valuation, not after. If anything undermines the filings, the name is dead regardless of how cheap it looks, and no ratio catches that. check_disqualifiers reads the submissions filing index in one request and reports 8-K item 4.02 (non-reliance on previously issued financials), 4.01 (auditor change), 1.03 (bankruptcy), 3.01 (listing deficiency), 2.06 (material impairment), Form 25 and 25-NSE (delisting), NT 10-K/NT 10-Q (late filing), and gaps where a periodic report should be. A full balance sheet is twelve requests; the scan is one, so it goes first.

2. "Could not compute" is not "failed". A check reads n/a when a line item is missing, and that is deliberately distinct from false. A filer that never tagged Liabilities gets no NCAV — a gap in the evidence, not a failed test. Collapsing the two is how a screen ends up confidently wrong.

3. Every line item comes from the same reporting period. Filers change which concepts they tag, so taking "the latest fact for each concept independently" can silently build NNWC from a years-old receivable. Items that do not reach the balance sheet's own period end are reported as stale and excluded from the arithmetic.

4. Enterprise value and net cash are meaningless for financials. For SIC 6000–6799 the deposits and the securities book are not spare cash, so the net-cash check returns n/a and says why, and debt/equity is reported without being allowed to veto — leverage is the business model. Use bank_call_report on those names instead: tangible common equity, noncurrent loans and the allowance held against them are the tests that do work on a bank.

5. The debt rule and the book rule fight each other. Most persistent sub-tangible-book names are banks and insurers, whose balance sheets are debt by construction. Apply "no real debt" literally and the universe collapses to industrials, metals, shippers and foreign micro caps. Schloss owned financials anyway. The server surfaces the conflict rather than resolving it silently.

6. Net-nets are rare. A screen of the whole US market routinely returns a handful. If you want twenty strict names, the universe may not contain twenty — and loosening the filters until it does means you are no longer running this strategy. An empty US screen is a real finding; say so, or look at Japan, where they have been considerably less scarce.

Getting started

Requires Node 24.21.0 or later (see .nvmrc). The cache uses node:sqlite, which needs no flag on Node 24.

Claude Code

claude mcp add cigar-butt -- npx -y cigar-butt

Claude Desktop, Cursor and other MCP clients

{
  "mcpServers": {
    "cigar-butt": {
      "command": "npx",
      "args": ["-y", "cigar-butt"],
      "env": {
        "SEC_USER_AGENT": "Your Name your-email@example.com"
      }
    }
  }
}

The env block is optional. With no credentials at all, a large part of the server still works, and the tools that need one say exactly which one and how to get it.

Once connected, ask the model to run setup_status, or open the Set up cigar-butt prompt the server registers, which lists every credential and how to obtain it.

From source

git clone https://github.com/mainfraame/cigar-butt.git
cd cigar-butt
pnpm install
pnpm build
node dist/index.js

Credentials

Credentials are optional and checked per tool. Nothing is globally blocked: a tool asks only for what it actually uses, so the rest of the server keeps working while you fill things in.

Tier

What you get

No credential at all

Congressional disclosures, FINRA short interest, FDIC call reports, UK Companies House status, ECB exchange rates, and all the allocation and rebalance arithmetic

SEC_USER_AGENT

check_disqualifiers, analyze_ticker, screen_market — the core. There is no API key: EDGAR wants a real name and email in the User-Agent, and returns 403 without one

Any one price provider

get_quotes, and the P/TBV and price-to-NCAV verdicts. Without one, analyze_ticker still reports the whole balance sheet and says the price is unavailable rather than refusing

Optional extras

FRED for the macro context, E*TRADE for reading your real book, Companies House and EDINET for the UK and Japan

Every tier listed is free.

To set them up, call setup_credentials. On a client that supports elicitation the server prompts for each value directly; otherwise it returns the registration links for the model to relay, and you pass the values back. They are written to a 0600 JSON file under your config directory, never into a project. Environment variables win over the stored file, so you can override one value for a single run.

Full credentials reference → — every integration, sign-up links, step-by-step instructions (including how to obtain E*TRADE sandbox and production keys), the credentials.json shape and every environment variable. Generated from the provider registry, so it cannot drift from what the server actually reads.

Two things worth knowing before you get there:

  • SEC EDGAR has no API key. A fake User-Agent is worse than none: EDGAR may block your IP.

  • E*TRADE issues two independent key pairs, sandbox and production, and they are not interchangeable. Both pairs and both access tokens are stored separately, so switching with broker_environment can never sign a production request with sandbox material. Sandbox returns canned data that does not match what you asked for — request GOOG, get AAPL — so use it to prove the connection works, never to read real numbers.

What you can do with it

Thirty-eight tools, grouped by what you are trying to do. The order below is roughly the order they are meant to run in; the server ships the same order of operations to the model as its instructions.

Set the server up

Tool

What it does

setup_status

Which credentials are configured, where each value came from, sign-up URLs for what is not

setup_credentials

Prompt for and store credentials in the 0600 file

provider_status

Every price provider: key, rate, budget consumed, and whether it is sitting out a cap

cache_status

What the local response cache holds, by source, and where the database lives

cache_clear

Drop cached responses so the next call refetches. expiredOnly never discards a live entry

Screen the market

Tool

What it does

screen_market

Every SEC filer that reported in a quarter, via the XBRL frames endpoint — five requests regardless of universe size. Ranked by NCAV as a share of tangible book

screen_market attaches no prices, on purpose: pairing a stale quote with a filing figure is the mistake this server exists to prevent. Its output is a candidate list for analyze_ticker, not a verdict.

Check the name is not already dead

Tool

What it does

check_disqualifiers

One request against the SEC filing index: restatements, auditor changes, bankruptcy, delisting, late filings

read_filing

The text of a filing, optionally scoped to one 8-K item. Item 3.01 covers both losing listing compliance and regaining it — only the words tell you which

uk_company_status

The UK analogue, from the Companies House register: liquidation, administration, strike-off, overdue accounts, insolvency history, charges over assets

Run these before any valuation work.

Verify one name

Tool

What it does

analyze_ticker

The full workup: disqualifier scan, then tangible book, NCAV, NNWC and net cash from XBRL line items, then a dated price, then the Schloss and Graham verdicts. Stops before valuation if the name is disqualified

get_quotes

Current prices for a list of tickers, each with its as-of date and the provider it came from

check_corporate_actions

Listing status, splits and dividends. A split between the balance-sheet date and today makes every per-share figure wrong by the split factor

short_interest

FINRA consolidated short interest — the market's own answer to "why is this cheap?". Context, not a veto

bank_call_report

FDIC call reports: tangible common equity, noncurrent loans, allowance coverage. The asset tests that work on a financial

Look outside the US

Tool

What it does

edinet_search

Japanese filings by company name, TSE ticker or EDINET code, from the FSA's EDINET. Indexed by date, not by company, so it walks back a day per request — annual reports cluster in late June

edinet_financials

Balance-sheet line items and the Graham tests for a Japanese filer, from its EDINET XBRL, converted at a dated ECB rate

uk_company_search

Find a UK company on the Companies House register and get its company number

fx_rate

Exchange rates from the ECB, current or historical. A balance sheet in yen cannot be compared against a dollar cash balance without one

uk_company_status returns no financials: UK accounts are filed as iXBRL or PDF documents rather than structured data, so the UK path is a disqualifier check, not a valuation.

Size a book and rebalance it

Tool

What it does

build_allocation

Verified candidates plus a cash balance into whole-share targets. Equal weight, per-name cap, always rounds down so the plan cannot exceed the balance

plan_rebalance

Current holdings against target weights into buys, sells and full exits. Compares market value rather than share count, reports sells before the buys they fund, and says when the buys are not fundable

Only pass names you have actually verified. A weighting implies a level of diligence a screen does not provide.

Read your actual portfolio

Read-only. This server never places, modifies or cancels an order.

Every tool here reads all connected brokerages as one book. Two hundred shares at one broker and a hundred at another is a three-hundred-share position, and weighting it per broker would be wrong at the only level that matters. What the combined view never loses is where the shares actually sit: a sale happens at a broker, and which one decides its tax consequence.

Tool

What it does

broker_connect

Authorize a broker that needs it. E*TRADE returns a URL and shows a short code out of band, which you pass back as verifier; Alpaca needs no handshake at all

broker_accounts

Every account at every connected broker, with the ref the other tools take and the tax treatment of each

broker_positions

The whole book, combined per ticker and marked at each broker's last trade with that trade's date, emitted in exactly the shape plan_rebalance takes

broker_balances

Cash available to invest, settled versus unsettled, total value and open margin calls, per account and summed

broker_transactions

Trades, dividends, transfers and fees for one account — history is where basis is reconstructed, and interleaving two ledgers would obscure it

broker_environment

Show or switch which book each broker is pointed at, without mixing credentials

broker_disconnect

Revoke and delete a stored session token, leaving the API keys in place

Supported today: E*TRADE and Alpaca, plus Fidelity read-only. Fidelity has no public retail API, so its adapter uses the services its own website calls, authenticated by a browser session cookie you copy into FIDELITY_COOKIE — it expires with the session and can break when Fidelity changes its site. It reads Brokerage-account positions and balances only: no orders, no transaction history, no 401(k) plans. Adding a third is an adapter against BrokerAdapter plus one line in the registry — no tool changes.

Four things the combined view does that a per-broker one cannot.

It never sums a simulated book into a real one. If one broker is live and another is in its paper or sandbox book, the live side is used and the other is excluded by name. Synthetic cash folded into a real balance is a figure someone could size an allocation against, and E*TRADE's sandbox in particular answers a request for GOOG with AAPL. Pass broker to read a simulated book on its own.

A broker that is down does not hide the rest. Its accounts are reported as missing and every affected total says it is short — a plan built from a book that quietly lost a broker is worse than one that admits a gap.

Tax treatment does not combine. The same ticker in a Roth and a taxable account has no single answer to "does selling realise a gain?". That reads mixed, the handoff to plan_rebalance says unknown, and no gain figure is offered for those names. Which account a sale comes out of is your decision.

Disagreeing marks are reported, not averaged. Two brokers can quote the same security differently, usually because one is showing a last trade from an earlier session. The newest mark is used and the gap is named.

E*TRADE tokens die at midnight US Eastern. They also go idle after two hours, which the server renews automatically; midnight it cannot. There is no refresh token, so re-authorising needs a human to read a verifier code back. Alpaca uses static API keys and has no such expiry, which makes it the better choice for anything scheduled.

Monitor positions between sessions

Tool

What it does

watch_status

Recent runs, snapshot age, rules armed, file locations. Check this before trusting that anything is being watched

watch_alerts

Alerts fired, each with the reference price and its date, the observed price and its date, and the rule that tripped

watch_rules

The armed rules and their thresholds

watch_rule_set

Create or update a price-move alarm. Local state only; never touches the broker

watch_rule_remove

Delete a rule and its recorded reference prices

watch_snapshot_set

Record the holdings to monitor, in the shape broker_positions emits

watch_snapshot_clear

Forget the recorded holdings, when the snapshot no longer describes the book

See Scheduled monitoring for how this runs when no session is open, and what it genuinely cannot do.

Understand the context

Tool

What it does

macro_context

Moody's Aaa yield, the 10-year, CPI, and the P/E ceiling they imply. Graham wanted an earnings yield of at least twice the Aaa yield, so the hurdle moves with the bond market. Needs a FRED key

price_history_stats

Liquidity, days to sell a position of a given size, distance below the 52-week high, normal daily move

congress_trades

Disclosed Senate transactions searchable by ticker or member, with each member's committee seats

congress_index

How much Senate disclosure history is indexed locally, and backfill further

congress_member_profile

A senator's committees, board seats and outside positions, plus every employer paying the household

congress_house_filings

House transaction-report filings with PDF links — the filing record, not the transactions inside it

Two warnings the tools repeat in their own output.

price_history_stats is not part of the screen. This is an asset test; no statistic in that tool bears on whether a balance sheet is cheap, and none of it may be used to time a purchase. Its one legitimate veto is liquidity — deep value lives in micro caps where the discount is often just the illiquidity, and a name you cannot exit is a name you cannot own. RSI, MACD and every other timing construct are deliberately absent.

Congressional disclosures sit outside the method. Amounts are bands reported weeks late, so nothing there can be a figure the screen acts on. The committee cross-reference is the part carrying real information. eFD cannot be searched by ticker — its form takes a filer name, a state and a filing-date window and nothing else — so transactions are parsed into a local SQLite index and queried there; congress_index reports how deep that index reaches, and a search finds only what has been indexed.

How it gets its data

SEC EDGAR is authoritative and everything else is a cross-check. EDGAR is the filing itself: exact line items, each carrying its accession number, form type, period end and filing date. A vendor's normalisation of a filing loses to the filing, and derived "net cash" figures from screeners have been wrong in testing.

Endpoint

Used for

api/xbrl/companyconcept

One concept, full history, small payload. The workhorse for balance-sheet work

api/xbrl/frames

One concept across every filer in a period. This is the market-wide screen

submissions

The filing index, including the 8-K items array that makes the disqualifier checks a structured lookup rather than a news read

Every price carries its date. In testing, two fetches of one ticker minutes apart returned $18.42 dated Sep 4 and $15.50 dated Jul 10 — a 19% spread on the same security, hours apart, both presented as "the price". A number without its date is arbitrary, which is why Quote.asOf is not optional, why a computed metric reports the date of its oldest input rather than its newest, and why a rebalance plan flags any order whose price is undated.

Sources that need no credential at all: SEC EDGAR (a contact string, not a key), FINRA, FDIC BankFind, Senate eFD, the House Clerk's index, the unitedstates/congress-legislators rosters, and Frankfurter for ECB reference rates.

Price providers and free-tier caps

Quote providers are a failover pool, not a fixed chain. A request tries them in order and skips any that has no key, is cooling down, or has spent its budget. Any one of them is enough; more simply buys headroom.

Provider

Free tier

Notes

Tiingo

~50 unique tickers/hour, 500 requests/day

Split- and dividend-adjusted. The preferred source

Polygon.io

5/minute, end-of-day, ~2 years of history

Also the reference data behind check_corporate_actions

Finnhub

60/minute, no daily cap

The most generous free quote tier here

Twelve Data

8/minute, 800/day

Carries an explicit trade date

Alpaca

200/minute on the free plan

Most headroom of any tier here. IEX feed, so a thin micro cap may not have printed at all

Financial Modeling Prep

250/day

Free tier restricted to large caps

Alpha Vantage

5/minute, 25/day

Effectively a spot-check

EOD Historical Data

20/day

The only non-US coverage. Pass 7203.TSE

Usage is counted locally and checked before a request goes out, against each service's documented limits, rather than inferred from a 429 afterwards. On a daily cap that distinction matters: a rejected call still counts against you, so learning reactively spends a request that was never going to work. A 429 is still honoured as a backstop, since the same key may be in use elsewhere. Counters live in SQLite and survive a restart, because a daily quota does not reset just because the process did.

Tiingo meters unique symbols per month, not only requests, so a single large screen can spend a substantial share of the month while the request counters still look healthy. Distinct symbols are tracked separately; re-reading one already counted this month is free.

If you pay for a plan

The defaults above are free-tier limits, so without overriding them a paid plan runs at free speed.

Variable

Effect

CIGAR_BUTT_BUDGET_<PROVIDER>_<PERIOD>

Call budget, e.g. CIGAR_BUTT_BUDGET_POLYGON_MINUTE=0. 0 means unlimited

CIGAR_BUTT_RATE_<PROVIDER>

Requests per second, e.g. CIGAR_BUTT_RATE_POLYGON=100

CIGAR_BUTT_PROVIDER_ORDER

Preference order, e.g. polygon,tiingo. Unlisted providers keep their default order behind these

Caching

Responses are cached in SQLite (node:sqlite, built into Node 24, so it costs no dependency). The free tiers are the binding constraint: a full per-name balance sheet is twelve companyconcept calls plus a submissions fetch. MCP servers also restart whenever a client reconnects, so an in-memory cache would throw the expensive work away at every session boundary.

TTLs are set by how fast the underlying fact can actually change.

Source

TTL

Why

Quotes

1 hour

Short on purpose. A stale price is the single largest source of wrong answers here

SEC balance-sheet concepts

24 hours

These change only when a filing lands

SEC filing index

6 hours

Gains rows continuously; a new 8-K must not be missed

SEC frames

7 days

A quarter's data is fixed once filed

Ticker index

7 days

A ~1MB payload that changes at the margins

Quotes are cached per provider, because two providers can legitimately disagree and blending them under one key would hide it. cache_status shows what is held, cache_clear drops it, and CIGAR_BUTT_NO_CACHE=1 bypasses it entirely.

Scheduled monitoring

cigar-butt watch polls your holdings on a timer and alerts on moves beyond a threshold you set. Bare cigar-butt is still the MCP server; only the explicit watch subcommand branches away.

cigar-butt watch rule add drawdown '*' 10   # alert on any held name moving 10%
cigar-butt watch install                    # write a launchd agent (macOS)
launchctl load -w ~/Library/LaunchAgents/dev.cigar-butt.watch.plist
cigar-butt watch status

cigar-butt watch with no arguments prints the full subcommand list. The watch_* tools do the same work over the same database from inside a session. Nothing here places, modifies or cancels an order.

The MCP server cannot schedule anything. A stdio server is a subprocess and dies with its client, and the protocol gives a server no way to reach an absent user, on any transport. So the OS scheduler runs a short-lived watch run, and the server reads what it recorded. See docs/scheduling-research.md for why this shape and not a daemon, and what is genuinely impossible.

Three limits worth knowing before relying on it:

  • Alarm latency is the poll interval. That is what free price tiers buy: Alpha Vantage allows 25 requests a day, Tiingo about 50 an hour, and a 20-name book polled every 15 minutes would exhaust them by lunchtime. This is a check, not a tripwire.

  • Price alarms need no broker. They run against a stored holdings snapshot using only a price key, so they work overnight, at weekends, and indefinitely.

  • Broker refresh does not survive midnight. E*TRADE tokens expire at midnight US Eastern with no refresh token. Refresh the snapshot while you are authorised; every alert states the snapshot's age rather than pretending it is current.

Alerts go to stderr, a log file, a macOS notification, or a Slack/Discord webhook (CIGAR_BUTT_WATCH_WEBHOOK). Test one before you need it: cigar-butt watch test macos. A cooldown, a hysteresis latch, optional re-baselining and one notification per cycle keep alerts from storming.

What it will not do

It will not place a trade unless you switch that on, twice. Every brokerage tool was read-only until order placement was added behind two independent switches: CIGAR_BUTT_ENABLE_ORDERS=1 enables paper and sandbox books, and real money additionally needs CIGAR_BUTT_ENABLE_LIVE_ORDERS=1. A fresh install cannot trade whatever anything asks of it.

Where it is enabled, no single call both decides and executes: order_preview prices an order and returns a ref, and order_place takes only a ref. Orders are limit-only, day-only, whole-share, and capped per order (CIGAR_BUTT_MAX_ORDER_VALUE, default $2,500). The risk being guarded against is not you mistyping a ticket — it is an assistant sending an order you never saw.

It will not backtest. A backtest assembled from a list picked with present-day knowledge is survivorship-biased by construction: you chose those names partly because they still exist, so any return figure flatters the strategy. Free price sources are neither survivorship-bias-free nor point-in-time correct, which is exactly what a research database like CRSP buys you. For a real backtest, use point-in-time data with delistings included.

It will not estimate what a trade costs. For a micro-cap book the published fee is a rounding error and the bid-ask spread is the trade cost, and the ratio between them is roughly two orders of magnitude: about $0.41 of statutory charges on a $10,000 sale, against a plausible several hundred dollars of round-trip spread. Spread and market impact are not observable from anything here, so they are not estimated — printing a precise figure for the $0.41 while saying nothing about the rest would be read as the cost. Fee figures in the output are statutory charges only. See docs/trading-costs-research.md.

It will not compute a tax liability. It reports the account classification and cost basis a broker records, and will do arithmetic on two figures it was given, but holding period, wash sales and basis adjustments are not modelled, and a number that looked like a tax bill would be believed as one. An account whose tax treatment reads unknown is undetermined and is never assumed taxable. See docs/tax-treatment-research.md.

It will not name a stock it has not fetched this session. A name reaches the output only with a dated figure behind it.

Configuration reference

Variable

Default

Purpose

CIGAR_BUTT_ENV_FILE

unset

Load credentials from this dotenv file

CIGAR_BUTT_CONFIG

$XDG_CONFIG_HOME/cigar-butt/credentials.json

Where credentials are stored

CIGAR_BUTT_CACHE

$XDG_CACHE_HOME/cigar-butt/cache.sqlite

Cache database location

CIGAR_BUTT_NO_CACHE

unset

Set to 1 to bypass the cache

CIGAR_BUTT_CONGRESS_DB

under the cache directory

Senate disclosure index location

CIGAR_BUTT_WATCH_DB

under the cache directory

Watch state: snapshot, rules, alerts

CIGAR_BUTT_WATCH_LOG

unset

Write watch alerts to this file

CIGAR_BUTT_WATCH_WEBHOOK

unset

Slack or Discord webhook for alerts

CIGAR_BUTT_SETTINGS_DB

under the cache directory

Remembered tool preferences

Provider budgets and rates are in Price providers; every credential variable is in docs/credentials.md, and .env.template is a complete annotated file.

Development

pnpm install
pnpm check        # lint, format:check, typecheck, knip, test
pnpm test         # vitest
pnpm build        # tsdown → dist/index.js
pnpm dev          # tsx watch

Concern

Tool

Package manager

pnpm

Bundler

tsdown (rolldown)

Lint

oxlint, with eslint-plugin-perfectionist loaded through its jsPlugins field

Format

oxfmt, including its built-in import sorting

Dead code and deps

knip

Tests

vitest

Two rules that are not obvious from the code:

All arithmetic goes through decimal.js. number appears at the I/O boundary — JSON in from an API, JSON out to the MCP client — and nowhere in between. Partly for pennies, mostly because these figures are compared against hard thresholds: binary floating point puts a name on the wrong side of "P/TBV below 1.0" often enough to matter when the whole method is buy below the line.

Nothing may write to stdout. That stream is the MCP protocol. A stray console.log corrupts it and the client drops the connection, which is why no-console is an error across src/ and why the watch CLI prints to stderr.

CLAUDE.md has the full architecture and the hard rules; STYLEGUIDE.md has the TypeScript conventions. docs/credentials.md is generated from src/config/providers.ts by pnpm docs:credentials — do not edit it by hand.

Disclaimer and licence

This software is not investment, financial, tax or legal advice, creates no advisory or fiduciary relationship, comes with no warranty of any kind, and its author accepts no liability for any loss arising from its use. Read DISCLAIMER.md in full before using it for anything involving real money.

Licensed under Apache-2.0. See LICENSE, whose sections 7 and 8 carry the warranty disclaimer and limitation of liability that govern.

Available Tools

29 tools
analyze_tickerAnalyze one tickerA
Read-only

Full deep-value workup for one name: the disqualifier scan first, then tangible book, NCAV, NNWC and net cash computed from SEC XBRL line items, then a current price, then the Schloss and Graham verdicts. Every figure carries the filing it came from and the date it was filed. Returns the disqualifier findings and stops before valuation if the name is disqualified.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYesUS-listed ticker symbol, e.g. "AAPL". Case-insensitive.
skipDisqualifiersNoCompute valuations even when a hard disqualifier is present. Off by default, because the balance sheet a disqualified name reports is the thing in doubt.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds valuable behavioral context beyond that: early termination when disqualified, provenance metadata (filing and date per figure), and the ordered pipeline. It does not discuss runtime cost, rate limits, or auth requirements, keeping it at a solid 4.

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?

Three sentences, front-loaded with the full pipeline and ending with the early-exit rule. Every clause adds specific, non-redundant information, and there is no filler.

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?

For a composite read-only analysis tool with no output schema, the description adequately covers the process, provenance, and conditional early return. It would benefit from a brief note on the shape of the returned report or typical latency, but nothing essential is missing for correct invocation.

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

Parameters3/5

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

Schema description coverage is 100%, so both parameters are fully documented in the schema itself. The description implicitly references the gated valuation behavior that skipDisqualifiers controls but does not add syntax, format, or meaning beyond the schema. Baseline 3 is appropriate.

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?

States a specific verb (analyze) and resource (one ticker) and enumerates the exact pipeline: disqualifier scan, tangible book, NCAV, NNWC, net cash, price, Schloss and Graham verdicts. This level of detail distinguishes it from a pure disqualifier sibling even without naming that sibling.

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?

Describes the internal gating condition (stops before valuation if disqualified) and the default behavior implied by that, giving clear context for when the tool applies. It does not explicitly name an alternative like check_disqualifiers for users who only want the first stage, so it falls short of a full when/when-not/alternatives statement.

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

bank_call_reportFDIC call report for a bankA
Read-only

Pull the latest FDIC call report for a bank, by name or FDIC certificate number. This is the asset test that works on a financial: enterprise value and net cash are meaningless for SIC 6000-6799, but tangible common equity over tangible assets, noncurrent loans over net loans, and the allowance held against those loans are exactly the figures a Schloss screen on a bank turns on. Straight from the quarterly call report, dated by report date. No credential required. Search by the holding company name — the SEC filer — and it will also match the insured bank underneath it.

ParametersJSON Schema
NameRequiredDescriptionDefault
certNoFDIC certificate number, when you already have it.
nameNoBank or holding-company name, e.g. "First Keystone Corp".
limitNoHow many matching institutions to report.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations only declare read-only and open-world; the description adds real behavioral context: no credential required, data is quarterly and dated by report date, and a holding-company name search also surfaces the insured bank beneath it. It stops short of describing response shape or result limits beyond the schema.

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?

Front-loads purpose and keying options in the first sentence, then justifies use-case. The Schloss/asset-test elaboration is longer than strictly needed but earns most of its space by clarifying why this tool exists; no sentence is pure filler.

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?

With zero required params, read-only/open-world annotations, and no output schema, the description carries the return-value burden and does so partially by naming the metrics returned. It omits result shape, limit interaction, and error behavior, but nothing critical for correct invocation is missing.

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?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: searching by the SEC-filing holding-company name will also match the insured bank underneath it — a matching behavior not captured by the name field's schema description.

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?

States a specific verb (pull), resource (latest FDIC call report), and the keying options (bank name or FDIC certificate number). No sibling covers FDIC call report data, so this is unambiguously distinguishable across the whole tool list.

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?

Explains when it applies — banks/financials in SIC 6000-6799, where enterprise value and net cash fail — and why the ratio set is the relevant test. It offers clear context but does not name an explicit alternative or state when NOT to reach for it.

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

build_allocationBuild an allocationA
Read-only

Turn a verified candidate list and a cash balance into whole-share position targets. Equal weight by default, with a per-name cap and whole-share rounding that always rounds down, so the plan can never exceed the balance. Only pass names you have actually verified with analyze_ticker: a weighting implies a level of diligence a screen does not provide.

ParametersJSON Schema
NameRequiredDescriptionDefault
candidatesYes
perTradeCostNoPer-trade commission, subtracted before sizing.
availableCashYesCash available to deploy.
maxPositionFractionNoHard ceiling on any one name, as a fraction of the balance.
allowFractionalSharesNoMost brokers settle whole lots; off by default.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations only declare readOnlyHint/openWorldHint, so the description adds real value: it discloses the rounding policy ('always rounds down'), the guarantee that the plan never exceeds the balance, and the equal-weight/cap defaults. It stops short of describing failure modes (e.g. cash too small for a single share) or the shape of the returned plan.

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?

Two sentences, tightly front-loaded with the transformation and its defaults, then the verification constraint. No filler, and every clause carries actionable information.

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?

No output schema exists, so the description must carry the return-value burden; it gestures at 'whole-share position targets' but never specifies the response fields or what a caller can expect back. Behavioral and input guidance are otherwise sufficient for a 5-parameter computation tool.

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?

Schema description coverage is already 80%, and the description reinforces the two behaviorally important parameters: omitting weight means equal weight (with rationale), and a per-name cap applies. It adds intent beyond the schema text but does not clarify perTradeCost or fractional-share edge cases beyond what the schema states.

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?

States a specific verb and resource ('Turn a verified candidate list and a cash balance into whole-share position targets') along with the core method defaults (equal weight, per-name cap). The mention of 'verified candidate list' implicitly separates it from screening tools, so an agent can distinguish it from siblings like screen_market or plan_rebalance.

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?

Explicit prerequisite: only pass names verified with analyze_ticker, with a stated reason ('a weighting implies a level of diligence a screen does not provide'), which steers agents away from screen_market output. It does not, however, state when to prefer this over plan_rebalance, so the alternative-selection guidance is incomplete rather than absent.

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

cache_clearClear the cacheA
DestructiveIdempotent

Drop cached responses so the next call refetches. Pass a source to clear just that one, or omit to clear everything. Use expiredOnly for routine housekeeping, which never discards a live entry.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceNoClear one source. Omit to clear all of them.
expiredOnlyNoRemove only entries past their TTL. Safe to run any time.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations declare destructiveHint=true and idempotentHint=true, so the safety profile is largely covered. The description adds real context beyond them: expiredOnly 'never discards a live entry,' clarifying that destructiveness is conditional and scoping via source limits blast radius.

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?

Three short sentences, front-loaded with the core effect, then scoping, then the safe mode. Every sentence earns its place with no 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?

No output schema and none needed for a cache-clear operation; the description covers effect, scoping, and the safe-vs-aggressive distinction. An agent has everything required to call it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so both parameters are already documented in the schema. The description's wording ('omit to clear everything', 'never discards a live entry') slightly reinforces but does not materially extend the schema semantics, so the baseline 3 applies.

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?

States a specific verb and resource ('Drop cached responses') plus the operational consequence ('so the next call refetches'). This clearly distinguishes it from the sibling cache_status (read) by being the mutating counterpart.

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?

Gives explicit conditional guidance for both parameters: pass a source to scope the clear, omit to clear all, and use expiredOnly for routine housekeeping. It stops short of naming cache_status as the inspection alternative, but the when-to-use guidance is clear.

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

cache_statusInspect the cacheA
Read-only

Report what the local response cache holds, by source, and where the database file lives. Useful when a figure looks stale or when you want to know whether the next screen will hit the network.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already establish readOnlyHint=true and openWorldHint=false, so safety is covered. The description goes beyond that by disclosing what the operation is local and diagnostic in nature and that it surfaces the database file path, which the annotations do not. It says nothing about cost, latency, or whether the cache is mutated, but for a local read that is minor.

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?

Two sentences, zero padding, and the what-is-it clause is front-loaded ahead of the when-to-use clause. Every sentence carries distinct information.

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?

For a zero-arg, read-only, no-output-schema tool this is nearly sufficient: it states what gets reported (cache contents by source, DB file path) and when to reach for it. The one loose end is relationship to cache_clear, which the description never references, leaving the read-vs-clear choice implicit.

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 tool takes zero arguments, so there are no parameter semantics to explain and the schema is trivially complete. Baseline for a no-parameter tool applies; no compensation is needed.

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

Purpose4/5

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

The description gives a specific verb (report) and a precisely scoped resource: the local response cache, broken down by source, plus the database file location. That is far more than a restatement of the title. It stops short of naming the obvious sibling (cache_clear), so the agent must infer the distinction between inspecting and clearing.

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?

It supplies concrete triggering conditions: 'when a figure looks stale' or 'when you want to know whether the next screen will hit the network.' That tells the agent when this tool is the right call. It does not state when not to use it or point to cache_clear as the alternative, so it is context-rich but not fully routing.

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

check_corporate_actionsCheck listing status and corporate actionsA
Read-only

Check listing status and corporate actions for a ticker against Polygon reference data. Two things this catches that a ratio cannot. A split between the balance-sheet date and today makes every per-share figure derived from the filing wrong — the share count is pre-split and the price is post-split — and a reverse split makes a name look cheap by exactly the split factor. And a delisted ticker still resolves in the EDGAR index long after it stopped trading. Pass the balance-sheet period end as since.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNoBalance-sheet period end. Splits on or after this date invalidate per-share figures taken from that filing.
tickerYesUS-listed ticker symbol, e.g. "AAPL". Case-insensitive.
includeDividendsNoReport recent cash dividends alongside the splits.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations cover read-only and open-world traits, and the description adds substantive domain behavior: splits corrupting per-share figures, reverse splits distorting cheapness, and delisted tickers persisting in EDGAR. It does not describe the actual response payload, but the added context is genuinely useful.

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?

Front-loaded with the purpose, then two concrete failure examples that justify the call. Efficient overall, though the two illustrative sentences are somewhat lengthy for the core payload.

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?

With no output schema, the description does not specify the exact return shape (splits, dividends, delisting status), which is a gap. Otherwise it gives enough rationale and parameter guidance for an agent to invoke it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all three parameters well. The description reinforces the `since` semantics ('Pass the balance-sheet period end as `since`') but adds little beyond the schema's own wording, meriting the baseline 3.

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?

States a specific verb (Check) and resource (listing status and corporate actions for a ticker against Polygon reference data), and the contrast with a 'ratio' plus the EDGAR index implicitly distinguishes it from sibling analysis tools.

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?

Explains the two failure modes it catches (split between balance-sheet date and today, delisted tickers in EDGAR) and instructs to pass the balance-sheet period end as `since`, giving clear context for use. It lacks an explicit when-not-to-use or named alternative sibling.

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

check_disqualifiersScan filing index for disqualifiersA
Read-only

Scan a company's SEC filing index for the events that void a deep-value thesis: 8-K item 4.02 (non-reliance on prior financials), 4.01 (auditor change), 1.03 (bankruptcy), 3.01 (listing deficiency), 2.06 (impairment), Form 25/25-NSE (delisting), NT 10-Q/NT 10-K (late filing), and filing gaps. Costs one request. Run this BEFORE any valuation work — a name that fails here is dead regardless of how cheap it looks, and no ratio would catch it.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYesUS-listed ticker symbol, e.g. "AAPL". Case-insensitive.
lookbackDaysNoHow far back to scan. Restatements from a decade ago are history.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint. The description adds genuinely useful behavioral context the annotations lack: the operation costs one request, and it clarifies the scanned universe of event types. It still does not describe what the call returns.

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?

Single dense paragraph, front-loaded with the core action, followed by the concrete event list and the sequencing rule. Every clause earns its place; nothing is filler.

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?

For a two-parameter scan with no output schema, the description covers what is checked, the cost, and when to call it. The main gap is the absence of any indication of the return shape (pass/fail vs. event list), which matters when no output schema exists.

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

Parameters3/5

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

Schema description coverage is 100%, so both ticker and lookbackDays are fully documented in the schema, including the lookback rationale ('Restatements from a decade ago are history'). The description adds no parameter syntax or default info beyond that, so baseline 3 applies.

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?

States a specific verb (scan) and resource (SEC filing index) and enumerates exactly which events it looks for (8-K items, Form 25, NT filings, gaps). It is clearly distinct from valuation siblings like analyze_ticker because it is framed as a pre-valuation disqualifier check.

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?

Explicitly instructs to run it BEFORE any valuation work and explains why (a failing name is 'dead' regardless of price). It gives strong ordering context but does not name an alternative sibling (e.g., analyze_ticker) to route against.

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

congress_house_filingsHouse transaction-report filingsA
Read-only

Periodic transaction reports filed by House members, from the Clerk's official yearly index. No credential needed. This returns the filing record and a link to the PDF, NOT the transactions inside it — House disclosures are PDFs and many are scanned images, so the tickers and amounts are only readable by opening the document. For actual transaction detail use congress_trades, which covers the Senate.

ParametersJSON Schema
NameRequiredDescriptionDefault
yearNoThe Clerk indexes by filing year, not transaction year.
memberNoFilter by surname or full name, matched loosely.
sinceDaysNo

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely useful behavior beyond that: it discloses that the payload is a filing record plus a PDF link, not the transactions, and explains why (scanned-image PDFs). It omits any mention of pagination or rate limits, keeping it short of a 5.

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?

Three sentences, zero waste, and the most decision-relevant fact (filing record only, not transactions) is front-loaded before the sibling hand-off. Each sentence earns its place.

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?

With no output schema, the description correctly compensates by defining what is returned and, critically, what is not. Only the un-described `sinceDays` filter and any result-volume behavior are left unaddressed.

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

Parameters3/5

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

Schema coverage is 67% and the description adds no parameter-specific meaning; the schema already explains that `year` is the filing index year and `member` is loosely matched. Baseline 3 is appropriate, though `sinceDays` remains undocumented in both places.

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?

States a specific verb+resource ('Periodic transaction reports filed by House members') and immediately distinguishes itself from the sibling `congress_trades` by scope and content type. An agent can pick the right tool without opening either schema.

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?

Explicitly names the alternative and the condition that selects it ('For actual transaction detail use `congress_trades`'), and states the access precondition ('No credential needed'). Routing is unambiguous.

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

congress_indexInspect or extend the disclosure indexA

Show how much Senate disclosure history is indexed locally, and extend it. Call with no arguments to report coverage; pass sinceDays to backfill. Each report is a separate request against a rate-limited government site, so work is capped per call and resumes where it left off — reports already indexed are never refetched, because a filed report never changes. Rough sizes: 12 months is ~180 reports, five years ~690, and the whole archive back to 2012 is ~2,400. Expect to call this several times to build deep history; each call reports how many reports remain.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceDaysNoFiling-date window to index. Omit to report coverage without fetching anything.
maxReportsNoReports to fetch on this call, at roughly one per second. Capped because MCP clients time a tool call out at 60 seconds — the backfill is resumable, so several short calls beat one that dies.

TDQS

A4.1/5.0
Behavior5/5

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

Adds substantial behavior beyond the annotations: the upstream site is rate-limited, each call is capped and resumable, already-indexed reports are never refetched because filings are immutable, and clients time out at 60 seconds. It also quantifies archive size (~180/690/~2,400 reports) so the agent can plan repeated calls. The 'extends local index' framing is consistent with readOnlyHint=false.

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?

Front-loads the purpose and mode switch in the first sentence, then layers operational detail economically. The 'Rough sizes' sentence is useful planning data rather than padding, though the resumability point is touched twice (once as mechanics, once as 'each call reports how many reports remain').

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?

With no output schema, the description still covers what a call returns ('each call reports how many reports remain'), how to resume, why calls are capped, and how many calls deep history will take. Nothing an agent needs to invoke this correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already carries both parameters and their bounds. The description reinforces the omit-vs-pass semantics of sinceDays and the per-call cap rationale, but adds little that the schema does not already state; baseline 3 applies.

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

Purpose4/5

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

States a specific dual purpose with concrete verbs and resource: 'Show how much Senate disclosure history is indexed locally, and extend it.' The 'Senate'/'indexed locally' scope implicitly separates it from House-filing and trade-query siblings, but no sibling is named explicitly, so it falls short of full differentiation.

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?

Gives precise mode selection: 'Call with no arguments to report coverage; pass sinceDays to backfill,' and sets expectations with 'Expect to call this several times to build deep history.' It lacks any explicit pointer to the alternatives an agent might reach for (e.g. congress_trades to read the data rather than index it).

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

congress_member_profileCommittee seats and outside interestsA
Read-only

A senator's committee assignments, outside positions and board seats, and every employer paying the household — self, spouse or child — read from their most recent annual financial disclosure. This is the conflict-of-interest picture behind a trade: which industries they have authority over, which boards they sit on, and who else pays the family. Senate only; House annual disclosures are scanned PDFs.

ParametersJSON Schema
NameRequiredDescriptionDefault
memberYesSenator name, e.g. "Tommy Tuberville". Matched loosely.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already cover the safe-read profile (readOnlyHint, openWorldHint), so credit goes to added context: the data provenance (most recent annual financial disclosure), the covered parties (self, spouse, child), and the Senate-only limitation. No auth, rate-limit, or freshness caveats are disclosed.

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?

Two dense sentences with the core resource declaration front-loaded and the scope limitation trailing. No filler or restatement of the tool name.

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?

With no output schema, the description carries the burden and does so: it enumerates the returned dimensions (committees, boards, household payers) and states the source and boundary. An agent knows what it will get and what it won't.

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

Parameters3/5

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

Only one parameter, and schema coverage is 100% — the schema already documents 'member' with the loose-match example 'Tommy Tuberville'. The description adds no matching syntax or format detail beyond what the schema states, so baseline 3 applies.

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?

States a specific verb+resource: a senator's committee assignments, outside positions, board seats, and household employers read from their annual disclosure. It explicitly scopes to the Senate, which cleanly separates it from congress_house_filings and adjacent siblings like congress_trades.

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?

Frames when this is the right tool: the 'conflict-of-interest picture behind a trade' tells the agent it complements congress_trades. The 'Senate only; House annual disclosures are scanned PDFs' line signals the coverage boundary, but it does not name the sibling to use instead for House members.

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

congress_tradesSearch congressional trades by tickerA
Read-only

Search disclosed Senate stock transactions by ticker, by member, or both. No credential needed. This is the natural entry point: ask "who in the Senate traded ASTE?" and get every disclosed transaction in the index, with the committees each member sits on.

eFD itself cannot be searched by ticker — its form takes a filer name, a state and a filing-date window and nothing else — so transactions are held in a local index. It refreshes itself when stale, and reports are immutable once filed, so keeping current costs only the new filings. Use congress_index to see how deep the index reaches and to backfill further; a search can only find what has been indexed.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
memberNoFilter by senator name; matched as a substring.
tickerNoTicker to search for, e.g. "NVDA". Bonds, funds and private holdings often have no ticker and will not match.
sinceDaysNoOnly transactions this recent, by transaction date.

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already establish read-only and open-world, but the description adds substantial non-obvious context: no credential required, an eFD limitation that forces a local index, self-refresh-on-stale behavior, immutability of filed reports, and the critical caveat that a search only finds what has been indexed.

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?

Front-loads the core search capability in the first sentence, then justifies the local-index design. The eFD internals paragraph is slightly long but earns its place by explaining the freshness caveat.

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?

With no output schema, the description helpfully previews the return content ('every disclosed transaction... with the committees each member sits on') and covers freshness and index depth. It is silent on pagination/limit behavior and result ordering.

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

Parameters3/5

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

Schema coverage is 75% and already documents ticker, member, and sinceDays. The description reinforces that filters are combinable but adds no syntax, matching, or defaulting detail beyond the schema, so baseline 3 applies.

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?

States a specific verb and resource (search disclosed Senate stock transactions) plus scope (by ticker, by member, or both), and names the sibling congress_index it is distinct from. An agent can identify the tool's job without opening the schema.

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?

Explicitly frames itself as 'the natural entry point' with a concrete example query, and routes index-depth/backfill questions to congress_index. It does not explicitly bound itself against the House-oriented sibling congress_house_filings, leaving that boundary to be inferred from 'Senate'.

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

edinet_financialsJapanese balance sheet (EDINET)A
Read-only

Balance-sheet line items and the Graham asset tests for a Japanese filer, read from its EDINET XBRL filing. Figures are in yen and converted to a currency of your choice at a dated ECB reference rate.

This is the point of the Japanese path: net-nets have been far scarcer in the US than in Japan for a decade, and a Graham screen that cannot read these filings is looking in the wrong market. Get a document ID from edinet_search first.

ParametersJSON Schema
NameRequiredDescriptionDefault
docIdYesEDINET document ID from `edinet_search`, e.g. "S100XXXX".
convertToNoISO currency to also report in, e.g. "USD". Uses a dated ECB rate.

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds real behavioral context beyond that: figures are in yen, converted via a dated ECB reference rate, sourced from an XBRL filing, and gated on a doc ID. It omits latency, rate limits, or error behavior.

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

Conciseness3/5

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

The opening sentence is front-loaded and load-bearing. The second paragraph is largely persuasive framing ('looking in the wrong market') rather than operational instruction, which spends budget without helping an agent select or invoke the 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?

With no output schema, the description does the work of characterizing the return (line items plus Graham asset tests) and the currency handling, and both parameters are covered. It is complete enough to call correctly, with only minor gaps around return shape detail.

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

Parameters3/5

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

Schema coverage is 100% and the schema already documents both parameters, including the ECB rate for `convertTo` and the `edinet_search` source for `docId`. The description largely reinforces rather than extends that, so the baseline 3 applies.

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 a specific resource (balance-sheet line items and Graham asset tests for a Japanese filer) and its source (EDINET XBRL filing), so an agent knows exactly what it returns. It clearly distinguishes itself from the sibling `edinet_search`, which supplies the input rather than the figures.

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?

It gives an explicit prerequisite ('Get a document ID from `edinet_search` first') and frames the use case (Japanese net-nets where the US market is thin). It stops short of stating when NOT to use it or naming what to use for non-Japanese filers, so it is strong but not exhaustive.

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

etrade_accountsList E*TRADE accountsA
Read-only

List the ETRADE accounts this connection can read, with the accountIdKey every other ETRADE tool needs. Call this before etrade_positions — the account number a user quotes is not the key the API accepts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds real behavior beyond them: the tool is scoped to the current connection's readable accounts, and its output is the accountIdKey prerequisite for other E*TRADE tools, including the warning that a user-quoted account number will not work. It does not cover pagination or error behavior, which keeps it from a 5.

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?

Two tight sentences, both carrying load. The purpose and the accountIdKey rationale come first, the call-ordering instruction second, with no filler.

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?

There is no output schema, so the description must convey what comes back; it does so by naming accountIdKey and warning about the account-number mismatch. For a zero-argument, read-only listing tool with annotations already covering safety, nothing essential is missing.

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?

Zero parameters, so the baseline is 4 and there is nothing for the schema to describe. The description usefully explains the semantic distinction between the returned key and the human-facing account number, which is the only parameter-adjacent ambiguity in this tool family.

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?

Specific verb (List) plus resource (E*TRADE accounts) and an explicit scope qualifier ('this connection can read'). It also names the payload that matters (accountIdKey) and distinguishes itself from etrade_positions, so an agent can place it without reading any schema.

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?

Gives an explicit sequencing rule — call this before etrade_positions — which is exactly the guidance an agent needs for a prerequisite tool. It stops short of stating when not to call it or what to do if the list is empty, so it is clear but not exhaustive.

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

etrade_balancesRead E*TRADE balancesA
Read-only

Full balance detail for one E*TRADE account: cash available to invest, settled versus unsettled, buying power, margin balance, market value, and any open margin calls. Use this when the question is "what do I have to deploy?" — etrade_positions answers "what do I hold?".

ParametersJSON Schema
NameRequiredDescriptionDefault
accountIdKeyYesThe account's `accountIdKey` from `etrade_accounts` — the opaque key, not the human-readable account number. The API rejects the account number.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds useful behavioral context by enumerating the returned data (settled vs unsettled, buying power, open margin calls), which tells the agent what state is exposed. It stops short of noting auth requirements, rate limits, or freshness of the balance snapshot.

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?

Two sentences, no waste. It front-loads the content enumeration and then immediately hands off the disambiguation rule, which is exactly the ordering an agent needs.

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?

For a read-only, single-parameter tool with a fully specified schema and no output schema, this is complete: content scope, account scoping, and the sibling distinction are all present, and the safety profile comes from annotations.

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

Parameters3/5

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

Schema coverage is 100% and the single accountIdKey parameter is thoroughly documented in the schema itself (opaque key vs account number, API rejects the number). The description adds no parameter detail beyond the schema, so the baseline 3 applies.

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?

States a specific verb+resource ('Read E*TRADE balances') and then enumerates exactly what the payload contains: cash available, settled vs unsettled, buying power, margin balance, market value, margin calls. It explicitly distinguishes itself from etrade_positions, so an agent can route correctly without opening the schema.

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?

Gives an explicit selection rule — use this for 'what do I have to deploy?' versus etrade_positions for 'what do I hold?' — naming the sibling alternative and the condition that picks between them. Nothing is left to inference.

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

etrade_connectConnect an E*TRADE accountA

Connect this server to an ETRADE brokerage account over OAuth 1.0a. Call with no arguments to get an authorization URL for the user to open; ETRADE shows them a short verification code, which you pass back as verifier on a second call. There is no browser redirect — ETRADE issues the code out-of-band, which is why the user has to read it back to you. ETRADE access tokens go idle after two hours without a request and expire outright at midnight US Eastern, no matter how recently they were used. After midnight the user must authorize again; there is no refresh token. Call this tool again whenever another E*TRADE tool reports an expired token. While a connection is live the server renews it in the background every ninety minutes, so the idle timeout should never be what ends a session — only midnight does.

ParametersJSON Schema
NameRequiredDescriptionDefault
verifierNoThe verification code from the authorization page. Omit on the first call.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations only flag a non-readonly, open-world, non-idempotent operation; the description adds the genuinely decision-relevant behavior: out-of-band code delivery, no browser redirect, two-hour idle timeout, hard midnight US Eastern expiry, no refresh token, and a background renewal every ninety minutes. That is exactly the context an agent needs to decide whether a re-auth is required.

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?

It is front-loaded with the action and the first-call contract, then layers the expiry mechanics in a logical order. Despite being paragraph-length, every sentence carries operational information; nothing is padding.

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?

With no output schema, the description compensates by stating what the first call returns (an authorization URL) and what the user must do with it, plus the full lifecycle constraints on the resulting token. Nothing an agent needs to invoke or re-invoke this tool correctly is missing.

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?

Schema coverage is 100% and the schema already documents verifier's role, so the baseline is 3. The description goes further by explaining the parameter's place in the flow ('which you pass back as `verifier` on a second call') and why it exists (E*TRADE issues the code out-of-band), adding meaning beyond the schema text.

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 first sentence gives a specific verb and resource ('Connect this server to an E*TRADE brokerage account over OAuth 1.0a'), and the rest of the definition makes the two-step handshake unmistakable. An agent can distinguish this from etrade_accounts, etrade_positions, and etrade_disconnect without opening any schema.

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?

It states exactly when to call with no arguments (to obtain the authorization URL), when to call a second time (to pass back the verifier), and when to call again later ('whenever another E*TRADE tool reports an expired token'). Both the trigger and the sequencing are explicit, leaving nothing to inference.

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

etrade_disconnectDisconnect E*TRADEA
DestructiveIdempotent

Revoke the stored E*TRADE access token and delete it, ending the session. The consumer key and secret are left in place, so etrade_connect can reconnect without re-entering them. Use this when handing the machine over, switching between the sandbox and production key pairs, or when a token is behaving oddly.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, but the description goes further by naming exactly what is destroyed (the access token) versus what survives (the consumer key and secret), and why that matters for reconnection. It stops short of mentioning auth requirements or error behavior on a missing/already-revoked token.

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?

Three sentences ordered by importance: what is revoked, what remains, then when to use it. No filler, and the reuse consequence is front-loaded with the destructive action rather than buried.

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?

For a zero-argument destructive tool with no output schema, the description supplies everything needed: the exact state change, the residual state, and the reconnect path. An agent can call this correctly and predict its effect without further context.

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 tool takes zero parameters, so the schema has nothing to document and there is no parameter semantics to add. Baseline for a no-argument tool.

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?

States a specific verb+resource pair — revoke and delete the stored E*TRADE access token — plus the end effect (session ends). It explicitly contrasts with `etrade_connect`, which it names, so an agent can distinguish the two without reading either schema.

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?

Gives three concrete triggering situations: handing over the machine, switching between sandbox and production key pairs, and a misbehaving token. It also names the follow-up alternative (`etrade_connect`), which is the only sensible sibling for the reverse action.

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

etrade_environmentShow or switch E*TRADE environmentA
Idempotent

Show or switch which E*TRADE environment is active. Call with no argument to see which key pairs are configured and which is in use; pass environment to switch. Sandbox and production hold entirely separate keys AND separate access tokens, so switching never mixes credentials and never invalidates the other side — you can keep both connected and flip between them. Sandbox returns canned data that does not match what you ask for, so use production for any real figure.

ParametersJSON Schema
NameRequiredDescriptionDefault
environmentNoOmit to report the current state without changing it.

TDQS

A4.7/5.0
Behavior5/5

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

With annotations only declaring readOnlyHint=false, idempotentHint=true and destructiveHint=false, the description adds real behavioral context: sandbox and production hold separate keys AND separate access tokens, switching never mixes credentials and never invalidates the other side. That is exactly the non-obvious operational detail an agent needs before flipping environments.

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?

Sentences are front-loaded with the core action, then the no-arg behavior, then the credential-isolation rationale, then the sandbox caveat. No filler or repetition; every sentence carries distinct information.

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?

For a single-optional-parameter tool with annotations already covering the safety profile and no output schema, the description covers both call modes, the resulting state change, and the data-quality caveat about sandbox. An agent has everything needed to invoke it correctly.

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?

Schema coverage is 100% and the schema already explains omitting the parameter, so baseline is 3. The description adds meaning beyond the schema by stating what an omitted argument actually reports (which key pairs are configured and which is in use), which clarifies the effect of the parameter's absence.

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 a specific verb and resource ('Show or switch which E*TRADE environment is active') and immediately distinguishes the two modes by their arguments. It is clearly separable from siblings like etrade_connect or setup_credentials, which handle connection setup rather than environment selection.

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?

It gives explicit conditions for both invocation modes ('Call with no argument to see... pass environment to switch') and directs the agent to use production for real figures since sandbox returns canned data. It does not, however, name a sibling alternative for related status questions (e.g., setup_status / provider_status), leaving some routing to inference.

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

etrade_positionsRead E*TRADE positions and cashA
Read-only

Current holdings and investable cash for one E*TRADE account, each position marked at its last trade with the date that trade happened. The response ends with a JSON block in exactly the shape plan_rebalance takes for its holdings argument, plus the cash figure for availableCash, so a rebalance can be planned against the real book without the user retyping it. Positions that came back without a symbol or a usable mark are omitted: an undated or unpriced position cannot be sized against.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountIdKeyYesThe account's `accountIdKey` from `etrade_accounts` — the opaque key, not the human-readable account number. The API rejects the account number.

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnlyHint, openWorldHint), and the description adds real behavioral detail beyond them: marking at last trade with trade date, an explicit omission rule for positions lacking a symbol or usable mark, and the trailing JSON block shape. It does not cover pagination or per-account limits, but the filtering behavior is a genuinely useful disclosure.

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?

Three sentences, front-loaded with what is returned, followed by the key integration detail and then the caveat. Each sentence earns its place; only the marketing-ish phrasing 'without the user retyping it' is mildly redundant.

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?

With no output schema, the description carries the return-value burden and does so: it describes the per-position mark, the cash figure, the trailing rebalance-shaped JSON block, and the omission rule. Adequate for a single-parameter read tool, though it does not address multiple-account selection or staleness of marks.

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

Parameters3/5

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

Schema coverage is 100% and the schema already explains that accountIdKey is the opaque key from etrade_accounts and that the human-readable number is rejected. The description says nothing about the parameter, so it adds no meaning beyond the schema — baseline 3 is correct when structured data does the work.

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

Purpose4/5

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

States a specific verb+resource: 'current holdings and investable cash for one E*TRADE account', and clarifies the marking semantics (last trade with its date). It does not explicitly distinguish itself from the sibling etrade_balances, so an agent must infer the boundary, but the purpose itself is unambiguous.

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?

Usage is implied through the integration note — the response is shaped for plan_rebalance's holdings argument, so this is what feeds a rebalance. However there is no explicit when-to-use statement, no 'use etrade_balances instead when X', and no prerequisite guidance. The context is inferable but not stated.

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

etrade_transactionsRead E*TRADE transactionsA
Read-only

Transaction history for one ETRADE account as a table: trades, dividends, transfers and fees, each with its date, symbol, quantity, price and amount. ETRADE keeps two years and pages at 50 rows. Useful for reconstructing cost basis, checking what a rebalance actually executed at, and separating dividend income from realised gains.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoE*TRADE's own page size cap is 50.
symbolNoFilter to one ticker after fetching. The API has no symbol filter, so this narrows the page rather than the query — widen `count` or the date range if a name is missing.
endDateNo
startDateNoDefaults to whatever E*TRADE returns; two years is the limit.
accountIdKeyYesThe account's `accountIdKey` from `etrade_accounts` — the opaque key, not the human-readable account number. The API rejects the account number.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds meaningful behavioral context beyond them: E*TRADE retains only two years of history and pages at 50 rows, plus the return shape (table with date, symbol, quantity, price, amount).

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?

Two sentences, front-loaded with what the tool returns before the use cases. Tight and readable, with no redundant filler.

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?

With read-only annotations and no output schema, the description carries the return-format burden and does so adequately (table columns, retention, pagination). For a filtered-history read tool, an agent has enough to call it correctly.

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

Parameters3/5

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

Schema coverage is high (80%), so the schema already explains symbol, count, startDate and accountIdKey semantics. The description only tangentially reinforces the 50-row page cap and two-year limit, adding little parameter meaning beyond the schema. Baseline 3 is appropriate.

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?

States a specific verb and resource ('Transaction history for one E*TRADE account') and enumerates the record types (trades, dividends, transfers, fees) and fields it returns. This clearly distinguishes it from siblings like etrade_positions and etrade_balances.

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 concrete use cases (reconstructing cost basis, verifying rebalance execution, separating dividend income from realised gains), which tells the agent when this tool is the right choice. It does not, however, explicitly name alternatives or state when NOT to use it.

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

fx_rateExchange rateA
Read-only

Exchange rate between two currencies, from the European Central Bank's daily reference rates via Frankfurter. No credential, no cap. Needed whenever a screen leaves the US — a balance sheet in yen cannot be compared against a dollar cash balance without one. Pass a date to get a historical rate, which is what a return calculation across currencies requires.

ParametersJSON Schema
NameRequiredDescriptionDefault
onNoRate as of this date. Omit for the latest. Weekends and holidays return the last published rate before them.
baseYesISO currency code to convert FROM, e.g. "USD".
quoteYesISO currency code to convert TO, e.g. "JPY".

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely new context: no credential is required, there is no call cap, and the upstream provenance (ECB via Frankfurter) is named, which matters for trusting the numbers. It does not describe the response payload, but for a read-only lookup the disclosure is solid.

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?

Front-loads the source and constraints in the first sentence, then the rationale, then the date behavior. The yen-vs-dollar illustration is slightly decorative but does real work in justifying the tool. Roughly four sentences with little waste.

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

Completeness3/5

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

There is no output schema, so the description should say what comes back — a single rate, a rate plus date, an object with both currencies — and it never does. Source, cost, and date semantics are all covered, but the return shape is left to inference for a tool whose whole value is the number it produces.

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?

Schema coverage is 100%, so the baseline is 3, and the description clears that bar by explaining the purpose of the date parameter — a historical rate is what a cross-currency return calculation requires — which is intent the schema's 'rate as of this date' does not convey. It does not restate base/quote, which the schema already documents with examples.

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 names a specific resource and verb-equivalent operation (exchange rate between two currencies) and identifies the data source (ECB daily reference rates via Frankfurter). It is unmistakable against every sibling, none of which deals in FX, so an agent can select it without opening the schema.

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?

It gives a clear trigger condition — 'needed whenever a screen leaves the US', with a concrete example of cross-currency balance comparison — and explains when to pass a date (historical rate for return calculations). It does not state exclusions or point to an alternative, but no sibling tool overlaps in purpose, so the routing guidance is effectively complete.

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

get_quotesGet current pricesA
Read-only

Current prices for a list of tickers, each with the date it is as of and the provider it came from. Providers are tried in order (Tiingo, Polygon, Alpha Vantage) and every failure is reported, so "no key", "bad ticker" and "rate limited" stay distinguishable.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickersYes

TDQS

A3.7/5.0
Behavior4/5

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

Annotations only cover read-only and open-world characteristics, and the description adds real behavioral context beyond that: a fixed provider fallback order (Tiingo, Polygon, Alpha Vantage), that every failure is reported rather than aborting, and that 'no key', 'bad ticker' and 'rate limited' remain distinguishable. It doesn't state authentication prerequisites or latency/rate-limit thresholds for the caller, so it stops short of a 5.

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?

Two tight sentences with zero filler, front-loading what is returned and then the provider/failure behavior. Every clause carries information an agent needs.

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?

With one parameter, no output schema and no pagination surface, the description fully covers the return shape (price plus as-of date plus provider) and the partial-failure semantics, which is exactly what an agent needs to interpret results.

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

Parameters2/5

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

Schema description coverage is reported as 0%, so the description carries the burden of explaining the single parameter, yet it only says 'a list of tickers'. It omits the US-listing constraint, case-insensitivity, the 1-100 item bounds and the 10-character ticker limit that the schema enforces.

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

Purpose4/5

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

States a specific resource and scope: current prices for a list of tickers. An agent can distinguish it from analytical siblings like analyze_ticker or macro_context, though the description never explicitly names an alternative to route against.

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?

Usage is implied ('current prices for a list of tickers') but there is no explicit when-to-use guidance, no when-not-to-use, and no pointer to a sibling such as analyze_ticker for deeper analysis. Adequate but with clear gaps.

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

macro_contextMacro context for the Graham testsA
Read-only

Fetch the macro figures Graham's tests are stated against: the Moody's Aaa corporate bond yield, the 10-year Treasury, and CPI with its trailing twelve-month change. Graham required an earnings yield of at least twice the Aaa yield, so the P/E a name must beat moves with the bond market — a fixed ceiling quoted from the book applies a 1973 bond yield to a current balance sheet. Every figure carries the date it is for. Needs a FRED key.

ParametersJSON Schema
NameRequiredDescriptionDefault
priceEarningsNoA candidate's P/E, to judge against the Aaa-derived ceiling. Optional.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds genuinely non-structured context: it requires a FRED key (an auth prerequisite) and states that every figure is stamped with the date it applies to. It does not discuss rate limits or error behavior.

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?

Front-loaded with what is fetched, then the rationale, then the auth/date caveats. Every sentence earns a place — the bond-market rationale justifies why dynamic figures are needed — though the Graham exposition is slightly more than strictly necessary to invoke the 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?

With no output schema, the description carries the return-value burden and does so well: it enumerates the figures returned, notes CPI's TTM change, and that each carries its date. For a single-optional-param read tool this is nearly complete; only the precise response shape and key-handling failure modes are unspecified.

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

Parameters3/5

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

Schema description coverage is 100% and the single optional priceEarnings param is already defined in the schema. The description supplies the conceptual rationale (the P/E ceiling moves with the bond market) but never references the parameter or its interaction with the fetched yields, so baseline 3 applies.

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?

Specific verb (Fetch) plus a precisely enumerated resource: the Aaa corporate bond yield, the 10-year Treasury, and CPI with its trailing twelve-month change. This is unmistakably distinct from every sibling (etrade_*, congress_*, edinet_*, cache_*), which are account, filing, and cache operations.

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 establishes clear when-to-use context by tying the tool to Graham's earnings-yield-twice-Aaa rule and warning that a book-quoted fixed ceiling applies an outdated bond yield to a current balance sheet. It stops short of naming an explicit alternative tool or a when-not condition, so it does not reach a 5.

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

plan_rebalancePlan a rebalanceA
Read-only

Compare current holdings against a target allocation and produce the buys, sells and full exits that close the gap. Compares market value, not share count, so a name that has re-rated shows as overweight. Sells are reported before buys because the proceeds fund them, and the plan says explicitly when the buys are not fundable from cash plus proceeds.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetsYes
holdingsYes
availableCashNoUninvested cash, folded into the portfolio value.
minTradeValueNoSuppress orders whose notional is below this.
driftToleranceNoIgnore drift below this fraction of target. Exits are never suppressed by it.
allowFractionalSharesNo

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already carry readOnlyHint=true, so safety is covered; the description adds real behavioral context beyond them — value-weighted rather than share-count comparison, sells ordered before buys, and an explicit flag when buys are not fundable from cash plus proceeds. It reveals useful output semantics without restating the read-only trait. No permission or rate-limit detail is needed for a pure computation.

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?

Three sentences, front-loaded with the core action, and each clause carries new information (value basis, ordering, fundability warning). No filler or 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?

With no output schema, the description usefully characterizes the return shape (buys, sells, full exits, ordering, unfundable-buys notice). It is strong on output behavior but silent on several input knobs, leaving a small gap for a 6-parameter tool.

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

Parameters3/5

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

Schema description coverage is 50% (targets/holdings subfields documented, top-level flags like allowFractionalShares bare). The description only obliquely touches availableCash via 'cash plus proceeds' and adds nothing on driftTolerance, minTradeValue, or weight normalization. This is the baseline-3 case where the schema does most of the work and the description fails to compensate for the gaps.

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

Purpose4/5

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

States a specific verb and resource: 'Compare current holdings against a target allocation and produce the buys, sells and full exits that close the gap.' An agent immediately knows this computes a rebalancing plan. It does not, however, name or differentiate itself from the related sibling build_allocation (which plausibly produces the target the plan consumes).

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

Usage Guidelines2/5

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

The description never states when to reach for this tool versus alternatives such as build_allocation, nor does it give prerequisites or exclusions. It describes how the tool behaves once called, but gives no routing guidance for an agent choosing between similar tools.

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

provider_statusPrice provider statusA
Idempotent

Show every price provider: whether it has a key, the rate it is being called at, and whether it is currently sitting out a free-tier cap. Providers are a failover pool — a request tries them in order and skips any that is unconfigured or cooling down — so this answers "why did that quote come from there?" and "why is this slow?". Pass clearCooldowns to forget recorded caps, which is worth doing when you know a daily quota has reset or you have just upgraded a plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
clearCooldownsNoForget every recorded cap and retry all providers.

TDQS

A4.7/5.0
Behavior5/5

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

With annotations already covering read/write and idempotency (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description adds rich behavioral context: providers form a failover pool, requests try them in order, and skip unconfigured or cooling-down ones. It also explains exactly what clearCooldowns does to internal state and when that mutation is warranted. No contradiction with annotations.

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?

Three tightly packed sentences: first the output scope, then the failover model and diagnostic value, then the single parameter's use case. Nothing is redundant and the most important information is front-loaded.

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?

For a one-parameter tool with full schema coverage, no output schema, and clear annotations, the description leaves no material gap. It covers what is shown, why the provider pool behaves as it does, and exactly when to clear cooldowns.

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?

Schema coverage is 100% and the parameter is already documented as 'Forget every recorded cap and retry all providers.' The description still adds value by explaining when clearing cooldowns is appropriate — after a daily quota reset or a plan upgrade — which is beyond the schema's mechanical description.

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 opens with a specific verb and resource: "Show every price provider" and enumerates exactly what is shown (key presence, call rate, free-tier cap status). This is far beyond restating the name and lets an agent distinguish it from sibling status tools like cache_status or setup_status.

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?

It clearly describes the diagnostic context — answering 'why did that quote come from there?' and 'why is this slow?' — and gives a concrete condition for passing clearCooldowns. It stops short of naming alternative tools or explicit when-not-to-use cases, but the intended use is unambiguous.

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

screen_marketScreen the whole marketA
Read-only

Screen every SEC filer that reported in a quarter, using the XBRL frames endpoint. Five requests total regardless of universe size. Computes tangible book and NCAV for the whole market from primary filing data — no commercial screener. Returns candidates ranked by NCAV as a share of tangible book. It attaches NO prices: pairing a stale quote with a filing figure is the mistake this server exists to prevent, so run analyze_ticker on the survivors to get a dated price and a verdict.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
periodYesReporting period, e.g. CY2026Q1I. Balance-sheet concepts need the trailing I. Use a quarter old enough that most filers have reported.
minNcavRatioNoRequire NCAV to be at least this fraction of tangible book. Higher means closer to a pure liquid-balance-sheet company.
minTangibleBookNoFloor on tangible book in dollars. Below roughly $50M of market cap, spreads eat the return.

TDQS

A4.3/5.0
Behavior5/5

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

Adds substantial behavior beyond the readOnly/openWorld annotations: a fixed cost of five requests regardless of universe size, computation from primary filing data, a defined ranking (NCAV as a share of tangible book), and an explicit exclusion of price data with the rationale behind it. This is exactly the kind of disclosure annotations cannot carry.

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?

One dense paragraph with the purpose front-loaded and no filler sentences; each clause carries new information. It is slightly heavy as a single block rather than separated usage/behavior notes, which costs it the top mark.

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?

With annotations covering safety and open-world scope, and no output schema, the description responsibly states the return shape (candidates ranked by NCAV share of tangible book) and the deliberate absence of prices. It does not describe record fields or how the `limit` interacts with the ranking, leaving a minor gap.

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

Parameters3/5

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

Schema coverage is 75% and the schema already documents `period` thoroughly (trailing I, use an older quarter) plus the two threshold parameters. The description reinforces the NCAV/tangible-book relationship behind `minNcavRatio`, but adds no format or boundary detail for `limit` or the numeric thresholds, so it sits at the baseline.

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?

States a specific verb (screen), a precise resource and scope (every SEC filer that reported in a quarter), and names the underlying data source (XBRL frames endpoint). It is unmistakably distinct from siblings like analyze_ticker or get_quotes, which operate on single tickers.

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?

Explicitly routes the agent downstream: run `analyze_ticker` on the survivors to get a dated price and a verdict, and explains why this tool deliberately omits prices. The when-to-use case (whole-market, filing-derived screening) is clear, though it never states a negative condition such as when a per-ticker tool is the better first call.

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

setup_credentialsConfigure API credentialsA
Idempotent

Store API credentials for this server. Call with no arguments to prompt the user for them. Call with arguments to save values the user has already given you. Values are written to a 0600 file in the user config directory, never into a project. Pass an empty string to remove a credential.

ParametersJSON Schema
NameRequiredDescriptionDefault
FMP_API_KEYNo
FRED_API_KEYNo
EODHD_API_KEYNoThe only non-US quote coverage here. Free tier is 20 calls/day. https://eodhd.com/register
EDINET_API_KEYNoJapanese filings (FSA EDINET). Free and instant, but the signup has a trap: get the key at https://api.edinet-fsa.go.jp/WEEE0090.aspx — the account page renders blank because it relies on a popup. See `setup_status` for the full walkthrough.
SEC_USER_AGENTNoRequired. A real name and email, e.g. "Jane Doe jane@example.com". EDGAR returns 403 without one and may block the IP. No registration needed.
TIINGO_API_KEYNoRecommended price source. Free key at https://www.tiingo.com/account/api/token
FINNHUB_API_KEYNoQuotes. The most generous free tier here — 60 calls/minute. Free key at https://finnhub.io/register
POLYGON_API_KEYNo
ALPACA_API_KEY_IDNoQuotes with the most free headroom here (200/min). Free paper-trading account, no card: https://alpaca.markets/
TWELVEDATA_API_KEYNo
ALPHAVANTAGE_API_KEYNo
ALPACA_API_SECRET_KEYNo
ETRADE_PROD_CONSUMER_KEYNoReads your real holdings, balances and transactions. Read-only — this server never places an order. Obtain at https://developer.etrade.com/getting-started; `setup_status` spells out the three-form process.
ETRADE_PROD_CONSUMER_SECRETNo
ETRADE_SANDBOX_CONSUMER_KEYNoSynthetic data, for proving the connection works. Instant and self-service at https://us.etrade.com/etx/ris/apikey
ETRADE_SANDBOX_CONSUMER_SECRETNo

TDQS

A4.1/5.0
Behavior4/5

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

Annotations declare a non-read-only, idempotent, non-destructive write; the description adds real context beyond that: values land in a 0600 file in the user config directory and never in a project, and empty strings delete a credential. It does not explain partial-update behavior (whether supplying one key preserves the other fifteen) or whether values are validated, which matters for a 16-field secret store.

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?

Four short sentences, zero padding, ordered from purpose to invocation modes to storage location to deletion. The most decision-relevant information (which mode to call) is front-loaded.

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?

For a 16-parameter, no-output-schema configuration writer, the description covers invocation modes, storage location, permissions and removal. It leaves the save semantics ambiguous (merge vs. overwrite of untouched keys) and never points at setup_status, which the schema itself references for signup walkthroughs.

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?

Schema description coverage is 50%, so the schema carries much of the burden via titles and per-key descriptions. The description contributes a global per-parameter rule the schema never states — an empty string removes that credential — which is meaningful semantics above the baseline.

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

Purpose4/5

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

States a specific verb and resource ('Store API credentials for this server') and enumerates the three distinct invocation modes (no args = prompt, args = save given values, empty string = remove). It does not name or differentiate itself from the sibling setup_status, which is the one tool an agent could plausibly confuse it with, so it stops short of full sibling differentiation.

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?

Usage is explicit for each mode: call with no arguments to prompt the user, call with arguments when the user has already supplied values, pass an empty string to delete. No alternatives or exclusions are named relative to setup_status/setup_status-style tools, so it gives clear context but no comparative routing.

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

setup_statusCheck credential setupA
Read-only

Report which API credentials are configured, where each value came from, and the sign-up URL for anything missing. Call this first in a new session, and whenever another tool reports that the server is not configured.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds value by disclosing what the report contains (configured credentials, value provenance, sign-up URLs), which goes beyond the annotations.

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?

Two tight sentences, zero waste. What the tool returns is front-loaded, followed by the invocation triggers.

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?

For a no-argument, read-only diagnostic with no output schema, the description supplies exactly what an agent needs: the report's contents and when to invoke it. Nothing material is missing.

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?

Zero parameters, so the baseline is 4. There is nothing to document, and the description correctly makes no parameter claims.

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?

States a specific verb ('Report') and precise resource (which API credentials are configured, their source, and sign-up URLs for missing ones). This is clearly distinguishable from the mutating setup_credentials sibling by being purely diagnostic.

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?

Gives strong explicit triggers: 'Call this first in a new session' and 'whenever another tool reports that the server is not configured.' It lacks an explicit when-not and does not name setup_credentials as the alternative, so it stops short of a 5.

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

short_interestShort interestA
Read-only

FINRA consolidated short interest for one ticker — the market's own answer to "why is this cheap?". Free, no credential. Reports shares short, days to cover, and the trend across the reporting window. Heavy short interest on a sub-tangible-book name belongs in the reason the name is cheap; it is not an automatic veto, and Schloss owned plenty of names the market disliked.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYesUS-listed ticker symbol, e.g. "AAPL". Case-insensitive.

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, and the description usefully adds that access is free and requires no credential, plus which metrics are returned. It omits rate limits, reporting lag, or refresh cadence, so it stops short of full behavioral disclosure.

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 core capability is front-loaded in the first sentence with the returned metrics in the second. The closing Schloss remark is interpretive padding, but it does convey how to weigh the output, so the length is defensible rather than wasteful.

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?

For a single-parameter tool with no output schema, the description compensates by naming the returned metrics and the source of the data. What remains missing is freshness/lag information and any hint about error behavior for non-US tickers.

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

Parameters3/5

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

Schema description coverage is 100% and the single ticker parameter is already documented there as case-insensitive with a max length. The description adds no syntax, format, or edge-case guidance beyond what the schema supplies, so baseline 3 applies.

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?

Names the specific source (FINRA consolidated short interest) and the exact scope (one ticker), and enumerates the reported fields: shares short, days to cover, and trend across the reporting window. No sibling tool covers short interest, and an agent can distinguish this from analyze_ticker or get_quotes immediately.

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 frames the data's interpretive role (a reason a name is cheap, not an automatic veto) but never states when to call the tool versus alternatives or what preconditions exist beyond one ticker. Usage is implied rather than directed.

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. 29 tool updatesv0.1.0
    • First observedanalyze_ticker
    • First observedbank_call_report
    • First observedbuild_allocation
    • First observedcache_clear
    • First observedcache_status
    • First observedcheck_corporate_actions
    • First observedcheck_disqualifiers
    • First observedcongress_house_filings
    • First observedcongress_index
    • First observedcongress_member_profile
    • First observedcongress_trades
    • First observededinet_financials
    • First observededinet_search
    • First observedetrade_accounts
    • First observedetrade_balances
    • First observedetrade_connect
    • First observedetrade_disconnect
    • First observedetrade_environment
    • First observedetrade_positions
    • First observedetrade_transactions
    • First observedfx_rate
    • First observedget_quotes
    • First observedmacro_context
    • First observedplan_rebalance
    • First observedprovider_status
    • First observedscreen_market
    • First observedsetup_credentials
    • First observedsetup_status
    • First observedshort_interest

TDQS

A3.9/5.0

Scored across 29 tools

Disambiguation4/5

Tools target well-separated purposes across distinct domains (SEC valuation, E*TRADE brokerage, Congress disclosures, Japanese EDINET, cache/provider infra). There is minor friction where check_disqualifiers overlaps with analyze_ticker (which also runs a disqualifier scan) and etrade_balances vs etrade_positions are close, but the descriptions explicitly draw those lines ("what do I have to deploy?" vs "what do I hold?"). An agent can reliably pick the right tool.

Naming Consistency4/5

Everything is uniformly snake_case with consistent family prefixes (etrade_*, congress_*, edinet_*, cache_*, setup_*), which makes grouping obvious. The verb style is not uniform—some are verb_noun (get_quotes, analyze_ticker, plan_rebalance) while others are noun_noun (short_interest, fx_rate, bank_call_report)—so it falls short of a single predictable pattern.

Tool Count3/5

29 tools is on the heavy side and sits at the boundary of the 'too many' band, though the breadth of scope (brokerage, SEC analysis, Congress, Japan, caching) justifies most of them. A few could be consolidated (cache_status/cache_clear, the E*TRADE credential tools), but each domain genuinely needs its surface.

Completeness4/5

Coverage of the deep-value workflow is strong end-to-end: screen_market → check_disqualifiers → analyze_ticker → quotes/macro/fx/corporate-actions → build_allocation → plan_rebalance, plus brokerage read and disclosure data. The main gap is that the E*TRADE integration is read-only—there is no order-placement tool, so a rebalance plan can be produced but not executed through the server.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides comprehensive stock screening and fundamental analysis capabilities using Finviz data, including earnings tracking, volume surge detection, technical indicators, dividend growth screening, and SEC filing retrieval.
    49
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Provides derived financial intelligence for AI agents, including insider activity analysis, earnings surprises, institutional moves, stock screening with a proprietary composite value score, and macro indicators.
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables aggregated investment research by combining data from Yahoo/SEC EDGAR, Finnhub, and GDELT with analysis modules for price momentum, news signals, and estimate revisions.
    -
  • A
    license
    A
    quality
    B
    maintenance
    Provides as-reported US equity fundamentals, live quotes, financial statements, valuation comps, and a screener from SEC filings, with per-cell filing provenance for citations.
    7
    MIT