@pipeworx/mcp-edgar 0.3.4 → 0.3.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeworx/mcp-edgar",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "EDGAR MCP — SEC EDGAR public APIs (free, no auth)",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -26,7 +26,7 @@
26
26
  "@cloudflare/workers-types": "^4.20260405.1"
27
27
  },
28
28
  "pipeworx": {
29
- "sourceHash": "v1-da12d4be03a1cfefdc692b867a5dfa74a7d539061c1d7ff62c65bb2d24944675",
30
- "sourceCommit": "4fa4c64448be06f4a2ee4cee19f756f3558a7cad"
29
+ "sourceHash": "v1-8ebd704e53458e829aea1033aa14ef78911a50cd60211956318c1574f8b1eb4c",
30
+ "sourceCommit": "1064560fd9dcd0d6fc2606298c2ba244b3a1fbeb"
31
31
  }
32
32
  }
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.pipeworx-io/edgar",
4
4
  "title": "Edgar",
5
5
  "description": "EDGAR MCP — SEC EDGAR public APIs (free, no auth)",
6
- "version": "0.3.4",
6
+ "version": "0.3.5",
7
7
  "websiteUrl": "https://pipeworx.io/packs/edgar",
8
8
  "repository": {
9
9
  "url": "https://github.com/pipeworx-io/mcp-edgar",
package/src/index.ts CHANGED
@@ -1569,7 +1569,7 @@ const tools: McpToolExport['tools'] = [
1569
1569
  },
1570
1570
  form_type: {
1571
1571
  type: 'string',
1572
- description: 'When accession is omitted, the form type of the latest filing to fetch, e.g. "10-K", "10-Q", "8-K", "DEF 14A". Omit both accession and form_type to get the single most recent filing of any type.',
1572
+ description: 'When accession is omitted, the form type of the latest filing to fetch, e.g. "10-K", "10-Q", "8-K", "DEF 14A" — or a `|`-separated SET ("10-K|10-Q") for "the most recent of either, whichever is newer". Omit both accession and form_type to get the single most recent filing of ANY type at all (routine 8-Ks/Form 4s/Form 144s included, not just annual/quarterly reports) — use the `|` set instead when you specifically want the newest 10-K or 10-Q.',
1573
1573
  },
1574
1574
  include_primary_text: {
1575
1575
  type: 'boolean',
@@ -1605,7 +1605,7 @@ const tools: McpToolExport['tools'] = [
1605
1605
  },
1606
1606
  form_type: {
1607
1607
  type: 'string',
1608
- description: 'When accession is omitted, the form type of the latest filing to fetch — "10-K", "10-Q", "8-K", "DEF 14A", etc. A question asking for the "most recent 10-K OR 10-Q" (or otherwise not committed to one type) should OMIT this field entirely rather than guess "10-K" by habit — omitting form_type (along with accession) returns the single most recent filing of ANY type, and a 10-Q is very often more recent than the last 10-K since it files quarterly while the 10-K only files once a year (verified live 2026-09-25, fleet #2450: NTRA\'s most recent 10-Q was filed 2026-08-07, five months after its 2026-02-27 10-K — passing form_type:"10-K" here silently skips the newer filing and the KPI it asked about).',
1608
+ description: 'When accession is omitted, the form type of the latest filing to fetch — "10-K", "10-Q", "8-K", "DEF 14A", etc. For "the most recent 10-K OR 10-Q" (or any "whichever of these is newer" question), pass a `|`-separated SET, e.g. "10-K|10-Q" — do NOT guess a single type ("10-K" by habit skips a newer 10-Q) and do NOT omit this field to get "any type", since a company files far more 8-Ks/Form 4s/Form 144s between annual or quarterly reports than it files the reports themselves and an empty form_type returns the single most recent filing of ANY kind (verified live 2026-09-25, fleet #2450: NTRA\'s single most recent SEC filing was a Form 144 insider-sale notice, filed weeks after its real 10-Q and completely unrelated to the question asked).',
1609
1609
  },
1610
1610
  section: {
1611
1611
  type: 'string',
@@ -2368,6 +2368,34 @@ function htmlToText(html: string): string {
2368
2368
  .trim();
2369
2369
  }
2370
2370
 
2371
+ /**
2372
+ * Index into SEC's own recent-first `forms` array of the latest filing
2373
+ * matching `wantFormTypeArg` — a single form ("10-Q") or a `|`-separated SET
2374
+ * ("10-K|10-Q" for "the most recent annual or quarterly report, whichever is
2375
+ * newer"), same pipe convention this catalog already uses for status fields
2376
+ * (grants-gov's "posted|forecasted"). Omitted/empty returns 0 — the single
2377
+ * most recent filing of ANY type.
2378
+ *
2379
+ * Fleet #2450: a question asking for "the most recent 10-K or 10-Q" cannot
2380
+ * be answered by omitting form_type — that resolves to the single most
2381
+ * recent filing of ANY type, and a company files far more 8-Ks, Form 4s and
2382
+ * Form 144s between annual/quarterly reports than it files the reports
2383
+ * themselves. Verified live: NTRA's single most recent SEC filing on
2384
+ * 2026-09-23 was a Form 144 insider-sale notice, not an annual or quarterly
2385
+ * report at all — form_type left empty silently returns THAT instead of the
2386
+ * 10-Q the question meant. Nor does picking one type and hoping work: a
2387
+ * 10-Q is very often newer than the last 10-K. "10-K|10-Q" is the answer to
2388
+ * "I don't care which, just the newest of these".
2389
+ */
2390
+ function findLatestFormIndex(forms: string[], wantFormTypeArg: string | undefined): number {
2391
+ const wanted = (wantFormTypeArg ?? '')
2392
+ .split('|')
2393
+ .map((f) => f.trim().toUpperCase())
2394
+ .filter(Boolean);
2395
+ if (!wanted.length) return 0;
2396
+ return forms.findIndex((f) => wanted.includes(f.toUpperCase()));
2397
+ }
2398
+
2371
2399
  async function filingDocuments(
2372
2400
  accession: string | undefined,
2373
2401
  tickerOrCik: string,
@@ -2398,7 +2426,7 @@ async function filingDocuments(
2398
2426
  const r = sub.filings?.recent;
2399
2427
  const forms = r?.form ?? [];
2400
2428
  const accs = r?.accessionNumber ?? [];
2401
- const idx = wantForm ? forms.findIndex((f) => f.toUpperCase() === wantForm) : 0;
2429
+ const idx = findLatestFormIndex(forms, wantFormTypeArg);
2402
2430
  if (idx < 0 || !accs[idx]) {
2403
2431
  throw new Error(
2404
2432
  `No ${wantForm ?? 'recent'} filing found for ${tickerOrCik} in the recent index. Use edgar_company_filings({ticker:"${tickerOrCik}"${wantForm ? `, form_type:"${wantForm}"` : ''}}) to list available filings, then pass an accession.`,
@@ -2619,7 +2647,7 @@ async function filingText(
2619
2647
 
2620
2648
  if (!acc) {
2621
2649
  const wantForm = wantFormTypeArg?.trim().toUpperCase();
2622
- const idx = wantForm ? forms.findIndex((f) => f.toUpperCase() === wantForm) : 0;
2650
+ const idx = findLatestFormIndex(forms, wantFormTypeArg);
2623
2651
  if (idx < 0 || !accs[idx]) {
2624
2652
  throw new Error(`No ${wantForm ?? 'recent'} filing found for ${tickerOrCik}. Use edgar_company_filings({ticker_or_cik:"${tickerOrCik}"${wantForm ? `, form_type:"${wantForm}"` : ''}}) to list filings, then pass an accession.`);
2625
2653
  }
package/src/server.ts CHANGED
@@ -9,7 +9,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprot
9
9
  import pack from './index.js';
10
10
 
11
11
  const server = new Server(
12
- { name: '@pipeworx/mcp-edgar', version: '0.3.4' },
12
+ { name: '@pipeworx/mcp-edgar', version: '0.3.5' },
13
13
  { capabilities: { tools: {} } },
14
14
  );
15
15