.codex-plugin — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited .codex-plugin (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<div align="center"> <h1>@cyanheads/secedgar-mcp-server</h1> <p><b>Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.</b> <div>10 Tools (+1 opt-in) • 2 Resources • 1 Prompt</div> </p> </div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
Public Hosted Server: https://secedgar.caseyjhand.com/mcp
</div>
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.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 [email protected]",
"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 [email protected]",
"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/mcpgit clone https://github.com/cyanheads/secedgar-mcp-server.gitcd secedgar-mcp-serverbun installbun run buildAll 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 [email protected]". 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 |
bun run rebuild
bun run start:http # or start:stdio bun run devcheck # Lints, formats, type-checks
bun run test # Runs test suitedocker build -t secedgar-mcp-server .
docker run -e EDGAR_USER_AGENT="MyApp [email protected]" -p 3010:3010 secedgar-mcp-serverThe 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 testThis project is licensed under the Apache 2.0 License. See the LICENSE file for details.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.