@cyanheads/secedgar-mcp-server 0.1.10 → 0.2.0
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/README.md +18 -5
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/resources/definitions/concepts.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/concepts.resource.js +15 -38
- package/dist/mcp-server/resources/definitions/concepts.resource.js.map +1 -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 +4 -4
- package/dist/mcp-server/tools/definitions/company-search.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-metric.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-metric.tool.js +8 -24
- package/dist/mcp-server/tools/definitions/compare-metric.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-filing.tool.d.ts +3 -3
- package/dist/mcp-server/tools/definitions/get-filing.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-filing.tool.js +102 -70
- package/dist/mcp-server/tools/definitions/get-filing.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.js +23 -35
- package/dist/mcp-server/tools/definitions/get-financials.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-concepts.tool.d.ts +43 -0
- package/dist/mcp-server/tools/definitions/search-concepts.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-concepts.tool.js +113 -0
- package/dist/mcp-server/tools/definitions/search-concepts.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.js +4 -7
- package/dist/mcp-server/tools/definitions/search-filings.tool.js.map +1 -1
- package/dist/services/edgar/concept-map.d.ts +14 -0
- package/dist/services/edgar/concept-map.d.ts.map +1 -1
- package/dist/services/edgar/concept-map.js +47 -0
- package/dist/services/edgar/concept-map.js.map +1 -1
- package/dist/services/edgar/edgar-api-service.d.ts +24 -3
- package/dist/services/edgar/edgar-api-service.d.ts.map +1 -1
- package/dist/services/edgar/edgar-api-service.js +87 -15
- package/dist/services/edgar/edgar-api-service.js.map +1 -1
- package/dist/services/edgar/types.d.ts +8 -3
- package/dist/services/edgar/types.d.ts.map +1 -1
- package/package.json +17 -12
- package/server.json +3 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>@cyanheads/secedgar-mcp-server</h1>
|
|
3
3
|
<p><b>Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.</b>
|
|
4
|
-
<div>
|
|
4
|
+
<div>6 Tools • 2 Resources • 1 Prompt</div>
|
|
5
5
|
</p>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
[](https://www.npmjs.com/package/@cyanheads/secedgar-mcp-server) [](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [](https://modelcontextprotocol.io/)
|
|
11
11
|
|
|
12
|
-
[](./LICENSE) [](./LICENSE) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
## Tools
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
Six tools for querying SEC EDGAR data:
|
|
27
27
|
|
|
28
28
|
| Tool | Description |
|
|
29
29
|
|:---|:---|
|
|
@@ -32,6 +32,7 @@ Five tools for querying SEC EDGAR data:
|
|
|
32
32
|
| `secedgar_get_filing` | Fetch a specific filing's metadata and document content |
|
|
33
33
|
| `secedgar_get_financials` | Get historical XBRL financial data for a company |
|
|
34
34
|
| `secedgar_compare_metric` | Compare a financial metric across all reporting companies |
|
|
35
|
+
| `secedgar_search_concepts` | Discover supported XBRL concept names or reverse-lookup a raw tag |
|
|
35
36
|
|
|
36
37
|
### `secedgar_company_search`
|
|
37
38
|
|
|
@@ -86,6 +87,17 @@ Compare a financial metric across all reporting companies for a specific period.
|
|
|
86
87
|
- Sorted ranking with configurable limit and direction
|
|
87
88
|
- Enriches results with ticker symbols where available
|
|
88
89
|
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### `secedgar_search_concepts`
|
|
93
|
+
|
|
94
|
+
Discover supported XBRL concept names before querying financials or cross-company comparisons.
|
|
95
|
+
|
|
96
|
+
- Search by friendly name, label, or raw XBRL tag
|
|
97
|
+
- Filter by statement group (`income_statement`, `balance_sheet`, `cash_flow`, `per_share`, `entity_info`) or taxonomy
|
|
98
|
+
- Reverse-lookup raw tags like `NetIncomeLoss` to the supported friendly names
|
|
99
|
+
- Returns the same catalog used by `secedgar_get_financials`, `secedgar_compare_metric`, and `secedgar://concepts`
|
|
100
|
+
|
|
89
101
|
## Resources
|
|
90
102
|
|
|
91
103
|
| URI | Description |
|
|
@@ -115,6 +127,7 @@ SEC EDGAR–specific:
|
|
|
115
127
|
- Rate-limited HTTP client respecting SEC's 10 req/s limit with automatic inter-request delay
|
|
116
128
|
- CIK resolution from tickers, company names, or raw CIK numbers with local caching
|
|
117
129
|
- Friendly XBRL concept name mapping with historical tag change handling
|
|
130
|
+
- Searchable concept catalog with statement-group metadata and reverse XBRL tag lookup
|
|
118
131
|
- HTML-to-text conversion for filing documents via `html-to-text`
|
|
119
132
|
- No API keys required — SEC EDGAR is a free, public API
|
|
120
133
|
|
|
@@ -253,7 +266,7 @@ docker run -e EDGAR_USER_AGENT="MyApp my@email.com" -p 3010:3010 secedgar-mcp-se
|
|
|
253
266
|
|
|
254
267
|
| Directory | Purpose |
|
|
255
268
|
|:---|:---|
|
|
256
|
-
| `src/mcp-server/tools/definitions/` | Tool definitions (`*.tool.ts`).
|
|
269
|
+
| `src/mcp-server/tools/definitions/` | Tool definitions (`*.tool.ts`). Six SEC EDGAR tools. |
|
|
257
270
|
| `src/mcp-server/resources/definitions/` | Resource definitions. XBRL concepts and filing types. |
|
|
258
271
|
| `src/mcp-server/prompts/definitions/` | Prompt definitions. Company analysis prompt. |
|
|
259
272
|
| `src/services/edgar/` | SEC EDGAR API client, XBRL concept mapping, HTML-to-text conversion. |
|
|
@@ -262,7 +275,7 @@ docker run -e EDGAR_USER_AGENT="MyApp my@email.com" -p 3010:3010 secedgar-mcp-se
|
|
|
262
275
|
|
|
263
276
|
## Development guide
|
|
264
277
|
|
|
265
|
-
See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
|
|
278
|
+
See [`CLAUDE.md`](./CLAUDE.md) and [`AGENTS.md`](./AGENTS.md) for development guidelines and architectural rules. The short version:
|
|
266
279
|
|
|
267
280
|
- Handlers throw, framework catches — no `try/catch` in tool logic
|
|
268
281
|
- Use `ctx.log` for logging, `ctx.state` for storage
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { companySearchTool } from './mcp-server/tools/definitions/company-search
|
|
|
11
11
|
import { compareMetricTool } from './mcp-server/tools/definitions/compare-metric.tool.js';
|
|
12
12
|
import { getFilingTool } from './mcp-server/tools/definitions/get-filing.tool.js';
|
|
13
13
|
import { getFinancialsTool } from './mcp-server/tools/definitions/get-financials.tool.js';
|
|
14
|
+
import { searchConceptsTool } from './mcp-server/tools/definitions/search-concepts.tool.js';
|
|
14
15
|
import { searchFilingsTool } from './mcp-server/tools/definitions/search-filings.tool.js';
|
|
15
16
|
import { initEdgarApiService } from './services/edgar/edgar-api-service.js';
|
|
16
17
|
await createApp({
|
|
@@ -20,6 +21,7 @@ await createApp({
|
|
|
20
21
|
getFilingTool,
|
|
21
22
|
getFinancialsTool,
|
|
22
23
|
compareMetricTool,
|
|
24
|
+
searchConceptsTool,
|
|
23
25
|
],
|
|
24
26
|
resources: [conceptsResource, filingTypesResource],
|
|
25
27
|
prompts: [companyAnalysisPrompt],
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,yDAAyD,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,SAAS,CAAC;IACd,KAAK,EAAE;QACL,iBAAiB;QACjB,iBAAiB;QACjB,aAAa;QACb,iBAAiB;QACjB,iBAAiB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,yDAAyD,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,SAAS,CAAC;IACd,KAAK,EAAE;QACL,iBAAiB;QACjB,iBAAiB;QACjB,aAAa;QACb,iBAAiB;QACjB,iBAAiB;QACjB,kBAAkB;KACnB;IACD,SAAS,EAAE,CAAC,gBAAgB,EAAE,mBAAmB,CAAC;IAClD,OAAO,EAAE,CAAC,qBAAqB,CAAC;IAChC,KAAK;QACH,mBAAmB,EAAE,CAAC;IACxB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"concepts.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/concepts.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"concepts.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/concepts.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,eAAO,MAAM,gBAAgB;;6CAmD3B,CAAC"}
|
|
@@ -4,56 +4,33 @@
|
|
|
4
4
|
* @module mcp-server/resources/definitions/concepts
|
|
5
5
|
*/
|
|
6
6
|
import { resource } from '@cyanheads/mcp-ts-core';
|
|
7
|
-
import {
|
|
7
|
+
import { listConcepts } from '../../../services/edgar/concept-map.js';
|
|
8
|
+
const GROUP_LABELS = {
|
|
9
|
+
income_statement: 'Income Statement',
|
|
10
|
+
balance_sheet: 'Balance Sheet',
|
|
11
|
+
cash_flow: 'Cash Flow',
|
|
12
|
+
per_share: 'Per Share',
|
|
13
|
+
entity_info: 'Entity Info',
|
|
14
|
+
};
|
|
8
15
|
export const conceptsResource = resource('secedgar://concepts', {
|
|
9
16
|
name: 'XBRL Financial Concepts',
|
|
10
17
|
description: 'Reference list of common XBRL financial concepts grouped by financial statement, ' +
|
|
11
18
|
'mapping friendly names to XBRL tags. Read this before calling secedgar_get_financials to see available concept names.',
|
|
12
19
|
mimeType: 'text/markdown',
|
|
13
20
|
handler(_params, _ctx) {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'Per Share': [],
|
|
20
|
-
'Entity Info': [],
|
|
21
|
-
};
|
|
22
|
-
const groupMap = {
|
|
23
|
-
revenue: 'Income Statement',
|
|
24
|
-
net_income: 'Income Statement',
|
|
25
|
-
operating_income: 'Income Statement',
|
|
26
|
-
gross_profit: 'Income Statement',
|
|
27
|
-
assets: 'Balance Sheet',
|
|
28
|
-
liabilities: 'Balance Sheet',
|
|
29
|
-
equity: 'Balance Sheet',
|
|
30
|
-
cash: 'Balance Sheet',
|
|
31
|
-
debt: 'Balance Sheet',
|
|
32
|
-
eps_basic: 'Per Share',
|
|
33
|
-
eps_diluted: 'Per Share',
|
|
34
|
-
operating_cash_flow: 'Cash Flow',
|
|
35
|
-
capex: 'Cash Flow',
|
|
36
|
-
shares_outstanding: 'Entity Info',
|
|
37
|
-
};
|
|
38
|
-
for (const [name, mapping] of Object.entries(concepts)) {
|
|
39
|
-
const group = groupMap[name] ?? 'Other';
|
|
40
|
-
if (!groups[group])
|
|
41
|
-
groups[group] = [];
|
|
42
|
-
groups[group].push({
|
|
43
|
-
name,
|
|
44
|
-
label: mapping.label,
|
|
45
|
-
tags: mapping.tags,
|
|
46
|
-
taxonomy: mapping.taxonomy,
|
|
47
|
-
unit: mapping.unit,
|
|
48
|
-
});
|
|
21
|
+
const groups = new Map();
|
|
22
|
+
for (const entry of listConcepts()) {
|
|
23
|
+
const list = groups.get(entry.group) ?? [];
|
|
24
|
+
list.push(entry);
|
|
25
|
+
groups.set(entry.group, list);
|
|
49
26
|
}
|
|
50
27
|
const lines = ['# XBRL Financial Concepts', ''];
|
|
51
28
|
lines.push('Use these friendly names with `secedgar_get_financials` and `secedgar_compare_metric`.', '');
|
|
52
29
|
lines.push('Raw XBRL tags are also accepted as an escape hatch for concepts not listed here.', '');
|
|
53
|
-
for (const [group, items] of
|
|
30
|
+
for (const [group, items] of groups) {
|
|
54
31
|
if (items.length === 0)
|
|
55
32
|
continue;
|
|
56
|
-
lines.push(`## ${group}`, '');
|
|
33
|
+
lines.push(`## ${GROUP_LABELS[group]}`, '');
|
|
57
34
|
lines.push('| Friendly Name | Label | XBRL Tags | Taxonomy | Unit |');
|
|
58
35
|
lines.push('|:------|:------|:----------|:---------|:-----|');
|
|
59
36
|
for (const item of items) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"concepts.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/concepts.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"concepts.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/concepts.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAG/D,MAAM,YAAY,GAAiC;IACjD,gBAAgB,EAAE,kBAAkB;IACpC,aAAa,EAAE,eAAe;IAC9B,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,qBAAqB,EAAE;IAC9D,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EACT,mFAAmF;QACnF,uHAAuH;IACzH,QAAQ,EAAE,eAAe;IAEzB,OAAO,CAAC,OAAO,EAAE,IAAI;QACnB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgC,CAAC;QACvD,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;QAED,MAAM,KAAK,GAAa,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QAC1D,KAAK,CAAC,IAAI,CACR,wFAAwF,EACxF,EAAE,CACH,CAAC;QACF,KAAK,CAAC,IAAI,CACR,kFAAkF,EAClF,EAAE,CACH,CAAC;QAEF,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACjC,KAAK,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;YACtE,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;YAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CACR,OAAO,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,IAAI,IAAI,CAC1H,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACjB,SAAS,EAAE;YACT;gBACE,GAAG,EAAE,qBAAqB;gBAC1B,IAAI,EAAE,yBAAyB;gBAC/B,WAAW,EAAE,4DAA4D;gBACzE,QAAQ,EAAE,eAAe;aAC1B;SACF;KACF,CAAC;CACH,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company-search.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/company-search.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"company-search.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/company-search.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAajD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;kBAwJ5B,CAAC"}
|
|
@@ -7,8 +7,7 @@ import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
|
7
7
|
import { notFound } from '@cyanheads/mcp-ts-core/errors';
|
|
8
8
|
import { getEdgarApiService } from '../../../services/edgar/edgar-api-service.js';
|
|
9
9
|
export const companySearchTool = tool('secedgar_company_search', {
|
|
10
|
-
description: 'Find companies and retrieve entity info with optional recent filings. '
|
|
11
|
-
'Entry point for most EDGAR workflows — resolve tickers, names, or CIKs to entity details.',
|
|
10
|
+
description: 'Find companies and retrieve entity info with optional recent filings. Entry point for most EDGAR workflows — resolve tickers, names, or CIKs to entity details.',
|
|
12
11
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
13
12
|
input: z.object({
|
|
14
13
|
query: z
|
|
@@ -64,7 +63,9 @@ export const companySearchTool = tool('secedgar_company_search', {
|
|
|
64
63
|
throw notFound(`No company found for '${input.query}'. Try a ticker symbol (e.g., 'AAPL'), full company name, or 10-digit CIK.`);
|
|
65
64
|
}
|
|
66
65
|
if (resolved.length > 1) {
|
|
67
|
-
const matches = resolved
|
|
66
|
+
const matches = resolved
|
|
67
|
+
.map((m) => `${m.ticker ?? m.cik} (${m.name ?? 'Unknown'})`)
|
|
68
|
+
.join(', ');
|
|
68
69
|
throw notFound(`Multiple matches for '${input.query}': ${matches}. Specify a ticker for an exact match.`);
|
|
69
70
|
}
|
|
70
71
|
}
|
|
@@ -94,7 +95,6 @@ export const companySearchTool = tool('secedgar_company_search', {
|
|
|
94
95
|
description: recent.primaryDocDescription[i] || undefined,
|
|
95
96
|
});
|
|
96
97
|
}
|
|
97
|
-
// Filter by form types
|
|
98
98
|
const filtered = input.form_types
|
|
99
99
|
? all.filter((f) => input.form_types?.some((ft) => f.form.toUpperCase() === ft.toUpperCase()))
|
|
100
100
|
: all;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company-search.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/company-search.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"company-search.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/company-search.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-metric.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-metric.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"compare-metric.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-metric.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAKjD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoI5B,CAAC"}
|
|
@@ -7,22 +7,15 @@ import { notFound } from '@cyanheads/mcp-ts-core/errors';
|
|
|
7
7
|
import { resolveConcept } from '../../../services/edgar/concept-map.js';
|
|
8
8
|
import { getEdgarApiService } from '../../../services/edgar/edgar-api-service.js';
|
|
9
9
|
export const compareMetricTool = tool('secedgar_compare_metric', {
|
|
10
|
-
description: 'Compare a financial metric across all reporting companies for a specific period. '
|
|
11
|
-
'Uses the same friendly concept names as secedgar_get_financials (e.g., "revenue", "assets").',
|
|
10
|
+
description: 'Compare a financial metric across all reporting companies for a specific period. Uses the same friendly concept names as secedgar_get_financials (e.g., "revenue", "assets").',
|
|
12
11
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
13
12
|
input: z.object({
|
|
14
13
|
concept: z
|
|
15
14
|
.string()
|
|
16
|
-
.describe('Financial concept — same friendly names as secedgar_get_financials '
|
|
17
|
-
'(e.g., "revenue", "assets", "eps_basic") or raw XBRL tag.'),
|
|
15
|
+
.describe('Financial concept — same friendly names as secedgar_get_financials (e.g., "revenue", "assets", "eps_basic") or raw XBRL tag.'),
|
|
18
16
|
period: z
|
|
19
17
|
.string()
|
|
20
|
-
.describe('Calendar period. Formats:\n'
|
|
21
|
-
' "CY2023" — full year 2023 (duration, for income statement items)\n' +
|
|
22
|
-
' "CY2024Q2" — Q2 2024 (duration, for quarterly income items)\n' +
|
|
23
|
-
' "CY2023Q4I" — Q4 2023 instant (balance sheet items like assets, cash)\n' +
|
|
24
|
-
'Use duration periods (no I suffix) for income/cash flow items. ' +
|
|
25
|
-
'Use instant periods (I suffix) for balance sheet items.'),
|
|
18
|
+
.describe('Calendar period. Formats:\n "CY2023" — full year 2023 (duration, for income statement items)\n "CY2024Q2" — Q2 2024 (duration, for quarterly income items)\n "CY2023Q4I" — Q4 2023 instant (balance sheet items like assets, cash)\nUse duration periods (no I suffix) for income/cash flow items. Use instant periods (I suffix) for balance sheet items.'),
|
|
26
19
|
unit: z
|
|
27
20
|
.enum(['USD', 'USD-per-shares', 'shares', 'pure'])
|
|
28
21
|
.default('USD')
|
|
@@ -60,22 +53,13 @@ export const compareMetricTool = tool('secedgar_compare_metric', {
|
|
|
60
53
|
const taxonomy = mapping?.taxonomy ?? 'us-gaap';
|
|
61
54
|
const label = mapping?.label ?? input.concept;
|
|
62
55
|
const unit = mapping ? mapping.unit.replace('/', '-per-') : input.unit;
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
framesResponse = await api.getFrames(taxonomy, tag, unit, input.period);
|
|
67
|
-
}
|
|
68
|
-
catch (err) {
|
|
69
|
-
const is404 = err instanceof Error && /404|not found/i.test(err.message);
|
|
70
|
-
if (!is404)
|
|
71
|
-
throw err;
|
|
56
|
+
// `tryGetFrames` returns null when no companies report this combination for this period.
|
|
57
|
+
const framesResponse = await api.tryGetFrames(taxonomy, tag, unit, input.period);
|
|
58
|
+
if (!framesResponse) {
|
|
72
59
|
// Distinguish unknown concept (no mapping + 404) from valid concept with no data
|
|
73
60
|
const hint = !mapping
|
|
74
|
-
? `Unknown concept '${input.concept}'. Use a friendly name (e.g., "revenue", "assets")
|
|
75
|
-
|
|
76
|
-
: `No data for ${label}/${unit}/${input.period}. Check: ` +
|
|
77
|
-
'duration vs. instant period (add "I" for balance sheet items), ' +
|
|
78
|
-
'correct unit (USD-per-shares for EPS), and period exists (data starts ~CY2009).';
|
|
61
|
+
? `Unknown concept '${input.concept}'. Use a friendly name (e.g., "revenue", "assets") or a valid XBRL tag.`
|
|
62
|
+
: `No data for ${label}/${unit}/${input.period}. Check: duration vs. instant period (add "I" for balance sheet items), correct unit (USD-per-shares for EPS), and period exists (data starts ~CY2009).`;
|
|
79
63
|
throw notFound(hint);
|
|
80
64
|
}
|
|
81
65
|
// Sort by value
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-metric.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-metric.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"compare-metric.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-metric.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,9 @@ export declare const getFilingTool: import("@cyanheads/mcp-ts-core").ToolDefinit
|
|
|
10
10
|
document: z.ZodOptional<z.ZodString>;
|
|
11
11
|
}, z.core.$strip>, z.ZodObject<{
|
|
12
12
|
accession_number: z.ZodString;
|
|
13
|
-
form: z.ZodString
|
|
14
|
-
filing_date: z.ZodString
|
|
15
|
-
company_name: z.ZodString
|
|
13
|
+
form: z.ZodOptional<z.ZodString>;
|
|
14
|
+
filing_date: z.ZodOptional<z.ZodString>;
|
|
15
|
+
company_name: z.ZodOptional<z.ZodString>;
|
|
16
16
|
cik: z.ZodString;
|
|
17
17
|
period_ending: z.ZodOptional<z.ZodString>;
|
|
18
18
|
primary_document: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-filing.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-filing.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"get-filing.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-filing.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AASjD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;kBAkJxB,CAAC"}
|
|
@@ -6,9 +6,9 @@ import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
|
6
6
|
import { notFound } from '@cyanheads/mcp-ts-core/errors';
|
|
7
7
|
import { getEdgarApiService } from '../../../services/edgar/edgar-api-service.js';
|
|
8
8
|
import { filingToText } from '../../../services/edgar/filing-to-text.js';
|
|
9
|
+
const MAX_DOCUMENTS_IN_FORMAT = 10;
|
|
9
10
|
export const getFilingTool = tool('secedgar_get_filing', {
|
|
10
|
-
description: "Fetch a specific filing's metadata and document content by accession number. "
|
|
11
|
-
'Returns the primary document as readable text, with option to fetch specific exhibits.',
|
|
11
|
+
description: "Fetch a specific filing's metadata and document content by accession number. Returns the primary document as readable text, with option to fetch specific exhibits.",
|
|
12
12
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
13
13
|
input: z.object({
|
|
14
14
|
accession_number: z
|
|
@@ -17,16 +17,14 @@ export const getFilingTool = tool('secedgar_get_filing', {
|
|
|
17
17
|
cik: z
|
|
18
18
|
.string()
|
|
19
19
|
.optional()
|
|
20
|
-
.describe('Company CIK. Optional but recommended — speeds up
|
|
20
|
+
.describe('Company CIK. Optional but recommended — speeds up archive lookup. If omitted, the server resolves likely filing CIKs from SEC search metadata and archive paths.'),
|
|
21
21
|
content_limit: z
|
|
22
22
|
.number()
|
|
23
23
|
.int()
|
|
24
24
|
.min(1000)
|
|
25
25
|
.max(200000)
|
|
26
26
|
.default(50000)
|
|
27
|
-
.describe('Maximum characters of document text to return. 10-K filings can exceed 500,000 characters. '
|
|
28
|
-
'Default 50,000 captures ~12,000 words (typically business overview, risk factors, and MD&A). ' +
|
|
29
|
-
'Increase to 200,000 for full financial statements, or decrease for quick summaries.'),
|
|
27
|
+
.describe('Maximum characters of document text to return. 10-K filings can exceed 500,000 characters. Default 50,000 captures ~12,000 words (typically business overview, risk factors, and MD&A). Increase to 200,000 for full financial statements, or decrease for quick summaries.'),
|
|
30
28
|
document: z
|
|
31
29
|
.string()
|
|
32
30
|
.optional()
|
|
@@ -34,9 +32,18 @@ export const getFilingTool = tool('secedgar_get_filing', {
|
|
|
34
32
|
}),
|
|
35
33
|
output: z.object({
|
|
36
34
|
accession_number: z.string().describe('Filing accession number.'),
|
|
37
|
-
form: z
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
form: z
|
|
36
|
+
.string()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Form type. Omitted when the filing predates the recent-submissions window.'),
|
|
39
|
+
filing_date: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Date filed. Omitted when the filing predates the recent-submissions window.'),
|
|
43
|
+
company_name: z
|
|
44
|
+
.string()
|
|
45
|
+
.optional()
|
|
46
|
+
.describe('Filing entity name, if the CIK resolved to a known entity.'),
|
|
40
47
|
cik: z.string().describe('Company CIK.'),
|
|
41
48
|
period_ending: z.string().optional().describe('Period of report.'),
|
|
42
49
|
primary_document: z.string().describe('Primary document filename.'),
|
|
@@ -54,84 +61,60 @@ export const getFilingTool = tool('secedgar_get_filing', {
|
|
|
54
61
|
}),
|
|
55
62
|
async handler(input, ctx) {
|
|
56
63
|
const api = getEdgarApiService();
|
|
57
|
-
// Normalize accession number to dash format
|
|
58
64
|
const accn = normalizeAccessionNumber(input.accession_number);
|
|
65
|
+
const { cik, index, html, targetName } = await resolveFilingArchive(api, accn, input.cik, input.document);
|
|
59
66
|
const accnNoDashes = accn.replace(/-/g, '');
|
|
60
|
-
// Derive CIK from accession number prefix if not provided
|
|
61
|
-
const cik = input.cik ?? accn.split('-')[0] ?? accn.slice(0, 10);
|
|
62
|
-
const paddedCik = cik.padStart(10, '0');
|
|
63
|
-
// Fetch filing index
|
|
64
|
-
let index;
|
|
65
|
-
try {
|
|
66
|
-
index = await api.getFilingIndex(paddedCik, accn);
|
|
67
|
-
}
|
|
68
|
-
catch (err) {
|
|
69
|
-
const is404 = err instanceof Error && /404|not found/i.test(err.message);
|
|
70
|
-
if (is404) {
|
|
71
|
-
throw notFound(`Filing '${accn}' not found (CIK ${paddedCik}). Verify the accession number and CIK are correct.`);
|
|
72
|
-
}
|
|
73
|
-
throw err;
|
|
74
|
-
}
|
|
75
67
|
const items = index.directory.item;
|
|
76
68
|
const documents = items.map((item) => ({
|
|
77
69
|
name: item.name,
|
|
78
70
|
type: item.type,
|
|
79
71
|
size: item.size ? Number.parseInt(item.size, 10) : undefined,
|
|
80
72
|
}));
|
|
81
|
-
// Find the target document
|
|
82
|
-
const targetName = input.document || findPrimaryDocument(items);
|
|
83
|
-
if (!targetName) {
|
|
84
|
-
throw notFound(`No document found in filing ${accn}. Available documents: ${items.map((i) => i.name).join(', ')}`);
|
|
85
|
-
}
|
|
86
|
-
const docExists = items.some((i) => i.name === targetName);
|
|
87
|
-
if (!docExists) {
|
|
88
|
-
throw notFound(`Document '${targetName}' not found in this filing. Available documents: ${items.map((i) => i.name).join(', ')}. Use one of these names.`);
|
|
89
|
-
}
|
|
90
|
-
// Fetch and convert document
|
|
91
|
-
const html = await api.getFilingDocument(paddedCik, accn, targetName);
|
|
92
73
|
const { text, truncated, totalLength } = filingToText(html, input.content_limit);
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
let companyName = '';
|
|
97
|
-
let periodEnding;
|
|
98
|
-
// Try to get metadata from the index page or a quick submissions lookup
|
|
99
|
-
const submissions = await api.getSubmissions(paddedCik);
|
|
100
|
-
companyName = submissions.name;
|
|
74
|
+
// Enrich with metadata from the recent-submissions window — not every accession lands here
|
|
75
|
+
// (older filings live in paginated archive files), so these fields remain optional.
|
|
76
|
+
const submissions = await api.getSubmissions(cik);
|
|
101
77
|
const recentAccns = submissions.filings.recent.accessionNumber;
|
|
102
78
|
const idx = recentAccns.indexOf(accn);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
periodEnding = submissions.filings.recent.reportDate[idx] || undefined;
|
|
107
|
-
}
|
|
79
|
+
const form = idx >= 0 ? submissions.filings.recent.form[idx] : undefined;
|
|
80
|
+
const filingDate = idx >= 0 ? submissions.filings.recent.filingDate[idx] : undefined;
|
|
81
|
+
const periodEnding = idx >= 0 ? submissions.filings.recent.reportDate[idx] || undefined : undefined;
|
|
108
82
|
ctx.log.info('Filing retrieved', {
|
|
109
83
|
accessionNumber: accn,
|
|
110
|
-
cik
|
|
84
|
+
cik,
|
|
111
85
|
contentLength: totalLength,
|
|
86
|
+
inRecentWindow: idx >= 0,
|
|
112
87
|
});
|
|
113
88
|
return {
|
|
114
89
|
accession_number: accn,
|
|
115
|
-
form,
|
|
116
|
-
filing_date: filingDate,
|
|
117
|
-
company_name:
|
|
118
|
-
cik
|
|
90
|
+
form: form || undefined,
|
|
91
|
+
filing_date: filingDate || undefined,
|
|
92
|
+
company_name: submissions.name || undefined,
|
|
93
|
+
cik,
|
|
119
94
|
period_ending: periodEnding,
|
|
120
95
|
primary_document: targetName,
|
|
121
96
|
documents,
|
|
122
97
|
content: text,
|
|
123
98
|
content_truncated: truncated,
|
|
124
99
|
content_total_length: totalLength,
|
|
125
|
-
filing_url: `https://www.sec.gov/Archives/edgar/data/${
|
|
100
|
+
filing_url: `https://www.sec.gov/Archives/edgar/data/${cik}/${accnNoDashes}/${targetName}`,
|
|
126
101
|
};
|
|
127
102
|
},
|
|
128
103
|
format: (result) => {
|
|
129
|
-
const
|
|
130
|
-
const
|
|
104
|
+
const formLabel = result.form ?? 'Filing';
|
|
105
|
+
const entity = result.company_name ?? 'Unknown entity';
|
|
106
|
+
const header = `**${formLabel}** — ${entity} (CIK ${result.cik})`;
|
|
107
|
+
const filedPart = result.filing_date ? `Filed: ${result.filing_date}` : 'Filed: Unknown';
|
|
108
|
+
const periodPart = result.period_ending ? ` | Period: ${result.period_ending}` : '';
|
|
109
|
+
const dateLine = `${filedPart}${periodPart}`;
|
|
131
110
|
const meta = `Accession: ${result.accession_number} | ${result.content_total_length.toLocaleString()} chars${result.content_truncated ? ' (truncated)' : ''}`;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
111
|
+
let docs = '';
|
|
112
|
+
if (result.documents.length > 1) {
|
|
113
|
+
const shown = result.documents.slice(0, MAX_DOCUMENTS_IN_FORMAT);
|
|
114
|
+
const extra = result.documents.length - shown.length;
|
|
115
|
+
const list = shown.map((d) => `${d.name} (${d.type})`).join(', ');
|
|
116
|
+
docs = `\nDocuments (${result.documents.length}): ${list}${extra > 0 ? `, +${extra} more` : ''}`;
|
|
117
|
+
}
|
|
135
118
|
const url = `\nURL: ${result.filing_url}`;
|
|
136
119
|
return [
|
|
137
120
|
{ type: 'text', text: `${header}\n${dateLine}\n${meta}${docs}${url}\n\n${result.content}` },
|
|
@@ -149,16 +132,65 @@ function normalizeAccessionNumber(input) {
|
|
|
149
132
|
}
|
|
150
133
|
return cleaned;
|
|
151
134
|
}
|
|
152
|
-
|
|
135
|
+
async function resolveFilingArchive(api, accessionNumber, providedCik, requestedDocument) {
|
|
136
|
+
const candidateCiks = await resolveCandidateCiks(api, accessionNumber, providedCik);
|
|
137
|
+
let lastIndexedItems = [];
|
|
138
|
+
for (const cik of candidateCiks) {
|
|
139
|
+
const index = await api.tryGetFilingIndex(cik, accessionNumber);
|
|
140
|
+
if (!index)
|
|
141
|
+
continue;
|
|
142
|
+
const items = index.directory.item;
|
|
143
|
+
lastIndexedItems = items;
|
|
144
|
+
const targetName = requestedDocument ?? findPrimaryDocument(items);
|
|
145
|
+
if (!targetName)
|
|
146
|
+
continue;
|
|
147
|
+
if (!items.some((item) => item.name === targetName))
|
|
148
|
+
continue;
|
|
149
|
+
const html = await api.tryGetFilingDocument(cik, accessionNumber, targetName);
|
|
150
|
+
if (!html)
|
|
151
|
+
continue;
|
|
152
|
+
return { cik, html, index, targetName };
|
|
153
|
+
}
|
|
154
|
+
if (requestedDocument && lastIndexedItems.length > 0) {
|
|
155
|
+
throw notFound(`Document '${requestedDocument}' not found in this filing. Available documents: ${lastIndexedItems.map((item) => item.name).join(', ')}. Use one of these names.`);
|
|
156
|
+
}
|
|
157
|
+
if (lastIndexedItems.length > 0) {
|
|
158
|
+
throw notFound(`No document found in filing ${accessionNumber}. Available documents: ${lastIndexedItems.map((item) => item.name).join(', ')}`);
|
|
159
|
+
}
|
|
160
|
+
if (providedCik) {
|
|
161
|
+
throw notFound(`Filing '${accessionNumber}' not found (CIK ${providedCik.padStart(10, '0')}). Verify the accession number and CIK are correct.`);
|
|
162
|
+
}
|
|
163
|
+
throw notFound(`Filing '${accessionNumber}' not found. Verify the accession number or provide the company CIK explicitly.`);
|
|
164
|
+
}
|
|
165
|
+
async function resolveCandidateCiks(api, accessionNumber, providedCik) {
|
|
166
|
+
if (providedCik)
|
|
167
|
+
return [providedCik.padStart(10, '0')];
|
|
168
|
+
const ciks = await api.findFilingCiks(accessionNumber);
|
|
169
|
+
const prefixCik = (accessionNumber.split('-')[0] ?? accessionNumber.slice(0, 10)).padStart(10, '0');
|
|
170
|
+
return [...new Set([...ciks, prefixCik])];
|
|
171
|
+
}
|
|
172
|
+
/** Find the primary document in a filing index (prefer real filing docs over SEC index pages). */
|
|
153
173
|
function findPrimaryDocument(items) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
!
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
174
|
+
const htmlDocs = items.filter((item) => isNonIndexFile(item.name) &&
|
|
175
|
+
(item.name.endsWith('.htm') || item.name.endsWith('.html')) &&
|
|
176
|
+
!item.name.startsWith('R'));
|
|
177
|
+
if (htmlDocs.length > 0)
|
|
178
|
+
return getLargestDocument(htmlDocs)?.name;
|
|
179
|
+
const xmlDocs = items.filter((item) => isNonIndexFile(item.name) && item.name.endsWith('.xml') && !isXbrlSupportFile(item.name));
|
|
180
|
+
if (xmlDocs.length > 0)
|
|
181
|
+
return getLargestDocument(xmlDocs)?.name;
|
|
182
|
+
const textDocs = items.filter((item) => isNonIndexFile(item.name) && item.name.endsWith('.txt'));
|
|
183
|
+
if (textDocs.length > 0)
|
|
184
|
+
return getLargestDocument(textDocs)?.name;
|
|
185
|
+
return items.find((item) => isNonIndexFile(item.name))?.name ?? items[0]?.name;
|
|
186
|
+
}
|
|
187
|
+
function getLargestDocument(items) {
|
|
188
|
+
return [...items].sort((a, b) => (Number.parseInt(b.size, 10) || 0) - (Number.parseInt(a.size, 10) || 0))[0];
|
|
189
|
+
}
|
|
190
|
+
function isNonIndexFile(name) {
|
|
191
|
+
return !name.toLowerCase().includes('index');
|
|
192
|
+
}
|
|
193
|
+
function isXbrlSupportFile(name) {
|
|
194
|
+
return /(?:_cal|_def|_lab|_pre|_sch)\.xml$/i.test(name);
|
|
163
195
|
}
|
|
164
196
|
//# sourceMappingURL=get-filing.tool.js.map
|