@pipeworx/mcp-emarket-storage 0.1.7 → 0.1.8
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 +2 -2
- package/package.json +3 -3
- package/server.json +1 -1
- package/src/index.ts +45 -6
- package/src/server.ts +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Italian regulated company disclosures direct from eMarket Storage (Teleborsa)
|
|
|
5
5
|
built to fix the months-long lag in the community ESEF index for current-year
|
|
6
6
|
Italian filings.
|
|
7
7
|
|
|
8
|
-
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to
|
|
8
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1881+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
|
|
9
9
|
|
|
10
10
|
## Tools
|
|
11
11
|
|
|
@@ -200,7 +200,7 @@ directly, instead of just this one's:
|
|
|
200
200
|
}
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
Both URLs reach the same gateway and the same
|
|
203
|
+
Both URLs reach the same gateway and the same 1881+ data sources. The
|
|
204
204
|
only difference is which pack's tools are listed **directly**; `ask_pipeworx`
|
|
205
205
|
reaches all of them from either one.
|
|
206
206
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipeworx/mcp-emarket-storage",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Italian regulated disclosures direct from eMarket Storage (Teleborsa) — keyless, same-day-fresh.",
|
|
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-
|
|
30
|
-
"sourceCommit": "
|
|
29
|
+
"sourceHash": "v1-7a1300e601cda197b5f68de83d9ff1dc4320a675b1ee1eed7eff8fadf52856fa",
|
|
30
|
+
"sourceCommit": "24e32b525f9c0b2fd7d94b519b08abb108cc11cd"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.pipeworx-io/emarket-storage",
|
|
4
4
|
"title": "Emarket Storage",
|
|
5
5
|
"description": "Italian regulated disclosures direct from eMarket Storage (Teleborsa) — keyless, same-day-fresh.",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.8",
|
|
7
7
|
"websiteUrl": "https://pipeworx.io/packs/emarket-storage",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/pipeworx-io/mcp-emarket-storage",
|
package/src/index.ts
CHANGED
|
@@ -978,25 +978,64 @@ function rankMatches<T>(
|
|
|
978
978
|
query: string,
|
|
979
979
|
items: T[],
|
|
980
980
|
getName: (item: T) => string,
|
|
981
|
+
getAliases?: (item: T) => string[],
|
|
981
982
|
): RankedMatch<T>[] {
|
|
982
983
|
const q = normalize(query);
|
|
983
984
|
if (!q) return [];
|
|
984
985
|
const scored: { item: T; kind: MatchKind; score: number; len: number }[] = [];
|
|
985
986
|
for (const item of items) {
|
|
986
987
|
const name = getName(item);
|
|
987
|
-
|
|
988
|
+
// `getAliases` (optional, fleet #3607) are OTHER spellings of the same name,
|
|
989
|
+
// each scored on its own; the best-scoring spelling wins. Additive on
|
|
990
|
+
// purpose: the raw name is always tried, so a query that already matched
|
|
991
|
+
// keeps matching exactly as before, and an alias can only ADD a match.
|
|
988
992
|
let kind: MatchKind | null = null;
|
|
989
993
|
let score = 0;
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
+
for (const spelling of [name, ...(getAliases?.(item) ?? [])]) {
|
|
995
|
+
const n = normalize(spelling);
|
|
996
|
+
let k: MatchKind | null = null;
|
|
997
|
+
let sc = 0;
|
|
998
|
+
if (n === q) { k = 'exact'; sc = 4; }
|
|
999
|
+
else if (n.startsWith(`${q} `)) { k = 'prefix'; sc = 3; }
|
|
1000
|
+
else if (n.includes(` ${q} `) || n.endsWith(` ${q}`)) { k = 'word'; sc = 2; }
|
|
1001
|
+
else if (n.includes(q)) { k = 'substring'; sc = 1; }
|
|
1002
|
+
if (k && sc > score) { kind = k; score = sc; }
|
|
1003
|
+
}
|
|
994
1004
|
if (kind) scored.push({ item, kind, score, len: name.length });
|
|
995
1005
|
}
|
|
996
1006
|
scored.sort((a, b) => b.score - a.score || a.len - b.len);
|
|
997
1007
|
return scored.map(({ item, kind, score }) => ({ item, kind, score }));
|
|
998
1008
|
}
|
|
999
1009
|
|
|
1010
|
+
/**
|
|
1011
|
+
* The trailing designators EDGAR appends to a registrant name that are NOT part
|
|
1012
|
+
* of the company's name: state or country of incorporation ("/DE/", "/MD",
|
|
1013
|
+
* "/CAN/", "/Cayman"), "/NEW", and the ADR marker. Matched case-insensitively
|
|
1014
|
+
* against the WHOLE segment after the last slash, so a name with a slash INSIDE
|
|
1015
|
+
* it ("CULLEN/FROST BANKERS", "M/I HOMES", "Quad/Graphics", "DATA I/O CORP",
|
|
1016
|
+
* "GENMAB A/S") is never cut. A genuine legal form that happens to look like a
|
|
1017
|
+
* 2-letter designator ("Anheuser-Busch InBev SA/NV") gains an extra alias
|
|
1018
|
+
* ("...SA"); the raw title is always tried too, so that costs nothing. Measured
|
|
1019
|
+
* against SEC's company_tickers.json 2026-10-26: 951 of 10,429 titles carry a
|
|
1020
|
+
* slash; the trailing segments are ADR (545), CAN, state codes, NEW, CAYMAN,
|
|
1021
|
+
* DEL(AWARE), CANADA, JAPAN, or empty ("TOYOTA MOTOR CORP/").
|
|
1022
|
+
*/
|
|
1023
|
+
const EDGAR_TRAILING_DESIGNATOR =
|
|
1024
|
+
/\s*\/\s*(?:[A-Za-z]{2}|ADR|CAN|NEW|CAYMAN|DEL|DELAWARE|CANADA|JAPAN|UK)?\s*\/?\s*$/i;
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* Other spellings of an EDGAR registrant title that name the same company:
|
|
1028
|
+
* the title with its jurisdiction/ADR designator removed ("TOYOTA MOTOR CORP/"
|
|
1029
|
+
* -> "TOYOTA MOTOR CORP"). Empty when there is nothing to remove. Used as
|
|
1030
|
+
* `rankMatches`'s aliases, never as a replacement for the title (fleet #3607).
|
|
1031
|
+
* Deliberately NOT a change to `normalize`: that is shared by every pack that
|
|
1032
|
+
* ranks its own list, and "/" is not a registrant-name artefact in those.
|
|
1033
|
+
*/
|
|
1034
|
+
function edgarNameAliases(title: string): string[] {
|
|
1035
|
+
const stripped = title.replace(EDGAR_TRAILING_DESIGNATOR, '').trim();
|
|
1036
|
+
return stripped && stripped !== title.trim() && /\S/.test(stripped) ? [stripped] : [];
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1000
1039
|
interface SecTickerRow { cik_str: number; ticker: string; title: string }
|
|
1001
1040
|
|
|
1002
1041
|
interface SecEntity {
|
|
@@ -1053,7 +1092,7 @@ async function resolveSecEntity(
|
|
|
1053
1092
|
}
|
|
1054
1093
|
|
|
1055
1094
|
// 2) Company-name fallback.
|
|
1056
|
-
const ranked = rankMatches(query, rows, (r) => r.title);
|
|
1095
|
+
const ranked = rankMatches(query, rows, (r) => r.title, (r) => edgarNameAliases(r.title));
|
|
1057
1096
|
if (ranked.length) {
|
|
1058
1097
|
const best = toEntity(ranked[0].item, 'company_name');
|
|
1059
1098
|
best.matched_kind = ranked[0].kind;
|
package/src/server.ts
CHANGED