Fundamentals, insider filings, BDC holdings, bonds, and SEC documents
— the same public-filings data behind the site, as typed tool
calls for Claude Code, Claude Desktop, Codex, or any Model Context
Protocol client.
Real tool call · captured 2026-10-13
“How healthy is Ares Capital’s loan book?”
In the ARCC filing dated 2026-07-29, loans flagged non-accrual were 1.79% of debt fair value: $404,400,000 out of $22,547,800,000. That is up from 0.87% at the filing dated 2023-10-24, the oldest of the 12 quarters returned, though the older quarters were read by an earlier version of the parser. All 12 quarters pass the tool's coverage check, so none of the rates is withheld.
Call: ol_bdc_credit_quality with arguments {"ticker": "ARCC"}
Tier: free, no key · Source: Oxford Ledge analysis, computed from ARCC’s 10-Q and 10-K filings on SEC EDGAR · A capture, not a live call; each new filing adds a quarter. The answer above is our summary of the tool’s reply.
More captured calls (9)Real tool call · captured 2026-10-13
“What is the U.S. Treasury’s debt made of this month?”
Total public debt outstanding was $40.17 trillion on 2026-09-30: $32.43 trillion held by the public and $7.75 trillion in intragovernmental holdings. Marketable notes were the largest class at $16.28 trillion; the next marketable classes were bills at $7.12 trillion and bonds at $5.55 trillion.
Call: ol_treasury_debt with arguments {}
Tier: free, no key · Source: U.S. Treasury Monthly Statement of the Public Debt (MSPD) · A capture, not a live call; the statement is published monthly. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“How are speculators positioned in gold, crude oil and the S&P 500?”
In the CFTC report for positions on 2026-10-06, Managed Money traders were net long 110,987 gold contracts and 53,598 WTI crude contracts. In E-mini S&P 500 futures, Leveraged Funds were net short 415,087 contracts. These are contract counts, not dollars, and each covers one speculative category per report.
Call: ol_cftc_cot with arguments {}
Tier: free, no key · Source: CFTC Commitments of Traders reports (public) · A capture, not a live call; the report is weekly. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“Which private companies just raised money in SEC Form D filings?”
The 50 newest Form D filings in the store were all filed on 2026-06-30, the end of the loaded data: the SEC posts this data set about one quarter after quarter-end. The largest amounts sold among them were $1,096,448,855 by Baseten Labs, Inc. and $1,059,759,405 by GreenLake Real Estate Fund LLC. Those are amounts sold as disclosed, not offering ceilings.
Call: ol_form_d_raises with arguments {}
Tier: free, no key · Source: the SEC’s quarterly Form D data set, from EDGAR (public) · A capture, not a live call; the next quarterly data set adds filings. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“What does the Treasury yield curve look like today?”
On 2026-10-09 the Treasury yield curve rose from 4.13% at 1M to 5.65% at 20Y, with 30Y slightly lower at 5.6%. The 2Y yield was 4.8% and the 10Y yield 5.24%. These tenor yields come from treasury.gov; the rest of the reply is a wider macro snapshot.
Call: get_yield_curve with arguments {}
Tier: free, no key · Source: U.S. Treasury constant-maturity yields; each tenor row names treasury.gov as its publisher · A capture, not a live call; yields change every trading day. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“Which are the largest U.S. banks by assets?”
JPMorgan Chase Bank, National Association is the largest of the 4,269 active FDIC institutions loaded, with $4.09 trillion in total assets as of 2026-06-30. Bank of America, National Association follows at $2.65 trillion, then Citibank, National Association at $1.98 trillion. The store holds active institutions only, so a bank that merged away or failed is absent by construction.
Call: ol_fdic_bank with arguments {}
Tier: free, no key · Source: FDIC call-report data (public), loaded active institutions only · A capture, not a live call; call reports are filed quarterly. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“How did Delta’s operating KPIs move last quarter?”
For 2026-Q3, DAL reported a load factor of 86.0%, unit revenue (RASM) of 25.46 cents and passenger unit revenue (PRASM) of 19.59 cents per available seat mile; the RASM figure includes refinery sales. The figures, as of 2026-10-09, were extracted from the issuer's own SEC earnings exhibit. An anonymous call returns 3 of the panel's 6 metrics; a keyed call gets the full panel.
Call: ol_operating_kpis with arguments {"ticker": "DAL"}
Tier: free, no key · Source: the issuer’s own SEC earnings exhibit, extracted by Oxford Ledge and not re-audited · A capture, not a live call; the next earnings exhibit replaces the panel. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“When does Microsoft next report earnings?”
MSFT has no published date on its investor-relations calendar in the store, so the reply gives an Oxford Ledge estimate instead: 2026-10-28, with a window of 4 days. The estimate projects the cadence of 40 past 8-K Item 2.02 filings at the SEC; it is not a company announcement.
Call: ol_earnings_calendar with arguments {"ticker": "MSFT"}
Tier: free, no key · Source: an Oxford Ledge projection from the issuer’s SEC 8-K filing dates · A capture, not a live call; the issuer may post its own date. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“Which BDCs lend to Coupa, and how does each one mark the loan?”
Nine BDC lenders hold Coupa debt: 20 senior secured tranches in all. Weighted by loan size, the lenders' marks run from 94.85 (Ares Capital Corporation) to 100.0 (Carlyle Secured Lending and Morgan Stanley Direct Lending Fund), in percent of par. Every lender marks the same quarter end, 2026-06-30, though their filings are dated 2026-07-29 to 2026-08-07.
Call: ol_bdc_borrower_dispersion with arguments {"borrower_norm": "coupa"}
Tier: free, no key · Source: each lender’s own Schedule of Investments on SEC EDGAR, at its most recent filing · A capture, not a live call; marks change every quarter. The answer above is our summary of the tool’s reply.
Real tool call · captured 2026-10-13
“Which private-credit borrowers are spread across the most BDCs?”
Auctane, Inc., MRI Software LLC, Coupa Holdings, LLC and Icefall Parent, Inc. lead the list, each held by 9 active BDC lenders. The ranking counts active lenders only, so iCIMS, Inc., held by 10 BDC lenders of which only 8 are still active filers, sits just below them. Each lender is read at its own most recent filing, so the rows span filings dated 2023-11-13 to 2026-08-20; the 25 rows returned hit the tool's cap, so the list may go on.
Call: ol_bdc_top_borrowers with arguments {}
Tier: free, no key · Source: Oxford Ledge analysis of each BDC’s Schedule of Investments on SEC EDGAR · A capture, not a live call; holdings change every quarter. The answer above is our summary of the tool’s reply.
The key is shown once — copy it now into your client's own configuration file (never into a chat); the steps for each client below show exactly where.
Come back to this page for your client's steps.
The key lives in your client's config — never in a chat. An assistant that asks for it is misconfigured. Treat it like a password: if it leaks, delete it under YOUR API KEYS and create another. Hosted transport reads X-API-Key; Authorization: Bearer is not supported.
A trial key (ol_trial_...) works the same way.
Claude Code
command line · nothing to install
Add the server
SHELL
claude mcp add --transport http --scope user oxford-ledge https://www.oxfordledge.com/mcp --header "X-API-Key: ol_live_YOUR_KEY_HERE"
Contains ol_live_YOUR_KEY_HERE — replace it with your key before you run this.
Put the key in
The command stores it for you in ~/.claude.json. Nothing else to do.
Verify
claude mcp list — expect oxford-ledge · connected.
Try the free tools without an account. Claude Code can also connect with no key. The free tools answer; any other tool replies with what it needs instead. Without a key the limit is per IP address (100 calls an hour).
SHELL
claude mcp add --transport http --scope user oxford-ledge https://www.oxfordledge.com/mcp
No key in this command. To add one later, remove the entry (claude mcp remove oxford-ledge --scope user) and run the keyed command above.
Notes & variants — scope, Windows paths, shared projects
With --scope user the entry lives in ~/.claude.json for every project; drop --scope user and it is stored for the current folder only. A server added at project scope shows Pending approval in claude mcp list until you approve it in an interactive claude session.
The command line is recorded in your shell history and the value is stored in plaintext in ~/.claude.json.
On Windows, ~/.claude.json is %USERPROFILE%\.claude.json.
Inside a session, type /mcp to see the server's tools.
For a project you share. Keep the key out of the file: add this to the project's .mcp.json and export OXFORD_LEDGE_API_KEY in your shell. Only ever the ${OXFORD_LEDGE_API_KEY} form there, never the key itself.
Notes & variants — Windows paths, FRED tools, the pip subset
Quit from the system tray or menu bar, not the window close button; Claude Desktop reads its config only at launch.
On Windows, use the full path to oxford-ledge-mcp.exe as command (Claude Desktop does not inherit your shell PATH; find it with where oxford-ledge-mcp).
Microsoft-Store Claude Desktop reads its config from %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\ — edits to %APPDATA%\Claude\ are silently ignored on Store installs.
Optional: the two FRED macro tools. Only get_yield_curve and get_fred_data call FRED directly, with a key you hold. To use them, add "FRED_API_KEY" to the env block with a real key from fred.stlouisfed.org as its value. JSON has no comments, so a sentence pasted as the value is sent to FRED as the key and every FRED call fails.
The pip package carries a subset of the hosted tools; the hosted endpoint always has the full catalog and the package catches up on its next release. Your client shows the package version when it connects — that version, not a number on any page, is what you are running. The cards below tag the hosted tools the package also carries as PIP; the contract states the split.
Codex
OpenAI's coding agent · nothing to install
Add the server
In ~/.codex/config.toml (create it if it is not there), add:
Contains ol_live_YOUR_KEY_HERE — replace it with your key before you run this.
This file then holds a secret in plaintext: keep it readable only by you.
Other MCP clients
any client that speaks streamable-HTTP MCP · nothing to install
Endpoint: POST https://www.oxfordledge.com/mcp. Header: X-API-Key, set once in the client's own config. Any client that speaks streamable-HTTP MCP works; use the contract below for the auth boundary and the limits.
Troubleshooting
Symptom
Cause
Fix
oxford-ledge not listed after add
wrong scope or URL typo
claude mcp get oxford-ledge — URL must be exactly https://www.oxfordledge.com/mcp, header X-API-Key
Shows “Pending approval”
project-scope server awaiting approval
approve inside an interactive claude session
Tools answer authentication_required
key deleted / mistyped / env not loaded
create a fresh key under YOUR API KEYS; Codex: open a new shell before starting
Free tier 100 calls / hr per caller (API key, OAuth subject, or session; IP for anonymous) · heavy tools (tagged HEAVY in the catalog; 13F holdings among them) max 2 concurrent · catalog cached 5 min · tools/list rows carry requires_key and min_tier. For volume, a Developer plan carries 100,000 or 1,000,000 data calls a month across every key on the account; it is bought in YOUR API KEYS (/?panel=api-keys). Developer and Developer Pro include everything in Power User, so their keys run at 5,000 MCP calls an hour, which makes the monthly allowance reachable.
62 hosted · 24 also in the pip package (the package carries 29: 5 are package-only). The handshake prints oxford-ledge-mcp <version> — plan from that, not from this page.
At source the package dispatches a 29-tool subset: 4 standalone tools that need no Oxford Ledge account (2 SEC-EDGAR keyless + 2 FRED-keyed), 23 that answer keyless once OXFORD_LEDGE_URL is set (14 name-proxies of the /mcp transport + 9 unauthenticated REST proxies), and 2 Researcher-tier tools (get_debt_maturities, get_capital_allocation) that need OXFORD_LEDGE_API_KEY — an agent planning calls against a pip install should plan from those 29, not from every card below. The hosted tools the package also carries are tagged PIP in the catalog.
reading_list_annotate and ol_paper_trade are listed; dispatch is refused unless the deployment sets OL_MCP_WRITE_ENABLED=1 (default: off). Every write defaults to a dry run, replays by _idempotency_key, is hourly-capped, and lands on your append-only account activity log. Writes need an X-API-Key or a linked OAuth token — a browser session cookie is refused.
Paper portfolio
ol_paper_portfolio reads YOUR practice portfolio (the /practice/ sandbox: cash, positions marked to a delayed quote, P&L, optional recent fills); ol_paper_trade places a buy or sell in it through the same engine the sandbox uses. Both are free for any signed-in key holder; the trade is capped at 20 executed fills per user per UTC day and the dry run shows the quote and cost first. No create or reset over MCP — start a portfolio in the sandbox. A fill placed this way is badged placed via API in the sandbox. Practice money only; every response says so in _meta.disclaimer.
10 toolsSOURCE: SEC EDGAR COMPANY-FACTS XBRL · 10-K/10-Q/8-K EXHIBITS · ~45-DAY POST-QUARTER LAG · VENDOR QUOTE LEG (ANOMALY FLAGS ONLY)
get_anomaly_flags
KEY REQUIRED
Fifteen red-flag screens on one ticker (short interest, Altman Z, leverage, FCF, payout); red or amber
Full contract & input schema
Run 15 red-flag screens on a ticker (short interest >12%, Altman Z distress, net leverage >4x, negative FCF, P/E >50, dividend yield >6%, insider net selling, revenue decline, payout >90%, goodwill >50% of assets, SBC >10% of revenue, declining ROIC and others). Returns {ticker, available, flags, count}; each flag is {severity, label, detail, scrollTo}: SEVERITY IS ONLY 'red' OR 'amber', red first. A flag is a question to investigate, NOT a sell signal. available: false (+ reason, no flags) = not checked. Empty flags is no all-clear either: a screen missing its input is skipped. Pair with get_fundamentals and ol_intrinsic_value. Source: vendor quote/fundamentals snapshot plus computed heuristics. Caveats ride the response's tool_notes.
Where the cash went, up to 30 fiscal years: dividends, net buybacks, net debt change, acquisitions
Full contract & input schema
Where a company sent its cash, up to 30 annual labels. Returns {ticker, capitalAllocation:{years, periods, dividends, netBuybacks, grossRepurchases, netDebtChange, acquisitions, sharesOut, isDilutive, basis, summary}} as PARALLEL ARRAYS aligned to `years` (newest first, fiscal labels). netBuybacks is a NET, DERIVED DILUTION PROXY, not a buyback figure (repurchases minus issuance, IPO proceeds and SBC); grossRepurchases is the filed line. Share-count cells on a pre-split basis are withheld, never shown as a phantom buyback. An IFRS reporter is REFUSED, never served zeros. Complements get_fundamentals and get_debt_maturities. Source: SEC EDGAR XBRL cash-flow tags, 24h cache. Requires Researcher tier. Caveats ride the response's tool_notes.
Forward debt maturity ladder from the latest 10-K/20-F footnote, in USD millions, with parser confidence
Full contract & input schema
Forward debt maturity ladder parsed from the latest 10-K/20-F footnote. Returns {ticker, maturities:[{year, amount}], thereafter, confidence, confidence_score, source, validation}. AMOUNTS ARE IN MILLIONS OF USD, not raw dollars -- 400 means $400M. THE LADDER IS AS OF the filing date, not today: the current-year bucket may already be repaid or refinanced. Check `validation` (the balance-sheet cross-check) before quoting a total. Every empty answer carries `refusal_reason` and a readable `refusal_note`. For historical issuance/repayment use get_capital_allocation. Source: SEC EDGAR 10-K note extraction. Requires Researcher tier. Caveats ride the response's tool_notes.
Up to 30 fiscal years of XBRL income, balance-sheet and cash-flow metrics, plus the last 12 quarters
Full contract & input schema
Full XBRL financial history for one ticker. Returns {ticker, fundamentals:{years, periods, metrics, balanceSheet, quarterly, basis, as_of}, source_period, as_of}: `years` is newest-first, UP TO 30 annual labels, and every entry under `metrics` / `balanceSheet` is a PARALLEL ARRAY aligned to it by index (revenue, netIncome, opCF, capex, epsDiluted, totalDebt, cash, derived fcf and margins ...). Dollar figures are whole USD; *Pct values are percentage numbers. A year the filer did not tag is null, never 0. Per-share cells on a pre-split basis are WITHHELD (null) rather than rescaled -- read `basis`. An IFRS reporter or a filer with no annual us-gaap fact returns {error, taxonomy, formsSeen, unitsSeen}. For cash deployment use get_capital_allocation; for per-share fair value ol_intrinsic_value; for industry operating metrics ol_operating_kpis. Source: SEC EDGAR company-facts XBRL (~45-day post-quarter lag), 24h cache. Caveats ride the response's tool_notes.
Pass/fail threshold screen over up to 10 supplied tickers on latest-year XBRL fundamentals
Full contract & input schema
Threshold screen over a caller-supplied ticker set (the FIRST 10 unique tickers, silently) on latest-year SEC EDGAR XBRL fundamentals. Optional criteria: min_revenue, min_free_cash_flow, min_ebit_margin_pct, min_gross_margin_pct, max_debt_to_assets_pct, min_current_ratio, min_net_income (whole USD; *_pct as percentage numbers). Returns {summary, count, passing_count, criteria, results, as_of}; each result is {ticker, available, fiscal_year, passes, failed_criteria, metrics}. A MISSING METRIC FAILS its criterion, so a fail can mean 'no data', not 'bad company'. It never sweeps a universe and is not a discovery screen; a fundamentals filter, NOT a buy signal. Source: SEC EDGAR company-facts XBRL. Caveats ride the response's tool_notes.
Per-share DCF, earnings-power value and Graham number from XBRL; no price or margin of safety
Full contract & input schema
Per-share intrinsic value from SEC EDGAR XBRL -- three textbook models: a levered-FCF DCF, a Greenwald Earnings-Power-Value, and the Graham number. Returns {summary, ticker, available, dcf_per_share, epv_per_share, graham_number, inputs, assumptions, as_of}; all three values are USD PER SHARE. `assumptions` are FIXED model constants, not per-name (10% discount, 2.5% terminal growth, 10y horizon, 21% tax). NO current price, market cap or margin of safety is returned -- fetch a price yourself and compare. A model is null when its inputs are negative or missing (null_reasons names the input), never computed as if debt-free. reason 'fetch_error' is transient: retry. The DCF is FCFE-style, not comparable to an enterprise-value DCF. Source: SEC EDGAR company-facts XBRL. Caveats ride the response's tool_notes.
Curated per-issuer KPI rows (ARR, NRR, RPO, DAU/MAU) from filing exhibits, with definitions and absences
Full contract & input schema
Tier-3 KPI PANEL for ONE issuer -- curated per-issuer metric rows (ARR, RPO/cRPO, NRR, logo retention, DAU/MAU, capacity utilization, ...) extracted from SEC filing exhibits, WITH the issuer's own metric definitions and full provenance. ABSENCE IS FIRST-CLASS: a row with value=null and is_absence=true is an answer (metric_availability says why), not a gap to fill from memory. Values are confidence-gated; needs_review rows are EXCLUDED. Optional filters: metric, period, industry. Per-issuer by design. For broad operating KPIs across 26 configured industries use ol_operating_kpis. Source: SEC 10-K/10-Q/8-K/6-K exhibits (Oxford Ledge parse); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Issuer symbol (single issuer, mandatory). There is deliberately NO cross-issuer panel read -- one metric across many issuers is not an answerable question on this surface."
},
"metric": {
"type": "string",
"description": "Optional metric key filter, e.g. arr, crpo, nrr."
},
"period": {
"type": "string",
"description": "Optional fiscal-period label, e.g. 2026-Q2."
},
"industry": {
"type": "string",
"description": "Optional panel tag filter, e.g. enterprise_saas."
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 800,
"description": "Max rows (default 200, hard cap 800)."
}
},
"required": [
"ticker"
]
}
ol_operating_kpis
ANONYMOUS OK
Industry operating KPIs for one issuer (same-store sales, RevPAR, load factor, NIM) from SEC filings
Full contract & input schema
Industry OPERATING KPIs for ONE issuer -- the operational numbers the income statement hides (same-store sales, RevPAR, load factor, medical-loss ratio, net interest margin, TEU, rig count ...) extracted from SEC filings across 26 configured industries, each switched on by a deployment flag, so live coverage is a subset. Returns the issuer's panel {ticker, industry, metrics, available, partial, total_metrics, period, as_of, provenance, caveat, ...}. Anonymous callers get at most 3 rows (partial, total_metrics says how many); keyed callers get the full panel. Values are AS-REPORTED and confidence-gated. available=false cannot tell an uncovered industry from a covered issuer with no rows or an outage: do not retry with variations. Per-issuer by design. Source: SEC 10-K/10-Q/8-K exhibits (Oxford Ledge parse); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Issuer symbol, e.g. DAL, MAR, HCA, JPM, DAC (single issuer, mandatory). There is deliberately no cross-issuer KPI screen: panels are per-issuer by design."
}
},
"required": [
"ticker"
]
}
ol_peer_fundamentals
ANONYMOUS OK
Latest-fiscal-year fundamentals side by side for up to 6 tickers; one year, no multiples
Full contract & input schema
Side-by-side latest-fiscal-year fundamentals for a peer set (the FIRST 6 unique tickers; the rest are named in `dropped`). Returns {summary, count, peers, dropped, as_of}; a peer is {ticker, available, fiscal_year, revenue, net_income, eps_diluted, free_cash_flow, gross_margin_pct, ebit_margin_pct, debt_to_assets_pct, current_ratio, stockholders_equity}. Dollar figures are whole USD; *_pct are percentage numbers. ONE YEAR ONLY -- no history (use get_fundamentals). Fiscal years are each filer's own, so peers are NOT calendar-aligned. A ticker without XBRL coverage returns {ticker, available: false} (no metric keys), never dropped. No price leg, so no P/E or EV multiples. Source: SEC EDGAR company-facts XBRL; one cold EDGAR fetch per ticker.
Resolve a company name, ticker or CIK to its SEC identity; up to 20 matches, substring not fuzzy
Full contract & input schema
Resolve a company name, ticker or CIK to its SEC identity. Returns {results, count}, up to 20 matches (hard cap); each result carries SEC-EDGAR-derivable identity fields only: ticker, companyName, cik, sicCode, exchange, fiscalYearEnd, tickerStatus (check it before treating a match as a live listing). A null field is OMITTED from the row, so never assume `cik` is present. Matching is a literal substring on ticker / companyName (plus the other class-share punctuation, and a digit-only CIK); former names and misspellings do NOT resolve. Once resolved, call get_fundamentals or get_business_summary. Source: Oxford Ledge company profiles, limited to SEC-submission identity fields. Caveats ride the response's tool_notes.
5 toolsSOURCE: SEC EDGAR 10-K/20-F · FORM D DATA SETS · USASPENDING.GOV · USPTO ODP · FILING SEARCH: RANK FUSION OVER AN EMBEDDED CORPUS (METERED)
get_business_summary
ANONYMOUS OK
Curated business overview from the 10-K Item 1 (20-F Item 4), with source form, period and URL
Full contract & input schema
First-party business summary for a ticker from its SEC annual report (10-K Item 1; 20-F Item 4 for a foreign private issuer): a curated, verifier-gated overview of what the company does. Returns `summary` (a one-line status line, NOT the content), `available`, `business_summary` (prose truncated at ~2400 chars), `short_summary`, and provenance (source_form, source_period, source_url, generated_at). available=false means the store answered with no verified row and the provenance keys are ABSENT; an unreachable store is REFUSED (DATA_UNAVAILABLE). Rows generated before 2026-09-13 carry '10-K' and an empty `source_period` regardless of filer until Oxford Ledge re-stamps their provenance. For semantic passage retrieval over the full filing corpus use ol_filing_search. Source: SEC EDGAR annual report (Oxford Ledge first-party summary); FREE. Caveats ride the response's tool_notes.
Federal-contract obligations by ticker and fiscal year from USAspending, or the fiscal-year leaderboard
Full contract & input schema
Federal-contract obligation history for a ticker, OR the fiscal-year leaderboard -- for government-revenue-dependence diligence. TWO SHAPES: one of `ticker` or `fiscal_year` is REQUIRED (if both, `ticker` wins). With `ticker`: per-fiscal-year obligations (USD, the ten largest recipients, dropped_unresolved), NEWEST FY FIRST; with fiscal_year only: a leaderboard of the public companies on Oxford Ledge's USAspending crosswalk, largest first -- not of all federal contractors. A fiscal year still in progress is PARTIAL (period_complete false) and year-to-date -- never compare it to a full year. Obligations are federal awards, not company-reported revenue. `limit` default 20, hard cap 100. An unreachable store is REFUSED (DATA_UNAVAILABLE). Source: USAspending.gov (public domain; OL ticker-crosswalked); FREE. Attributing awards to a ticker is an Oxford Ledge curated crosswalk. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker (omit for the FY leaderboard)."
},
"fiscal_year": {
"type": "integer",
"description": "Fiscal year for the top-contractors leaderboard."
},
"limit": {
"type": "integer",
"description": "Max rows (default 20, hard cap 100).",
"minimum": 1,
"maximum": 100
}
},
"required": []
}
ol_filing_search
KEY REQUIRED
Semantic retrieval over embedded SEC filings for a ticker: ask a question, get filing chunks; metered AI
Full contract & input schema
MOAT (PAID -- AI): semantic retrieval over EMBEDDED SEC filings for a ticker. Ask a natural-language question ('what did they say about supply-chain risk?') and get the most relevant filing CHUNKS back from an Oxford Ledge hybrid retrieval (lexical BM25 plus a dense pass, fused by reciprocal rank). This is the ONE metered tool: it draws on your daily AI quota (25 searches/day, UTC reset, plus a burst limiter) -- it needs a signed-in account or an API key, and an anonymous call fails AUTH_REQUIRED. Returns {summary, ticker, count, chunks, quota_remaining_today}; each chunk is {section, text (an excerpt), accession, url, score}. `score` is the FUSED RANK score (4dp), NOT a similarity: compare it only within one response. `k` default 5, hard cap 15. Source: SEC EDGAR filings (Oxford Ledge embedded corpus). Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g. AAPL)"
},
"query": {
"type": "string",
"description": "Natural-language question to retrieve relevant filing passages for."
},
"k": {
"type": "integer",
"description": "Number of chunks to return (default 5, hard cap 15).",
"minimum": 1,
"maximum": 15
}
},
"required": [
"ticker",
"query"
]
}
HEAVY · MAX 2 CONCURRENT
ol_form_d_raises
ANONYMOUS OKPIP ✓
Recent SEC Form D private-placement filings, newest first, by industry group or trailing window
Full contract & input schema
Recent SEC Form D private-placement filings from the SEC's QUARTERLY Form D data set -- newest first, optionally scoped to an industry group and/or a trailing filing-date window. Returns {summary, count, days, industry, offerings}. Amounts are whole USD as disclosed; total_offering_amount is a ceiling, not money raised. The data set lands about one quarter after quarter-end, so a short `days` window is EMPTY BY CONSTRUCTION -- not evidence that nothing was filed. `limit` default 50, hard cap 200. Source: SEC EDGAR Form D data sets (public domain); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"industry": {
"type": "string",
"description": "Industry group filter (optional)."
},
"days": {
"type": "integer",
"description": "Trailing filing-date window in days (optional). The data set is quarterly with ~1 quarter of posting lag: a window shorter than that is empty by construction.",
"minimum": 1,
"maximum": 1825
},
"limit": {
"type": "integer",
"description": "Max offerings (default 50, hard cap 200).",
"minimum": 1,
"maximum": 200
}
},
"required": []
}
ol_patents
ANONYMOUS OKPIP ✓
Recent USPTO patent filings for a ticker, newest first; a slice of up to 200, not the whole estate
Full contract & input schema
Recent USPTO patent filings for a ticker (innovation-intensity diligence). Returns {summary, ticker, count, filings}, NEWEST FIRST; `limit` default 50, hard cap 200, so this is a recent slice, never a full portfolio, and `count` is the number RETURNED. TRAP: a non-empty patent_number marks a continuation of an already-granted PARENT, NOT a grant of this application -- read the status field. Filings reflect Oxford Ledge's last on-demand USPTO ingest for the ticker, not a schedule; an unreachable store is REFUSED (DATA_UNAVAILABLE), never served as count 0. Source: USPTO (public domain); FREE. ATTRIBUTION: every filing field is USPTO ODP verbatim EXCEPT `ticker`, which is an Oxford Ledge applicant-name resolution, not a USPTO field. Caveats ride the response's tool_notes.
14 toolsSOURCE: SEC EDGAR 13F-HR · FORM 4 · SCHEDULE 13D/G · N-PORT · SEC FAILS-TO-DELIVER · FINRA SHORT INTEREST · ~45-DAY 13F DELAY
get_13f_holdings
ANONYMOUS OKPIP ✓
Largest positions in one institutional filer's latest 13F-HR, with quarter-over-quarter changes
Full contract & input schema
What one institutional filer owns: the largest positions in its latest SEC 13F-HR, plus quarter-over-quarter changes. Accepts a numeric CIK (preferred), a ticker (BRK-B or BRK.B for Berkshire), or a filer NAME (3-80 characters): ONE name-prefix match in the curated 13F filer universe resolves to its CIK (`resolved_from` says so); an ambiguous name is refused with candidates, never guessed. Returns {cik, fundName, filingDate, periodOfReport, totalHoldings, totalValue, holdings}; rows carry name, title_of_class, value (whole USD), shares, type, position_type, lots. There is NO ticker field and `cusip` is stripped on every channel (no plan carries a CUSIP Global Services licence today); `title_of_class` is the share-class discriminator. `position_type` is COM|PRN|PUT|CALL: do NOT sum across types. Source: SEC EDGAR 13F-HR, ~45-day quarterly delay. Heavy operation, max 2 concurrent. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"fund": {
"type": "string",
"description": "Fund CIK number (e.g. 1067983 for Berkshire Hathaway) -- preferred. A ticker is resolved via SEC's company map: letters with at most one class suffix (e.g. BLK, or BRK-B / BRK.B -- SEC lists Berkshire as BRK-A / BRK-B, so bare 'BRK' does not resolve). A filer NAME (3-80 chars) resolves when exactly one curated filer name starts with it; otherwise the error names ol_13f_filer_search. Any other shape is rejected as INVALID_PARAMS."
},
"max_holdings": {
"type": "integer",
"description": "Maximum number of holdings to return (default 50)",
"minimum": 1,
"maximum": 500
}
},
"required": [
"fund"
]
}
HEAVY · MAX 2 CONCURRENT
get_activist_stakes
ANONYMOUS OKPIP ✓
Schedule 13D/13G >5% beneficial-owner filings for a ticker, newest first, with staleness flags
Full contract & input schema
Schedule 13D/13G >5% beneficial-owner filings for a ticker -- event-driven stake-building, unlike quarterly 13F. Returns {ticker, count, filings}, newest first, limit default 50 (hard cap 200); rows carry filer_name, filing_date, form_type, shares, percent_of_class, accession_number and is_activist (a FORM-TYPE label: true iff the form is a 13D, not a judgement). `reports_zero` is the filer's own statement that it no longer owns more than 5% -- an exit OR a reporting realignment, so cross-check get_institutional_holders before reading it as a sale. FRESHNESS: keyless callers are served STORED rows and never trigger the EDGAR refresh -- read `stale` and `stale_basis`. Complements get_institutional_consensus. Source: SEC EDGAR. Caveats ride the response's tool_notes.
SEC fails-to-deliver history for one ticker, oldest first, anchored to the latest loaded date (~3-week lag)
Full contract & input schema
SEC fails-to-deliver history for one ticker -- the settlement-failure side of short pressure. Returns {ticker, days, history, count, window, coverage, as_of, summary}; each row is {date (settlement date), fails (SHARES, not dollars), price (USD), description}, OLDEST-FIRST. `days` (default 180, hard cap 730) is anchored to the latest LOADED settlement date, not to today; `end_date` ends it elsewhere. An empty or thin history describes the loaded SEC files, not an absence of fails: read `coverage` and `summary` before reading a gap. Prices are NOT split-adjusted. An unreachable store REFUSES (DATA_UNAVAILABLE). Pair with ol_short_interest_trend for the other half. Source: SEC Fails-to-Deliver dataset (published twice monthly, ~3-week lag). Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g. GME)"
},
"days": {
"type": "integer",
"description": "Trailing window in days (default 180, max 730), ending at `as_of` unless end_date is given",
"minimum": 1,
"maximum": 730
},
"end_date": {
"type": "string",
"description": "ISO date (YYYY-MM-DD) the window ends on; default = the latest loaded settlement date. Pass today's date to measure against the calendar."
}
},
"required": [
"ticker"
]
}
get_insider_activity
RESEARCHER+
The 20 most recent Form 4 transactions for one ticker, with role, code, price and amendment folding
Full contract & input schema
Recent Form 4 insider transactions for one ticker. Returns {ticker, transactions}: THE 20 MOST RECENT TRANSACTION ROWS ONLY, newest by filing date -- the `days` argument is currently a NO-OP on this path. Rows carry insiderName, position (the role, the load-bearing signal), transType (the raw SEC code: 'P' open-market buy, 'S' sale, 'A' grant, 'M' option exercise; filter on it yourself), shares, pricePerShare, totalValue (USD, computed by Oxford Ledge at ingest), isDerivative (read it before treating `shares` as common stock) and url. A 4/A that repeats its original line is served once. Leave issuerSelfFiled rows out of any total. Market-wide buys: ol_insider_recent_buys; clusters: ol_insider_cluster_scan; >5% stakes: get_activist_stakes. Source: SEC EDGAR Form 4 (~2-day filing deadline). Requires Researcher tier. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g. AAPL)"
},
"days": {
"type": "integer",
"description": "Number of days of history (default 365)",
"minimum": 1,
"maximum": 1825
}
},
"required": [
"ticker"
]
}
get_institutional_consensus
ANONYMOUS OK
Tickers the tracked 13F filers most widely hold in common, ranked by fund count then value
Full contract & input schema
Which tickers the tracked 13F filers most widely hold in common. Returns {as_of_quarter, tickers_found, min_funds, consensus}; each row is {ticker, issuer_name, fund_count, total_value_usd, total_shares, funds}, ranked by fund_count then value. `consensus` is truncated to top_n (default 50, cap 200) while `tickers_found` is the FULL count meeting min_funds (default 2, cap 20). COMMON STOCK ONLY: an ownership tally, not exposure. Each fund contributes its own latest quarter, which may differ across funds. Answers 'who is buying X?'; get_13f_holdings answers 'what does fund X own?'. Source: SEC EDGAR 13F-HR, ~45-day quarterly delay. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"top_n": {
"type": "integer",
"description": "Maximum number of consensus tickers to return (default 50, max 200).",
"minimum": 1,
"maximum": 200
},
"min_funds": {
"type": "integer",
"description": "Minimum number of notable funds that must hold a ticker for it to appear (default 2, max 20).",
"minimum": 1,
"maximum": 20
}
},
"required": []
}
get_institutional_holders
ANONYMOUS OK
Which institutions hold one ticker and which way they moved; top 100 by value, with coverage stats
Full contract & input schema
Which institutions hold one ticker, and which way they moved. Returns {ticker, holders, total_holders, as_of_quarter, coverage}. `holders` IS CAPPED AT THE TOP 100 BY VALUE while `total_holders` is the TRUE filer count. Each holder carries fund_name, fund_cik, shares, value_usd (whole USD), quarter, change_type and pct_change vs that fund's prior quarter. Check `coverage.basis` ('universe' vs 'top_display') before quoting an aggregate. Common stock only; funds file off-cadence, so quarters can differ per row. Rows are CUSIP-resolved: a resolution failure drops or mis-attributes a row. Direction-only view: ol_ownership_changes; fund-keyed inverse: get_13f_holdings. Source: SEC EDGAR 13F-HR, ~45-day quarterly delay. Caveats ride the response's tool_notes.
Concentration, turnover and holder persistence for one 13F filer by CIK; no position list
Full contract & input schema
Institutional-filer behavior derived purely from 13F holdings: concentration (top-N %, normalized HHI), turnover, and persistence (long-term holder vs fast money) for one filer. Pass a NUMERIC CIK (a ticker will not resolve here; ol_13f_filer_search finds it). Returns {summary, fund, quarter, n_positions, reported_long_equity_value, analytics}. The denominator is the filer's REPORTED 13F long-equity value, explicitly NOT AUM. NO position list -- use get_13f_holdings. A filer with one stored quarter gets no fabricated turnover rate; an unreachable store is REFUSED (DATA_UNAVAILABLE). Source: SEC EDGAR 13F-HR (public domain; Oxford Ledge derived); FREE. Caveats ride the response's tool_notes.
Resolve a 13F filer's name to its CIK and 13F page from the curated filer universe; up to 10 matches
Full contract & input schema
Resolve a 13F FILER name to its CIK -- the front door to get_13f_holdings and ol_13f_filer_analytics when you know the manager ('Berkshire Hathaway', 'Baupost') and not its CIK (search_company resolves ISSUERS). Returns {summary, query, filers: [{cik, name, last_filing, page_url}], count}; name-PREFIX matches rank first. THE UNIVERSE IS CURATED -- the filers Oxford Ledge ingests plus featured filers, never a live EDGAR full-text search. filers=[] means the store answered and nothing matched; an unreachable store is REFUSED (DATA_UNAVAILABLE). `query` 3-80 characters; `limit` default 5, hard cap 10. Source: SEC EDGAR 13F-HR (public domain; Oxford Ledge derived); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Filer name or fragment, 3-80 characters (e.g. 'Berkshire', 'Baupost').",
"minLength": 3,
"maxLength": 80
},
"limit": {
"type": "integer",
"description": "Max filers to return (default 5, hard cap 10).",
"minimum": 1,
"maximum": 10
}
},
"required": [
"query"
]
}
ol_etf_lookthrough
ANONYMOUS OK
Underlying holdings of up to 25 ETFs as filed on Form N-PORT, value-ranked, with a ticker crosswalk
Full contract & input schema
ETF look-through: expand up to 25 ETF tickers into the underlying holdings the fund ITSELF filed on Form N-PORT. Returns {summary, count, etfs, units}; per ETF {etf, name, category, net_assets, in_catalog, series_id, opaque, reason, period_date, holdings_available, top_holdings}. `top_holdings` is value-ranked (default 10, hard cap 50), each with underlying_ticker, issuer_name, value_usd (whole USD), pct_of_nav (as filed) and weight_pct (Oxford Ledge derived; the shown rows will not sum to 100). HOLDINGS-ONLY: no yield, NAV or premium. An ETF with no filed holdings comes back opaque=true with `reason`; a store outage is DATA_UNAVAILABLE, never opaque. Source: SEC EDGAR N-PORT, latest filed period per series (~60-day lag); FREE. Caveats ride the response's tool_notes.
Active multi-insider Form 4 buy or sell clusters for a watchlist, one ticker, or market-wide with no ticker
Full contract & input schema
FLAGSHIP MOAT: scan for ACTIVE multi-insider cluster-buy/sell signals (distinct-actor Form 4 clusters with statistical strength). THREE GRAINS: pass `tickers` for a watchlist, a single `ticker` for that name's recent fired clusters, or NEITHER for the MARKET-WIDE scan (top fired clusters across every ticker, one row per ticker and direction). Returns {summary, count, events, grain, since_days, limit}; each event is {ticker, direction, insider_count, z_score, sector_z_score, percentile, window_start, window_end}. No fired clusters returns events=[] -- absence is not a signal; an unreachable store is REFUSED. Source: SEC EDGAR Form 4, windowed on FILING date so it is look-ahead-safe; FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"tickers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Watchlist of ticker symbols (e.g. ['AAPL','MSFT']). Max 100. Use this OR `ticker`.",
"maxItems": 100
},
"ticker": {
"type": "string",
"description": "Single ticker for its recent fired clusters (alternative to `tickers`). Omit BOTH for the market-wide scan."
},
"since_days": {
"type": "integer",
"description": "Window in days: watchlist default 7 (max 365); market-wide default 30 (clamped to 90); ignored for the single-ticker grain.",
"minimum": 1,
"maximum": 365
},
"min_insider_count": {
"type": "integer",
"description": "Minimum distinct insiders for a fired cluster (default 3).",
"minimum": 1,
"maximum": 50
},
"limit": {
"type": "integer",
"description": "Max events to return (default 25, hard cap 100; market-wide grain: default 10, clamped to 25).",
"minimum": 1,
"maximum": 100
}
}
}
ol_insider_recent_buys
ANONYMOUS OKPIP ✓
Open-market insider purchases across ~5.3k tickers in a trailing window, newest first
Full contract & input schema
Recent OPEN-MARKET insider PURCHASES (SEC code 'P') across the Oxford Ledge issuer catalog (~5.3k tickers) -- a daily insider screen. Returns {summary, since_days, count, buys}, NEWEST FIRST; each buy carries ticker, filing and transaction dates, insiderName, position, shares, pricePerShare, totalValue (USD), url. since_days default 30 (hard cap 180), limit default 25 (hard cap 100). SAMPLING TRAP: when the window holds more purchases than `limit`, you get the NEWEST N filings, not the whole window -- never total these rows and call it the period's insider buying. totalValue and the fallback `position` label are the two derived fields. Source: SEC EDGAR Form 4 (public domain); FREE. Pairs with ol_insider_cluster_scan and get_insider_activity. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"since_days": {
"type": "integer",
"description": "Trailing window in days (default 30, hard cap 180).",
"minimum": 1,
"maximum": 180
},
"limit": {
"type": "integer",
"description": "Max purchases (default 25, hard cap 100).",
"minimum": 1,
"maximum": 100
},
"common_only": {
"type": "boolean",
"description": "Common stock only (default true): drops derivative rows and any security title naming preferred / pfd / warrant / debenture / note. Series-named common classes (\"Series A Common Stock\") are kept. false restores every 'P' row."
},
"min_value": {
"type": "number",
"minimum": 0,
"description": "Only purchases with totalValue >= this many USD (optional). Rows whose totalValue is null -- the filed price failed the plausibility gate -- are dropped when this is set."
}
},
"required": []
}
ol_institutional_confluence
ANONYMOUS OK
One verdict per ticker fusing 13F accumulation, Form 4 net buying and cluster confirmation
Full contract & input schema
Quarter-aligned institutional-confluence read for one ticker: 13F accumulation x insider Form 4 net buying x buy-cluster confirmation, fused on the ticker's reference 13F quarter. Returns a `verdict` (confluence_accumulation / confluence_distribution / partial_net_adding / partial_net_reducing / neutral, or insufficient_13f_coverage / insufficient_history, never coerced to neutral), plus `institutional`, `insider`, `cluster`, `coverage` and a one-line `summary`. A DERIVED verdict, not raw data: no per-fund rows. Pairs with get_institutional_holders and ol_insider_cluster_scan. Source: SEC EDGAR 13F-HR + Form 4 (Oxford Ledge derived fusion); FREE, no tier gate and no AI metering. Caveats ride the response's tool_notes.
Each fund's position in one ticker classified new, increased, decreased or exited; 50 rows per bucket
Full contract & input schema
Quarter-over-quarter institutional accumulation/distribution for one ticker: each fund's position classified new / increased / decreased / exited over the last ~4 quarters -- the 'who is moving on X?' flow read. Returns {summary, ticker, quarters_analyzed, counts, new_positions, increased, decreased, exited, split_suspect, ...}. `counts` is always the COMPLETE tally; `limit` bounds EACH row list (default 50, hard cap 250). Pairs whose delta looks like an unconfirmed corporate action are withheld into `split_suspect` with their as-filed counts. Share classes are never summed or netted. Rows are CUSIP-resolved, so treat share figures as close approximations. Complements get_institutional_holders (snapshot). Source: SEC EDGAR 13F-HR (public domain; OL derived); FREE. Caveats ride the response's tool_notes.
FINRA biweekly short-percent series for one ticker, oldest first, up to 26 readings
Full contract & input schema
FINRA short-interest trend for one ticker: the biweekly settlement-date short-percent series, OLDEST-FIRST. Returns {summary, ticker, count, as_of, trend}; each point is EXACTLY {date (settlement date), shortPct (a PERCENTAGE number)} -- no share counts and no days-to-cover. `points` default 6, max 26 (about one year). A fortnightly SNAPSHOT with a reporting lag, not a live short-float figure; `as_of` is the settlement date, not today. Honest-empty for a ticker FINRA does not publish; an unreachable store is REFUSED (DATA_UNAVAILABLE). Source: FINRA (public); FREE.
10 toolsSOURCE: SEC EDGAR BDC 10-K/10-Q SCHEDULES OF INVESTMENTS (OXFORD LEDGE PARSE) · ~45-60 DAY LAG · OL-DERIVED KEYS AND MARKS
get_bdc_list
ANONYMOUS OKPIP ✓
Roster of the active BDCs Oxford Ledge tracks, by portfolio size, with reconciled fair-value totals
Full contract & input schema
Roster of the ACTIVE BDCs tracked by Oxford Ledge, sorted by portfolio size -- our coverage, not the whole BDC universe; wound-down issuers are excluded by design. No arguments. Returns {bdcs, count}; per BDC: ticker, name, listed (false for a non-traded BDC carried under a pseudo-ticker such as AGTC), holdingCount, totalFairValue (whole USD, latest filing), filingDate, lastParsed and a reconciliation block (reportedTotalFairValue, fairValueBasis, parsedRowSumFairValue, fairValueRefused, fairValueGap, fairValueGapNote). READ fairValueBasis BEFORE using totalFairValue, and fairValueGap with it: an under-counting parse keeps the parsed-row sum, which UNDERSTATES the book. holdingCount, totalFairValue and the arbitration are Oxford Ledge's parse, not filer-published figures. Borrower-keyed counterpart: search_bdc_borrower. Source: SEC EDGAR BDC filings (Oxford Ledge parse). Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {}
}
ol_bdc_borrower_dispersion
ANONYMOUS OKPIP ✓
How each BDC lender prices the same private-credit loan: spread, mark and fair value, widest first
Full contract & input schema
MOAT: cross-lender loan-pricing DISPERSION for one private-credit borrower -- how N different BDCs each price the SAME loan (spread / mark / fair value); when one BDC marks a borrower S+550 @ 98 and another S+575 @ 99, the lenders disagree on the credit. Pass `borrower_norm` (a key from ol_bdc_top_borrowers or search_bdc_borrower, or a name). Returns {summary, borrower_norm, count, lender_count, tranche_count, lenders, ...}: ONE row per BDC lender, widest spread first, tranches nested. UNITS TRAP: `spread` is the raw as-filed number and mixes percent and bps across filers -- compare lenders on `spread_bps` only. Exited positions are excluded by default (include_stale=true shows them). Default 25 lenders, hard cap 100. Source: SEC EDGAR BDC schedules of investments (Oxford Ledge parse; ol-derived); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"borrower_norm": {
"type": "string",
"description": "Borrower key (from ol_bdc_top_borrowers or search_bdc_borrower) or a borrower name such as 'Coupa Holdings, LLC'; resolved to the stored key (see match_type)."
},
"limit": {
"type": "integer",
"description": "Max LENDERS to return (default 25, hard cap 100); each lender's tranches ride nested.",
"minimum": 1,
"maximum": 100
},
"include_stale": {
"type": "boolean",
"description": "Include lenders whose newest filing no longer names this borrower (stale marks). Default false."
}
},
"required": [
"borrower_norm"
]
}
HEAVY · MAX 2 CONCURRENT
ol_bdc_common_borrowers
ANONYMOUS OKPIP ✓
Borrowers held in common by a given set of BDCs, most widely held first; debt positions only
Full contract & input schema
Borrowers common to a GIVEN SET of BDCs -- the cross-portfolio set question ('what do ARCC, OBDC and AGTC all lend to?') in ONE call. Returns per borrower: borrower, borrower_norm, holder_count, holder_tickers, holders ([{ticker, name}]), total_fair_value and total_par_amount in USD, and as_of_oldest/as_of_newest. Each BDC is read at ITS most recent filing, so rows MIX filing dates -- read as_of_range before treating the marks as contemporaneous. Debt positions only. Caps: bdc_tickers truncated at 25, limit 50/200, min_holders max 50. Feed a borrower_norm to ol_bdc_borrower_dispersion for cross-lender pricing. Source: SEC EDGAR BDC schedules of investments (Oxford Ledge parse -- ol-derived); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"bdc_tickers": {
"type": "array",
"items": {
"type": "string"
},
"description": "BDC symbols to intersect, e.g. [\"ARCC\",\"OBDC\",\"AGTC\"] (max 25)"
},
"min_holders": {
"type": "integer",
"description": "Minimum number of the supplied BDCs that must hold the borrower (default 2, min 2 -- this answers what is SHARED; for one BDC's book use ol_bdc_top_borrowers)",
"minimum": 2,
"maximum": 50
},
"limit": {
"type": "integer",
"description": "Max borrowers to return (default 50, max 200)",
"minimum": 1,
"maximum": 200
}
},
"required": [
"bdc_tickers"
]
}
ol_bdc_credit_quality
ANONYMOUS OKPIP ✓
Share of a BDC's debt book on non-accrual, latest filing plus the trailing-quarter trend
Full contract & input schema
BDC non-accrual credit-deterioration signal: the share of debt fair value on non-accrual (loans that stopped paying) in the latest filing, plus the trailing-quarter trend. Returns {summary, ticker, latest, trend}; `trend` is OLDEST-FIRST. flagged_pct is a percentage over the DETERMINATE-flag denominator, never total_debt_fv, and it is deliberately NULL (withheld, never zero) when determinate coverage is under 90% of debt fair value or the flag rate looks like a parse misread -- read `coverage_state` before reading flagged_pct. `quarters` default 12, hard cap 24. Pairs with ol_bdc_borrower_dispersion and ol_bdc_top_borrowers. Source: SEC EDGAR BDC schedule-of-investments non-accrual flags (Oxford Ledge parse); FREE. Caveats ride the response's tool_notes.
One BDC's base and incentive fees for a fiscal year, with NII-based dividend coverage
Full contract & input schema
BDC fee load + NII-based dividend coverage for ONE fiscal year (not a series). Returns {summary, ticker, fiscal_year, fees, dividend_coverage}; `fees` holds base and incentive fees and net investment income in whole USD; `dividend_coverage` is NII divided by dividends paid, a ratio (0.92 means 0.92x) -- under 1.0 means the dividend is funded partly from capital. Fee RATE percentages and the dividend amount are not returned. A missing input is served as null and named, never as zero; an unreachable store is REFUSED (DATA_UNAVAILABLE). An internally-managed BDC carries no fee lines by construction. Source: SEC EDGAR 10-K/10-Q Statement-of-Operations XBRL, NOT a vendor fundamentals feed; FREE. Caveats ride the response's tool_notes.
Per-quarter weighted average spread, mark and position counts for one BDC's loan book
Full contract & input schema
Per-quarter loan-pricing trend for ONE BDC, from the parsed schedule of investments: fair-value-weighted average credit spread, average mark and position counts, OLDEST-FIRST. Returns {summary, ticker, count, spread_unit, trend}. `weighted_avg_spread` is in BASIS POINTS, normalized at the store (the as-filed column mixes percent and bps, so never average a raw spread yourself). Prefer `priced_borrowers` over `debt_positions` across quarters: position counts are parser-grain-dependent. `quarters` default 16, max 24. Honest-empty (trend=[]) for an unparsed BDC. Pairs with ol_bdc_borrower_dispersion. Source: SEC EDGAR BDC 10-Q/10-K schedules of investments (Oxford Ledge parse); FREE. Caveats ride the response's tool_notes.
Largest quarter-over-quarter mark moves across a set of BDC portfolios, up and down, by borrower
Full contract & input schema
MOAT / private credit: the largest quarter-over-quarter MARK moves across a SET of BDC portfolios -- 'which borrowers got marked up or down the most last quarter, and by whom' in ONE deterministic call. Returns {increases, decreases}, each a global ranking; each row is {borrower, portfolio, prior_mark, latest_mark, mark_delta, prior_filing, latest_filing}. Marks are percent of par, fair-value-weighted across the BDC's tranches; mark_delta is in points. A borrower enters only when |mark_delta| >= 1.0 point and its fair value is >= $500k. Implausible moves are held in `suspect_moves` rather than ranked. `coverage` names every BDC that was NOT read and why. bdc_tickers capped at 25; limit default 10 / hard 50 per direction. Source: SEC 10-K/10-Q schedules of investments (Oxford Ledge parse); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"bdc_tickers": {
"type": "array",
"items": {
"type": "string"
},
"description": "BDC symbols to compare, e.g. [\"ARCC\",\"FSK\",\"OBDC\"] (max 25; the excess is reported in `coverage.not_covered_detail` rather than dropped)"
},
"limit": {
"type": "integer",
"description": "Rows per direction (default 10, hard cap 50). Ranking is GLOBAL across the supplied portfolios, not per BDC.",
"minimum": 1,
"maximum": 50
}
},
"required": [
"bdc_tickers"
]
}
HEAVY · MAX 2 CONCURRENT
ol_bdc_top_borrowers
ANONYMOUS OKPIP ✓
Private-credit borrowers syndicated across the most BDCs, ranked by active lender count then exposure
Full contract & input schema
MOAT / BDC discovery: the private-credit borrowers syndicated across the MOST BDCs, ranked by ACTIVE lender count (holder_count_active), then holder_count, then exposure -- the entrypoint for the BDC/private-credit category. Returns {summary, count, borrowers}; each row is {borrower, borrower_norm (the key other ol_bdc_* tools take), holder_count, total_fair_value (whole USD, latest filings), industry}. Feed a borrower_norm into ol_bdc_borrower_dispersion for cross-lender pricing. Caps: limit default 25 / hard 100; min_holders default 2 (max 50). Parser mis-ingests are filtered out when the filter is available (`borrower_filters` says whether it ran). Source: SEC EDGAR BDC schedules of investments (Oxford Ledge parse); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"min_holders": {
"type": "integer",
"description": "Minimum number of BDC lenders a borrower must appear in (default 2).",
"minimum": 1,
"maximum": 50
},
"limit": {
"type": "integer",
"description": "Max borrowers to return (default 25, hard cap 100).",
"minimum": 1,
"maximum": 100
}
}
}
HEAVY · MAX 2 CONCURRENT
ol_borrower_profile
ANONYMOUS OK
Profile, verified M&A history and public-market footprint for one private-credit borrower by key
Full contract & input schema
Profile + verified M&A/ownership history for one private-credit borrower. Pass `borrower_norm` (a key from ol_bdc_top_borrowers, or a name). Returns {summary, borrower_norm, borrower, profile, acquisitions, count, public_footprint}: the `profile` (description, industry, known_lenders, lien_position, estimated_size, notes, source), VERIFIED-only `acquisitions` (unaudited or refuted events never surface), and `public_footprint` (patents, federal contracts, corporate events) matched by exact normalized name, with `matched_entities` provenance -- a same-name match is never a guaranteed identity, and an empty footprint is normal for a private borrower. Honest-empty when the key is unknown. Source: SEC EDGAR BDC Schedule-of-Investments + attributed public M&A events (Oxford Ledge proprietary parse); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"borrower_norm": {
"type": "string",
"description": "Borrower key (from ol_bdc_top_borrowers) or a borrower name such as 'Coupa Holdings, LLC'; resolved to the stored key (see match_type)."
},
"limit": {
"type": "integer",
"description": "Max M&A/ownership events to return (default 20, hard cap 100).",
"minimum": 1,
"maximum": 100
}
},
"required": [
"borrower_norm"
]
}
HEAVY · MAX 2 CONCURRENT
search_bdc_borrower
ANONYMOUS OKPIP ✓
Which BDCs lend to one private-credit borrower, fuzzy-matched on name, with per-tranche marks
Full contract & input schema
Which BDCs lend to one private-credit borrower, matched fuzzily on name -- Oxford Ledge's parse of SEC EDGAR BDC schedules of investments (ol-derived), not filer-published data. Returns borrowerName, borrowerNorm (the key the ol_bdc_* tools take), description, descriptionSource, industry, aggregates over CURRENT holders (totalHolders, totalParAmount, totalFairValue, avgMarkedPrice) and `holders`, one row per TRANCHE. ABOVE-PAR TRAP: a mark above 100 is not a credit premium until fairValue is checked against cost. `description` is a compiled company profile from public sources, NOT filing text. A miss is {found: false} -- a search miss, not a finding of no BDC exposure. `query` needs 3+ characters; `limit` / `offset` page `holders` only. Source: SEC EDGAR BDC schedules of investments (~45-60 day lag). Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Borrower/company name to search (e.g. Finastra, Medline); at least 3 characters."
},
"limit": {
"type": "integer",
"description": "Max `holders` rows to return (default 5000 = every row; hard cap 5000, refused above). Pages the tranche rows only.",
"minimum": 1,
"maximum": 5000
},
"offset": {
"type": "integer",
"description": "Rows to skip before the page (default 0; max 5000). Past the end returns an empty page with `page.total` intact.",
"minimum": 0,
"maximum": 5000
}
},
"required": [
"query"
]
}
HEAVY · MAX 2 CONCURRENT
Bonds & rates
5 toolsSOURCE: TREASURY.GOV PAR YIELDS VIA FRED · SEC EDGAR DEBT SCHEDULES · LQD/HYG DIRECTORY (REFERENCE ONLY) · FINRA TRACE (RETIRED PATH)
get_bond_data
KEY REQUIRED
Single-bond trade detail by CUSIP from FINRA TRACE; the host was retired in 2026-07, expect nulls
Full contract & input schema
RETIRED (2026-09-13). This was single-bond trade detail by CUSIP over FINRA's public TRACE bond page; FINRA auth-walled that host in 2026-07 and Oxford Ledge holds no licence to redistribute TRACE trade data, so no CUSIP can be priced here. It makes NO network call and returns, in under a millisecond, the same FIXED-KEY envelope it always did -- cusip, type, issuer, coupon, maturity, debtType, is144A, lastPrice, lastYield, ytm, high, low, volume, tradeDate, source, fetchedAt, ytw, callable, duration, modifiedDuration, moodysRating, spRating, fitchRating, error -- with every price field null, plus {status: 'retired', unavailable: true, note, use_instead: 'ol_bond_directory_screen'}; `error` carries the retirement note, or 'CUSIP must be at least 6 characters' when the input itself is malformed, so a caller can tell their input from our outage. The name is kept because the wheel and the licence-class registries pin it. Use ol_bond_directory_screen (the persisted LQD/HYG corporate-bond directory: issuer, grade, coupon and maturity -- reference data, no prices) or get_debt_maturities for one issuer's own maturity schedule. Source: none (retired FINRA TRACE endpoint).
US Treasury par yield curve over 11 tenors with 3-month and 1-year history, or the wider macro snapshot
Full contract & input schema
US Treasury yield curve, plus (by default) the wider macro dashboard. TWO DIFFERENT SHAPES. include_history=true returns PARALLEL ARRAYS over 11 tenors (1M..30Y) -- today, ~91 days ago and ~1 year ago -- for steepening/inversion work. include_history false (the DEFAULT) returns {data: [...]}, a flat LIST of latest-value rows that mixes the Treasury tenors WITH CPI, unemployment, GDP, mortgage-rate and national-debt series. UNITS: yields are PERCENT numbers (4.25 means 4.25%). The credit-spread OAS series and UMCSENT were removed 2026-07-21 (licensed data) and are NOT in the list. Source: Treasury.gov daily par yields (FRED fallback) plus FRED series; cached 4h. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"include_history": {
"type": "boolean",
"description": "Include yield curve from 1 year ago for comparison (default false)"
}
}
}
ol_bond_directory_screen
KEY REQUIRED
Screen the LQD/HYG corporate-bond directory by issuer, grade, coupon and maturity; reference only, no identifiers
Full contract & input schema
Screen the corporate-bond browse directory by issuer name, grade (IG or HY), and optional coupon and maturity bands. Returns {summary, count, total_matching, bonds}; each bond is {key, issuer_name, coupon (percent number), coupon_type, maturity_date, grade, source_etf}. REFERENCE DATA ONLY -- no price, yield, spread or trade activity, and no security identifier. `grade` is the coarse SOURCE BUCKET (IG=LQD, HY=HYG), NOT a credit rating. limit default 25, hard cap 100. NOTE ON PROVENANCE: the directory is sourced from the LQD (investment-grade) and HYG (high-yield) ETF holdings. Its ingest-source redistribution posture is unresolved (Oxford Ledge legal review, 2026-07-07), so this is a FIRST-PARTY-only tool and is off the third-party redistribution surface until cleared. FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"issuer": {
"type": "string",
"description": "Issuer-name substring to match (optional). Identifier lookups are not supported."
},
"grade": {
"type": "string",
"description": "Source bucket: 'IG' (LQD universe) or 'HY' (HYG universe). Not a rating."
},
"coupon_min": {
"type": "number",
"description": "Minimum coupon percent, applied in-tool over the fetched page (optional)."
},
"coupon_max": {
"type": "number",
"description": "Maximum coupon percent, applied in-tool over the fetched page (optional)."
},
"maturity_after": {
"type": "string",
"description": "Only bonds maturing on/after this ISO date (YYYY-MM-DD), optional."
},
"maturity_before": {
"type": "string",
"description": "Only bonds maturing on/before this ISO date (YYYY-MM-DD), optional."
},
"limit": {
"type": "integer",
"description": "Max bonds to return (default 25, hard cap 100).",
"minimum": 1,
"maximum": 100
},
"offset": {
"type": "integer",
"description": "Pagination offset (used only when no coupon/maturity band is set).",
"minimum": 0,
"maximum": 100000
}
}
}
ol_maturity_wall
ANONYMOUS OK
Corporate debt maturities aggregated by year, market-wide or for up to 50 tickers, in USD millions
Full contract & input schema
The corporate DEBT MATURITY WALL: scheduled bond/loan maturities aggregated by year -- total_by_year, by_rating, top_issuers_by_year, peak_year, concentration. Amounts are USD MILLIONS (see `units`). `by_rating` splits IG vs HY by an Oxford Ledge LEVERAGE HEURISTIC, NOT agency ratings. Market-wide when `tickers` is omitted, or scoped to up to 50 tickers. Coverage is companies with PARSED maturity schedules only; an issuer with debt and no parsed schedule is NAMED under `unscheduled`, never estimated. LATENCY: a scoped call can fetch each issuer's annual report LIVE from SEC EDGAR -- seconds per issuer, minutes for a cold list. Source: SEC filing debt schedules + balance sheets (Oxford Ledge parse); FREE. Caveats ride the response's tool_notes.
Retired: FINRA TRACE issuer search is auth-walled; answers status 'retired' and points at ol_bond_directory_screen
Full contract & input schema
RETIRED (2026-09-13). This was a bond search by issuer name over FINRA's public TRACE issuer-search host; FINRA auth-walled that path behind its Federated Identity Platform in 2026-07 and Oxford Ledge holds no licence to redistribute TRACE data, so the tool answers no query. It makes NO network call and returns, in under a millisecond, {status: 'retired', note, use_instead: 'ol_bond_directory_screen', query, issuers: [], totalBonds: 0, error} -- the empty lists are the retired shape, never a search result. The name is kept because the wheel and the licence-class registries pin it. Use ol_bond_directory_screen (the persisted LQD/HYG corporate-bond directory: issuer, grade, coupon and maturity filters) for corporate-bond discovery, or get_debt_maturities for one issuer's own maturity schedule. Source: none (retired FINRA TRACE endpoint).
6 toolsSOURCE: FRED (ST. LOUIS FED) · FRED RELEASE CALENDAR · TREASURY MSPD · CFTC COT · FDIC BANKFIND
get_economic_calendar
KEY REQUIRED
Upcoming US macro release dates for nine tracked series (CPI, jobs, GDP, PCE); dates only, no estimates
Full contract & input schema
Upcoming US macro DATA-RELEASE DATES (a schedule, not estimates) for the 9 tracked releases (CPI, Core CPI, Employment Situation, GDP, Jobless Claims, PCE, PPI, Industrial Production, Retail Sales). Returns {days, events, count, source_status, error}; each event is only {date, event, release_id, release_name} -- NO prior/consensus/actual values, and FOMC meeting dates are NOT included. `days` look-ahead default 90; above 180 is REFUSED. ALWAYS CHECK source_status: every failure mode returns events=[], otherwise indistinguishable from a quiet calendar. Cached 6h. Source: FRED releases/dates. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"days": {
"type": "integer",
"description": "Number of days to look ahead (default 90)",
"minimum": 1,
"maximum": 180
}
}
}
get_fred_data
KEY REQUIREDPIP ✓
One FRED or Treasury series from the ~41-series macro snapshot, latest observation only
Full contract & input schema
One series from Oxford Ledge's macro SNAPSHOT (about 41 FRED / Treasury series, newest observation each) by FRED id. Returns {series, data: {series, name, value, date, ytdChange, _source}, observation: 'latest_only', note} -- ONE observation, never a history. A series outside the snapshot returns {series, error, available}. THIRD-PARTY LICENSED SERIES ARE REFUSED WITH THE REASON (2026-09-13): the ICE BofA OAS credit spreads (BAMLH0A0HYM2, BAMLC0A0CM, BAMLC0A1CAAA, BAMLH0A1HYBB, BAMLH0A2HYB, BAMLH0A3HYC), VIXCLS and UMCSENT are licensed content FRED redistributes under its own terms and Oxford Ledge does not; the answer is {series, data: null, refusal_reason: 'third_party_licence', licensor, error, note, directional, directional_unavailable_reason}. RESTRICTED posture: a keyed tool on the hosted channel. Caveats ride the response's tool_notes.
FDIC structural events for one bank by cert or name: failures, mergers, acquisitions, charter changes
Full contract & input schema
FDIC STRUCTURAL EVENTS for one bank -- failures, assisted resolutions, mergers, acquisitions, charter changes -- newest first, with is_failure flagged from the FDIC CHANGECODE taxonomy. Pass `cert` (FDIC certificate) or `name`; a name resolves against active institutions AND closed charters, so a FAILED or merged-away bank (Signature Bank, First Republic) IS found, and `resolved_from` says which charter matched. Ambiguous names return an `ambiguous` candidate list instead of guessing -- call again with the `cert`. An unreachable FDIC store is DATA_UNAVAILABLE, never an empty list. Complements ol_fdic_bank (active institutions only). Source: FDIC public data; FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"cert": {
"type": "integer",
"description": "FDIC certificate number."
},
"name": {
"type": "string",
"description": "Bank name to resolve when cert is unknown."
},
"limit": {
"type": "integer",
"description": "Max events (default 25, cap 100).",
"minimum": 1,
"maximum": 100
}
},
"required": []
}
ol_cftc_cot
ANONYMOUS OKPIP ✓
CFTC Commitments of Traders positioning for gold, crude oil and S&P 500: weekly history or latest
Full contract & input schema
CFTC Commitments-of-Traders positioning for THREE curated markets (keys gold, crude_oil, sp500). Pass `market` for its weekly history, NEWEST FIRST (names are normalised: 'wti', 'GOLD', 'e-mini s&p' resolve), or omit it for the latest report across the three. Returns {summary, market, matched_market, rows}. mm_* and open_interest are CONTRACT counts, not dollars, and mm_* cover ONE speculative category per report family (Managed Money for gold and crude_oil, Leveraged Funds for sp500). `limit` (series only) default 52, hard cap 156. An unreachable store is REFUSED (DATA_UNAVAILABLE). Source: CFTC.gov (public domain); FREE. ATTRIBUTION: every field is CFTC verbatim EXCEPT market_key and market_label (Oxford Ledge's curated market catalog) and mm_net (mm_long minus mm_short, computed by Oxford Ledge). Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"market": {
"type": "string",
"description": "Market key, CFTC report name or desk symbol -- gold / GC / XAU, crude_oil / CL / WTI, sp500 / ES / S&P (case-insensitive; omit for the latest all-market snapshot)."
},
"limit": {
"type": "integer",
"description": "Weekly reports for a market series (default 52, hard cap 156).",
"minimum": 1,
"maximum": 156
}
},
"required": []
}
ol_fdic_bank
ANONYMOUS OKPIP ✓
FDIC-insured banks and thrifts by name prefix, largest first, with assets, deposits and report date
Full contract & input schema
FDIC-insured banks and thrifts. Pass `query` for a name PREFIX search against ACTIVE institutions (largest-asset first), or omit it for the largest active institutions. Returns {summary, query?, found?, institutions}. UNITS: `asset` and `dep` are THOUSANDS of dollars. The store is loaded ACTIVE-ONLY, so a bank that merged away or failed is absent by construction; a name miss says whether a structure event explains it (`structure_event`). An unreachable store is REFUSED (DATA_UNAVAILABLE). `limit` default 25, hard cap 100. Source: FDIC.gov (public domain); FREE. ATTRIBUTION: every field is FDIC BankFind verbatim EXCEPT `ticker`, which is an Oxford Ledge-verified CERT-to-ticker mapping, not an FDIC-published field. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Institution name prefix (omit for the top-by-assets list)."
},
"limit": {
"type": "integer",
"description": "Max institutions (default 25, hard cap 100).",
"minimum": 1,
"maximum": 100
}
},
"required": []
}
ol_treasury_debt
ANONYMOUS OKPIP ✓
US Treasury debt composition from the MSPD: latest month by class, or one class's monthly history
Full contract & input schema
US Treasury debt composition from the Monthly Statement of the Public Debt. Omit BOTH args for the newest month's full class breakdown; pass security_type AND security_class together for that one class's monthly history (passing only one of them is IGNORED). Returns {summary, rows}. AMOUNTS ARE IN MILLIONS OF USD -- a 28,000,000 value means $28 trillion. The breakdown holds component AND Total rows, so summing a column double-counts. `limit` (series only) default 120 months, hard cap 360. An unreachable store is REFUSED (DATA_UNAVAILABLE). Sibling of get_yield_curve. Source: Treasury.gov MSPD (public domain); FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"security_type": {
"type": "string",
"description": "e.g. 'Total Public Debt Outstanding' (with security_class for a series)."
},
"security_class": {
"type": "string",
"description": "Class within the type; '_' for Total rows."
},
"limit": {
"type": "integer",
"description": "Monthly points for a series (default 120, hard cap 360).",
"minimum": 1,
"maximum": 360
}
},
"required": []
}
News & events
5 toolsSOURCE: SEC EDGAR 8-K INDEX · ISSUER IR CALENDARS · NEWS ARCHIVE: MULTI-PUBLISHER VENDOR FEEDS · BORROWER NEWS: GOOGLE NEWS
get_corporate_events
ANONYMOUS OKPIP ✓
The 20 most recent 8-K item events for a ticker, newest first, categorised by item
Full contract & input schema
The 20 most recent 8-K item events for a ticker from Oxford Ledge's 8-K index of SEC EDGAR, NEWEST FIRST -- a hard cap with no caller-settable limit, so a recent-events feed, not a history. Returns {ticker, events, count, coverage, summary}; each event is {ticker, eventDate, eventType, headline, description, counterparty, counterpartyTicker, sourceUrl, source}. `eventType` is Oxford Ledge's 8-K item-to-category map. The event_type filter matches STORED CATEGORIES ONLY; for M&A use acquisition_disposition. Dual-class siblings (GOOG/GOOGL) are unioned. An unreachable store REFUSES (DATA_UNAVAILABLE) rather than serving events=[]. For Form 4 insider transactions use get_insider_activity. Source: SEC EDGAR 8-K index (Oxford Ledge parse), re-indexed about every 7 days. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g. AAPL)"
},
"event_type": {
"type": "string",
"description": "Optional filter, case-insensitive; one category, a comma-separated list, or ALL (the default). The STORED vocabulary is the 17 8-K item categories: material_agreement, material_agreement_termination, bankruptcy, acquisition_disposition, earnings, new_debt_obligation, debt_obligation_trigger, material_impairment, delisting, auditor_change, financial_restatement, change_of_control, executive_change, bylaw_amendment, shareholder_vote, reg_fd_disclosure, other_event. Anything else (acquisition, divestiture, restructuring, dividend, split, merger) matches no stored row and returns events=[]; for M&A use acquisition_disposition."
}
},
"required": [
"ticker"
]
}
get_news
KEY REQUIRED
Oxford Ledge news archive by ticker and/or keyword, newest first; two response shapes, up to 100 rows
Full contract & input schema
Read the Oxford Ledge news archive by ticker and/or keyword, newest first. Default limit 25, hard cap 100; no pagination offset. THE RESPONSE SHAPE DEPENDS ON THE ARGUMENTS: ticker only returns {articles, total}; any free-text query returns {articles, count} with richer rows (publisher, snippet, sentimentScore, tickers, tags). Handle both. `sentiment` is a LABEL string, NOT a number. Query matching is prefix-word, not semantic. Source: Oxford Ledge news archive (multi-provider, cron-populated). Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query (e.g. 'tariff', 'earnings beat')"
},
"ticker": {
"type": "string",
"description": "Filter to a specific ticker (e.g. AAPL)"
},
"limit": {
"type": "integer",
"description": "Max results to return (default 25, max 100)",
"minimum": 1,
"maximum": 100
}
}
}
ol_bdc_borrower_news_today
KEY REQUIRED
Recent verified headlines for borrowers held across multiple BDCs; headline and link only
Full contract & input schema
MOAT / daily pulse: recent VERIFIED news for the private-credit borrowers held across MULTIPLE BDCs -- 'what broke recently for the cross-BDC borrowers I should watch?'. Returns {summary, count, items}; each item is {borrower, headline, source, url, date}. Matcher-VERIFIED only (>=0.9 confidence) and headline + link only, NO provider summary, so a false attribution cannot surface. Caps: limit default 25 / hard 100; since_days default 7 / hard 90; min_holders default 2 (max 50). No recent headlines returns items=[] -- absence is not a signal; an unreachable store is REFUSED (DATA_UNAVAILABLE). Source: Google News, matched to SEC EDGAR BDC borrowers; FREE.
{
"type": "object",
"properties": {
"since_days": {
"type": "integer",
"description": "How many days back to look (default 7, hard cap 90).",
"minimum": 1,
"maximum": 90
},
"min_holders": {
"type": "integer",
"description": "Minimum number of BDC lenders a borrower must appear in (default 2).",
"minimum": 1,
"maximum": 50
},
"limit": {
"type": "integer",
"description": "Max news items to return (default 25, hard cap 100).",
"minimum": 1,
"maximum": 100
}
}
}
ol_earnings_calendar
ANONYMOUS OK
Upcoming earnings dates for one issuer: IR-published dates beside a filing-cadence estimate
Full contract & input schema
Upcoming EARNINGS DATES for one issuer, provenance-labelled: published_events are dates the ISSUER posted on its own IR calendar; estimate is an Oxford Ledge projection from the issuer's SEC filing cadence, with its confidence. Returns {ticker, published_events, published_events_degraded, estimate, provenance_rule, note}. The two are NOT merged: prefer a published date yourself, and never present the estimate as a company announcement. SCOPE: US domestic 8-K filers only. Read published_events_degraded before reading the note as an issuer fact. Distinct from get_economic_calendar (macro releases). Source: issuer IR pages + SEC filing cadence (Oxford Ledge); FREE. Caveats ride the response's tool_notes.
TF-IDF full-text search over archived headlines and the pulse-fact corpus; lexical, not semantic
Full contract & input schema
TF-IDF full-text search over the archived news headlines + the pulse-fact corpus (a lexical index, not embeddings). Returns {query, count, results, index}; each result is {type ('news' | 'fact'), text, score (0-1 cosine), metadata}. `limit` default 20, hard cap 50. The first call after a restart pays the index build (seconds); later calls are fast. RESTRICTED posture: a keyed tool (refuses anonymous callers). For per-ticker archive reads use get_news; for semantic retrieval over SEC filings use ol_filing_search. Caveats ride the response's tool_notes.
4 toolsSOURCE: YOUR ACCOUNT DATA (OXFORD LEDGE POSTGRES) · KEY REQUIRED · NO EXTERNAL SOURCE
get_portfolio_positions
KEY REQUIRED
Stored positions of one saved portfolio: ticker, shares, cost basis; no price leg
Full contract & input schema
Stored positions of one saved portfolio. Returns {portfolio_id, positions, error} on EVERY path (error is null on success, a string on failure, and positions is [] either way). Each position is ONLY {ticker, shares, costBasis (whole USD, may be null)}, ticker-sorted. THERE IS NO PRICE LEG: no price, market value, gain/loss or weight -- value the positions yourself. An unknown portfolio_id yields positions=[] with error=null, so an empty list does not prove the portfolio exists. For the catalog-wide sector mix use get_sector_breakdown. Source: the portfolio's stored positions.
Your paper (practice) portfolio: cash, positions marked to a delayed quote, P&L, optional recent fills
Full contract & input schema
YOUR paper (practice) portfolio on Oxford Ledge -- the same snapshot the web sandbox at /practice/ renders: {portfolio, positions, totals, position_theses, summary, has_portfolio}. include_history: true adds recent_trades (history_limit 1..50, default 20). A user with NO portfolio gets {has_portfolio: false, how_to_start} -- an honest empty, not an error. Positions are marked to the platform's DELAYED quote at read time. Requires an authenticated Oxford Ledge caller (API key or linked OAuth token) and serves the caller's own portfolio only; the local stdio server gets AUTH_REQUIRED. Never cached. Practice money: _meta.disclaimer says so on every response. Source: Oxford Ledge paper sandbox; FREE. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"include_history": {
"type": "boolean",
"default": false,
"description": "Add recent_trades (the last history_limit fills)."
},
"history_limit": {
"type": "integer",
"minimum": 1,
"maximum": 50,
"default": 20,
"description": "How many recent fills to include when include_history is true (1..50)."
}
},
"required": []
}
ol_paper_trade
WRITE · OFF BY DEFAULT
Place a buy or sell in your paper portfolio; dry run by default, key-only, 20 fills a day; a write tool
Full contract & input schema
WRITE (opt-in): place a market order in YOUR paper (practice) portfolio -- the same engine, quote, fills and rejections as the web sandbox; no real money, no real account. One of TWO mutating tools here (the other is reading_list_annotate). DEFAULTS TO A DRY RUN: with _dry_run omitted or true nothing is placed and you get {dry_run: true, tool, args, idempotency_key, preview, message}. Re-call with _dry_run: false AND that same _idempotency_key to execute; a rejection is a normal (non-error) response you must read and relay, and a repeat of the same key returns {replay: true, ...} without placing twice. shares is whole shares, 1..1,000,000; side is buy or sell; thesis (optional, max 250 chars) is the USER's own reason. Requires an API KEY or a linked OAuth token (a browser session cookie is refused). Capped at 20 executed fills per user per UTC day. Practice money: _meta.disclaimer says so on every response. Caveats ride the response's tool_notes.
{
"type": "object",
"additionalProperties": false,
"required": [
"ticker",
"side",
"shares"
],
"properties": {
"ticker": {
"type": "string",
"minLength": 1,
"maxLength": 20,
"description": "Symbol to trade in YOUR paper portfolio (e.g. DAC)."
},
"side": {
"type": "string",
"enum": [
"buy",
"sell"
],
"description": "buy or sell (market order at the platform's delayed quote)."
},
"shares": {
"type": "integer",
"minimum": 1,
"maximum": 1000000,
"description": "Whole shares, 1..1,000,000 per order (the engine's per-order cap)."
},
"thesis": {
"type": "string",
"maxLength": 250,
"description": "Optional: why (max 250 chars). Stored on the fill and shown back to the user beside the position; write it as the USER's reason."
},
"_dry_run": {
"type": "boolean",
"default": true,
"description": "Default true: preview the fill (quote, cost, cash after) without placing it. Re-call with false and the returned _idempotency_key to execute."
},
"_idempotency_key": {
"type": "string",
"maxLength": 128,
"description": "Optional replay-safety key; auto-derived if omitted. A repeat of the same key returns the first result and places nothing."
}
}
}
reading_list_annotate
WRITE · OFF BY DEFAULT
Save or update your private note on a reading-list entry; dry run by default; a write tool
Full contract & input schema
WRITE (opt-in): save or update YOUR private note on an Oxford Ledge reading-list entry. One of TWO mutating tools here (the other is ol_paper_trade). DEFAULTS TO A DRY RUN: with _dry_run omitted or true you get a proposal {dry_run: true, tool, args, idempotency_key, message}, not a save. Re-call with _dry_run: false AND that same _idempotency_key to execute; a repeat of the same key returns {replay: true, ...} without writing twice. Requires Researcher tier AND an authenticated Oxford Ledge caller -- the local stdio server has no account context and raises AUTH_REQUIRED. `slug` must already exist on /reading-list; `body` is capped at 500 chars. Notes stay PRIVATE; this tool can never publish one. Caveats ride the response's tool_notes.
{
"type": "object",
"additionalProperties": false,
"properties": {
"slug": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Reading-list entry slug (as on /reading-list)."
},
"body": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"description": "The note text (max 500 chars). Notes are PRIVATE; publishing requires the dashboard flow (age attestation)."
},
"_dry_run": {
"type": "boolean",
"default": true,
"description": "Default true: propose without persisting. Re-call with false to execute."
},
"_idempotency_key": {
"type": "string",
"maxLength": 128,
"description": "Optional replay-safety key; auto-derived if omitted."
}
},
"required": [
"slug",
"body"
]
}
Learn & reference
3 toolsSOURCE: OXFORD LEDGE EDITORIAL (PROFESSOR-REVIEWED GLOSSARY · CURATED QUOTATION CORPUS) · CATALOG SECTOR MIX FROM COMPANY PROFILES
get_sector_breakdown
ANONYMOUS OK
How the covered universe splits by sector and industry; ticker counts only, one row per pair
Full contract & input schema
How Oxford Ledge's covered universe splits across sectors and industries (the whole catalog, NOT a portfolio). No arguments. Returns a BARE LIST of {sector, industry, tickerCount, totalMarketCap}, one row per sector+industry PAIR -- aggregate rows to get a sector total. totalMarketCap IS ALWAYS NULL: a count-only breakdown. Rows with a blank sector are excluded; a blank industry is null. Each industry sits under the ONE sector holding most of its tickers. Returns {error} (a dict) when the read fails. For a named portfolio use get_portfolio_positions. Source: Oxford Ledge company profiles, ~5,200 tickers.
{
"type": "object",
"properties": {}
}
get_value_investing_fact
ANONYMOUS OKPIP ✓
A curated value-investing principle, paraphrase or fact from a ~2,000-entry corpus; by query, category or random
Full contract & input schema
Curated value-investing principle, historical fact or attributed paraphrase from Oxford Ledge's corpus (~2,000 entries about Buffett, Graham, Munger, Klarman and others). THE WORDING IS NOT VERIFIED against the primary source: none is a verbatim quotation unless `verbatim` is true -- so never present the text as the author's exact words, and credit it with the `attribution` line. THE SHAPE DEPENDS ON THE ARGUMENTS: a `query` returns {facts, count, total_facts} (facts capped at 10); a bare `category` or no arguments returns {fact, total_facts} (one random pick). Pedagogical content only -- never a market signal. Cached 24h per argument set. Caveats ride the response's tool_notes.
{
"type": "object",
"properties": {
"category": {
"type": "string",
"description": "Optional category filter. The vocabulary is EXACTLY: principle, historical_fact, psychology, quote, case_study, contrarian, mistake. Matched case-insensitively; leave empty for random. An unknown value returns {error, available_categories, total_facts} where available_categories is read from the store, so one retry always lands."
},
"query": {
"type": "string",
"description": "Optional search query to find facts by keyword (e.g. 'moat', 'fear')"
}
}
}
ol_glossary_term
ANONYMOUS OK
Look up one of ~1,500 editorial glossary terms: definition, worked example, etymology, related terms
Full contract & input schema
Oxford Ledge's editorial GLOSSARY: ~1,500 finance and investing terms written for lifelong students of the market -- definition, worked example, etymology, pronunciation, related terms (see-also), and the learning paths that teach the concept. Look up one term by name (case and punctuation tolerant: 'first lien', 'convexity', 'duration'). Use it to ground explanations in the SAME definitions the platform teaches from, instead of improvising one. Source: Oxford Ledge editorial (reviewed in-house); FREE.
{
"type": "object",
"properties": {
"term": {
"type": "string",
"description": "The term to look up, e.g. 'duration'."
}
},
"required": [
"term"
]
}
Full descriptions are preserved verbatim inside each card's fold — they are the contract; the summary is the index.
Notes
Cached server-side for 5 minutes; refresh after a new tool registers.
Source of truth: mcp_package/oxford_ledge_mcp/tools_manifest.py (generated) — this page renders from it; do not import server.py to enumerate tools.
JSON Schemas mirror what the MCP list_tools response sends to clients — copy-paste them into your agent config.