@cyanheads/secedgar-mcp-server 0.6.3 → 0.7.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 +27 -3
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/prompts/definitions/company-analysis.prompt.js +1 -1
- package/dist/mcp-server/prompts/definitions/company-analysis.prompt.js.map +1 -1
- package/dist/mcp-server/resources/definitions/concepts.resource.js +2 -2
- package/dist/mcp-server/resources/definitions/concepts.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.d.ts +5 -0
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.js +6 -0
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts +5 -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 +30 -3
- package/dist/mcp-server/tools/definitions/get-financials.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.d.ts +54 -0
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.js +258 -0
- package/dist/mcp-server/tools/definitions/get-insider-transactions.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.d.ts +58 -0
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.js +284 -0
- package/dist/mcp-server/tools/definitions/get-institutional-holdings.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-concepts.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/search-concepts.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-concepts.tool.js +12 -7
- package/dist/mcp-server/tools/definitions/search-concepts.tool.js.map +1 -1
- package/dist/services/edgar/concept-map.d.ts +4 -1
- package/dist/services/edgar/concept-map.d.ts.map +1 -1
- package/dist/services/edgar/concept-map.js +18 -3
- package/dist/services/edgar/concept-map.js.map +1 -1
- package/dist/services/edgar/edgar-api-service.d.ts +10 -0
- package/dist/services/edgar/edgar-api-service.d.ts.map +1 -1
- package/dist/services/edgar/edgar-api-service.js +20 -0
- package/dist/services/edgar/edgar-api-service.js.map +1 -1
- package/dist/services/edgar/ownership-parser.d.ts +76 -0
- package/dist/services/edgar/ownership-parser.d.ts.map +1 -0
- package/dist/services/edgar/ownership-parser.js +200 -0
- package/dist/services/edgar/ownership-parser.js.map +1 -0
- package/dist/services/edgar/types.d.ts +6 -0
- package/dist/services/edgar/types.d.ts.map +1 -1
- package/package.json +4 -1
- package/server.json +3 -3
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fetch Form 4 insider transactions (purchases, sales, awards, exercises)
|
|
3
|
+
* for a company by parsing ownership XML from SEC EDGAR.
|
|
4
|
+
* @module mcp-server/tools/definitions/get-insider-transactions
|
|
5
|
+
*/
|
|
6
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
8
|
+
import { getEdgarApiService } from '../../../services/edgar/edgar-api-service.js';
|
|
9
|
+
import { parseForm4Xml, } from '../../../services/edgar/ownership-parser.js';
|
|
10
|
+
/** Transaction type filter → SEC transaction codes. */
|
|
11
|
+
const PURCHASE_CODES = new Set(['P']);
|
|
12
|
+
const SALE_CODES = new Set(['S']);
|
|
13
|
+
function matchesFilter(tx, filter) {
|
|
14
|
+
if (filter === 'all')
|
|
15
|
+
return true;
|
|
16
|
+
if (filter === 'purchase')
|
|
17
|
+
return PURCHASE_CODES.has(tx.transaction_code);
|
|
18
|
+
if (filter === 'sale')
|
|
19
|
+
return SALE_CODES.has(tx.transaction_code);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
/** Build a human-readable relationship string from reporting owner flags. */
|
|
23
|
+
function ownerRelationship(owner) {
|
|
24
|
+
const parts = [];
|
|
25
|
+
if (owner.is_director)
|
|
26
|
+
parts.push('Director');
|
|
27
|
+
if (owner.is_officer) {
|
|
28
|
+
parts.push(owner.officer_title ? `Officer (${owner.officer_title})` : 'Officer');
|
|
29
|
+
}
|
|
30
|
+
if (owner.is_ten_percent_owner)
|
|
31
|
+
parts.push('10% Owner');
|
|
32
|
+
if (owner.is_other)
|
|
33
|
+
parts.push('Other');
|
|
34
|
+
return parts.join(', ') || 'Unknown';
|
|
35
|
+
}
|
|
36
|
+
export const getInsiderTransactionsTool = tool('secedgar_get_insider_transactions', {
|
|
37
|
+
title: 'Get Insider Transactions',
|
|
38
|
+
description: 'Fetch Form 4 insider transactions (purchases, sales, grants, exercises) for a company by parsing SEC EDGAR ownership XML. Returns the reporting person, their relationship to the issuer, transaction date, type, shares traded, price per share, and shares owned after the transaction. Covers nonDerivative transactions (open-market buys/sells, gifts) and derivative transactions (option exercises, RSU vests). Use secedgar_search_filings with forms=["4"] for broader date-range queries or to search across all companies.',
|
|
39
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
40
|
+
errors: [
|
|
41
|
+
{
|
|
42
|
+
reason: 'company_not_found',
|
|
43
|
+
code: JsonRpcErrorCode.NotFound,
|
|
44
|
+
when: 'The ticker or CIK does not resolve to a known company',
|
|
45
|
+
recovery: 'Use secedgar_company_search to find the correct ticker or CIK.',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
reason: 'no_filings_found',
|
|
49
|
+
code: JsonRpcErrorCode.NotFound,
|
|
50
|
+
when: 'No Form 4 filings exist for this company in the recent submissions window',
|
|
51
|
+
recovery: 'Use secedgar_search_filings with forms=["4"] for broader historical coverage.',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
input: z.object({
|
|
55
|
+
ticker_or_cik: z
|
|
56
|
+
.string()
|
|
57
|
+
.min(1)
|
|
58
|
+
.describe('Company ticker symbol (e.g., "AAPL") or 10-digit CIK number (e.g., "0000320193"). The issuer, not the reporting person.'),
|
|
59
|
+
transaction_type: z
|
|
60
|
+
.enum(['purchase', 'sale', 'all'])
|
|
61
|
+
.default('all')
|
|
62
|
+
.describe('Filter by direction. "purchase" = open-market buys (code P). "sale" = open-market sells (code S). "all" includes grants, awards, exercises, gifts, and other coded transaction types as well.'),
|
|
63
|
+
limit: z
|
|
64
|
+
.number()
|
|
65
|
+
.int()
|
|
66
|
+
.min(1)
|
|
67
|
+
.max(100)
|
|
68
|
+
.default(20)
|
|
69
|
+
.describe('Maximum number of transactions to return across all Form 4 filings fetched. Filings are scanned newest-first. Default 20.'),
|
|
70
|
+
}),
|
|
71
|
+
output: z.object({
|
|
72
|
+
issuer_name: z.string().describe('Issuer entity name (SEC-conformed).'),
|
|
73
|
+
issuer_cik: z.string().describe('Issuer CIK, zero-padded to 10 digits.'),
|
|
74
|
+
issuer_ticker: z.string().optional().describe('Issuer ticker symbol when available.'),
|
|
75
|
+
transactions: z
|
|
76
|
+
.array(z
|
|
77
|
+
.object({
|
|
78
|
+
filing_date: z.string().describe('Date the Form 4 was filed (YYYY-MM-DD).'),
|
|
79
|
+
period_of_report: z
|
|
80
|
+
.string()
|
|
81
|
+
.optional()
|
|
82
|
+
.describe('Transaction date per the filing period (YYYY-MM-DD).'),
|
|
83
|
+
accession_number: z
|
|
84
|
+
.string()
|
|
85
|
+
.describe('Form 4 accession number — pass to secedgar_get_filing for the raw XML.'),
|
|
86
|
+
reporting_person: z.string().describe('Name of the insider who filed the Form 4.'),
|
|
87
|
+
relationship: z
|
|
88
|
+
.string()
|
|
89
|
+
.describe('Relationship to issuer (e.g., "Director", "Officer (CEO)", "10% Owner").'),
|
|
90
|
+
security_title: z.string().describe('Security type (e.g., "Common Stock").'),
|
|
91
|
+
transaction_date: z
|
|
92
|
+
.string()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe('Date the transaction occurred (YYYY-MM-DD). Absent on some filings.'),
|
|
95
|
+
transaction_code: z
|
|
96
|
+
.string()
|
|
97
|
+
.describe('Single-letter SEC transaction code: P = purchase, S = sale, M = exercise, A = award, G = gift, F = tax withholding, C = conversion, others exist.'),
|
|
98
|
+
transaction_type: z
|
|
99
|
+
.string()
|
|
100
|
+
.describe('Human-readable description of the transaction code (e.g., "purchase", "sale", "conversion_of_derivative").'),
|
|
101
|
+
is_derivative: z
|
|
102
|
+
.boolean()
|
|
103
|
+
.describe('True for derivative security transactions (options, RSUs, convertible notes). False for direct equity transactions.'),
|
|
104
|
+
shares_traded: z
|
|
105
|
+
.number()
|
|
106
|
+
.optional()
|
|
107
|
+
.describe('Shares involved. Negative = disposal (sale, return, gift), positive = acquisition. Absent when the filing omits this field.'),
|
|
108
|
+
price_per_share: z
|
|
109
|
+
.number()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe('Price per share in USD. 0 for gifts and RSU awards (no cash consideration). Absent when not reported.'),
|
|
112
|
+
shares_owned_after: z
|
|
113
|
+
.number()
|
|
114
|
+
.optional()
|
|
115
|
+
.describe('Total shares owned after this transaction, as reported. Absent when omitted by the filer.'),
|
|
116
|
+
ownership_type: z
|
|
117
|
+
.enum(['direct', 'indirect'])
|
|
118
|
+
.optional()
|
|
119
|
+
.describe('D = direct ownership, I = indirect (through a trust, family member, etc.). Absent when not reported.'),
|
|
120
|
+
ownership_nature: z
|
|
121
|
+
.string()
|
|
122
|
+
.optional()
|
|
123
|
+
.describe('Nature of indirect ownership (e.g., "By Trust", "By Spouse"). Only present when ownership_type is indirect.'),
|
|
124
|
+
})
|
|
125
|
+
.describe('One insider transaction parsed from a Form 4 filing.'))
|
|
126
|
+
.describe('Insider transactions, newest filing first.'),
|
|
127
|
+
filings_scanned: z.number().describe('Number of Form 4 filings scanned to produce the result.'),
|
|
128
|
+
}),
|
|
129
|
+
enrichment: {
|
|
130
|
+
notice: z
|
|
131
|
+
.string()
|
|
132
|
+
.optional()
|
|
133
|
+
.describe('Guidance when results are empty after filtering — explains the filter applied and suggests alternatives.'),
|
|
134
|
+
},
|
|
135
|
+
async handler(input, ctx) {
|
|
136
|
+
const api = getEdgarApiService();
|
|
137
|
+
// Resolve company to CIK
|
|
138
|
+
const resolved = await api.resolveCik(input.ticker_or_cik);
|
|
139
|
+
const match = Array.isArray(resolved) ? resolved[0] : resolved;
|
|
140
|
+
if (!match || (Array.isArray(resolved) && resolved.length === 0)) {
|
|
141
|
+
throw ctx.fail('company_not_found', `Company '${input.ticker_or_cik}' not found.`, {
|
|
142
|
+
...ctx.recoveryFor('company_not_found'),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// Fetch recent Form 4 filing metadata from submissions API
|
|
146
|
+
// We over-fetch by 5x to account for multi-transaction filings and filter losses.
|
|
147
|
+
const filingBatch = await api.getRecentFilingsByForm(match.cik, ['4', '4/A'], Math.min(input.limit * 5, 100));
|
|
148
|
+
if (filingBatch.length === 0) {
|
|
149
|
+
throw ctx.fail('no_filings_found', `No Form 4 filings found for '${input.ticker_or_cik}'.`, {
|
|
150
|
+
...ctx.recoveryFor('no_filings_found'),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const transactions = [];
|
|
154
|
+
let filingsScanned = 0;
|
|
155
|
+
for (const filing of filingBatch) {
|
|
156
|
+
if (transactions.length >= input.limit)
|
|
157
|
+
break;
|
|
158
|
+
// primaryDocument may be prefixed with xslF345X06/ — strip to get the bare filename
|
|
159
|
+
const docName = filing.primaryDocument.replace(/^xsl[^/]+\//, '');
|
|
160
|
+
const xmlText = await api.tryGetFilingDocument(match.cik, filing.accessionNumber, docName);
|
|
161
|
+
if (!xmlText)
|
|
162
|
+
continue;
|
|
163
|
+
filingsScanned++;
|
|
164
|
+
let parsed;
|
|
165
|
+
try {
|
|
166
|
+
parsed = parseForm4Xml(xmlText);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Malformed XML in edge cases — skip and continue
|
|
170
|
+
ctx.log.warning('Failed to parse Form 4 XML', {
|
|
171
|
+
accessionNumber: filing.accessionNumber,
|
|
172
|
+
});
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
// Build a single primary owner label from the first reporting owner
|
|
176
|
+
const primaryOwner = parsed.reporting_owners[0];
|
|
177
|
+
const personName = primaryOwner?.name ?? 'Unknown';
|
|
178
|
+
const relationship = primaryOwner ? ownerRelationship(primaryOwner) : 'Unknown';
|
|
179
|
+
for (const tx of parsed.transactions) {
|
|
180
|
+
if (!matchesFilter(tx, input.transaction_type))
|
|
181
|
+
continue;
|
|
182
|
+
if (transactions.length >= input.limit)
|
|
183
|
+
break;
|
|
184
|
+
transactions.push({
|
|
185
|
+
filing_date: filing.filingDate,
|
|
186
|
+
period_of_report: parsed.period_of_report,
|
|
187
|
+
accession_number: filing.accessionNumber,
|
|
188
|
+
reporting_person: personName,
|
|
189
|
+
relationship,
|
|
190
|
+
security_title: tx.security_title,
|
|
191
|
+
transaction_date: tx.transaction_date,
|
|
192
|
+
transaction_code: tx.transaction_code,
|
|
193
|
+
transaction_type: tx.transaction_type,
|
|
194
|
+
is_derivative: tx.is_derivative,
|
|
195
|
+
shares_traded: tx.shares_traded,
|
|
196
|
+
price_per_share: tx.price_per_share,
|
|
197
|
+
shares_owned_after: tx.shares_owned_after,
|
|
198
|
+
ownership_type: tx.ownership_type,
|
|
199
|
+
ownership_nature: tx.ownership_nature,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (transactions.length === 0) {
|
|
204
|
+
const filterNote = input.transaction_type !== 'all'
|
|
205
|
+
? ` with transaction_type="${input.transaction_type}"`
|
|
206
|
+
: '';
|
|
207
|
+
ctx.enrich.notice(`No insider transactions found for '${input.ticker_or_cik}'${filterNote} in the ${filingsScanned} most recent Form 4 filings. ` +
|
|
208
|
+
`Try transaction_type="all" or use secedgar_search_filings with forms=["4"] for broader coverage.`);
|
|
209
|
+
}
|
|
210
|
+
ctx.log.info('Insider transactions retrieved', {
|
|
211
|
+
cik: match.cik,
|
|
212
|
+
filingsScanned,
|
|
213
|
+
transactionCount: transactions.length,
|
|
214
|
+
filter: input.transaction_type,
|
|
215
|
+
});
|
|
216
|
+
// Use issuer data from the first successfully parsed filing when available
|
|
217
|
+
// (the submissions API may not always surface ticker in the same place)
|
|
218
|
+
const issuerTicker = match.ticker ?? undefined;
|
|
219
|
+
return {
|
|
220
|
+
issuer_name: match.name ?? input.ticker_or_cik,
|
|
221
|
+
issuer_cik: match.cik,
|
|
222
|
+
issuer_ticker: issuerTicker,
|
|
223
|
+
transactions,
|
|
224
|
+
filings_scanned: filingsScanned,
|
|
225
|
+
};
|
|
226
|
+
},
|
|
227
|
+
format: (result) => {
|
|
228
|
+
const lines = [
|
|
229
|
+
`**Insider Transactions** — ${result.issuer_name} (CIK ${result.issuer_cik}${result.issuer_ticker ? `, ${result.issuer_ticker}` : ''})`,
|
|
230
|
+
`${result.transactions.length} transaction(s) from ${result.filings_scanned} Form 4 filing(s) scanned`,
|
|
231
|
+
];
|
|
232
|
+
for (const tx of result.transactions) {
|
|
233
|
+
lines.push('');
|
|
234
|
+
const sharesStr = tx.shares_traded !== undefined
|
|
235
|
+
? tx.shares_traded < 0
|
|
236
|
+
? `${Math.abs(tx.shares_traded).toLocaleString()} shares disposed`
|
|
237
|
+
: `${tx.shares_traded.toLocaleString()} shares acquired`
|
|
238
|
+
: 'shares not reported';
|
|
239
|
+
const priceStr = tx.price_per_share !== undefined ? `@ $${tx.price_per_share.toFixed(2)}` : '';
|
|
240
|
+
const ownedStr = tx.shares_owned_after !== undefined
|
|
241
|
+
? ` | owns ${tx.shares_owned_after.toLocaleString()} after`
|
|
242
|
+
: '';
|
|
243
|
+
const derivStr = tx.is_derivative ? ' [derivative]' : '';
|
|
244
|
+
const ownershipStr = tx.ownership_nature
|
|
245
|
+
? ` (${tx.ownership_type ?? 'indirect'}: ${tx.ownership_nature})`
|
|
246
|
+
: tx.ownership_type
|
|
247
|
+
? ` (${tx.ownership_type})`
|
|
248
|
+
: '';
|
|
249
|
+
lines.push(`**${tx.reporting_person}** (${tx.relationship}) — ${tx.transaction_type}${derivStr}`);
|
|
250
|
+
const txDate = tx.transaction_date ?? tx.filing_date;
|
|
251
|
+
const periodStr = tx.period_of_report ? ` | report period: ${tx.period_of_report}` : '';
|
|
252
|
+
lines.push(`${txDate} | ${tx.security_title} | ${sharesStr} ${priceStr}${ownedStr}${ownershipStr}${periodStr}`);
|
|
253
|
+
lines.push(`Code: ${tx.transaction_code} | Filed: ${tx.filing_date} [${tx.accession_number}]`);
|
|
254
|
+
}
|
|
255
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
//# sourceMappingURL=get-insider-transactions.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-insider-transactions.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-insider-transactions.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fetch 13F-HR quarterly institutional holdings by parsing the SEC EDGAR
|
|
3
|
+
* information table XML. Works for both issuer lookup (which institutions hold a stock)
|
|
4
|
+
* and institution lookup (what a specific institution holds).
|
|
5
|
+
* @module mcp-server/tools/definitions/get-institutional-holdings
|
|
6
|
+
*/
|
|
7
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
+
export declare const getInstitutionalHoldingsTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
10
|
+
ticker_or_cik: z.ZodString;
|
|
11
|
+
quarter: z.ZodOptional<z.ZodString>;
|
|
12
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
filer_name: z.ZodString;
|
|
15
|
+
filer_cik: z.ZodString;
|
|
16
|
+
reporting_period: z.ZodOptional<z.ZodString>;
|
|
17
|
+
filing_date: z.ZodString;
|
|
18
|
+
accession_number: z.ZodString;
|
|
19
|
+
total_holdings_in_filing: z.ZodNumber;
|
|
20
|
+
holdings: z.ZodArray<z.ZodObject<{
|
|
21
|
+
issuer_name: z.ZodString;
|
|
22
|
+
title_of_class: z.ZodOptional<z.ZodString>;
|
|
23
|
+
cusip: z.ZodOptional<z.ZodString>;
|
|
24
|
+
value_in_thousands: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
shares_or_principal_amount: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
shares_or_principal_type: z.ZodOptional<z.ZodEnum<{
|
|
27
|
+
SH: "SH";
|
|
28
|
+
PRN: "PRN";
|
|
29
|
+
}>>;
|
|
30
|
+
put_call: z.ZodOptional<z.ZodEnum<{
|
|
31
|
+
Put: "Put";
|
|
32
|
+
Call: "Call";
|
|
33
|
+
}>>;
|
|
34
|
+
investment_discretion: z.ZodOptional<z.ZodEnum<{
|
|
35
|
+
SOLE: "SOLE";
|
|
36
|
+
DFND: "DFND";
|
|
37
|
+
OTR: "OTR";
|
|
38
|
+
}>>;
|
|
39
|
+
}, z.core.$strip>>;
|
|
40
|
+
}, z.core.$strip>, readonly [{
|
|
41
|
+
readonly reason: "company_not_found";
|
|
42
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
43
|
+
readonly when: "The ticker or CIK does not resolve to a known company or institution";
|
|
44
|
+
readonly recovery: "Use secedgar_company_search to find the correct CIK or full entity name.";
|
|
45
|
+
}, {
|
|
46
|
+
readonly reason: "no_filings_found";
|
|
47
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
48
|
+
readonly when: "No 13F-HR filings found for this entity in the recent submissions window";
|
|
49
|
+
readonly recovery: "Use secedgar_search_filings with forms=[\"13F-HR\"] for broader search, or check that the entity is an institutional investment manager.";
|
|
50
|
+
}, {
|
|
51
|
+
readonly reason: "no_info_table";
|
|
52
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
53
|
+
readonly when: "The 13F-HR filing was found but the information table XML document could not be located";
|
|
54
|
+
readonly recovery: "Use secedgar_get_filing with the accession number to inspect the filing documents directly.";
|
|
55
|
+
}], {
|
|
56
|
+
readonly notice: z.ZodOptional<z.ZodString>;
|
|
57
|
+
}>;
|
|
58
|
+
//# sourceMappingURL=get-institutional-holdings.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-institutional-holdings.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-institutional-holdings.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AA6CjE,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmUvC,CAAC"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fetch 13F-HR quarterly institutional holdings by parsing the SEC EDGAR
|
|
3
|
+
* information table XML. Works for both issuer lookup (which institutions hold a stock)
|
|
4
|
+
* and institution lookup (what a specific institution holds).
|
|
5
|
+
* @module mcp-server/tools/definitions/get-institutional-holdings
|
|
6
|
+
*/
|
|
7
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
+
import { getEdgarApiService } from '../../../services/edgar/edgar-api-service.js';
|
|
10
|
+
import { parseInfoTableXml } from '../../../services/edgar/ownership-parser.js';
|
|
11
|
+
/**
|
|
12
|
+
* Parse a quarter string like "2025-Q3" into startDate/endDate for EFTS search.
|
|
13
|
+
* Returns undefined when the quarter string is absent or malformed.
|
|
14
|
+
*/
|
|
15
|
+
function quarterToDateRange(quarter) {
|
|
16
|
+
if (!quarter)
|
|
17
|
+
return;
|
|
18
|
+
const m = quarter.match(/^(\d{4})-Q([1-4])$/i);
|
|
19
|
+
if (!m)
|
|
20
|
+
return;
|
|
21
|
+
const year = Number(m[1]);
|
|
22
|
+
const q = Number(m[2]);
|
|
23
|
+
// 13F filing deadlines: 45 days after quarter end.
|
|
24
|
+
// Q1 ends Mar 31 → filed by May 15; Q2 ends Jun 30 → by Aug 15; etc.
|
|
25
|
+
const quarterEndMonth = q * 3; // 3, 6, 9, 12
|
|
26
|
+
const filingWindowStart = new Date(year, quarterEndMonth - 1, 1).toISOString().slice(0, 10);
|
|
27
|
+
// Window: from quarter end month to 3 months after (covers the 45-day lag)
|
|
28
|
+
const filingWindowEndDate = new Date(year, quarterEndMonth + 2, 28);
|
|
29
|
+
const filingWindowEnd = filingWindowEndDate.toISOString().slice(0, 10);
|
|
30
|
+
return { startDate: filingWindowStart, endDate: filingWindowEnd };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Locate the information table XML document in a 13F filing. The holdings table is the
|
|
34
|
+
* one XML document that is neither the cover page (`primary_doc.xml`) nor an index file —
|
|
35
|
+
* its name varies (infotable.xml, form13fInfoTable.xml, or a numeric name like 53405.xml),
|
|
36
|
+
* and the index `type` field carries only a display icon, so selection is name-based.
|
|
37
|
+
*/
|
|
38
|
+
function findInfoTableDocument(items) {
|
|
39
|
+
const candidates = items.filter((it) => /\.xml$/i.test(it.name) &&
|
|
40
|
+
it.name.toLowerCase() !== 'primary_doc.xml' &&
|
|
41
|
+
!it.name.toLowerCase().includes('index'));
|
|
42
|
+
return (candidates.find((it) => /informationtable|infotable|form13f/i.test(it.name))?.name ??
|
|
43
|
+
candidates[0]?.name);
|
|
44
|
+
}
|
|
45
|
+
export const getInstitutionalHoldingsTool = tool('secedgar_get_institutional_holdings', {
|
|
46
|
+
title: 'Get Institutional Holdings',
|
|
47
|
+
description: 'Fetch 13F-HR quarterly institutional holdings by parsing the SEC EDGAR information table XML. Use ticker_or_cik to look up an institution (e.g., "Vanguard Group" or its CIK) and see what it holds — or pass a company ticker/CIK to find which institutions filed 13Fs covering that period. The 13F information table lists each position: issuer name, CUSIP, shares held, market value (in thousands), and put/call designation for options. Institutions with less than $100M in 13(f) securities are exempt and may not file. Use secedgar_search_filings with forms=["13F-HR"] for broader search.',
|
|
48
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
49
|
+
errors: [
|
|
50
|
+
{
|
|
51
|
+
reason: 'company_not_found',
|
|
52
|
+
code: JsonRpcErrorCode.NotFound,
|
|
53
|
+
when: 'The ticker or CIK does not resolve to a known company or institution',
|
|
54
|
+
recovery: 'Use secedgar_company_search to find the correct CIK or full entity name.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
reason: 'no_filings_found',
|
|
58
|
+
code: JsonRpcErrorCode.NotFound,
|
|
59
|
+
when: 'No 13F-HR filings found for this entity in the recent submissions window',
|
|
60
|
+
recovery: 'Use secedgar_search_filings with forms=["13F-HR"] for broader search, or check that the entity is an institutional investment manager.',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
reason: 'no_info_table',
|
|
64
|
+
code: JsonRpcErrorCode.NotFound,
|
|
65
|
+
when: 'The 13F-HR filing was found but the information table XML document could not be located',
|
|
66
|
+
recovery: 'Use secedgar_get_filing with the accession number to inspect the filing documents directly.',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
input: z.object({
|
|
70
|
+
ticker_or_cik: z
|
|
71
|
+
.string()
|
|
72
|
+
.min(1)
|
|
73
|
+
.describe('Ticker symbol or CIK of the institutional filer (e.g., "0000102909" for Vanguard) or a company name. For institution lookups, CIK or the full legal name resolves most reliably — tickers are typically for operating companies, not fund managers.'),
|
|
74
|
+
quarter: z
|
|
75
|
+
.string()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe('Reporting quarter to target, in "YYYY-QN" format (e.g., "2025-Q4"). When omitted, returns the most recent 13F-HR available. Quarters map to the filing window: Q4 2025 = filings submitted roughly Jan–Mar 2026.'),
|
|
78
|
+
limit: z
|
|
79
|
+
.number()
|
|
80
|
+
.int()
|
|
81
|
+
.min(1)
|
|
82
|
+
.max(500)
|
|
83
|
+
.default(20)
|
|
84
|
+
.describe('Maximum number of holdings rows to return. 13F filings from large institutions can contain thousands of positions. Default 20.'),
|
|
85
|
+
}),
|
|
86
|
+
output: z.object({
|
|
87
|
+
filer_name: z.string().describe('Name of the institutional filer (the 13F submitter).'),
|
|
88
|
+
filer_cik: z.string().describe('CIK of the 13F filer, zero-padded to 10 digits.'),
|
|
89
|
+
reporting_period: z
|
|
90
|
+
.string()
|
|
91
|
+
.optional()
|
|
92
|
+
.describe('The calendar-quarter end date this 13F covers (YYYY-MM-DD), from the filing cover page. Absent if not surfaced in the filing.'),
|
|
93
|
+
filing_date: z.string().describe('Date the 13F was submitted (YYYY-MM-DD).'),
|
|
94
|
+
accession_number: z
|
|
95
|
+
.string()
|
|
96
|
+
.describe('Accession number for this 13F-HR filing — pass to secedgar_get_filing for the full document.'),
|
|
97
|
+
total_holdings_in_filing: z
|
|
98
|
+
.number()
|
|
99
|
+
.describe('Total number of infoTable rows in this filing before the limit was applied.'),
|
|
100
|
+
holdings: z
|
|
101
|
+
.array(z
|
|
102
|
+
.object({
|
|
103
|
+
issuer_name: z.string().describe('Name of the issuer whose securities are held.'),
|
|
104
|
+
title_of_class: z
|
|
105
|
+
.string()
|
|
106
|
+
.optional()
|
|
107
|
+
.describe('Security class (e.g., "COM", "CL A", "ETF"). Absent when not reported.'),
|
|
108
|
+
cusip: z
|
|
109
|
+
.string()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe('9-digit CUSIP identifier. Absent when omitted by the filer.'),
|
|
112
|
+
value_in_thousands: z
|
|
113
|
+
.number()
|
|
114
|
+
.optional()
|
|
115
|
+
.describe('Market value of the position in thousands of USD at the reporting date. Absent when not reported.'),
|
|
116
|
+
shares_or_principal_amount: z
|
|
117
|
+
.number()
|
|
118
|
+
.optional()
|
|
119
|
+
.describe('Number of shares (for equities) or principal amount (for debt securities). Absent when not reported.'),
|
|
120
|
+
shares_or_principal_type: z
|
|
121
|
+
.enum(['SH', 'PRN'])
|
|
122
|
+
.optional()
|
|
123
|
+
.describe('SH = share position, PRN = principal amount (bonds, notes). Absent when not reported.'),
|
|
124
|
+
put_call: z
|
|
125
|
+
.enum(['Put', 'Call'])
|
|
126
|
+
.optional()
|
|
127
|
+
.describe('Options designation. Present only when the row represents a put or call option position.'),
|
|
128
|
+
investment_discretion: z
|
|
129
|
+
.enum(['SOLE', 'DFND', 'OTR'])
|
|
130
|
+
.optional()
|
|
131
|
+
.describe('SOLE = sole investment discretion, DFND = defined (shared/advised), OTR = other. Absent when not reported.'),
|
|
132
|
+
})
|
|
133
|
+
.describe('One row from the 13F information table.'))
|
|
134
|
+
.describe('Holdings rows from the information table, truncated to limit.'),
|
|
135
|
+
}),
|
|
136
|
+
enrichment: {
|
|
137
|
+
notice: z
|
|
138
|
+
.string()
|
|
139
|
+
.optional()
|
|
140
|
+
.describe('Guidance when no filings were found or the result set is empty — suggests alternatives.'),
|
|
141
|
+
},
|
|
142
|
+
async handler(input, ctx) {
|
|
143
|
+
const api = getEdgarApiService();
|
|
144
|
+
// Resolve entity to CIK
|
|
145
|
+
const resolved = await api.resolveCik(input.ticker_or_cik);
|
|
146
|
+
const match = Array.isArray(resolved) ? resolved[0] : resolved;
|
|
147
|
+
if (!match || (Array.isArray(resolved) && resolved.length === 0)) {
|
|
148
|
+
throw ctx.fail('company_not_found', `Entity '${input.ticker_or_cik}' not found.`, {
|
|
149
|
+
...ctx.recoveryFor('company_not_found'),
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// Use submissions API for recent 13F filings
|
|
153
|
+
let filingMeta;
|
|
154
|
+
if (input.quarter) {
|
|
155
|
+
// With a quarter filter, use EFTS to search for the filing in the right window
|
|
156
|
+
const dateRange = quarterToDateRange(input.quarter);
|
|
157
|
+
if (dateRange) {
|
|
158
|
+
const eftsResp = await api.searchFilings({
|
|
159
|
+
query: `cik:${match.cik}`,
|
|
160
|
+
forms: ['13F-HR'],
|
|
161
|
+
startDate: dateRange.startDate,
|
|
162
|
+
endDate: dateRange.endDate,
|
|
163
|
+
from: 0,
|
|
164
|
+
size: 5,
|
|
165
|
+
});
|
|
166
|
+
const hit = eftsResp.hits.hits.find((h) => h._source.ciks?.includes(match.cik));
|
|
167
|
+
if (hit) {
|
|
168
|
+
filingMeta = {
|
|
169
|
+
accessionNumber: hit._source.adsh,
|
|
170
|
+
filingDate: hit._source.file_date,
|
|
171
|
+
primaryDocument: 'primary_doc.xml',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (!filingMeta) {
|
|
177
|
+
// Fall back to submissions API most-recent
|
|
178
|
+
const recentFilings = await api.getRecentFilingsByForm(match.cik, ['13F-HR'], 3);
|
|
179
|
+
filingMeta = recentFilings[0];
|
|
180
|
+
}
|
|
181
|
+
if (!filingMeta) {
|
|
182
|
+
const quarterNote = input.quarter ? ` for quarter "${input.quarter}"` : '';
|
|
183
|
+
throw ctx.fail('no_filings_found', `No 13F-HR filings found for '${input.ticker_or_cik}'${quarterNote}.`, { ...ctx.recoveryFor('no_filings_found') });
|
|
184
|
+
}
|
|
185
|
+
// Get the filing index to find the information table document
|
|
186
|
+
const filingIndex = await api.tryGetFilingIndex(match.cik, filingMeta.accessionNumber);
|
|
187
|
+
if (!filingIndex) {
|
|
188
|
+
throw ctx.fail('no_info_table', `Filing ${filingMeta.accessionNumber} index could not be fetched.`, { ...ctx.recoveryFor('no_info_table') });
|
|
189
|
+
}
|
|
190
|
+
const infoTableDoc = findInfoTableDocument(filingIndex.directory.item);
|
|
191
|
+
if (!infoTableDoc) {
|
|
192
|
+
throw ctx.fail('no_info_table', `No information table XML found in filing ${filingMeta.accessionNumber}.`, {
|
|
193
|
+
accession_number: filingMeta.accessionNumber,
|
|
194
|
+
available_documents: filingIndex.directory.item.map((i) => i.name),
|
|
195
|
+
...ctx.recoveryFor('no_info_table'),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const xmlText = await api.tryGetFilingDocument(match.cik, filingMeta.accessionNumber, infoTableDoc);
|
|
199
|
+
if (!xmlText) {
|
|
200
|
+
throw ctx.fail('no_info_table', `Information table document '${infoTableDoc}' could not be fetched.`, { ...ctx.recoveryFor('no_info_table') });
|
|
201
|
+
}
|
|
202
|
+
// Pull reporting period and filing-manager name from the primary_doc.xml cover page.
|
|
203
|
+
// The CIK resolver only knows names for ticker-listed entities, but most 13F filers
|
|
204
|
+
// are investment managers that aren't listed — the cover page is the reliable source.
|
|
205
|
+
let reportingPeriod;
|
|
206
|
+
let filerName;
|
|
207
|
+
const primaryXml = await api.tryGetFilingDocument(match.cik, filingMeta.accessionNumber, 'primary_doc.xml');
|
|
208
|
+
if (primaryXml) {
|
|
209
|
+
// <periodOfReport>12-31-2025</periodOfReport> or <reportCalendarOrQuarter>12-31-2025</reportCalendarOrQuarter>
|
|
210
|
+
const periodMatch = primaryXml.match(/<periodOfReport>(\d{2}-\d{2}-\d{4})<\/periodOfReport>/) ??
|
|
211
|
+
primaryXml.match(/<reportCalendarOrQuarter>(\d{2}-\d{2}-\d{4})<\/reportCalendarOrQuarter>/);
|
|
212
|
+
if (periodMatch?.[1]) {
|
|
213
|
+
// Convert MM-DD-YYYY to YYYY-MM-DD
|
|
214
|
+
const [mm, dd, yyyy] = periodMatch[1].split('-');
|
|
215
|
+
reportingPeriod = `${yyyy}-${mm}-${dd}`;
|
|
216
|
+
}
|
|
217
|
+
const nameMatch = primaryXml.match(/<(?:\w+:)?filingManager>[\s\S]*?<(?:\w+:)?name>([^<]+)<\/(?:\w+:)?name>/i);
|
|
218
|
+
if (nameMatch?.[1])
|
|
219
|
+
filerName = nameMatch[1].trim();
|
|
220
|
+
}
|
|
221
|
+
let parsed;
|
|
222
|
+
try {
|
|
223
|
+
parsed = parseInfoTableXml(xmlText);
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
throw ctx.fail('no_info_table', `Failed to parse information table XML for filing ${filingMeta.accessionNumber}.`, { ...ctx.recoveryFor('no_info_table') });
|
|
227
|
+
}
|
|
228
|
+
const totalHoldings = parsed.holdings.length;
|
|
229
|
+
const holdings = parsed.holdings.slice(0, input.limit);
|
|
230
|
+
if (holdings.length === 0) {
|
|
231
|
+
ctx.enrich.notice(`The information table for this filing contained no holdings rows. ` +
|
|
232
|
+
`This may be a 13F-NT (notice-only) filing or an amendment. ` +
|
|
233
|
+
`Use secedgar_search_filings with forms=["13F-HR"] to find the correct filing.`);
|
|
234
|
+
}
|
|
235
|
+
ctx.log.info('Institutional holdings retrieved', {
|
|
236
|
+
cik: match.cik,
|
|
237
|
+
accessionNumber: filingMeta.accessionNumber,
|
|
238
|
+
totalHoldings,
|
|
239
|
+
returned: holdings.length,
|
|
240
|
+
});
|
|
241
|
+
return {
|
|
242
|
+
filer_name: filerName ?? match.name ?? input.ticker_or_cik,
|
|
243
|
+
filer_cik: match.cik,
|
|
244
|
+
reporting_period: reportingPeriod,
|
|
245
|
+
filing_date: filingMeta.filingDate,
|
|
246
|
+
accession_number: filingMeta.accessionNumber,
|
|
247
|
+
total_holdings_in_filing: totalHoldings,
|
|
248
|
+
holdings: holdings.map((h) => ({
|
|
249
|
+
issuer_name: h.issuer_name,
|
|
250
|
+
title_of_class: h.title_of_class,
|
|
251
|
+
cusip: h.cusip,
|
|
252
|
+
value_in_thousands: h.value_in_thousands,
|
|
253
|
+
shares_or_principal_amount: h.shares_or_principal_amount,
|
|
254
|
+
shares_or_principal_type: h.shares_or_principal_type,
|
|
255
|
+
put_call: h.put_call,
|
|
256
|
+
investment_discretion: h.investment_discretion,
|
|
257
|
+
})),
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
format: (result) => {
|
|
261
|
+
const period = result.reporting_period ? ` (period: ${result.reporting_period})` : '';
|
|
262
|
+
const lines = [
|
|
263
|
+
`**13F-HR Holdings** — ${result.filer_name} (CIK ${result.filer_cik})`,
|
|
264
|
+
`Filed: ${result.filing_date}${period} | Accession: ${result.accession_number}`,
|
|
265
|
+
`Showing ${result.holdings.length} of ${result.total_holdings_in_filing} total positions`,
|
|
266
|
+
];
|
|
267
|
+
for (const h of result.holdings) {
|
|
268
|
+
lines.push('');
|
|
269
|
+
const valueStr = h.value_in_thousands !== undefined
|
|
270
|
+
? `$${(h.value_in_thousands / 1000).toFixed(2)}M (${h.value_in_thousands}K)`
|
|
271
|
+
: 'value N/A';
|
|
272
|
+
const sharesStr = h.shares_or_principal_amount !== undefined
|
|
273
|
+
? `${h.shares_or_principal_amount.toLocaleString()} ${h.shares_or_principal_type ?? 'shares'}`
|
|
274
|
+
: 'shares N/A';
|
|
275
|
+
const putCallStr = h.put_call ? ` [${h.put_call}]` : '';
|
|
276
|
+
const cusipStr = h.cusip ? ` CUSIP ${h.cusip}` : '';
|
|
277
|
+
const classStr = h.title_of_class ? ` (${h.title_of_class})` : '';
|
|
278
|
+
lines.push(`**${h.issuer_name}**${classStr}${cusipStr}${putCallStr}`);
|
|
279
|
+
lines.push(`${sharesStr} | ${valueStr} | discretion: ${h.investment_discretion ?? 'N/A'}`);
|
|
280
|
+
}
|
|
281
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
//# sourceMappingURL=get-institutional-holdings.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-institutional-holdings.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-institutional-holdings.tool.ts"],"names":[],"mappings":"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"}
|