@cyanheads/secedgar-mcp-server 0.15.5 → 0.15.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +416 -0
- package/CLAUDE.md +416 -0
- package/README.md +181 -151
- package/changelog/0.1.x/0.1.0.md +33 -0
- package/changelog/0.1.x/0.1.1.md +27 -0
- package/changelog/0.1.x/0.1.10.md +27 -0
- package/changelog/0.1.x/0.1.11.md +15 -0
- package/changelog/0.1.x/0.1.2.md +28 -0
- package/changelog/0.1.x/0.1.3.md +20 -0
- package/changelog/0.1.x/0.1.4.md +13 -0
- package/changelog/0.1.x/0.1.5.md +19 -0
- package/changelog/0.1.x/0.1.6.md +20 -0
- package/changelog/0.1.x/0.1.7.md +20 -0
- package/changelog/0.1.x/0.1.8.md +14 -0
- package/changelog/0.1.x/0.1.9.md +14 -0
- package/changelog/0.10.x/0.10.0.md +18 -0
- package/changelog/0.10.x/0.10.1.md +21 -0
- package/changelog/0.10.x/0.10.2.md +23 -0
- package/changelog/0.10.x/0.10.3.md +21 -0
- package/changelog/0.10.x/0.10.4.md +12 -0
- package/changelog/0.10.x/0.10.5.md +18 -0
- package/changelog/0.11.x/0.11.0.md +41 -0
- package/changelog/0.11.x/0.11.1.md +30 -0
- package/changelog/0.11.x/0.11.2.md +27 -0
- package/changelog/0.11.x/0.11.3.md +15 -0
- package/changelog/0.12.x/0.12.0.md +16 -0
- package/changelog/0.12.x/0.12.1.md +29 -0
- package/changelog/0.12.x/0.12.2.md +23 -0
- package/changelog/0.12.x/0.12.3.md +24 -0
- package/changelog/0.12.x/0.12.4.md +19 -0
- package/changelog/0.12.x/0.12.5.md +42 -0
- package/changelog/0.13.x/0.13.0.md +29 -0
- package/changelog/0.13.x/0.13.1.md +27 -0
- package/changelog/0.14.x/0.14.0.md +30 -0
- package/changelog/0.15.x/0.15.0.md +20 -0
- package/changelog/0.15.x/0.15.1.md +38 -0
- package/changelog/0.15.x/0.15.2.md +28 -0
- package/changelog/0.15.x/0.15.3.md +22 -0
- package/changelog/0.15.x/0.15.4.md +14 -0
- package/changelog/0.15.x/0.15.5.md +21 -0
- package/changelog/0.15.x/0.15.6.md +42 -0
- package/changelog/0.15.x/0.15.7.md +36 -0
- package/changelog/0.2.x/0.2.0.md +25 -0
- package/changelog/0.3.x/0.3.0.md +17 -0
- package/changelog/0.4.x/0.4.0.md +24 -0
- package/changelog/0.4.x/0.4.1.md +34 -0
- package/changelog/0.4.x/0.4.2.md +14 -0
- package/changelog/0.4.x/0.4.3.md +28 -0
- package/changelog/0.4.x/0.4.4.md +19 -0
- package/changelog/0.4.x/0.4.5.md +17 -0
- package/changelog/0.5.x/0.5.0.md +35 -0
- package/changelog/0.5.x/0.5.1.md +13 -0
- package/changelog/0.5.x/0.5.2.md +13 -0
- package/changelog/0.6.x/0.6.0.md +24 -0
- package/changelog/0.6.x/0.6.1.md +21 -0
- package/changelog/0.6.x/0.6.2.md +34 -0
- package/changelog/0.6.x/0.6.3.md +23 -0
- package/changelog/0.7.x/0.7.0.md +25 -0
- package/changelog/0.7.x/0.7.1.md +12 -0
- package/changelog/0.7.x/0.7.2.md +23 -0
- package/changelog/0.7.x/0.7.3.md +12 -0
- package/changelog/0.7.x/0.7.4.md +16 -0
- package/changelog/0.8.x/0.8.0.md +20 -0
- package/changelog/0.8.x/0.8.1.md +17 -0
- package/changelog/0.8.x/0.8.2.md +14 -0
- package/changelog/0.8.x/0.8.3.md +20 -0
- package/changelog/0.8.x/0.8.4.md +12 -0
- package/changelog/0.9.x/0.9.0.md +20 -0
- package/changelog/template.md +151 -0
- package/dist/config/server-config.d.ts +1 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +7 -0
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +16 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/resources/definitions/filing-types.resource.js +2 -2
- package/dist/mcp-server/resources/definitions/filing-types.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/company-search.tool.d.ts +8 -1
- package/dist/mcp-server/tools/definitions/company-search.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/company-search.tool.js +24 -8
- package/dist/mcp-server/tools/definitions/company-search.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-companies.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/compare-companies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-companies.tool.js +8 -0
- package/dist/mcp-server/tools/definitions/compare-companies.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.d.ts +31 -2
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.js +47 -5
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.js +8 -0
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/find-holders.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/find-holders.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/find-holders.tool.js +9 -1
- package/dist/mcp-server/tools/definitions/find-holders.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-beneficial-owners.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/get-beneficial-owners.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-beneficial-owners.tool.js +8 -0
- package/dist/mcp-server/tools/definitions/get-beneficial-owners.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-filing.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/get-filing.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-filing.tool.js +8 -0
- package/dist/mcp-server/tools/definitions/get-filing.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.js +10 -0
- package/dist/mcp-server/tools/definitions/get-financials.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-fund-holdings.tool.d.ts +8 -1
- package/dist/mcp-server/tools/definitions/get-fund-holdings.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-fund-holdings.tool.js +9 -1
- package/dist/mcp-server/tools/definitions/get-fund-holdings.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.d.ts +9 -2
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.js +19 -9
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.d.ts +10 -3
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.js +25 -15
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-material-events.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/get-material-events.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-material-events.tool.js +18 -0
- package/dist/mcp-server/tools/definitions/get-material-events.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.js +10 -0
- package/dist/mcp-server/tools/definitions/get-snapshot.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +135 -12
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts +14 -4
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.js +37 -18
- package/dist/mcp-server/tools/definitions/search-filings.tool.js.map +1 -1
- package/dist/services/canvas-bridge/canvas-bridge.d.ts +4 -1
- package/dist/services/canvas-bridge/canvas-bridge.d.ts.map +1 -1
- package/dist/services/canvas-bridge/canvas-bridge.js +4 -1
- package/dist/services/canvas-bridge/canvas-bridge.js.map +1 -1
- package/dist/services/edgar/edgar-api-service.d.ts +29 -10
- package/dist/services/edgar/edgar-api-service.d.ts.map +1 -1
- package/dist/services/edgar/edgar-api-service.js +124 -28
- package/dist/services/edgar/edgar-api-service.js.map +1 -1
- package/dist/services/edgar/mirror/index.d.ts +6 -0
- package/dist/services/edgar/mirror/index.d.ts.map +1 -1
- package/dist/services/edgar/mirror/index.js +12 -0
- package/dist/services/edgar/mirror/index.js.map +1 -1
- package/package.json +15 -11
- package/server.json +17 -3
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "secedgar_get_filing now renders every document filename into content[] and embeds a categorized catalog in its not-found errors; fetch_frames and get_institutional_holdings gain offset paging; bare-CIK 404s return declared errors instead of a raw SEC URL; the insider tool's Form 3/5 coverage claim is corrected to Form 4 / 4-A."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.12.5 — 2026-07-26
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`secedgar_fetch_frames` `offset`** — 0-based rank to start the page at over the sorted frame. The response echoes the effective `offset` and carries `next_offset` while companies remain, so ranks past `limit` stay reachable when no canvas is available; the frame is fetched whole and sliced, so paging is contiguous and stable. An offset at or past the reporter count returns an empty page with a `notice` enrichment naming the total. ([#89](https://github.com/cyanheads/secedgar-mcp-server/issues/89))
|
|
12
|
+
- **`secedgar_get_institutional_holdings` `offset`** — the same shape over the ordered position list of one 13F information table, with `offset`/`next_offset` in both `structuredContent` and `format()`. ([#94](https://github.com/cyanheads/secedgar-mcp-server/issues/94))
|
|
13
|
+
- **`entity_not_found` declared error reason** on `secedgar_search_filings` (`NotFound`, -32001) — a `cik:` targeting token on a pre-2001 date range naming a CIK with no EDGAR submissions history. ([#93](https://github.com/cyanheads/secedgar-mcp-server/issues/93))
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- **`formatDocList` renders every filename** — the first `MAX_DOCUMENTS_IN_FORMAT` (10) entries per category keep type/size/description, and the remainder now follow as bare names instead of a `+N more` count. Filenames are the selectable keys for the `document` input, so `content[]` and the uncapped `structuredContent.documents` carry the same catalog. ([#88](https://github.com/cyanheads/secedgar-mcp-server/issues/88))
|
|
18
|
+
- **`document_not_found` and `no_documents` messages carry a catalog** — the new `renderDocumentCatalog` appends a labeled per-category block (capped at `MAX_DOCUMENTS_IN_ERROR` = 10, each line stating the category's true total and how many entries were withheld). Both recovery hints now point at that list rather than at `documents.primary` in error data. ([#88](https://github.com/cyanheads/secedgar-mcp-server/issues/88))
|
|
19
|
+
- **`secedgar_get_financials` `ambiguous_company` message lists the candidates** — CIK, name, and ticker for up to 10 matches are rendered into the message text, not only into `data.matches`. ([#90](https://github.com/cyanheads/secedgar-mcp-server/issues/90))
|
|
20
|
+
- **`secedgar_company_analysis` insider step** — describes `secedgar_get_insider_transactions` as Form 4 / 4-A coverage and routes Form 3 initial statements and Form 5 annual statements to `secedgar_search_filings` (`forms: ["3", "5"]`) plus `secedgar_get_filing`. The same correction lands in the tool table and prose of README, `CLAUDE.md`, `AGENTS.md`, and `.codex-plugin/plugin.json`. ([#92](https://github.com/cyanheads/secedgar-mcp-server/issues/92))
|
|
21
|
+
- **`scripts/clean-mcpb.ts` and `scripts/lint-packaging.ts` handle native bindings** — `NATIVE_BINDING_ENTRY` (`node_modules/@duckdb/node-bindings-*`) is stripped from the packed `.mcpb` alongside the existing agent-doc strip, and `checkBundleEntries` reports the two classes separately. A platform slice would otherwise pin the bundle to its build host and push it past the 25 MB registry cap.
|
|
22
|
+
- **`scripts/devcheck.ts` outdated gate** — `(peer)` rows are skipped (a peer range declares the lowest supported version, not the version to track) and any row where `Update` equals `Current` is no longer a finding, whether held by `minimumReleaseAge` or by a range that deliberately caps below latest. The gate now fails only on being behind within the declared range.
|
|
23
|
+
- **`scripts/check-dependency-specifiers.ts` scans `overrides`** under the strict no-floating rule — an override exists to hold a transitive off a vulnerable version, so a floating specifier there re-resolves the pin it was added to enforce.
|
|
24
|
+
- **`.gitignore`** — `/data/` is anchored to the repo root, replacing the unanchored `data/` rule and the two re-include exceptions that kept `src/services/edgar/data/former-names.json` tracked.
|
|
25
|
+
- **`Dockerfile`** — the optional OTel install runs `bun add --omit=dev --ignore-scripts`.
|
|
26
|
+
- **Skills synced to mcp-ts-core 0.11.0** — `api-canvas`, `api-config`, `api-utils`, `field-test`, `git-wrapup`, `orchestrations` (with its `field-test-fix`, `fix-wrapup-release`, and `maintenance-release` workflows), and `tool-defs-analysis`.
|
|
27
|
+
|
|
28
|
+
## Fixed
|
|
29
|
+
|
|
30
|
+
- **`secedgar_get_insider_transactions` bare-CIK 404** — a numeric CIK absent from the ticker cache resolves to a name-less, ticker-less match whose submissions feed 404s. That 404 is now converted to the declared `company_not_found` with a message pointing at `secedgar_company_search` and naming the accession-number-prefix trap, instead of surfacing the raw SEC URL. A cache-hit or ticker-resolved match that 404s still propagates unchanged. ([#91](https://github.com/cyanheads/secedgar-mcp-server/issues/91))
|
|
31
|
+
- **`secedgar_search_filings` pre-2001 bare-CIK 404** — `serveSubmissionsArchive` resolves the `cik:` token against the ticker cache before fetching, and converts only the bare-CIK 404 into `entity_not_found`. The lookup is confined to the pre-2001 archive arm, leaving the EFTS path untouched. ([#93](https://github.com/cyanheads/secedgar-mcp-server/issues/93))
|
|
32
|
+
|
|
33
|
+
## Dependencies
|
|
34
|
+
|
|
35
|
+
- `@cyanheads/mcp-ts-core` ^0.10.14 → ^0.11.0
|
|
36
|
+
- `@duckdb/node-api` ^1.5.4-r.1 → ^1.5.5-r.1
|
|
37
|
+
- `better-sqlite3` ^12.11.1 → ^13.0.1
|
|
38
|
+
- `typescript` ^6.0.3 → ^7.0.2
|
|
39
|
+
- `@biomejs/biome` ^2.5.2 → ^2.5.5
|
|
40
|
+
- `@types/node` ^26.1.0 → ^26.1.1
|
|
41
|
+
- `ignore` ^7.0.5 → ^7.0.6
|
|
42
|
+
- `tsc-alias` ^1.9.0 → ^1.9.1
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Two new tools — secedgar_get_snapshot (one-call company profile) and secedgar_compare_companies (2-10 companies aligned on calendar periods). Frame dedup and fiscal-period caveats move into shared modules, the local mirror now serves companyfacts, and the fiscal-Q4 caveat is corrected and extended to per-filer series."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.13.0 — 2026-07-26
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`secedgar_get_snapshot`** — one-call financial profile. Reads the filer's whole companyfacts payload once and resolves every concept in the catalog against it, instead of one upstream request per concept. Duration concepts report their latest full year and latest single quarter (`period_type`: `annual` | `quarterly` | `both`); balance-sheet and entity-info concepts report their latest point-in-time value. Concepts the filer does not report land in `gaps` with `tags_tried` — never zero-filled. Declared errors: `company_not_found`, `ambiguous_company`, `no_company_facts`. ([#84](https://github.com/cyanheads/secedgar-mcp-server/issues/84))
|
|
12
|
+
- **`secedgar_compare_companies`** — period-aligned comparison of 2-10 companies across 1-8 concepts, one companyfacts read per company. Instant frames key on the calendar year (annual) or quarter (quarterly) they fall in, so balance-sheet lines sit in the same matrix as income-statement lines while each cell keeps its underlying `frame`. The inline matrix covers up to `periods` (1-12, default 4) and shrinks further at a 120-cell ceiling, disclosed through the `truncated` enrichment; the full aligned series is always registered as `df_<id>`. A company that fails to resolve is reported in `failed_companies` with a `not_found` / `ambiguous` / `no_company_facts` reason and the comparison proceeds with the rest. ([#85](https://github.com/cyanheads/secedgar-mcp-server/issues/85))
|
|
13
|
+
- **`concept-series.ts`** — `resolveFrameSeries` (frame dedup by tag priority, then latest `filed`), `matchesPeriodType`, and `seriesFromCompanyFacts` for whole-company reads. Every tool reading XBRL facts resolves through it, so their numbers agree.
|
|
14
|
+
- **`fiscal-periods.ts`** — `fiscalQ4Caveats(period)` for the cross-company frame view and `missingQuarterCaveats(frames)` for the per-filer series view.
|
|
15
|
+
- **`resolveConceptTarget(input, requestedTaxonomy)`** in `concept-map.ts` — returns the label, tag list, taxonomy, and unit to query. A mapping's own taxonomy wins over the `us-gaap` default; `ifrs-full` uses `ifrsTags` when present; unknown input passes through as a raw tag.
|
|
16
|
+
- **`EdgarMirror.getCompanyFacts(cik)`** — reassembles one filer's whole fact set in companyfacts API shape from its `(cik, taxonomy, tag)` rows, through a new `cik` index created idempotently on open. `tryGetCompanyFacts` routes to it behind `companyFactsReady()` with the live API as the fallback, so `get_snapshot` and `compare_companies` serve from the mirror when it is enabled and synced.
|
|
17
|
+
- **`tests/scripts/bundle-entry-patterns.test.ts`** — asserts `scripts/clean-mcpb.ts` and `scripts/lint-packaging.ts` declare identical `AGENT_DOC_ENTRY` and `NATIVE_BINDING_ENTRY` patterns. A narrower linter pattern would pass a bundle that still ships the entries; a wider one would fail every bundle.
|
|
18
|
+
|
|
19
|
+
## Changed
|
|
20
|
+
|
|
21
|
+
- **`secedgar_get_financials` rebuilt on the shared modules** — the inline dedup, tag-priority collision resolution, period filter, and taxonomy/tag resolution now come from `concept-series.ts` and `resolveConceptTarget`. Output is unchanged apart from the new `caveats` field.
|
|
22
|
+
- **`CompanyFactsResponse` and `CompanyFactsConcept`** in `types.ts` — `tryGetCompanyFacts` returns them instead of `{ facts: Record<string, Record<string, unknown>> }`, and the mirror ingester's `CompanyFactsFile` is now `Partial<CompanyFactsResponse>`.
|
|
23
|
+
- **Server instructions** name `secedgar_get_snapshot` and `secedgar_compare_companies` alongside the existing financials tools.
|
|
24
|
+
- **`changelog/template.md`** — the tag-annotation reference is reconciled to `skills/git-wrapup/SKILL.md` v1.8: headline digest, flat bullets only, one deps line, no gates line, changelog link last.
|
|
25
|
+
|
|
26
|
+
## Fixed
|
|
27
|
+
|
|
28
|
+
- **`secedgar_get_financials` quarterly gap is now named** — a filer whose fiscal Q4 is reported as the 10-K residual has no frame-tagged value for the calendar quarter that fiscal Q4 spans, and the series returned it as a silent hole. Quarterly and `all` results now carry a `caveats` entry naming the absent quarter and how to recover it. Detection reads the frames themselves — no maintained filer list — over the newest 4 years carrying quarterly frames, requiring at least 3 reported quarters in a year for it to count and at least 2 counting years to agree on the same missing quarter. Calendar-year filers are affected as much as off-calendar ones. ([#95](https://github.com/cyanheads/secedgar-mcp-server/issues/95))
|
|
29
|
+
- **`secedgar_fetch_frames` fiscal-Q4 examples grouped by frame span** — the table keyed filers by the calendar quarter their fiscal year closes in, which put January year-ends under Q1. A January year-end closes a fiscal Q4 running Nov–Jan, which SEC frames as calendar Q4. Q1 is now `SJM Apr-end, and other Feb-to-Apr year ends`, Q4 gains `WMT/TGT Jan-end`, and the caveat reads "spans calendar Q*n*" rather than "closes in". ([#97](https://github.com/cyanheads/secedgar-mcp-server/issues/97))
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "revenue no longer resolves through a tag SEC retired in 2018, and any concept falling through to a retired tag says so in caveats. The missing-quarter detector names every absent quarter instead of at most one, binary filing documents are rejected rather than decoded, and ifrs-full coverage goes 3 to 31 of 33 concepts."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.13.1 — 2026-07-26
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`deprecatedTagCaveats(tag, label)`** in `concept-series.ts` — matches SEC's `(Deprecated YYYY-MM-DD)` stamp in the taxonomy label already carried on every companyconcept and companyfacts payload, so the check costs no upstream call. `secedgar_get_financials`, `secedgar_get_snapshot`, and `secedgar_compare_companies` thread it into their `caveats`; the snapshot entry is prefixed with the concept name, the comparison entry with the company and concept. ([#98](https://github.com/cyanheads/secedgar-mcp-server/issues/98))
|
|
12
|
+
- **`binary` on `secedgar_get_filing`'s document entries** — `true` for scanned pages, PDF exhibits, packaged archives, and `Financial_Report.xlsx`, absent for readable entries. Derived from the filename extension, plus a header type of `GRAPHIC` for oddly-named entries. ([#96](https://github.com/cyanheads/secedgar-mcp-server/issues/96))
|
|
13
|
+
- **`binary_document` declared error** on `secedgar_get_filing` — raised from `resolveFilingArchive` before the document body is fetched, naming the entry's inferred type (`GRAPHIC`, `PDF`, `BINARY`) and the readable entries in the same filing. ([#96](https://github.com/cyanheads/secedgar-mcp-server/issues/96))
|
|
14
|
+
- **`ifrs_tags` on `secedgar_search_concepts`** and an `ifrs-full:` line in the `secedgar://concepts` table — the IFRS element set is a different list from `tags`, not a synonym of it, and neither surface showed it. Absent for a concept with no IFRS equivalent. ([#99](https://github.com/cyanheads/secedgar-mcp-server/issues/99))
|
|
15
|
+
|
|
16
|
+
## Changed
|
|
17
|
+
|
|
18
|
+
- **`ifrsTags` coverage 3 → 31 of the 33 concepts** in `concept-map.ts` — every income-statement, balance-sheet, cash-flow, and per-share entry now resolves under `taxonomy: "ifrs-full"`. Each element is confirmed present in a live 20-F filer's companyfacts rather than read off the taxonomy. `notes_payable` stays unmapped (IFRS presents borrowings as one caption, with no notes/debt split) and `shares_outstanding` remains `dei`. Order is semantic the same way `tags` is: `accounts_receivable` leads with the trade-only caption over the combined trade-and-other one, `share_repurchases` with the IAS 7 financing outflow over the treasury-only line a share-cancelling filer tags zero, `interest_expense` with the exact `InterestExpense` counterpart over the broader `FinanceCosts`. ([#99](https://github.com/cyanheads/secedgar-mcp-server/issues/99))
|
|
19
|
+
- **`MIN_QUARTERS_PER_YEAR` 3 → 2** in `fiscal-periods.ts` — two is also the floor at which a year still carries signal, bounding the absent set at two quarters so a stub year reporting one quarter cannot drag a third in. The recency-then-quorum order is unchanged: the newest 4 years carrying quarterly frames are sliced first, then the per-year quorum applies inside that window. ([#100](https://github.com/cyanheads/secedgar-mcp-server/issues/100))
|
|
20
|
+
- **Document catalog sorts readable entries ahead of binary ones** in `secedgar_get_filing`'s error catalogs — the 10-per-category sample was otherwise consumed by scan images on filings that carry hundreds of them, handing back a recovery list of names the caller cannot pass. Stable sort, so order within each half is the filing index's own. Names render as `file.jpg [GRAPHIC, binary]`. ([#96](https://github.com/cyanheads/secedgar-mcp-server/issues/96))
|
|
21
|
+
- **`caveats` and `period_type` field descriptions** on `secedgar_get_financials`, `secedgar_get_snapshot`, and `secedgar_compare_companies` — reworded for the two-quarter case and the new staleness entry.
|
|
22
|
+
|
|
23
|
+
## Fixed
|
|
24
|
+
|
|
25
|
+
- **`revenue` resolved through a tag retired in 2018 for filers reporting gross of assessed tax** — `RevenueFromContractWithCustomerIncludingAssessedTax` is the ASC 606 election used by food, beverage, and tobacco filers, and it was absent from the tag array, so the walk fell past every current tag to `SalesRevenueGoodsNet` and returned a plausible series that stopped years ago. Added at index 2, behind `Revenues` rather than ahead of it: the two disagree for filers that tag gross sales and net-of-excise sales under separate elements, so promoting it over `Revenues` would swap the definition partway back through the history and print a step change that is a tag switch, not a business fact. `RevenueFromContractWithCustomerExcludingAssessedTax` stays at index 0, so a filer reporting both variants still resolves to the net total. ([#98](https://github.com/cyanheads/secedgar-mcp-server/issues/98))
|
|
26
|
+
- **`missingQuarterCaveats` emitted nothing for a filer missing two calendar quarters** — the detector required exactly one absent quarter and at least three reported quarters per counting year, so a filer whose remaining fiscal quarters also span non-calendar durations (holding steady at two frame-tagged quarters a year) tripped neither gate and got no caveat at all. It now reports the full set of consistently-absent quarters, with wording and derivation advice that differ between the one- and two-quarter cases — a single absent quarter is the fiscal-Q4 residual and can be derived as the annual total minus the three reported quarters; two can only be derived together. ([#100](https://github.com/cyanheads/secedgar-mcp-server/issues/100))
|
|
27
|
+
- **`secedgar_get_filing` returned binary documents as decoded text** — `filingToExtract` runs `html-to-text` over whatever bytes arrive and never inspects a content type, so passing a `.jpg`, `.pdf`, `.zip`, or `.xlsx` entry as `document` succeeded with mojibake `content` and a plausible `content_total_length`, no error raised. Detection is filename-only by design: the canonical `GRAPHIC` type lives in the submission header, which the archive path fetches after the document, and requiring it would trade today's parallel header/submissions fetch for a sequential one. The catalog marker alone could not close this — `document` is an unconstrained string — so the guard sits in the fetch path as well. ([#96](https://github.com/cyanheads/secedgar-mcp-server/issues/96))
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Two new tools — secedgar_find_holders (reverse 13F lookup, issuer to the managers reporting it) and secedgar_get_material_events (8-K filings filtered by decoded item code). Series-staleness caveats now cover a current tag whose series simply ends, and ifrs-full stock_based_compensation picks its element per filer by coverage."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.14.0 — 2026-07-26
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`secedgar_find_holders`** — the reverse direction of `secedgar_get_institutional_holdings`: an issuer in, the institutional managers reporting a position out, each row chaining back by `filer_cik`. Matches 13F-HR information tables through EFTS by `cusip` (the identifier the table itself carries) or, without one, by the issuer's EDGAR-conformed name as a phrase. `quarter` defaults to the newest reporting quarter whose 45-day deadline has passed; the search window runs from the day after that quarter end through the end of the next one, and rows are kept by their reported `period_ending`, so amendments restating an older quarter drop out and a manager that amended this quarter is kept once at its latest filing. Up to 500 filings are fetched — EFTS ignores `size` and answers every request with 100 hits, so the budget is 5 `from`-paged requests — with `total_filings` carrying the full count and `dataset.truncated` flagging the rest. The list is unranked and the `ordering` enrichment says so: search relevance carries no signal about position size. Declared errors: `issuer_not_found`, `ambiguous_issuer`. ([#81](https://github.com/cyanheads/secedgar-mcp-server/issues/81))
|
|
12
|
+
- **`secedgar_get_material_events`** — a company's 8-K history with item codes decoded and filterable through `items`, which neither `secedgar_search_filings` nor `secedgar_company_search` can see. `item_distribution` counts every code across the scanned window *before* the filter, so a zero-hit filter returns the codes that are present rather than a dead end. A date window pages into the submissions archive (capped at 10 pages) to reach 8-K filings older than the ~1000-filing recent window, with the depth disclosed as `history_scanned_through`. The full filtered set registers as `df_<id>`, item codes riding as a comma-separated `item_codes` column. Declared errors: `no_match`, `multiple_matches`. ([#82](https://github.com/cyanheads/secedgar-mcp-server/issues/82))
|
|
13
|
+
- **`eight-k-items.ts`** — Form 8-K item decode tables for both numbering regimes, with `decodeEightKItem`, `parseEightKItems`, and `EIGHT_K_ITEM_CODES` backing the `items` input enum. Decoding keys off the code's shape — dotted is the current scheme, a bare integer the one before it — never the filing date, because filers reported pre-changeover events under the old numbers for months after Release 33-8400 took effect on 2004-08-23. A code matching a shape but absent from that regime's table comes back with no label rather than a guess.
|
|
14
|
+
- **`newestReportedPeriod(facts, taxonomy)`** in `concept-series.ts` — the newest standard calendar period a filer reports anywhere in the concept catalog, and the reference `secedgar_get_snapshot` and `secedgar_compare_companies` measure each line against. Reads the whole catalog rather than the requested concepts, or a single-concept comparison would measure a series against itself. Skips the `dei` namespace, whose cover-page facts stay current for a registrant that stopped reporting under the taxonomy. ([#102](https://github.com/cyanheads/secedgar-mcp-server/issues/102))
|
|
15
|
+
- **`preferredTagIndex(units, selection)`** and the `TagSelection` type (`priority` | `coverage`) — `priority` is the default and the existing behavior. Under `coverage` the tag covering the most standard calendar periods for this filer wins, ties broken by declared order, and the losing tags drop out entirely instead of filling the winner's gaps: alternates disagree where they overlap, so a gap-filled series prints a step that is a tag switch rather than a business fact. ([#101](https://github.com/cyanheads/secedgar-mcp-server/issues/101))
|
|
16
|
+
- **`ConceptMapping.ifrsTagSelection`** — opt-in per concept and scoped to `ifrsTags`, since a concept's us-gaap array can be a genuine priority ladder while its IFRS counterparts are alternates. `resolveConceptTarget` returns the resolved `tagSelection` alongside the tags.
|
|
17
|
+
- **`cleanDisplayName`** exported from `edgar-api-service.ts` — the EFTS `display_names[0]` ticker/CIK parenthetical strip, moved out of `search-filings.tool.ts` so `secedgar_find_holders` reads the same clean entity name.
|
|
18
|
+
|
|
19
|
+
## Changed
|
|
20
|
+
|
|
21
|
+
- **`seriesStalenessCaveats(tag, label, newest, reference)`** replaces `deprecatedTagCaveats(tag, label)` — it keeps the retired-tag case and adds the one a taxonomy label cannot mark: a current tag whose series simply ends, which is what a filer migrating to another element or dropping the disclosure looks like. Fires at 730 days behind the reference, two full fiscal years, clear of the ~500 days a healthy annual-only 20-F filer reaches on its own. At most one caveat per line — the retirement stamp wins when both apply, since it names the concrete cause. ([#102](https://github.com/cyanheads/secedgar-mcp-server/issues/102))
|
|
22
|
+
- **`secedgar_get_snapshot` and `secedgar_compare_companies` measure staleness against the filer's own newest reported period**, so a filer that stopped filing altogether — every line equally old — is not flagged concept by concept. `secedgar_get_financials` measures against today, because one companyconcept payload holds no filer-wide period and fetching one would cost an extra upstream call. All three read the full deduped set rather than the period-filtered slice.
|
|
23
|
+
- **`resolveFrameSeries` and `seriesFromCompanyFacts` take a `TagSelection`**, defaulting to `priority`. `seriesFromCompanyFacts` now reports the `tag`, `label`, `description`, and `unit` of the tag that won for the filer rather than the first one to answer — under `coverage` those differ, and describing a series by a tag that lost every frame would misname the values.
|
|
24
|
+
- **`secedgar://filing-types`** carries the full 8-K item tables for both numbering regimes, the current one grouped by its Form 8-K section headings.
|
|
25
|
+
- **Ownership tools cross-link both directions** — `secedgar_get_institutional_holdings`' description, input describe text, `@fileoverview`, and its operating-company `no_filings_found` message, recovery hint, and suggestions now route to `secedgar_find_holders` instead of declaring reverse lookup unsupported. The `secedgar_company_analysis` prompt's Institutional Ownership step chains the two, and its Material Events step targets `secedgar_get_material_events`.
|
|
26
|
+
- **Server instructions** name `secedgar_get_material_events` and both directions of the ownership pair.
|
|
27
|
+
|
|
28
|
+
## Fixed
|
|
29
|
+
|
|
30
|
+
- **`ifrs-full` `stock_based_compensation` resolved a fringe disclosure** — the concept mapped to one IFRS element, `ExpenseFromSharebasedPaymentTransactionsWithEmployees`, and filers split between it and the IFRS 2.51(a) expense total in both directions. SAP returned CY2020 = EUR 46,000,000, a two-period employee-scheme disclosure, in place of its real 11-period series reaching EUR 1,695,000,000; TSM and HSBC returned no data at all. Both elements are now mapped under `ifrsTagSelection: 'coverage'`, so each filer resolves to the one it maintains — no fixed order is right for both, since Sanofi is the exact inversion of SAP. Coverage stays opt-in and `priority` remains the general rule: ranking `revenue` that way would hand Molson Coors either an element SEC retired in 2018 or its gross-of-excise line in place of the continuous net series. ([#101](https://github.com/cyanheads/secedgar-mcp-server/issues/101))
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Two new tools — secedgar_get_beneficial_owners (SCHEDULE 13D/13G blockholders) and secedgar_get_fund_holdings (NPORT-P fund portfolios) — plus bounded pre-2001 full-text and straddling-range merge for secedgar_search_filings."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.0 — 2026-07-27
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`secedgar_get_beneficial_owners`** — 5%-and-over blockholders of an issuer, parsed from the structured SCHEDULE 13D / SCHEDULE 13G XML SEC has required since 2024-12-18. Filters by `form_kind` (13D activist vs. 13G passive) and `include_amendments`; returns each reporting person separately (voting/dispositive power and percent of class are per person, never summed across a joint filing) and reports `legacy_filings_before_coverage` for pre-2024-12-18 text filings the schema can't parse. Full parsed set registers as `df_<id>`, one row per reporting person. New service `src/services/edgar/beneficial-ownership-parser.ts` branches per schema (13D repeats `reportingPersons/reportingPersonInfo`, 13G repeats `coverPageHeaderReportingPersonDetails` with the powers nested and the percentage field named `classPercent`). ([#83](https://github.com/cyanheads/secedgar-mcp-server/issues/83))
|
|
12
|
+
- **`secedgar_get_fund_holdings`** — ETF and mutual fund portfolio holdings from the quarterly NPORT-P report. Resolves a fund ticker, series ID, or registrant CIK to the matching series-scoped filing via EDGAR's company-browse Atom feed (`EdgarApiService.getFundSeriesFilings`, new `resolveFundSeries`/`listFundSeries` backed by a new `bySeriesId` index on the ticker cache); a registrant with more than one listed series throws `series_required` naming the candidates. Positions page largest-first by percent of net assets (`limit`/`offset`); the full report (up to thousands of positions) registers as `df_<id>`. Every result carries `report_period_date` and `publication_lag_days` since NPORT-P publishes on a ~60-day lag. New service `src/services/edgar/nport-parser.ts`. ([#80](https://github.com/cyanheads/secedgar-mcp-server/issues/80))
|
|
13
|
+
- **`secedgar://filing-types`** — added an `NPORT-P` row.
|
|
14
|
+
- **`secedgar_company_analysis`** — a `blockholder`/`activist`/`beneficial`/`13d`/`13g`/`stake` focus area now routes to a `secedgar_get_beneficial_owners` step alongside the existing insider/institutional ones.
|
|
15
|
+
- **`EdgarApiService.tryGetFilingDocumentHead`** — reads a filing document's leading bytes and cancels the stream once a stop marker appears or a byte ceiling is hit, since SEC's archive host ignores `Range` requests; backs the fund-series header scan.
|
|
16
|
+
- **`src/services/edgar/xml-nodes.ts`** — prefix-insensitive tag lookup (`findTag`/`findTags`/`childText`/`childTexts`/`childAttr`) and value coercion (`parseNumber`/`toIsoDate`) shared by both new XML parsers.
|
|
17
|
+
|
|
18
|
+
## Changed
|
|
19
|
+
|
|
20
|
+
- **`secedgar_search_filings`** — pre-2001 entity-scoped free text (`ticker:`/`cik:` with search terms and a date range before 2001-01-01) is now served instead of rejected: the form+date pre-filter selects candidates, up to 50 documents (`DOCUMENT_SCAN_CAP`) are fetched and matched locally against the query (phrases, `OR`, `-exclusion`, `wildcard*`), and the response's new `scan` field reports `candidates`/`scanned`/`matched`/`capped`. A date range straddling 2001-01-01 now auto-splits at the boundary and merges the EFTS (≥2001) and archive (<2001) sides by date, each row keeping its `source` tag; `total`/`total_is_exact` reflect both sides and a new offset/window-gap notice explains the merged list's shape. Replaces the `straddling_date_range` and `pre2001_full_text_scoped` error reasons — `pre2001_full_text_unscoped` (unscoped pre-2001 free text, still unservable) now covers what those two used to reject. ([#87](https://github.com/cyanheads/secedgar-mcp-server/issues/87))
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts @cyanheads/mcp-ts-core 0.12.3: tool inputs are strict, so an undeclared argument key is rejected by name instead of silently dropped. .env.example now defaults MCP_SESSION_MODE to stateless, and the three tools that cap their inline results disclose the cap through enrichment."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.1 — 2026-08-22
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`truncated` / `shown` / `cap` enrichment** on `secedgar_get_filing`, `secedgar_company_search`, and `secedgar_dataframe_query` — a client reading only enrichment now sees that an inline result was capped and by which limit. `secedgar_dataframe_query`'s `cap` names whichever of `preview` or `row_limit` actually bound, and its guidance points at that lever.
|
|
12
|
+
- **`.github/CONTRIBUTING.md` and `.github/CODE_OF_CONDUCT.md`** — contribution workflow and the Contributor Covenant.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **Tool inputs are strict.** An argument key a tool does not declare is rejected by name before the handler runs rather than silently dropped, and each advertised `inputSchema` now carries `additionalProperties: false`. No tool here needed an explicit escape hatch. Inherited from the framework.
|
|
17
|
+
- **`.env.example` sets `MCP_SESSION_MODE=stateless`** as an active default rather than a commented-out `stateful` ([#108](https://github.com/cyanheads/secedgar-mcp-server/issues/108)). An HTTP consumer running from a copied `.env.example` no longer receives an `Mcp-Session-Id` on `initialize`; the published container already set the variable, so it and the hosted deployment are unchanged.
|
|
18
|
+
- **`secedgar_get_insider_transactions`** — rendered text carries one direction legend instead of repeating the `acquire`/`dispose` enum on every row.
|
|
19
|
+
- **`secedgar_get_filing`'s `outline`** — the description states the 50-heading ceiling `detectHeadings` already applied.
|
|
20
|
+
- **Security contact is `security@caseyjhand.com`** in `.github/SECURITY.md`.
|
|
21
|
+
- **Docker builds on Bun 1.4.0**, with the build stage pinned to `$BUILDPLATFORM` — Bun's JavaScriptCore aborts under QEMU, so a cross-arch build of that stage failed outright. The OTel install passes `--omit=peer`.
|
|
22
|
+
- **`tsconfig.json` typechecks `tests/` alongside `src/`** under `noEmit`; emission moves to `tsconfig.build.json`, which keeps `rootDir: src`. `tests/support/assertions.ts` holds the narrowing helpers the suite needs under `noUncheckedIndexedAccess`.
|
|
23
|
+
- **`bundle` invokes `npx`** instead of `bunx`, and `packageManager` is `bun@1.4.0`.
|
|
24
|
+
|
|
25
|
+
## Fixed
|
|
26
|
+
|
|
27
|
+
- **`bun run tree` honors directory-only `.gitignore` patterns.** `isIgnored` takes the entry's `Dirent` flag and tests `<path>/` for a directory, which is the only form a pattern like `/data/` matches.
|
|
28
|
+
|
|
29
|
+
## Dependencies
|
|
30
|
+
|
|
31
|
+
- `@cyanheads/mcp-ts-core` ^0.11.0 → ^0.12.3
|
|
32
|
+
- `@duckdb/node-api` ^1.5.5-r.1 → ^1.5.5-r.4
|
|
33
|
+
- `better-sqlite3` ^13.0.1 → ^13.0.3
|
|
34
|
+
- `html-to-text` ^10.0.0 → ^10.0.1
|
|
35
|
+
- `@biomejs/biome` ^2.5.5 → ^2.5.9 (dev)
|
|
36
|
+
- `@types/node` ^26.1.1 → ^26.2.0 (dev)
|
|
37
|
+
- `tsc-alias` ^1.9.1 → ^1.9.2 (dev)
|
|
38
|
+
- `vitest` ^4.1.10 → ^4.1.11 (dev)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts @cyanheads/mcp-ts-core 0.12.5. An SEC 5xx now classifies as ServiceUnavailable rather than InternalError, a caller disconnect as RequestCancelled, and server identity resolves from the served package instead of the launching client's working directory. No changes to this server's own source."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.2 — 2026-09-02
|
|
8
|
+
|
|
9
|
+
Framework adoption and dependency updates — this server's own source is unchanged.
|
|
10
|
+
|
|
11
|
+
## Changed
|
|
12
|
+
|
|
13
|
+
- **An SEC 5xx surfaces as `ServiceUnavailable` instead of `InternalError`.** `EdgarApiService` classifies every non-OK SEC response through the framework's `httpErrorFromResponse`, which no longer maps 500 or 501 to a code asserting that this server failed. A client branching on `InternalError` for an upstream EDGAR outage must move to `ServiceUnavailable`.
|
|
14
|
+
- **A caller that disconnects mid-call classifies as `RequestCancelled` (-32011)** rather than `InternalError` or `Timeout`. It is a baseline code, so no tool declares it and it is never retried.
|
|
15
|
+
|
|
16
|
+
## Fixed
|
|
17
|
+
|
|
18
|
+
- **Server identity resolves from the served package, not the launching client's working directory.** `createApp` declares only `name` and `title` here, so the advertised version, description, and keywords are read from this package's `package.json` on every launch path (`npx`, `.mcpb`, a client config naming `dist/index.js`).
|
|
19
|
+
- **Records logged from `setup()` are no longer dropped** — the EDGAR mirror's refresh-scheduling messages (`EDGAR_MIRROR_REFRESH_CRON` under the HTTP transport) are buffered and replayed once the logger initializes.
|
|
20
|
+
- **The README's MCP SDK badge reads `^2.0.0`**, matching the `@modelcontextprotocol/server` range the framework depends on; it had been left at `^1.29.0`.
|
|
21
|
+
|
|
22
|
+
## Dependencies
|
|
23
|
+
|
|
24
|
+
- `@cyanheads/mcp-ts-core` ^0.12.3 → ^0.12.5
|
|
25
|
+
- `zod` ^4.4.3 → ^4.5.4
|
|
26
|
+
- `@biomejs/biome` ^2.5.9 → ^2.5.11 (dev)
|
|
27
|
+
- `@types/node` ^26.2.0 → ^26.4.0 (dev)
|
|
28
|
+
- `ignore` ^7.0.6 → ^7.0.7 (dev)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Fixes four EDGAR resolution gaps: corporate-suffix name matching, dotted share-class tickers, ticker near-match suggestions, and a 429 that retried into SEC's ten-minute rate-limit block. Adopts mcp-ts-core 0.12.8 plus dependency refresh."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.3 — 2026-09-09
|
|
8
|
+
|
|
9
|
+
## Fixed
|
|
10
|
+
|
|
11
|
+
- **`secedgar_company_search` name matching now normalizes the terminal corporate-suffix token** (`Beacon Financial Corporation` matches registry entry `Beacon Financial Corp`), while keeping `Corp`, `Inc`, `Co`, and `Ltd` as four separate buckets so real registrants differing only by suffix (`TORO CO` vs `TORO CORP.`) stay distinct ([#107](https://github.com/cyanheads/secedgar-mcp-server/issues/107)).
|
|
12
|
+
- **Dotted share-class tickers (`BRK.B`) now resolve** via SEC's hyphenated form (`BRK-B`) in `secedgar_company_search` and `secedgar_search_filings`'s `ticker:` targeting ([#110](https://github.com/cyanheads/secedgar-mcp-server/issues/110)).
|
|
13
|
+
- **A zero-hit ticker query now returns near-ticker suggestions** (`CSWI` → `CSW`), scored alongside name suggestions in one ranked list; the `no_match` recovery message is unified for both ticker- and name-shaped misses ([#111](https://github.com/cyanheads/secedgar-mcp-server/issues/111)).
|
|
14
|
+
- **A 429 from SEC no longer retries into its ten-minute rate-limit block.** `EdgarApiService` fails fast on the first 429 with a `recovery` hint naming the cool-down, and SEC's raw HTML block page is no longer captured into `data.body` ([#112](https://github.com/cyanheads/secedgar-mcp-server/issues/112)).
|
|
15
|
+
|
|
16
|
+
## Dependencies
|
|
17
|
+
|
|
18
|
+
- `@cyanheads/mcp-ts-core` ^0.12.5 → ^0.12.8
|
|
19
|
+
- `@biomejs/biome` ^2.5.11 → ^2.5.12 (dev)
|
|
20
|
+
- `ignore` ^7.0.7 → ^7.0.8 (dev)
|
|
21
|
+
- `tsc-alias` ^1.9.2 → ^1.9.4 (dev)
|
|
22
|
+
- `vitest` ^4.1.11 → ^5.0.0 (dev)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Fixes secedgar_get_filing's heading outline and section matching: 20-F filings with bare Item markers and running page headers now produce a full outline of all Items and Parts, and section now resolves headings whose whitespace or quote style differs from the caller's input."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.4 — 2026-09-09
|
|
8
|
+
|
|
9
|
+
## Fixed
|
|
10
|
+
|
|
11
|
+
- **`detectHeadings`'s all-caps arm now matches horizontal whitespace only**, so a run of consecutive all-caps lines (a "TABLE OF CONTENTS" header directly above "PART I") no longer fuses into one composite entry ([#105](https://github.com/cyanheads/secedgar-mcp-server/issues/105)).
|
|
12
|
+
- **A bare `Item N` marker with its title on a following line is now detected and joined to it** — the shape every Item takes in a 20-F — deduplicated against its TOC occurrence, with the suffix widened to `16A`–`16K` and the trailing period made optional. On a C3is FY2025 20-F the outline went from 15 entries (zero Items) to 42, covering all 30 Items and 3 Parts ([#105](https://github.com/cyanheads/secedgar-mcp-server/issues/105)).
|
|
13
|
+
- **A heading repeated 5+ times at distinct offsets is now treated as a running page header**: a bare marker (`Item 1`, `PART I`) drops every occurrence, and any other repeated heading keeps only its first — at most one entry per running header ([#105](https://github.com/cyanheads/secedgar-mcp-server/issues/105)).
|
|
14
|
+
- **`secedgar_get_filing`'s `section` match now folds Unicode whitespace and typographic quotes on both operands**, so a heading copied from the rendered outline resolves whether its NBSP runs or curly quotes were normalized to plain characters or not ([#106](https://github.com/cyanheads/secedgar-mcp-server/issues/106)).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Registers the gated dataframe-drop tool as discoverable-but-disabled, adds a describe-then-query pointer across every dataframe-producing tool, and fixes secedgar_dataframe_query's row_limit-bound truncation disclosure with a new row_count_capped field."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.5 — 2026-09-09
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`secedgar_dataframe_query`** gains `row_count_capped` — `true` when `row_limit` bound the query, so `row_count` is that cap rather than a total ([#109](https://github.com/cyanheads/secedgar-mcp-server/issues/109)).
|
|
12
|
+
|
|
13
|
+
## Changed
|
|
14
|
+
|
|
15
|
+
- **`secedgar_dataframe_drop`** now registers through `disabledTool()` when `EDGAR_DATAFRAME_DROP_ENABLED` is off — still absent from `tools/list` and uncallable, but shown on the HTTP landing page as disabled, with its reason and enable hint (the Server Card at `/.well-known/mcp.json` carries no per-tool list) ([#103](https://github.com/cyanheads/secedgar-mcp-server/issues/103)).
|
|
16
|
+
- **Every dataframe-producing tool** now names both `secedgar_dataframe_describe` and `secedgar_dataframe_query`, describe-then-query, in its tool description, `dataset.name` field, and runtime guidance whenever a `df_<id>` handle is staged; `secedgar_get_financials` and `secedgar_compare_companies` gained a `notice` enrichment field so that guidance actually reaches the wire instead of being stripped ([#104](https://github.com/cyanheads/secedgar-mcp-server/issues/104)).
|
|
17
|
+
- `secedgar_dataframe_describe` and `secedgar_dataframe_query`'s descriptions replace their stale producer enumeration (5 and 3 of 11 named) with a shape description ([#104](https://github.com/cyanheads/secedgar-mcp-server/issues/104)).
|
|
18
|
+
|
|
19
|
+
## Fixed
|
|
20
|
+
|
|
21
|
+
- **`secedgar_dataframe_query`** now discloses truncation when `row_limit` alone bound the result — previously `rowCount === rows.length` on that path hid the cap entirely. The guidance and `format()` output name the cap rather than claiming a false total ([#109](https://github.com/cyanheads/secedgar-mcp-server/issues/109)).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts mcp-ts-core through 0.13.2: HTTP sessions resolve stateless by default, shutdown closes the EDGAR mirror, and a linear-time SQL comment stripper replaces a regex a crafted query could hang on. Plugin manifests now deliver EDGAR_USER_AGENT correctly, and an empty or placeholder value fails startup instead of running blank."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.6 — 2026-09-16
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`createApp({ teardown })` closes the EDGAR mirror's SQLite handles on shutdown** ([cyanheads/mcp-ts-core#435](https://github.com/cyanheads/mcp-ts-core/issues/435)) — `EdgarMirror.close()` existed but nothing called it.
|
|
12
|
+
- **The Server Card publishes the resolved session mode** under the `_meta` key `io.github.cyanheads.mcp-ts-core/sessionMode` ([cyanheads/mcp-ts-core#387](https://github.com/cyanheads/mcp-ts-core/issues/387)) — `stateless` or `stateful`, never `auto`.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **`MCP_SESSION_MODE` unset now resolves `stateless`** from `createApp({ sessionMode })` ([cyanheads/mcp-ts-core#376](https://github.com/cyanheads/mcp-ts-core/issues/376)) — previously fell through the schema default `auto` to `stateful`; an exported `MCP_SESSION_MODE` still overrides. The Docker image and `.env.example` already set `stateless`, so a container deployment is unchanged.
|
|
17
|
+
- **`SIGTERM`/`SIGINT` now end the process explicitly** ([cyanheads/mcp-ts-core#435](https://github.com/cyanheads/mcp-ts-core/issues/435)) — exit `0` once shutdown settles, `1` when the 10s ceiling fires.
|
|
18
|
+
- **The framework skill tree moved from `skills/` to `framework-skills/`** ([cyanheads/mcp-ts-core#428](https://github.com/cyanheads/mcp-ts-core/issues/428)) — installing the Claude Code or Codex plugin no longer loads the server's development skills into the agent.
|
|
19
|
+
- **README restructured** — a new `## Overview` section replaces the bare `## Tools` opener, and every tool, resource, and prompt now has its own `### <name> <sub>tool|resource|prompt</sub>` entry under one `## Capability reference` section rather than separate `## Resources`/`## Prompts` sections.
|
|
20
|
+
- **Issue templates** — bug and feature forms auto-assign `cyanheads` and add secondary-label guidance (`regression`, `performance`, `security`, `breaking-change`, `surplus-token-idea`); `config.yml` allows blank issues and links a private security-advisory form.
|
|
21
|
+
- `bun run audit:fix` added (`bun audit fix`) — the first move when `devcheck` flags an advisory; the npm tarball's `files` also now ships `changelog/`, `CLAUDE.md`, and `AGENTS.md`.
|
|
22
|
+
- `.env.example` documents `MCP_HTTP_HOST`'s default as `127.0.0.1` (previously said `localhost`).
|
|
23
|
+
|
|
24
|
+
## Fixed
|
|
25
|
+
|
|
26
|
+
- **An empty `EDGAR_USER_AGENT=` or a whole-value unsubstituted `${…}` placeholder now reads as unset** ([cyanheads/mcp-ts-core#427](https://github.com/cyanheads/mcp-ts-core/issues/427)) — startup fails naming the missing variable instead of running with a blank `User-Agent` header.
|
|
27
|
+
- **`.claude-plugin/plugin.json` now delivers `EDGAR_USER_AGENT`** — declares `userConfig.EDGAR_USER_AGENT` (required) and passes `${user_config.EDGAR_USER_AGENT}`; it previously had no `userConfig`, so Claude Code couldn't prompt for the value and only an already-exported variable reached the server.
|
|
28
|
+
- **`.codex-plugin/mcp.json` now lists `EDGAR_USER_AGENT` in `env_vars`** — Codex's whitelisted child environment never delivered it before; `.codex-plugin/plugin.json`'s `interface.category` is now `finance` (was empty).
|
|
29
|
+
|
|
30
|
+
## Security
|
|
31
|
+
|
|
32
|
+
- **`secedgar_dataframe_query` SQL now passes through a linear-time comment stripper** ([cyanheads/mcp-ts-core#431](https://github.com/cyanheads/mcp-ts-core/issues/431)) — the framework canvas gate's comment stripper was a polynomial-time regex; a crafted statement up to the 1 MiB request-body cap could pin the event loop for minutes.
|
|
33
|
+
|
|
34
|
+
## Dependencies
|
|
35
|
+
|
|
36
|
+
- `@cyanheads/mcp-ts-core` ^0.12.8 → ^0.13.2
|
|
37
|
+
- `zod` ^4.5.4 → ^4.6.4
|
|
38
|
+
- `@biomejs/biome` ^2.5.12 → ^2.5.13 (dev)
|
|
39
|
+
- `ignore` ^7.0.8 → ^7.0.9 (dev)
|
|
40
|
+
- `tsc-alias` ^1.9.4 → ^1.9.5 (dev)
|
|
41
|
+
- `@types/node` ^26.4.0 → ^26.5.1 (dev)
|
|
42
|
+
- Bun engines floor `>=1.3.0` → `>=1.4.0`
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "After a 429, calls are refused locally for SEC's cool-down instead of each reaching SEC and restarting its block. company/filed_after/filed_before/forms replace ticker_or_cik/start_date/end_date/form_types, old spellings accepted as aliases. secedgar_dataframe_query fixes a backslash-escaping bug and gains a fuller SQL error contract."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.15.7 — 2026-09-21
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **SEC rate-limit block gate** ([#116](https://github.com/cyanheads/secedgar-mcp-server/issues/116)) — after SEC answers a 429, nothing more is sent to SEC for `EDGAR_RATE_LIMIT_COOLDOWN_SECONDS` (default `600`): calls fail locally with reason `rate_limited` and `retryAfter` set to the seconds remaining, the first call after the cool-down goes out alone as a probe, and mirror-served reads keep answering throughout. A 429 is still never retried. `rate_limited` is declared, `thrownBy: 'service'`, on every tool that reaches SEC.
|
|
12
|
+
- **`EDGAR_RATE_LIMIT_COOLDOWN_SECONDS`** env var (default `600`) — documented in `.env.example`, `manifest.json`, and `server.json`.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **One parameter name per concept, with the other spellings accepted as aliases** ([#115](https://github.com/cyanheads/secedgar-mcp-server/issues/115)) — `company` replaces `ticker_or_cik` on `secedgar_get_insider_transactions` and `secedgar_get_institutional_holdings`; `filed_after`/`filed_before` replace `start_date`/`end_date` on `secedgar_search_filings`; `forms` replaces `form_types` on `secedgar_company_search`. Every tool carrying one of those keys declares `inputAliases` for the retired spelling, each sibling tool's spelling, and `ticker`/`cik`/`date_from`/`date_to`, so a name carried over from another tool is never rejected. Dataframe provenance (`query_params` in `secedgar_dataframe_describe`) now records the canonical names.
|
|
17
|
+
- **Server `instructions` rewritten**, shorter and less repetitive across tool mentions.
|
|
18
|
+
- **mcp-ts-core 0.13.3–0.13.6 adoption**: an argument rejection carries reason `invalid_arguments` and a `Recovery:` line derived from the schema, naming the accepted keys when a key is unknown (0.13.3, [cyanheads/mcp-ts-core#445](https://github.com/cyanheads/mcp-ts-core/issues/445)); `_meta`, `tool_call_description`, and `toolCallId` are dropped from arguments rather than rejected, a case-style key variant (e.g. `Company`) resolves to its declared key, and a JSON-stringified array is repaired against the schema (0.13.4, [cyanheads/mcp-ts-core#453](https://github.com/cyanheads/mcp-ts-core/issues/453), [cyanheads/mcp-ts-core#452](https://github.com/cyanheads/mcp-ts-core/issues/452), [cyanheads/mcp-ts-core#234](https://github.com/cyanheads/mcp-ts-core/issues/234)); tool error text now closes with `(reason <reason>)`, adding `· retryable` or `· not retryable` when the error carries a `retryable` flag (0.13.5, [cyanheads/mcp-ts-core#458](https://github.com/cyanheads/mcp-ts-core/issues/458)).
|
|
19
|
+
- `.env.example`'s framework block synced with the template — comments reworded, newly documented variables (`MCP_HTTP_RESUMABILITY*`, `MCP_GC_PRESSURE_INTERVAL_MS`, `MCP_LOG_RATE_LIMIT_*`) added; `MCP_SESSION_MODE` stays `stateless`.
|
|
20
|
+
- `devcheck.config.json` gains a `lint` block; `scripts/lint-mcp.ts` reads `lint.truncationAllowlist` from it (a declared value wins over `MCP_LINT_TRUNCATION_ALLOWLIST`), and now guards its `main()` behind an entrypoint check so it's importable without executing.
|
|
21
|
+
- Added `.github/workflows/codeql.yml` — the one GitHub Actions workflow this project carries; CodeQL is GitHub-owned end to end and the file only runs while the repo's CodeQL default setup is off.
|
|
22
|
+
- Framework skills (`framework-skills/`), `changelog/template.md`, and the issue-report forms synced to the current framework template.
|
|
23
|
+
|
|
24
|
+
## Fixed
|
|
25
|
+
|
|
26
|
+
- **`secedgar_dataframe_query` table cells now escape backslashes before pipes** ([#114](https://github.com/cyanheads/secedgar-mcp-server/issues/114)) — a backslash already in a cell value was left unescaped, so a Markdown renderer read it as an escape and `content[]` rendered `x\|y` as `x|y` and `a\*b` as `a*b`; the header row gets the same escaping as data cells, which it previously skipped entirely.
|
|
27
|
+
- **A SELECT that prepares and then fails on the data it reads** (a bad cast, an out-of-range value) now returns `ValidationError` with reason `sql_execution_error` instead of an unreasoned `DatabaseError` (mcp-ts-core 0.13.4, [cyanheads/mcp-ts-core#451](https://github.com/cyanheads/mcp-ts-core/issues/451)). `multi_statement`, `denied_function`, and `plan_operator_not_allowed` are now declared on the tool's error contract alongside the framework's own recovery hints for each.
|
|
28
|
+
|
|
29
|
+
## Dependencies
|
|
30
|
+
|
|
31
|
+
- `@cyanheads/mcp-ts-core` ^0.13.2 → ^0.13.6
|
|
32
|
+
- `@duckdb/node-api` ^1.5.5-r.4 → ^1.5.5-r.5
|
|
33
|
+
- `zod` ^4.6.4 → ^4.6.5
|
|
34
|
+
- `@biomejs/biome` ^2.5.13 → ^2.5.14 (dev)
|
|
35
|
+
- `@types/node` ^26.5.1 → ^26.6.2 (dev)
|
|
36
|
+
- `vitest` ^5.0.0 → ^5.0.1 (dev)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Concept discovery, filing lookup resilience, and framework sync."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.2.0 — 2026-04-17
|
|
7
|
+
|
|
8
|
+
Concept discovery, filing lookup resilience, and framework sync.
|
|
9
|
+
|
|
10
|
+
## Added
|
|
11
|
+
|
|
12
|
+
- Added `secedgar_search_concepts` for browsing friendly XBRL names, filtering by statement group or taxonomy, and reverse-looking up raw tags
|
|
13
|
+
- Added `AGENTS.md` and the `add-app-tool` skill to align the repo with current framework conventions
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- Updated `@cyanheads/mcp-ts-core` from `^0.2.10` to `^0.3.5`
|
|
18
|
+
- Updated dev tooling: `@biomejs/biome` `^2.4.10→^2.4.12`, `@types/node` `^25.5.0→^25.6.0`, `typescript` `^6.0.2→^6.0.3`, `vitest` `^4.1.2→^4.1.4`
|
|
19
|
+
- Added statement-group metadata to concept mappings and refreshed the README, agent docs, tree doc, and skills for the six-tool surface
|
|
20
|
+
|
|
21
|
+
## Fixed
|
|
22
|
+
|
|
23
|
+
- Improved `secedgar_get_filing` when CIK is omitted by resolving candidate CIKs from SEC search metadata and handling missing documents more reliably
|
|
24
|
+
- Serialized EDGAR throttling so concurrent requests cannot bypass the configured inter-request delay
|
|
25
|
+
- Preserved sparse upstream EDGAR data as optional fields in filing and financial responses, with clearer not-found behavior for concept and frame lookups
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework upgrade, content parity across tools, and cleaner entity names."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.3.0 — 2026-04-20
|
|
7
|
+
|
|
8
|
+
Framework upgrade, content parity across tools, and cleaner entity names.
|
|
9
|
+
|
|
10
|
+
## Changed
|
|
11
|
+
|
|
12
|
+
- Updated `@cyanheads/mcp-ts-core` from `^0.3.5` to `^0.5.3`
|
|
13
|
+
- Updated `format()` output across all six tools so every terminal field in the output schema renders in the markdown twin, satisfying the framework's new `format-parity` linter — clients reading `content[]` now see the same data as clients reading `structuredContent`
|
|
14
|
+
- Stripped trailing `(TICKER)` and `(CIK …)` parentheticals from `company_name` in `secedgar_search_filings` results — ticker and CIK are already separate fields, so the duplicate was removed from both `structuredContent` and rendered text
|
|
15
|
+
- `secedgar_get_financials` and `secedgar_get_filing` now always render `tags_tried` and the filing document list when present (previously hidden for single-entry cases)
|
|
16
|
+
- Refreshed project skills from the package (`add-tool` 1.3→1.6, `api-config` 1.1→1.2, `design-mcp-server` 2.2→2.4, `field-test` 1.1→1.2, `maintenance` 1.2→1.3, `polish-docs-meta` 1.3→1.4, `setup` 1.2→1.3) and propagated to `.claude/skills/` and `.agents/skills/`
|
|
17
|
+
- Bumped MCP SDK badge in README to `^1.29.0`
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework upgrade to @cyanheads/mcp-ts-core 0.7.0, shared SEC fetch path with retry on filing document downloads, and the lint-warning cleanup that framework 0.6.16 surfaced."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.4.0 — 2026-04-24
|
|
7
|
+
|
|
8
|
+
Framework upgrade to `@cyanheads/mcp-ts-core` 0.7.0, shared SEC fetch path with retry on filing document downloads, and the lint-warning cleanup that framework 0.6.16 surfaced.
|
|
9
|
+
|
|
10
|
+
## Changed
|
|
11
|
+
|
|
12
|
+
- Updated `@cyanheads/mcp-ts-core` from `^0.5.3` to `^0.7.0` (covers 0.5.4 through 0.7.0 — directory-based changelog system, landing page + SEP-1649 Server Card at `/.well-known/mcp.json`, `MCP_PUBLIC_URL` override for TLS-terminating proxies, flattened ZodError messages with structured `issues`, locale-aware format-parity, new `describe-on-fields` recursion, HTTP transport hardening, and more)
|
|
13
|
+
- Updated dev tooling: `@biomejs/biome` `^2.4.12→^2.4.13`, `vitest` `^4.1.4→^4.1.5`
|
|
14
|
+
- Refactored `EdgarApiService` to share a single `rawFetch` across JSON and text fetches. Filing document downloads (`fetchText` / `tryFetchText`) now retry on 429 / 500 / 502 / 503 / 504 with exponential backoff — previously they bypassed the retry loop and failed immediately on transient upstream errors. Retryable status codes hoisted to a `RETRYABLE_STATUSES` Set
|
|
15
|
+
- Added `.describe()` on the array-element `z.object({...})` in every tool's output schema (`company-search` filings, `compare-metric` data, `get-filing` documents, `get-financials` data, `search-concepts` concepts, `search-filings` results) — satisfies the new recursive `describe-on-fields` linter
|
|
16
|
+
- Refreshed all project skills from the package; most external skills bumped (`add-tool` 1.6→1.8, `design-mcp-server` 2.4→2.7, `field-test` 1.2→2.0, `maintenance` 1.3→1.5, `polish-docs-meta` 1.4→1.7, `setup` 1.3→1.5, `report-issue-local` / `report-issue-framework` 1.1→1.3, and others). Skills also re-synced to `.claude/skills/` and `.agents/skills/`
|
|
17
|
+
- Synced framework `scripts/` additions: `build-changelog.ts`, `check-docs-sync.ts`, `check-skills-sync.ts`. The latter two back new devcheck steps that verify `CLAUDE.md` ↔ `AGENTS.md` and `skills/` ↔ agent-dir mirrors stay aligned
|
|
18
|
+
- CLAUDE.md / AGENTS.md skills table updated with `api-linter`, `release-and-publish`, and `security-pass`; agent-skill-directory guidance now references the `maintenance` skill's automatic Phase-B sync. AGENTS.md realigned byte-identical to CLAUDE.md for the new `Docs Sync` devcheck step
|
|
19
|
+
|
|
20
|
+
## Added
|
|
21
|
+
|
|
22
|
+
- Three new skills adopted from the framework: `api-linter` (v1.1) — definition-lint rule reference; `release-and-publish` (v2.1) — post-wrapup ship workflow across npm / MCP Registry / GHCR with transient-failure retries; `security-pass` (v1.1) — eight-axis MCP-flavored security audit
|
|
23
|
+
- Documented `MCP_PUBLIC_URL` in `.env.example` and surfaced it in `server.json` — public-facing origin override for deployments behind TLS-terminating reverse proxies (Cloudflare Tunnel, Caddy, nginx)
|
|
24
|
+
- Tracked `.github/ISSUE_TEMPLATE/` (bug_report, feature_request, config) that were previously on disk but untracked
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework upgrade to @cyanheads/mcp-ts-core 0.8.7 with full typed-error-contract adoption, two domain bug fixes against issues #1 and #2, and skill / script syncs."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.4.1 — 2026-04-30
|
|
7
|
+
|
|
8
|
+
Framework upgrade to `@cyanheads/mcp-ts-core` 0.8.7 with full typed-error-contract adoption, two domain bug fixes against issues [#1](https://github.com/cyanheads/secedgar-mcp-server/issues/1) and [#2](https://github.com/cyanheads/secedgar-mcp-server/issues/2), and skill / script syncs.
|
|
9
|
+
|
|
10
|
+
## Fixed
|
|
11
|
+
|
|
12
|
+
- **`secedgar_get_financials` no longer throws on default invocation for balance-sheet concepts** ([#1](https://github.com/cyanheads/secedgar-mcp-server/issues/1)) — `period_type` is now optional. The handler computes the effective default from the resolved concept's mapping group: balance-sheet items default to `'all'` (so instant frames `CYxxxxQxI` aren't filtered out), every other group keeps the previous `'annual'` default. Bare calls for `assets`, `liabilities`, `equity`, `cash`, `debt` now return data instead of a recovery hint. Income-statement defaults are unchanged.
|
|
13
|
+
- **`EdgarApiService` HTTP errors now classify by status** — `rawFetch` uses `httpErrorFromResponse` from `@cyanheads/mcp-ts-core/utils`, mapping 401/403/408/422/429/5xx to the correct `JsonRpcErrorCode` and capturing body + `Retry-After` into `error.data`. The `EDGAR_USER_AGENT` hint for 403 is preserved as a structured `data.recovery.hint`. 404 paths in `fetchJson` / `fetchText` now throw `notFound` instead of `serviceUnavailable` — semantically correct.
|
|
14
|
+
|
|
15
|
+
## Added
|
|
16
|
+
|
|
17
|
+
- **Typed error contracts on five tools** — `company_search`, `search_filings`, `get_filing`, `get_financials`, `compare_metric` declare `errors[]` arrays per the framework's 0.8.0 contract pattern. Twelve declared reasons total (`no_match`, `multiple_matches`, `invalid_date_range`, `document_not_found`, `no_documents`, `filing_not_found`, `company_not_found`, `no_concept_data`, `no_frame_data`, `no_period_data`, `unknown_concept`, `no_data`), each with a ≥5-word `recovery` string. Handlers throw via `ctx.fail(reason, msg, { ...ctx.recoveryFor(reason) })`; the `get_filing` archive helper carries reasons via `data: { reason }` per the 0.8.1 service-layer pattern. Error responses now mirror `data.recovery.hint` into `content[]` text per 0.8.3's parity invariant — clients see the same recovery guidance whether they read `structuredContent` or `content[]`.
|
|
18
|
+
- **Two new friendly XBRL concept names** ([#2](https://github.com/cyanheads/secedgar-mcp-server/issues/2)) — `depreciation_amortization` (tags: `DepreciationDepletionAndAmortization`, `DepreciationAndAmortization`, `Depreciation`) and `notes_payable` (tags: `LongTermNotesPayable`, `NotesPayable`, `LongTermDebt`). The multi-tag fallback chain handles cross-filer variation observed in production traffic for D&A across LMT / NOC / GD.
|
|
19
|
+
- **`bun run start` script** — bare `.env`-respecting transport script for hosted MCP runners (template change adopted from framework 0.7.6).
|
|
20
|
+
|
|
21
|
+
## Changed
|
|
22
|
+
|
|
23
|
+
- **`@cyanheads/mcp-ts-core` `^0.7.0` → `^0.8.7`** (1 minor + 8 patches: typed error contracts, `ctx.fail` / `ctx.recoveryFor` helpers, `httpErrorFromResponse` utility, error-path parity, framework-antipatterns devcheck step, security hardening for HTTP origin guard / landing auth / log scrubbing, vitest config `.mjs` fix, and skill drift fixes).
|
|
24
|
+
- **`html-to-text` `^9.0.5` → `^10.0.0`** — maintenance major release; minimum Node bumped to 20.19+ (project already requires ≥22), no API breaks.
|
|
25
|
+
- **Dropped `dev:stdio` / `dev:http` watch scripts** from `package.json` (template cleanup adopted from framework 0.8.6 — smoke tests now run via `bun run rebuild && bun run start:stdio`).
|
|
26
|
+
- **Errors section in `CLAUDE.md` / `AGENTS.md`** rewritten to lead with the typed-contract pattern; checklist updated to require `recovery` strings (≥5 words) and `createMockContext({ errors: tool.errors })` for tests with declared contracts.
|
|
27
|
+
- **Refreshed all project skills from the package** (12 updated: `add-service` 1.3→1.5, `add-tool` 1.8→2.4, `api-context` 1.1→1.2, `api-errors` 1.0→1.4, `api-linter` 1.1→1.2, `design-mcp-server` 2.7→2.8, `field-test` 2.0→2.3, `maintenance` 1.5→2.0, `release-and-publish` 2.1→2.2, `report-issue-framework` 1.3→1.4, `security-pass` 1.1→1.2, `setup` 1.5→1.6). Re-synced into `.claude/skills/` and `.agents/skills/`.
|
|
28
|
+
- **Synced framework `scripts/` additions** — `check-framework-antipatterns.ts` (new devcheck step) and `split-changelog.ts`.
|
|
29
|
+
|
|
30
|
+
## Tests
|
|
31
|
+
|
|
32
|
+
- All five tool test files thread `createMockContext({ errors: tool.errors })` so `ctx.fail` is wired against the contract's reasons.
|
|
33
|
+
- Two new regression tests for issue [#1](https://github.com/cyanheads/secedgar-mcp-server/issues/1) — bare `concept: 'assets'` returns data; explicit `period_type: 'annual'` against a balance-sheet item still surfaces the structured `no_period_data` recovery hint.
|
|
34
|
+
- Two new tests in `concept-map.test.ts` lock the tag ordering for `depreciation_amortization` and `notes_payable`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework bump to @cyanheads/mcp-ts-core 0.8.13; secedgar_get_filing now routes its three contract reasons through ctx.fail in the archive-resolution helper for full lint conformance."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.4.2 — 2026-05-04
|
|
7
|
+
|
|
8
|
+
Framework upgrade to `@cyanheads/mcp-ts-core` 0.8.13 and an internal coherence pass on `secedgar_get_filing`'s error path so every declared contract reason throws via `ctx.fail` from handler-visible code. No behavioural change on the wire — same JSON-RPC error codes, same `data.reason`, same recovery hints.
|
|
9
|
+
|
|
10
|
+
## Changed
|
|
11
|
+
|
|
12
|
+
- **`secedgar_get_filing` archive helper threads `ctx`** — `resolveFilingArchive` now accepts a typed `HandlerContext<ReasonOf<typeof FILING_ERRORS>>` and throws via `ctx.fail('document_not_found' | 'no_documents' | 'filing_not_found', …)` instead of `new McpError(JsonRpcErrorCode.NotFound, …, { reason, recovery })`. The `errors[]` contract is hoisted to a module-level `FILING_ERRORS` const so the helper's `ctx` parameter can be typed against the reason union via the framework's `ReasonOf` utility. Brings the tool in line with the other five contract-bearing tools and lets the framework's `error-contract-prefer-fail` lint actually enforce conformance — previously the lint couldn't see throws from helpers.
|
|
13
|
+
- **`@cyanheads/mcp-ts-core` `^0.8.11` → `^0.8.13`** (two patches). Both releases are Canvas-focused (SQL gate hardening for `read_json*`/`read_parquet*` file-disclosure bypass, typed `appendValue` for TIMESTAMP/DATE/BLOB, new `registerView` / `importFrom` primitives, refreshed DuckDB v1.5.x plan-operator allowlist, spatial-extension pre-staging) — none apply here since this server doesn't use Canvas. Universal carry-over: vitest `silent: 'passed-only'` and node-cron sourcemap-warning suppression flow in via the shared `coreConfig` import, no project changes needed.
|
|
14
|
+
- **Refreshed `api-canvas` skill** from the package (1.0 → 1.1). Other 27 skills already at package version. All 10 framework `scripts/*.ts` unchanged.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "secedgar_search_filings adds sort (filing_date_desc default); secedgar_get_filing categorizes documents into primary/exhibits/auxiliary/xbrl from SEC headers and gates XBRL artifacts behind include_xbrl. Closes #3, #5."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.4.3 — 2026-05-04
|
|
7
|
+
|
|
8
|
+
Two long-standing usability bugs on the document-fetching path are fixed: `secedgar_search_filings` now sorts by filing date by default (closes [#5](https://github.com/cyanheads/secedgar-mcp-server/issues/5)) and `secedgar_get_filing`'s `documents` field is now categorized rather than a flat list dominated by XBRL viewer artifacts (closes [#3](https://github.com/cyanheads/secedgar-mcp-server/issues/3)). Both ship with new optional inputs and richer schema descriptions.
|
|
9
|
+
|
|
10
|
+
## Added
|
|
11
|
+
|
|
12
|
+
- **`secedgar_search_filings` — `sort` input** with values `filing_date_desc` (default), `filing_date_asc`, `relevance`. EFTS exposes no native sort knob and ranks purely by relevance, so date sorts re-order the EFTS top-100 sample client-side. For broad queries with more than 100 EFTS matches and no entity targeting, absolute newest filings can sit outside that window — schema documents the bound and recommends `ticker:` / `cik:` targeting or query tightening when absolute recency matters. Pure relevance mode preserves the prior pass-through behaviour for callers that want it.
|
|
13
|
+
- **`secedgar_get_filing` — `include_xbrl` input** (default `false`) gates XBRL viewer fragments and machine-readable taxonomy files (`R*.htm`, `*_cal/_def/_lab/_pre.xml`, `*_htm.xml`, `*.xsd`, `MetaLinks.json`, `FilingSummary.xml`, `Show.js`, `report.css`, `*-xbrl.zip`, `Financial_Report.xlsx`, `EX-101.*`) under a separate `documents.xbrl` bucket. A typical 10-K archive contains ~100 such entries; suppressing them by default removes most of the noise from the response.
|
|
14
|
+
- **`EdgarApiService.tryGetFilingHeaders(cik, accession)`** + new `services/edgar/filing-headers.ts` parser. Fetches `<accession>-index-headers.html` (the HTML re-encoding of the original SGML submission header) and parses each `<DOCUMENT>` block into a `filename → { type, sequence, description }` map. The header file exposes canonical SEC TYPE values like `EX-21.1`, `EX-31.1`, `GRAPHIC` that the directory-listing JSON does not — `index.json` only returns icon hints (`text.gif`). Best-effort: returns `null` when the header file is absent.
|
|
15
|
+
|
|
16
|
+
## Changed
|
|
17
|
+
|
|
18
|
+
- **`secedgar_get_filing` — `documents` is now an object, not an array.** Schema groups entries into `primary` / `exhibits` / `auxiliary` / `xbrl` (the last only present when `include_xbrl=true`). Each entry carries SEC's canonical `type` from the submission header and an optional `description` (e.g. `"Subsidiaries of the Registrant"`). When the header file is unavailable, `type` falls back to a name-pattern label (`XBRL-LINKBASE`, `XBRL-INSTANCE`, `XBRL-VIEWER`, etc.) and exhibits whose filename does not match a known pattern fall through to `auxiliary`. Output schema change — clients that previously iterated `documents[]` need to read `documents.primary`, `documents.exhibits`, `documents.auxiliary`.
|
|
19
|
+
- **`secedgar_get_filing` — submissions metadata + filing-headers fetch parallelized** via `Promise.all`. Adds one HTTP roundtrip per call but runs alongside the existing submissions fetch, so wall-clock cost is roughly nil.
|
|
20
|
+
- **`secedgar_search_filings` — `total_is_exact` is now correctly `false` under entity targeting** when EFTS returned more matches than the sample window covered. Previously the post-filter unconditionally set `total_is_exact = true` even when additional entity hits could exist beyond the 100-hit sample.
|
|
21
|
+
- **`secedgar_compare_metric` — `unit` accepts `USD/shares` in addition to `USD-per-shares`.** SEC's frames API path requires the dashed form, but the slash form is more natural for callers and matches the unit string returned by `secedgar_search_concepts`. Either form is normalized to the dashed form before the lookup.
|
|
22
|
+
- **Schema descriptions polished across all six tools.** Optional output fields now name the conditions under which they're absent (e.g. "Absent for filings older than the last ~1,000 the company has filed", "Absent when SEC has no location for this filer") rather than vague "Optional." labels. Cross-tool references added where workflows chain (`secedgar_company_search` → `secedgar_get_filing`, `secedgar_search_concepts` → `secedgar_get_financials` / `secedgar_compare_metric`).
|
|
23
|
+
- **`secedgar_company_analysis` prompt** points step 4 at `secedgar_search_filings` and `secedgar_company_search` with `form_types: ["8-K"]` for material-events discovery, rather than referring to a generic "search for 8-K filings" without a tool name.
|
|
24
|
+
|
|
25
|
+
## Fixed
|
|
26
|
+
|
|
27
|
+
- **[#3](https://github.com/cyanheads/secedgar-mcp-server/issues/3) — `secedgar_get_filing` documents array bloated with XBRL viewer artifacts.** A typical 10-K archive has ~110 entries, ~95% of which are XBRL rendering fragments. Categorization + the `include_xbrl=false` default removes the bloat from the default response.
|
|
28
|
+
- **[#5](https://github.com/cyanheads/secedgar-mcp-server/issues/5) — `secedgar_search_filings` result sort order unpredictable.** Default sort is now `filing_date_desc` (most recent first); `filing_date_asc` and `relevance` available as overrides.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "secedgar_search_filings reports form_distribution consistent with total under entity targeting; framework ^0.8.13 → ^0.8.19, Node engine ≥24, schema descriptions tightened across all tools and resources."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.4.4 — 2026-05-08
|
|
7
|
+
|
|
8
|
+
## Changed
|
|
9
|
+
|
|
10
|
+
- **`secedgar_get_filing` — handler owns all error throws.** `resolveFilingArchive` returns a discriminated outcome union (`document_not_found | no_documents | filing_not_found | ok`); the handler maps each to `ctx.fail`. Pure refactor — wire format and contract unchanged.
|
|
11
|
+
- **Schema descriptions tightened across all six tools and both resources.** Date fields spell out `YYYY-MM-DD`; optional output fields name the conditions under which they're absent (e.g. `report_date` "Absent for filings without a reporting period (proxy statements, ownership reports)"); `accession_number` notes its dash format; cross-tool references use full `secedgar_*` names.
|
|
12
|
+
- **Engines** — `node` minimum bumped `>=22.0.0 → >=24.0.0`; Dockerfile base image pinned `oven/bun:1 → oven/bun:1.3` for build and runtime stages.
|
|
13
|
+
- **Dependencies** — `@cyanheads/mcp-ts-core ^0.8.13 → ^0.8.19`, `@types/node ^25.6.0 → ^25.6.2`.
|
|
14
|
+
- **Changelog tooling — `security: true` frontmatter flag** with a `🛡️ Security` badge in the rollup, rendered alongside the existing `⚠️ Breaking` badge (Breaking before Security when both set). `changelog/template.md` rewritten as a format reference plus authoring guide for new release files.
|
|
15
|
+
- **Skills sync** — refreshed `skills/`: `add-tool`, `api-canvas`, `api-context`, `api-errors`, `api-utils`, `api-workers`, `design-mcp-server`, `maintenance`, `report-issue-framework`, `report-issue-local`, `setup`. Added `api-telemetry` (OTel catalog) and `tool-defs-analysis` (read-only definition-language audit). `AGENTS.md` / `CLAUDE.md` skill table updated to match.
|
|
16
|
+
|
|
17
|
+
## Fixed
|
|
18
|
+
|
|
19
|
+
- **`secedgar_search_filings` — `form_distribution` now matches `total` under entity targeting.** When `ticker:` or `cik:` in the query filtered the EFTS sample client-side, `form_distribution` previously reflected EFTS's pre-filter aggregation buckets and could disagree with the post-filter `total`. The distribution now rebuilds from the filtered hits whenever entity targeting is active.
|