Loading repository data…
Loading repository data…
jibarix / repository
Analyst-grade SEC EDGAR financials: XBRL pull plus a vendor-comparable normalized metric/comps/beta engine, with an MCP server
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
Analyst-grade SEC EDGAR financials. A Python library, CLI, and MCP server that pulls XBRL filings directly from the SEC and layers an analyst-normalized metric engine on top.
Unlike raw filing tools, edgar-link aims to return usable financial
outputs such as normalized revenue, EBIT, EBITDA, FCF, leverage, margins,
returns, growth, LTM rollups, and structural balance-sheet / cash-flow
buildups. It also includes 5-year peer beta / R^2 utilities. No API key, no
subscription; the live data source is the SEC.
SEC identity required. SEC fair-access policy requires every requester to identify themselves. Before any live call, set:
export EDGAR_IDENTITY="Your Name your@email.com" # macOS/Linux $env:EDGAR_IDENTITY = "Your Name your@email.com" # Windows PowerShellWithout it the SEC will throttle requests. Do not hardcode, borrow, or commit someone else's identity.
SEC_EDGAR_USER_AGENTis also accepted as an alias for compatibility with other SEC tooling.
This project primarily uses the SEC XBRL APIs:
https://data.sec.gov/api/xbrl/companyfacts/CIK##########.jsonhttps://data.sec.gov/api/xbrl/companyconcept/CIK##########/taxonomy/tag.jsonAssets or RevenuesThe engine uses:
EDGAR_IDENTITYMore information: https://www.sec.gov/developer
pipThe pinned dependency set (
pandas,numpy) requires Python 3.11+, so 3.11 is the hard floor. The hash-verified clean-room install and CI path are validated on Windows / CPython 3.11 (requirements.lockis Windows/cp311-specific); a Linux lock is deferred until a fresh dependency resolve is safe under the active supply-chain incident policy.
No PyPI release yet.
# library + metric engine
pip install "git+https://github.com/jibarix/edgar-link.git#egg=edgar-link"
# with MCP support
pip install "edgar-link[mcp] @ git+https://github.com/jibarix/edgar-link.git"
git clone https://github.com/jibarix/edgar-link.git
cd edgar-link
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # macOS/Linux
pip install -e .
Dependencies are declared in pyproject.toml and pinned to
reviewed versions. requirements.lock is the corresponding hash-pinned lockfile.
Three ways to drive the engine. They share the same Python core; pick the one that fits the workflow.
| Talk to Claude (MCP) | CLI | Library | |
|---|---|---|---|
| Best for | Ad-hoc questions, exploration, no coding | One-shot pulls, scripted or scheduled exports | Building analyses, pipelines, custom code |
| Invocation | Natural-language prompt to an MCP client | python main.py ... | from edgar.metrics import ... |
| Setup | Install [mcp] extra, register the server once | Install the runtime | Install the runtime |
| Output | Conversational response in the client | Console table or Excel / CSV / JSON / HTML file | Python objects (dicts, DataFrames) |
| Lookup by | Name, ticker, or CIK | Name, ticker, or --cik | CIK (resolve names via edgar.company_lookup) |
EDGAR_IDENTITY | In the MCP client's env config | In your shell env | In your shell env |
The conversational path. The same engine is exposed as an MCP stdio server, so an MCP-aware client (Claude Code, Claude Desktop) can call it directly in natural language:
Install and register the server once — see MCP server reference below — then just ask. No code from the caller.
Interactive mode:
python main.py
Command-line mode:
python main.py --company "Apple Inc" --statement-type BS --period-type annual --num-periods 3 --output-format excel
Supported statement types:
BS - Balance SheetIS - Income StatementCF - Cash Flow StatementEQ - Equity StatementCI - Comprehensive IncomeALL - All supported statementsFor building analyses on top of the engine in your own code:
from edgar.filing_retrieval import FilingRetrieval
from edgar.xbrl_parser import XBRLParser
from edgar.metrics import REGISTRY, NormalizedStatement, compute, list_slugs
filings = FilingRetrieval()
parser = XBRLParser()
facts = filings.get_company_facts("0000320193") # Apple Inc.
normalized = parser.parse_company_facts(
facts,
statement_type="IS",
period_type="annual",
num_periods=3,
)
ns = NormalizedStatement(normalized)
ebit_series = compute("ebit", ns) # {period: value}
margin_slugs = list_slugs(category="margins") # discover what's registered
spec = REGISTRY["roic"] # MetricSpec (fn, unit, ...)
EDGAR_IDENTITY must be set in the environment for any live retrieval.
See Architecture for module boundaries and
MCP server reference for the equivalent tool
surface.
Install, registration, configuration, and the tool surface for the
stdio server invoked via python -m edgar_mcp.
pip install -e ".[mcp]"
claude mcp add edgar -e EDGAR_IDENTITY="Your Name your@email.com" -- python -m edgar_mcp
{
"mcpServers": {
"edgar": {
"command": "python",
"args": ["-m", "edgar_mcp"],
"env": {
"EDGAR_IDENTITY": "Your Name your@email.com"
}
}
}
}
| Tool | Purpose |
|---|---|
lookup_company(query) | Resolve a name or ticker to SEC CIK candidates |
get_financial_statement(cik_or_ticker, statement_type, period_type, num_periods) | Return normalized BS / IS / CF / EQ / CI / ALL data by period |
get_concept(cik_or_ticker, concept, taxonomy) | Return a full historical time series for one XBRL concept |
search_companies(sic, industry, country_inc, revenue_country, name_substring, limit) | Filter the local company classification index |
list_metrics(category) | Enumerate registered derived metrics |
compute_metric(slug, cik_or_ticker, period_type, num_periods) | Compute one derived metric series with the required internal lookback |
search_companies reads data/company_index.json; build it first with:
python -m edgar.company_classifier --build
The MCP server gives Claude access to the engine; the bundled
edgar-link-financials skill gives Claude
the workflow knowledge to use it well. Together they mean a question like
"show MSFT's ROIC over 5 quarters" resolves the ticker, computes the metric
with the right internal lookback, and reports the result with units — without
the user having to know tool names, that EBIT is analyst-normalized, or that
search_companies needs a prebuilt index.
The skill is a portable folder (SKILL.md + references/) that works in
Claude.ai, Claude Code, and the API. To use it in Claude Code, copy the folder
into your skills directory, or upload it in Claude.ai via Settings →
Capabilities → Skills. It triggers on financial / fundamentals / filings
questions and defers detailed metric and error guidance to its references/
files (progressive disclosure), so it adds little to context until needed.
EDGAR_IDENTITY must still be set in the MCP server's environment — the skill
documents that precondition but cannot supply the identity itself.
edgar/filing_retrieval.py
edgar/company_lookup.py
edgar/xbrl_parser.py
edgar/tag_classifier.py
The metric engine is registry-based. Metric functions register themselves in
edgar/metrics/registry.py, and the public
surface is imported through edgar/metrics/__init__.py.
Main metric modules:
| Module | Examples |
|---|---|
derived_lines.py | revenue, gross_profit, ebit, ebitda, fcf, total_debt |
margins.py | ebit_margin, ebitda_margin, ni_margin, fcf_margin |
ratios.py | debt_to_capital, debt_to_equity, current_ratio, quick_ratio |
returns.py | roa, roe, roic, asset_turnover |
working_capital.py | dso, dio, dpo, cash_conversion_cycle |
growth.py | <base>_growth, <base>_cagr_{3,5,7}y |
ltm.py | trailing-twelve-months rollups |
The repo also includes a second normalization path for balance-sheet and cash-flow structure:
edgar/metrics/_statement_taxonomy.py
edgar/metrics/_bs_prefilter.py
edgar/metrics/_cf_prefilter.py
edgar/metrics/statement_buildup.py
Important design rule:
edgar/metrics/beta.py computes 5-year monthly
beta and R^2 versus the S&P 500 from Yahoo monthly bars.
What it does today:
What it does not currently implement:
derived_lines.ebit() is intentionally not just raw
us-gaap:OperatingIncomeLoss.
Current normalization:
EBIT = OperatingIncomeLoss + goodwill_impairment + asset_impairment
This is meant to move the output closer to institutional analyst convention for
names where unusual impairments sit inside reported operating income. A
pretax-plus-interest fallback is also used for some hybrid-finance issuers that
do not tag OperatingIncomeLoss cleanly.
The current scripts/ directory is focused on validation, maintenance,
and workbook/reporting workflows:
| Script | Purpose |
|---|---|
scripts/smoke_test_metrics.py | Live AAPL smoke test for the parser + metric registry. Prints a compact multi-period table of hand-checked metrics. Requires EDGAR_IDENTITY or SEC_EDGAR_USER_AGENT. |
scripts/gen_lockfile.py | Regenerates `requirements |