@pipeworx/mcp-edgar 0.3.14 → 0.3.15

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The Securities and Exchange Commission's filings database. Every public company in the US files here, every filing is timestamped and immutable, and every disclosure (revenue, debt, risk factors, executive compensation, M&A activity, insider trading) is structured for machine retrieval. Free and authoritative.
4
4
 
5
- Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1878+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
5
+ Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1879+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
6
6
 
7
7
  ## Why this matters for AI agents
8
8
 
@@ -111,7 +111,7 @@ directly, instead of just this one's:
111
111
  }
112
112
  ```
113
113
 
114
- Both URLs reach the same gateway and the same 1878+ data sources. The
114
+ Both URLs reach the same gateway and the same 1879+ data sources. The
115
115
  only difference is which pack's tools are listed **directly**; `ask_pipeworx`
116
116
  reaches all of them from either one.
117
117
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeworx/mcp-edgar",
3
- "version": "0.3.14",
3
+ "version": "0.3.15",
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-22732e078cc175e931b642bd5804d7ba1b2610fd58415c9f8811ec32ff5939f5",
30
- "sourceCommit": "29fb434ca65fe0f61191f19c3502f583f5fb99d7"
29
+ "sourceHash": "v1-786eb4a2338149a713e1e23d15c1173ad5ffa949b94abc23a72ee39bf75db46e",
30
+ "sourceCommit": "445bacc5596a845c12d6945fbfcdf330ef60dcc4"
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.14",
6
+ "version": "0.3.15",
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
@@ -1100,6 +1100,13 @@ interface SecEntity {
1100
1100
  * `matched_by: 'company_name'` alone cannot (fleet #3100).
1101
1101
  */
1102
1102
  matched_kind?: MatchKind;
1103
+ /**
1104
+ * Other companies whose names also matched — distinct companies, deduped
1105
+ * by CIK, excluding this issuer's own share classes (never the winner's
1106
+ * own ticker/CIK under a different symbol). Consumers read this to tell a
1107
+ * genuinely CONTESTED name match from a clean one. See
1108
+ * `distinctCompanyAlternatives` below for how it's built (fleet #3621).
1109
+ */
1103
1110
  alternatives?: { ticker: string; company_name: string; cik: string; kind: MatchKind }[];
1104
1111
  }
1105
1112
 
@@ -1137,12 +1144,7 @@ async function resolveSecEntity(
1137
1144
  if (ranked.length) {
1138
1145
  const best = toEntity(ranked[0].item, 'company_name');
1139
1146
  best.matched_kind = ranked[0].kind;
1140
- const alts = ranked.slice(1, 4).map((m) => ({
1141
- ticker: m.item.ticker,
1142
- company_name: m.item.title,
1143
- cik: String(m.item.cik_str),
1144
- kind: m.kind,
1145
- }));
1147
+ const alts = distinctCompanyAlternatives(ranked);
1146
1148
  if (alts.length) best.alternatives = alts;
1147
1149
  return best;
1148
1150
  }
@@ -1150,6 +1152,33 @@ async function resolveSecEntity(
1150
1152
  throw new Error(`No SEC company matches "${query}". Pass a US-listed ticker ("AAPL") or the exact listed-company name ("Apple Inc."). If this is a clinical-trial sponsor, an operating subsidiary (e.g. "Merck Sharp & Dohme" → Merck & Co), or a foreign/private entity, call sponsor_to_filer({sponsor}) instead — it resolves subsidiaries to the listed parent and honestly reports when no US-listed filer exists.`);
1151
1153
  }
1152
1154
 
1155
+ /** `alternatives` lists at most this many OTHER companies; company-spine.test.ts pins it to the real function. */
1156
+ const ALTERNATIVES_CAP = 3;
1157
+
1158
+ /**
1159
+ * The runners-up for a name match, as DISTINCT COMPANIES (fleet #3621).
1160
+ *
1161
+ * company_tickers.json lists one row per ticker, so an issuer with preferred
1162
+ * shares appears several times under one CIK (Ford: F, F-PB, F-PC, F-PD; AT&T:
1163
+ * T, TBB, T-PA, T-PC). Slicing the ranked rows left those rows to fill every
1164
+ * alternatives slot, hiding any real rival ranked behind them, and made a company
1165
+ * its own "alternative". So: drop every row that is the winner's own CIK, keep
1166
+ * only the best-ranked row of each other CIK, THEN cap. The winner's other
1167
+ * tickers are not lost information: they are the same company, and `ticker` /
1168
+ * `cik` already identify it. `ranked` is already best-first, so first-seen wins.
1169
+ */
1170
+ function distinctCompanyAlternatives(ranked: RankedMatch<SecTickerRow$shared>[]): NonNullable<SecEntity['alternatives']> {
1171
+ const seen = new Set<number>([ranked[0].item.cik_str]);
1172
+ const out: NonNullable<SecEntity['alternatives']> = [];
1173
+ for (const m of ranked.slice(1)) {
1174
+ if (seen.has(m.item.cik_str)) continue;
1175
+ seen.add(m.item.cik_str);
1176
+ out.push({ ticker: m.item.ticker, company_name: m.item.title, cik: String(m.item.cik_str), kind: m.kind });
1177
+ if (out.length >= ALTERNATIVES_CAP) break;
1178
+ }
1179
+ return out;
1180
+ }
1181
+
1153
1182
  function toEntity(r: SecTickerRow$shared, matched_by: 'ticker' | 'company_name'): SecEntity {
1154
1183
  return {
1155
1184
  ticker: r.ticker,
@@ -1797,7 +1826,7 @@ const tools: McpToolExport['tools'] = [
1797
1826
  {
1798
1827
  name: 'edgar_ticker_to_cik',
1799
1828
  description:
1800
- 'Resolve a US stock ticker (e.g. "TSLA") OR a company name (e.g. "Tesla", "Apple Inc") to the SEC\'s 10-digit CIK identifier — required by every other SEC tool. Call THIS FIRST when you have a ticker/name and need to use edgar_company_concept, edgar_company_filings, edgar_company_facts, sec_8k_recent, or any other SEC-keyed tool. Returns {cik, cik_padded, company_name, ticker, matched_by}; when matched by name it also returns `alternatives` for disambiguation. Cheap, no rate limit concerns. Most other tools also accept tickers/names directly and call this internally — only use it explicitly when you want the CIK as data. The response carries a `next` hint: the usual NEXT step after resolving is edgar_company_snapshot({ticker_or_cik}), which returns the recent filings list AND the headline XBRL financials in one call — do not chain edgar_company_filings then edgar_company_concept by hand to get that.',
1829
+ 'Resolve a US stock ticker (e.g. "TSLA") OR a company name (e.g. "Tesla", "Apple Inc") to the SEC\'s 10-digit CIK identifier — required by every other SEC tool. Call THIS FIRST when you have a ticker/name and need to use edgar_company_concept, edgar_company_filings, edgar_company_facts, sec_8k_recent, or any other SEC-keyed tool. Returns {cik, cik_padded, company_name, ticker, matched_by}; when matched by name it also returns `alternatives` — up to 3 OTHER companies whose names also matched, one per distinct CIK, with the winner\'s OWN share classes/tickers excluded (never listed as its own alternative). Use `alternatives` to tell a genuinely CONTESTED name match (a real rival company also matched) from a clean one (nothing else did). Cheap, no rate limit concerns. Most other tools also accept tickers/names directly and call this internally — only use it explicitly when you want the CIK as data. The response carries a `next` hint: the usual NEXT step after resolving is edgar_company_snapshot({ticker_or_cik}), which returns the recent filings list AND the headline XBRL financials in one call — do not chain edgar_company_filings then edgar_company_concept by hand to get that.',
1801
1830
  summary: 'The SEC CIK number for a stock ticker or company name, from EDGAR\'s company list.',
1802
1831
  inputSchema: {
1803
1832
  type: 'object' as const,
package/src/server.ts CHANGED
@@ -10,7 +10,7 @@ import pack from './index.js';
10
10
 
11
11
 
12
12
  const server = new Server(
13
- { name: '@pipeworx/mcp-edgar', version: '0.3.14' },
13
+ { name: '@pipeworx/mcp-edgar', version: '0.3.15' },
14
14
  { capabilities: { tools: {} } },
15
15
  );
16
16