canli-markets-mcp 0.7.2 → 0.7.4
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/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/src/news.mjs +1 -1
- package/src/tools.mjs +31 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.4
|
|
4
|
+
|
|
5
|
+
- `treasury_yields` over several years lines each maturity up by name. The Treasury added the 4-month
|
|
6
|
+
bill in 2022 and the 6-week in 2025, so a range across those years had shorter rows under the newest
|
|
7
|
+
year's headings (a 2021 row's 10-year yield sat under "7 Yr"). Columns are now every maturity in any
|
|
8
|
+
year asked for, in maturity order, with null where a year did not publish one.
|
|
9
|
+
|
|
10
|
+
## 0.7.3
|
|
11
|
+
|
|
12
|
+
- `news` and `explain_move` search for a company by its plain name when its SEC name ends in "/NEW"
|
|
13
|
+
(Costco Wholesale was searched as "Costco Wholesale CORP /NEW" and found nothing).
|
|
14
|
+
|
|
3
15
|
## 0.7.2
|
|
4
16
|
|
|
5
17
|
- `market_overview`: the market at a glance in one call: US indices and the VIX, the eleven S&P sectors
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canli-markets-mcp",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "MCP server for markets, funds and the economy from the sources themselves, no key: European companies' ESEF annual reports, central-bank rates (SOFR, €STR, SONIA, 40 policy rates), Polymarket and Kalshi odds, DeFi value locked and fees, financial statements as filed, the tables in filings, earnings guidance as ranges and a draft's figures checked against the filings, options chains and volatility, short interest, dark pools, futures positioning, fund and ETF holdings, 13D/13G, earnings dates and 8-K press-release headlines, segment revenue, executive pay, Form D, the Fed, Treasury auctions, World Bank and OECD macro, screens, filings and prices. Every result cites its sources.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
package/src/news.mjs
CHANGED
|
@@ -22,7 +22,7 @@ export const newsInput = z.object({
|
|
|
22
22
|
|
|
23
23
|
// A company's legal name as people write it: "NVIDIA CORP" -> "NVIDIA", "Apple Inc." -> "Apple".
|
|
24
24
|
export function plainName(name) {
|
|
25
|
-
return String(name).replace(/\s*\/[A-Z]{2}\/?\s*$/, "").replace(/\s*&\s*co\.?$/i, "").replace(/[,.]?\s+(inc|corp|corporation|co|company|ltd|plc|holdings|group|incorporated|lp|llc|sa|nv|ag|se)\.?$/i, "").replace(/[,.]?\s+(inc|corp|corporation|co|ltd|plc)\.?$/i, "").trim()
|
|
25
|
+
return String(name).replace(/\s*\/[A-Z]{2,3}\/?\s*$/, "").replace(/\s*&\s*co\.?$/i, "").replace(/[,.]?\s+(inc|corp|corporation|co|company|ltd|plc|holdings|group|incorporated|lp|llc|sa|nv|ag|se)\.?$/i, "").replace(/[,.]?\s+(inc|corp|corporation|co|ltd|plc)\.?$/i, "").trim()
|
|
26
26
|
.replace(/\b([A-Z])([A-Z]+)\b/g, (w) => (w.length > 4 ? w[0] + w.slice(1).toLowerCase() : w));
|
|
27
27
|
}
|
|
28
28
|
|
package/src/tools.mjs
CHANGED
|
@@ -370,6 +370,30 @@ export const treasuryInput = z.object({
|
|
|
370
370
|
start: DATE.optional().describe("A range instead of one day: first date."),
|
|
371
371
|
end: DATE.optional().describe("Last date of the range; default today."),
|
|
372
372
|
}).strict();
|
|
373
|
+
// A maturity in months ("1 Mo", "1.5 Month", "4 WEEKS BANK DISCOUNT", "10 Yr"), or null.
|
|
374
|
+
const tenorMonths = (h) => {
|
|
375
|
+
const m = /^(\d+(?:\.\d+)?)\s*(wk|weeks?|mo|months?|yr|years?)\b/i.exec(h);
|
|
376
|
+
if (!m) return null;
|
|
377
|
+
const u = m[2].toLowerCase();
|
|
378
|
+
return Number(m[1]) * (u.startsWith("w") ? 12 / 52 : u.startsWith("m") ? 1 : 12);
|
|
379
|
+
};
|
|
380
|
+
// Years of rates as one table. The Treasury adds and drops maturities (the 4-month bill in 2022,
|
|
381
|
+
// the 6-week in 2025), so each year's columns are matched by name; the newest year's order is kept
|
|
382
|
+
// and a maturity only older years have is placed by its length.
|
|
383
|
+
export function joinYears(parts) {
|
|
384
|
+
const names = parts[0].header.slice(1);
|
|
385
|
+
for (const p of parts.slice(1)) for (const h of p.header.slice(1)) {
|
|
386
|
+
if (names.includes(h)) continue;
|
|
387
|
+
const m = tenorMonths(h), at = m === null ? -1 : names.findIndex((x) => (tenorMonths(x) ?? Infinity) > m);
|
|
388
|
+
names.splice(at < 0 ? names.length : at, 0, h);
|
|
389
|
+
}
|
|
390
|
+
const rows = parts.flatMap((p) => {
|
|
391
|
+
const ix = names.map((h) => p.header.indexOf(h));
|
|
392
|
+
return p.rows.map((r) => [r[0], ...ix.map((i) => (i < 1 ? null : r[i] ?? null))]);
|
|
393
|
+
});
|
|
394
|
+
rows.sort((x, y) => x[0].localeCompare(y[0]));
|
|
395
|
+
return { names, rows };
|
|
396
|
+
}
|
|
373
397
|
export async function treasuryYields(session, args) {
|
|
374
398
|
const a = treasuryInput.parse(args);
|
|
375
399
|
const curve = a.curve ?? "nominal";
|
|
@@ -379,17 +403,17 @@ export async function treasuryYields(session, args) {
|
|
|
379
403
|
const years = [];
|
|
380
404
|
for (let y = Number(last.slice(0, 4)); y >= Number(first.slice(0, 4)); y--) years.push(y);
|
|
381
405
|
if (years.length > 40) throw new Error("treasury_yields reads at most 40 years at once.");
|
|
382
|
-
|
|
406
|
+
const parts = [];
|
|
383
407
|
for (const y of years) {
|
|
384
408
|
let t;
|
|
385
409
|
try { t = await treasuryYear(session, y, curve); } catch (err) { if (err instanceof NotFound) continue; throw err; }
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (!ranged &&
|
|
410
|
+
const kept = t.rows.filter((r) => r[0] >= first && r[0] <= last);
|
|
411
|
+
if (kept.length) parts.push({ ...t, rows: kept });
|
|
412
|
+
if (!ranged && kept.length) break;
|
|
389
413
|
}
|
|
390
|
-
if (!
|
|
391
|
-
rows
|
|
392
|
-
const cols = ["date", ...
|
|
414
|
+
if (!parts.length) throw new NotFound(`No ${curve} Treasury rates between ${first} and ${last}.`);
|
|
415
|
+
const { names, rows } = joinYears(parts), url = parts[0].url;
|
|
416
|
+
const cols = ["date", ...names];
|
|
393
417
|
const base = { curve, units: "percent a year", columns: cols, source: url, limits: ["U.S. Department of the Treasury daily rates, as published; par yields on a bond-equivalent basis.", "Not investment advice."] };
|
|
394
418
|
if (!ranged) {
|
|
395
419
|
const day = rows[rows.length - 1];
|