A production-grade interface to the SEC's EDGAR archive with serious depth. You get full-text search across 30 years of filings, XBRL financials with friendly concept names that handle historical tag changes, parsed insider transactions from Forms 3/4/5, and institutional holdings from 13F-HR filings. The frames tool pulls cross-company datasets for a single metric across all filers. Results beyond inline limits land in DuckDB-backed dataframes you can query with SQL. Runs locally via stdio or connects to a public HTTP endpoint. Reach for this when you need structured financial data or filing content without writing your own EDGAR parser or wrestling with raw XBRL taxonomies.
claude mcp add --transport http secedgar https://secedgar.caseyjhand.com/mcpRun in your terminal. Add --scope user to make it available in every project.
Review the command, arguments, and environment values before installing — MCP servers run with your local permissions.
Verified live against the running server on Jun 10, 2026.
secedgar_company_searchFind companies and retrieve entity info with optional recent filings. Entry point for most EDGAR workflows — resolves tickers, names, or CIKs to entity details, with accession numbers in the result feeding secedgar_get_filing for document content.4 paramsFind companies and retrieve entity info with optional recent filings. Entry point for most EDGAR workflows — resolves tickers, names, or CIKs to entity details, with accession numbers in the result feeding secedgar_get_filing for document content.
query*stringform_typesarrayfiling_limitintegerinclude_filingsbooleansecedgar_search_filingsSearch the full-text index of EDGAR filings since 1993. Supports exact phrases, boolean operators, wildcards, and entity targeting (ticker:AAPL or cik:320193 in query).7 paramsSearch the full-text index of EDGAR filings since 1993. Supports exact phrases, boolean operators, wildcards, and entity targeting (ticker:AAPL or cik:320193 in query).
sortstringfiling_date_desc · filing_date_asc · relevancedefault: filing_date_descformsarraylimitintegerquery*stringoffsetintegerend_datevaluestart_datevaluesecedgar_get_filingFetch a specific filing's metadata and document content by accession number. Returns the primary document as readable text, with option to fetch specific exhibits.5 paramsFetch a specific filing's metadata and document content by accession number. Returns the primary document as readable text, with option to fetch specific exhibits.
cikstringdocumentstringinclude_xbrlbooleancontent_limitintegeraccession_number*stringsecedgar_get_financialsGet historical XBRL financial data for a company. Accepts friendly concept names (e.g., "revenue", "net_income", "assets") or raw XBRL tags. Discover available friendly names with secedgar_search_concepts. Handles historical tag changes and deduplicates data automatically.5 paramsGet historical XBRL financial data for a company. Accepts friendly concept names (e.g., "revenue", "net_income", "assets") or raw XBRL tags. Discover available friendly names with secedgar_search_concepts. Handles historical tag changes and deduplicates data automatically.
limitintegercompany*stringconcept*stringtaxonomystringus-gaap · ifrs-full · deidefault: us-gaapperiod_typestringannual · quarterly · allsecedgar_get_insider_transactionsFetch Form 4 insider transactions (purchases, sales, grants, exercises) for a company by parsing SEC EDGAR ownership XML. Returns the reporting person, their relationship to the issuer, transaction date, type, shares traded (absolute magnitude), direction (acquire/dispose), pr...3 paramsFetch Form 4 insider transactions (purchases, sales, grants, exercises) for a company by parsing SEC EDGAR ownership XML. Returns the reporting person, their relationship to the issuer, transaction date, type, shares traded (absolute magnitude), direction (acquire/dispose), pr...
limitintegerticker_or_cik*stringtransaction_typestringpurchase · sale · alldefault: allsecedgar_get_institutional_holdingsFetch 13F-HR quarterly institutional holdings by parsing the SEC EDGAR information table XML. Use ticker_or_cik to look up an institution (e.g., "Vanguard Group" or its CIK) and see what it holds — or pass a company ticker/CIK to find which institutions filed 13Fs covering tha...4 paramsFetch 13F-HR quarterly institutional holdings by parsing the SEC EDGAR information table XML. Use ticker_or_cik to look up an institution (e.g., "Vanguard Group" or its CIK) and see what it holds — or pass a company ticker/CIK to find which institutions filed 13Fs covering tha...
limitintegerquarterstringconsolidatebooleanticker_or_cik*stringsecedgar_fetch_framesFetch SEC XBRL frames for one concept × one period across all reporting companies. Inline response returns the top N ranked companies; the full frames response (all reporters) is materialized as df_<id> when a canvas is available, queryable via secedgar_dataframe_query. Accept...5 paramsFetch SEC XBRL frames for one concept × one period across all reporting companies. Inline response returns the top N ranked companies; the full frames response (all reporters) is materialized as df_<id> when a canvas is available, queryable via secedgar_dataframe_query. Accept...
sortstringdesc · ascdefault: descunitstringUSD · USD-per-shares · USD/shares · shares · puredefault: USDlimitintegerperiod*stringconcept*stringsecedgar_search_conceptsSearch supported XBRL financial concepts by keyword, statement group, or taxonomy. Use before secedgar_get_financials or secedgar_fetch_frames to discover the right friendly name, or pass a raw XBRL tag (e.g., "NetIncomeLoss") to reverse-lookup which friendly names map to it....3 paramsSearch supported XBRL financial concepts by keyword, statement group, or taxonomy. Use before secedgar_get_financials or secedgar_fetch_frames to discover the right friendly name, or pass a raw XBRL tag (e.g., "NetIncomeLoss") to reverse-lookup which friendly names map to it....
groupstringincome_statement · balance_sheet · cash_flow · per_share · entity_infosearchstringtaxonomystringus-gaap · ifrs-full · deisecedgar_dataframe_describeList dataframes (df_XXXXX_XXXXX) materialized by secedgar_fetch_frames, secedgar_search_filings, secedgar_get_financials, secedgar_get_insider_transactions, and secedgar_get_institutional_holdings. Each entry surfaces source tool, query parameters, creation/expiry timestamps,...1 paramsList dataframes (df_XXXXX_XXXXX) materialized by secedgar_fetch_frames, secedgar_search_filings, secedgar_get_financials, secedgar_get_insider_transactions, and secedgar_get_institutional_holdings. Each entry surfaces source tool, query parameters, creation/expiry timestamps,...
namestringsecedgar_dataframe_queryRun a single-statement SELECT against the canvas dataframes registered by secedgar_fetch_frames, secedgar_search_filings, and secedgar_get_financials. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected. System catalogs (informati...4 paramsRun a single-statement SELECT against the canvas dataframes registered by secedgar_fetch_frames, secedgar_search_filings, and secedgar_get_financials. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected. System catalogs (informati...
sql*stringpreviewintegerrow_limitintegerregister_asstringQuery SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.
Public Hosted Server: https://secedgar.caseyjhand.com/mcp
Eight tools for querying SEC EDGAR data, plus three for SQL analytics over the DuckDB-backed canvas dataframes those tools materialize:
| Tool | Description |
|---|---|
secedgar_company_search | Find companies and retrieve entity info with optional recent filings |
secedgar_search_filings | Full-text search across all EDGAR filing documents since 1993 |
secedgar_get_filing | Fetch a specific filing's metadata and document content |
secedgar_get_financials | Get historical XBRL financial data for a company |
secedgar_get_insider_transactions | Form 3/4/5 insider transactions (buys, sells, grants, exercises) parsed from ownership XML |
secedgar_get_institutional_holdings | 13F-HR quarterly institutional holdings parsed from the information table |
secedgar_fetch_frames | Fetch SEC XBRL frames for one concept × one period across all reporting companies |
secedgar_search_concepts | Discover supported XBRL concept names or reverse-lookup a raw tag |
secedgar_dataframe_describe | List canvas dataframes with provenance, TTL, and schema |
secedgar_dataframe_query | Run a single-statement SELECT across dataframes |
secedgar_dataframe_drop | Drop a canvas dataframe by name. Opt-in via EDGAR_DATAFRAME_DROP_ENABLED=true — off by default since TTL already handles cleanup |
secedgar_company_searchEntry point for most EDGAR workflows — resolve tickers, names, or CIKs to entity details.
AAPL, VOO), company names (Apple), or CIK numbers (320193)company_tickers_mf.json; fund results include series_id and class_id for downstream scopingFacebook → Meta Platforms, Square → Block)Microsfot → MICROSOFT CORP / MSFT)secedgar_search_filingsFull-text search across all EDGAR filing documents since 1993.
"material weakness"), boolean operators (revenue OR income), wildcards (account*)cik:320193 or ticker:AAPL) — scoped server-side by CIK, so filings made under a former company name (same CIK) are includeddf_<id> dataframe — query it with secedgar_dataframe_querysecedgar_get_filingFetch a specific filing's metadata and document content by accession number.
next_offset from a truncated response as offset on the next call to continue reading; first-page truncated responses include a detected outline (headings with offsets) for targeted navigationsection param: jumps directly to a named heading by case-insensitive substring match (e.g. "risk factors", "item 7", "certain relationships"); on a miss, the error carries the detected outline so you can pick the correct headingaccession + document (bounded LRU, 8 entries), making subsequent paged calls cheapsecedgar_get_financialsGet historical XBRL financial data for a company with friendly concept name resolution.
"revenue", "net_income", "eps_diluted" auto-resolve to correct XBRL tagslimit caps the inline series to the most-recent N periods; the full series stays queryable via the df_<id> dataframesecedgar://concepts resource for the full mappingsecedgar_get_insider_transactionsSurface Form 3/4/5 insider activity for a company by parsing ownership XML.
transaction_type (purchase, sale, all); scans newest filings firstdf_<id> dataframe (the inline list is a preview capped at limit) — query it with secedgar_dataframe_query to aggregate net buy/sell by insidersecedgar_get_institutional_holdingsSurface 13F-HR quarterly institutional holdings by parsing the information table.
consolidate: false for raw filing rowsquarter (e.g. "2025-Q4")total_holdings_in_filing counts raw info-table rows; total_positions counts distinct positions after consolidation (both before limit)df_<id> dataframe (the inline list is a preview capped at limit) — query it with secedgar_dataframe_query for full-filing aggregation or cross-quarter joins on cusip + reporting_periodsecedgar_fetch_framesFetch SEC XBRL frames for one concept × one period across all reporting companies.
secedgar_get_financialsCY2023), quarterly (CY2024Q2), and instant (CY2023Q4I) periodsdf_<id> dataframe — query it with secedgar_dataframe_queryrelated_tags flags alternate-definition tags some filers use as their primary line (e.g. cash → restricted-cash-inclusive total, equity → NCI-inclusive total), so a whole-universe screen on the base tag isn't silently under-inclusive — query those separatelysecedgar_search_conceptsDiscover supported XBRL concept names before querying financials or cross-company comparisons.
income_statement, balance_sheet, cash_flow, per_share, entity_info) or taxonomyNetIncomeLoss to the supported friendly namesrelated_tags for concepts with a high-coverage alternate-definition tag (e.g. restricted-cash-inclusive cash) so callers can discover them before screeningsecedgar_get_financials, secedgar_fetch_frames, and secedgar://conceptssecedgar_dataframe_describe / secedgar_dataframe_query / secedgar_dataframe_dropIn-conversation SQL analytics over the dataframes that secedgar_fetch_frames, secedgar_search_filings, secedgar_get_financials, secedgar_get_insider_transactions, and secedgar_get_institutional_holdings materialize on a shared DuckDB-backed canvas. Each data-returning call adds a dataset field with a df_XXXXX_XXXXX handle; pass that handle to secedgar_dataframe_query for joins, aggregates, window functions, percentiles — standard DuckDB SQL.
information_schema, pg_catalog, sqlite_master, duckdb_*) are denied at the bridge layer so callers can't enumerate dataframes they don't already hold a handle for. secedgar_dataframe_drop is the only destructive tool and is opt-in (EDGAR_DATAFRAME_DROP_ENABLED=true); TTL handles cleanup otherwise.EDGAR_DATASET_TTL_SECONDS). The canvas itself uses the framework's sliding TTL.register_as chaining. secedgar_dataframe_query can persist its result as a new dataframe (df_XXXXX_XXXXX) with a fresh TTL — pipe analyses without re-running the source query.| URI | Description |
|---|---|
secedgar://concepts | Common XBRL financial concepts grouped by statement, mapping friendly names to XBRL tags |
secedgar://filing-types | Common SEC filing types with descriptions, cadence, and use cases |
| Prompt | Description |
|---|---|
secedgar_company_analysis | Guides a structured analysis of a public company's SEC filings: identify recent filings, extract financial trends, surface risk factors, and note material events |
Built on @cyanheads/mcp-ts-core:
none, jwt, oauth)SEC EDGAR–specific:
company_tickers_mf.json), company names (current and former), or raw CIK numbers with local caching; near-match trigram suggestions on zero-result name queries; committed former-names.json asset for prior-name resolution (Facebook → Meta, Square → Block)html-to-textsecedgar_fetch_frames, secedgar_search_filings, secedgar_get_financials, secedgar_get_insider_transactions, and secedgar_get_institutional_holdings materialize their full result as a DuckDB-backed canvas dataframe queryable via secedgar_dataframe_queryA public instance is available at https://secedgar.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"secedgar-mcp-server": {
"type": "streamable-http",
"url": "https://secedgar.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file.
{
"mcpServers": {
"secedgar-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/secedgar-mcp-server@latest"],
"env": {
"EDGAR_USER_AGENT": "YourAppName your-email@example.com",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"secedgar-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/secedgar-mcp-server@latest"],
"env": {
"EDGAR_USER_AGENT": "YourAppName your-email@example.com",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/secedgar-mcp-server.git
cd secedgar-mcp-server
bun install
bun run build
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default |
|---|---|---|
EDGAR_USER_AGENT | Required. User-Agent header for SEC compliance. Format: "AppName contact@email.com". SEC blocks IPs without a valid User-Agent. | — |
EDGAR_RATE_LIMIT_RPS | Max requests/second to SEC APIs. Do not exceed 10. | 10 |
EDGAR_TICKER_CACHE_TTL | Seconds to cache the company tickers lookup file. | 3600 |
EDGAR_DATASET_TTL_SECONDS | Per-table TTL for canvas-registered dataframes. Sliding window touched on every dataframe op. | 86400 |
EDGAR_DATAFRAME_DROP_ENABLED | Set to true to expose secedgar_dataframe_drop — the only destructive tool on this server. Off by default; TTL handles cleanup. | false |
EDGAR_MIRROR_ENABLED | Enable the local SQLite mirror of company_tickers + XBRL company-facts so CIK resolution and financials read from disk instead of the live API. Node/Bun only (skipped on Workers). Bootstrap once with bun run mirror:init. | false |
EDGAR_MIRROR_PATH | Directory holding the mirror SQLite databases. | ./data/edgar-mirror |
EDGAR_MIRROR_REFRESH_CRON | Cron for the in-process nightly refresh (HTTP transport only). Recommended 0 9 * * *. Omit to refresh out-of-band via bun run mirror:refresh. | — |
EDGAR_MIRROR_FALLBACK_LIVE | When the mirror misses (not yet synced, or a filing newer than the last refresh), fall back to the live SEC API. Set false for strict mirror-only reads. | true |
CANVAS_PROVIDER_TYPE | Canvas engine. Defaults to duckdb; set to none to disable the canvas (e.g. when running on Cloudflare Workers, where DuckDB has no V8-isolate build). | duckdb |
MCP_TRANSPORT_TYPE | Transport: stdio or http | stdio |
MCP_HTTP_PORT | HTTP server port | 3010 |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.) | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
Build and run the production version:
bun run rebuild
bun run start:http # or start:stdio
Run checks and tests:
bun run devcheck # Lints, formats, type-checks
bun run test # Runs test suite
docker build -t secedgar-mcp-server .
docker run -e EDGAR_USER_AGENT="MyApp my@email.com" -p 3010:3010 secedgar-mcp-server
The image ships the mirror CLI, so the local mirror (EDGAR_MIRROR_ENABLED) can be bootstrapped, inspected, and refreshed inside a running container:
docker exec <container> bun run mirror:verify # sync status + sample reads
docker exec <container> bun run mirror:init # one-time bootstrap (downloads the SEC bulk archive)
docker exec <container> bun run mirror:refresh # re-ingest when the archive has been rebuilt
| Directory | Purpose |
|---|---|
src/mcp-server/tools/definitions/ | Tool definitions (*.tool.ts). Eight SEC EDGAR tools plus three dataframe_* tools for SQL analytics. |
src/mcp-server/resources/definitions/ | Resource definitions. XBRL concepts and filing types. |
src/mcp-server/prompts/definitions/ | Prompt definitions. Company analysis prompt. |
src/services/edgar/ | SEC EDGAR API client, XBRL concept mapping, HTML-to-text conversion. |
src/services/canvas-bridge/ | Adapter over the framework DataCanvas: df_<id> minting, all-nullable schema derivation, per-table TTL bookkeeping, bridge-layer system-catalog SQL deny. |
src/config/ | Server-specific environment variable parsing and validation with Zod. |
tests/ | Unit and integration tests, mirroring the src/ structure. |
See CLAUDE.md and AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for logging, ctx.state for storagecreateApp() arraysIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
EDGAR_USER_AGENT*User-Agent header for SEC compliance. Format: "AppName contact@email.com".
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_PUBLIC_URLPublic-facing origin override for TLS-terminating proxies (e.g., https://mcp.example.com). Leave unset for direct deployments.
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
explorium-ai/vibeprospecting-mcp
io.github.compuute/lead-enrichment
dev.workers.selbyventurecap.cf-worker/apollo-salesforce-mapper
io.github.br0ski777/company-enrichment
com.mcparmory/apollo
mambalabsdev/mcp-gtm-tech-stack-signal-scraper