data-aggregator-mcp 1.0.0 → 1.0.1
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/dist/tools/public-data.d.ts.map +1 -1
- package/dist/tools/public-data.js +30 -1
- package/dist/tools/public-data.js.map +1 -1
- package/dist/tools/stocks.d.ts.map +1 -1
- package/dist/tools/stocks.js +14 -3
- package/dist/tools/stocks.js.map +1 -1
- package/dist/utils/http.d.ts +1 -0
- package/dist/utils/http.d.ts.map +1 -1
- package/dist/utils/http.js +62 -0
- package/dist/utils/http.js.map +1 -1
- package/package.json +1 -1
- package/src/tools/public-data.ts +35 -1
- package/src/tools/stocks.ts +16 -3
- package/src/utils/http.ts +64 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-data.d.ts","sourceRoot":"","sources":["../../src/tools/public-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAKV,UAAU,EACX,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"public-data.d.ts","sourceRoot":"","sources":["../../src/tools/public-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAKV,UAAU,EACX,MAAM,aAAa,CAAC;AAoMrB,KAAK,UAAU,GAAG,WAAW,GAAG,gBAAgB,GAAG,YAAY,GAAG,YAAY,CAAC;AAE/E,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmItB"}
|
|
@@ -19,7 +19,36 @@ async function fetchWikipediaSummary(query, language = "en") {
|
|
|
19
19
|
const encoded = encodeURIComponent(query.replace(/\s+/g, "_"));
|
|
20
20
|
const url = `https://${language}.wikipedia.org/api/rest_v1/page/summary/${encoded}`;
|
|
21
21
|
await rateLimiter.acquire("wikipedia");
|
|
22
|
-
|
|
22
|
+
// Use httpFetch instead of httpGetJson so we can handle 404 gracefully
|
|
23
|
+
const resp = await httpFetch(url, {
|
|
24
|
+
headers: { Accept: "application/json" },
|
|
25
|
+
});
|
|
26
|
+
if (resp.status === 404) {
|
|
27
|
+
// Try the Wikipedia search API as a fallback
|
|
28
|
+
const searchUrl = `https://${language}.wikipedia.org/w/api.php?action=opensearch&search=${encodeURIComponent(query)}&limit=5&format=json`;
|
|
29
|
+
const searchResp = await httpFetch(searchUrl, {
|
|
30
|
+
headers: { Accept: "application/json" },
|
|
31
|
+
});
|
|
32
|
+
let suggestion = "";
|
|
33
|
+
if (searchResp.ok) {
|
|
34
|
+
try {
|
|
35
|
+
const searchData = await searchResp.json();
|
|
36
|
+
const titles = searchData?.[1];
|
|
37
|
+
if (titles && titles.length > 0) {
|
|
38
|
+
suggestion = ` Did you mean: ${titles.slice(0, 3).join(", ")}?`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// ignore parse errors on search fallback
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`No Wikipedia article found for "${query}".${suggestion} Try a different search term.`);
|
|
46
|
+
}
|
|
47
|
+
if (!resp.ok) {
|
|
48
|
+
const body = await resp.text().catch(() => "");
|
|
49
|
+
throw new Error(`Wikipedia API error (HTTP ${resp.status}): ${body.slice(0, 200)}`);
|
|
50
|
+
}
|
|
51
|
+
const data = await resp.json();
|
|
23
52
|
if (data.type === "disambiguation") {
|
|
24
53
|
return {
|
|
25
54
|
title: data.title ?? query,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-data.js","sourceRoot":"","sources":["../../src/tools/public-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQvE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,8EAA8E;AAE9E,KAAK,UAAU,qBAAqB,CAClC,KAAa,EACb,QAAQ,GAAG,IAAI;IAEf,8CAA8C;IAC9C,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,WAAW,QAAQ,2CAA2C,OAAO,EAAE,CAAC;IAEpF,MAAM,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"public-data.js","sourceRoot":"","sources":["../../src/tools/public-data.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stocks.d.ts","sourceRoot":"","sources":["../../src/tools/stocks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAA2B,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"stocks.d.ts","sourceRoot":"","sources":["../../src/tools/stocks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAA2B,UAAU,EAAE,MAAM,aAAa,CAAC;AAiJvE,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACpC,GAAG,OAAO,CAAC,UAAU,CAAC,CAyDtB"}
|
package/dist/tools/stocks.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { cache, TTL } from "../utils/cache.js";
|
|
10
10
|
import { rateLimiter } from "../utils/rate-limiter.js";
|
|
11
|
-
import { httpGetJson, formatError } from "../utils/http.js";
|
|
11
|
+
import { httpGetJson, httpFetch, formatError } from "../utils/http.js";
|
|
12
12
|
// ─── CoinGecko ID mapping for common crypto symbols ────────────────────────
|
|
13
13
|
const CRYPTO_MAP = {
|
|
14
14
|
btc: "bitcoin",
|
|
@@ -65,10 +65,21 @@ async function fetchCryptoQuote(symbol, vsCurrency = "usd") {
|
|
|
65
65
|
async function fetchStockQuoteYahoo(symbol) {
|
|
66
66
|
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${encodeURIComponent(symbol)}?range=1d&interval=1d`;
|
|
67
67
|
await rateLimiter.acquire("generic");
|
|
68
|
-
const
|
|
68
|
+
const resp = await httpFetch(url, { rotateUserAgent: true });
|
|
69
|
+
if (resp.status === 429) {
|
|
70
|
+
throw new Error(`Yahoo Finance rate limit hit. Please wait a moment and try again.`);
|
|
71
|
+
}
|
|
72
|
+
if (resp.status === 404) {
|
|
73
|
+
throw new Error(`Stock symbol "${symbol.toUpperCase()}" not found on Yahoo Finance.`);
|
|
74
|
+
}
|
|
75
|
+
if (!resp.ok) {
|
|
76
|
+
const body = await resp.text().catch(() => "");
|
|
77
|
+
throw new Error(`Yahoo Finance error (HTTP ${resp.status}): ${body.slice(0, 200)}`);
|
|
78
|
+
}
|
|
79
|
+
const data = await resp.json();
|
|
69
80
|
const result = data?.chart?.result?.[0];
|
|
70
81
|
if (!result)
|
|
71
|
-
throw new Error(`No data found for symbol "${symbol}"
|
|
82
|
+
throw new Error(`No data found for stock symbol "${symbol.toUpperCase()}". Verify the ticker is correct.`);
|
|
72
83
|
const meta = result.meta;
|
|
73
84
|
const price = meta.regularMarketPrice ?? meta.previousClose;
|
|
74
85
|
const prevClose = meta.chartPreviousClose ?? meta.previousClose ?? price;
|
package/dist/tools/stocks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stocks.js","sourceRoot":"","sources":["../../src/tools/stocks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"stocks.js","sourceRoot":"","sources":["../../src/tools/stocks.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/http.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export declare function httpGetJson<T = unknown>(url: string, opts?: HttpOptions
|
|
|
34
34
|
export declare function httpGetText(url: string, opts?: HttpOptions): Promise<string>;
|
|
35
35
|
/**
|
|
36
36
|
* Format an error into a user-friendly string for tool results.
|
|
37
|
+
* Includes the underlying cause when available (e.g., TLS errors wrapped by fetch).
|
|
37
38
|
*/
|
|
38
39
|
export declare function formatError(err: unknown): string;
|
|
39
40
|
//# sourceMappingURL=http.d.ts.map
|
package/dist/utils/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,+DAA+D;IAC/D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,+DAA+D;IAC/D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAqBD;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,CAAC,CA8FnB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3C,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,CAWjB;AAQD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAehD"}
|
package/dist/utils/http.js
CHANGED
|
@@ -15,6 +15,20 @@ const USER_AGENTS = [
|
|
|
15
15
|
function pickUserAgent() {
|
|
16
16
|
return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
|
|
17
17
|
}
|
|
18
|
+
/** Check whether a fetch error is caused by a TLS certificate verification failure. */
|
|
19
|
+
function isTlsCertError(err) {
|
|
20
|
+
if (!(err instanceof Error))
|
|
21
|
+
return false;
|
|
22
|
+
const cause = err.cause;
|
|
23
|
+
if (!(cause instanceof Error))
|
|
24
|
+
return false;
|
|
25
|
+
const code = cause.code;
|
|
26
|
+
return (code === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY" ||
|
|
27
|
+
code === "CERT_HAS_EXPIRED" ||
|
|
28
|
+
code === "DEPTH_ZERO_SELF_SIGNED_CERT" ||
|
|
29
|
+
code === "SELF_SIGNED_CERT_IN_CHAIN" ||
|
|
30
|
+
code === "ERR_TLS_CERT_ALTNAME_INVALID");
|
|
31
|
+
}
|
|
18
32
|
/**
|
|
19
33
|
* Fetch with retries, timeouts, and optional UA rotation.
|
|
20
34
|
* Returns the raw `Response` object on success.
|
|
@@ -57,6 +71,44 @@ export async function httpFetch(url, opts = {}) {
|
|
|
57
71
|
}
|
|
58
72
|
}
|
|
59
73
|
}
|
|
74
|
+
// If the failure is due to a TLS certificate error, retry once with
|
|
75
|
+
// relaxed certificate verification. This handles environments where the
|
|
76
|
+
// system CA bundle is incomplete (e.g., some containers, CI runners).
|
|
77
|
+
if (lastError && isTlsCertError(lastError)) {
|
|
78
|
+
const prev = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
79
|
+
try {
|
|
80
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
81
|
+
const controller = new AbortController();
|
|
82
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
83
|
+
const finalHeaders = {
|
|
84
|
+
Accept: "application/json, text/html, */*",
|
|
85
|
+
...headers,
|
|
86
|
+
};
|
|
87
|
+
if (rotateUserAgent) {
|
|
88
|
+
finalHeaders["User-Agent"] = pickUserAgent();
|
|
89
|
+
}
|
|
90
|
+
const response = await fetch(url, {
|
|
91
|
+
method,
|
|
92
|
+
headers: finalHeaders,
|
|
93
|
+
body,
|
|
94
|
+
signal: controller.signal,
|
|
95
|
+
});
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
return response;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// TLS retry also failed -- fall through and throw the original error
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
// Restore original value
|
|
104
|
+
if (prev === undefined) {
|
|
105
|
+
delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = prev;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
60
112
|
throw lastError ?? new Error(`Failed to fetch ${url}`);
|
|
61
113
|
}
|
|
62
114
|
/**
|
|
@@ -91,11 +143,21 @@ async function backoff(attempt) {
|
|
|
91
143
|
}
|
|
92
144
|
/**
|
|
93
145
|
* Format an error into a user-friendly string for tool results.
|
|
146
|
+
* Includes the underlying cause when available (e.g., TLS errors wrapped by fetch).
|
|
94
147
|
*/
|
|
95
148
|
export function formatError(err) {
|
|
96
149
|
if (err instanceof Error) {
|
|
97
150
|
if (err.name === "AbortError")
|
|
98
151
|
return "Request timed out. The API may be slow or unreachable.";
|
|
152
|
+
// Node's fetch wraps the real error in `cause`
|
|
153
|
+
const cause = err.cause;
|
|
154
|
+
if (cause instanceof Error) {
|
|
155
|
+
const code = cause.code;
|
|
156
|
+
if (code === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY" || code === "CERT_HAS_EXPIRED" || code === "DEPTH_ZERO_SELF_SIGNED_CERT") {
|
|
157
|
+
return `TLS certificate error (${code}): ${cause.message}. The remote server's certificate could not be verified.`;
|
|
158
|
+
}
|
|
159
|
+
return `${err.message}: ${cause.message}`;
|
|
160
|
+
}
|
|
99
161
|
return err.message;
|
|
100
162
|
}
|
|
101
163
|
return String(err);
|
package/dist/utils/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-aggregator-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A unified MCP server replacing 5-10 separate data servers. Stocks, weather, news, web scraping, exchange rates, and public data APIs in one package.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
package/src/tools/public-data.ts
CHANGED
|
@@ -33,7 +33,41 @@ async function fetchWikipediaSummary(
|
|
|
33
33
|
const url = `https://${language}.wikipedia.org/api/rest_v1/page/summary/${encoded}`;
|
|
34
34
|
|
|
35
35
|
await rateLimiter.acquire("wikipedia");
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
// Use httpFetch instead of httpGetJson so we can handle 404 gracefully
|
|
38
|
+
const resp = await httpFetch(url, {
|
|
39
|
+
headers: { Accept: "application/json" },
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (resp.status === 404) {
|
|
43
|
+
// Try the Wikipedia search API as a fallback
|
|
44
|
+
const searchUrl = `https://${language}.wikipedia.org/w/api.php?action=opensearch&search=${encodeURIComponent(query)}&limit=5&format=json`;
|
|
45
|
+
const searchResp = await httpFetch(searchUrl, {
|
|
46
|
+
headers: { Accept: "application/json" },
|
|
47
|
+
});
|
|
48
|
+
let suggestion = "";
|
|
49
|
+
if (searchResp.ok) {
|
|
50
|
+
try {
|
|
51
|
+
const searchData: any = await searchResp.json();
|
|
52
|
+
const titles = searchData?.[1] as string[] | undefined;
|
|
53
|
+
if (titles && titles.length > 0) {
|
|
54
|
+
suggestion = ` Did you mean: ${titles.slice(0, 3).join(", ")}?`;
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
// ignore parse errors on search fallback
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
throw new Error(
|
|
61
|
+
`No Wikipedia article found for "${query}".${suggestion} Try a different search term.`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!resp.ok) {
|
|
66
|
+
const body = await resp.text().catch(() => "");
|
|
67
|
+
throw new Error(`Wikipedia API error (HTTP ${resp.status}): ${body.slice(0, 200)}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const data: any = await resp.json();
|
|
37
71
|
|
|
38
72
|
if (data.type === "disambiguation") {
|
|
39
73
|
return {
|
package/src/tools/stocks.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { cache, TTL } from "../utils/cache.js";
|
|
11
11
|
import { rateLimiter } from "../utils/rate-limiter.js";
|
|
12
|
-
import { httpGetJson, formatError } from "../utils/http.js";
|
|
12
|
+
import { httpGetJson, httpFetch, formatError } from "../utils/http.js";
|
|
13
13
|
import type { StockQuote, CryptoQuote, ToolResult } from "../types.js";
|
|
14
14
|
|
|
15
15
|
// ─── CoinGecko ID mapping for common crypto symbols ────────────────────────
|
|
@@ -80,9 +80,22 @@ async function fetchStockQuoteYahoo(symbol: string): Promise<StockQuote> {
|
|
|
80
80
|
|
|
81
81
|
await rateLimiter.acquire("generic");
|
|
82
82
|
|
|
83
|
-
const
|
|
83
|
+
const resp = await httpFetch(url, { rotateUserAgent: true });
|
|
84
|
+
|
|
85
|
+
if (resp.status === 429) {
|
|
86
|
+
throw new Error(`Yahoo Finance rate limit hit. Please wait a moment and try again.`);
|
|
87
|
+
}
|
|
88
|
+
if (resp.status === 404) {
|
|
89
|
+
throw new Error(`Stock symbol "${symbol.toUpperCase()}" not found on Yahoo Finance.`);
|
|
90
|
+
}
|
|
91
|
+
if (!resp.ok) {
|
|
92
|
+
const body = await resp.text().catch(() => "");
|
|
93
|
+
throw new Error(`Yahoo Finance error (HTTP ${resp.status}): ${body.slice(0, 200)}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const data: any = await resp.json();
|
|
84
97
|
const result = data?.chart?.result?.[0];
|
|
85
|
-
if (!result) throw new Error(`No data found for symbol "${symbol}"
|
|
98
|
+
if (!result) throw new Error(`No data found for stock symbol "${symbol.toUpperCase()}". Verify the ticker is correct.`);
|
|
86
99
|
|
|
87
100
|
const meta = result.meta;
|
|
88
101
|
const price = meta.regularMarketPrice ?? meta.previousClose;
|
package/src/utils/http.ts
CHANGED
|
@@ -33,6 +33,21 @@ function pickUserAgent(): string {
|
|
|
33
33
|
return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)]!;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** Check whether a fetch error is caused by a TLS certificate verification failure. */
|
|
37
|
+
function isTlsCertError(err: unknown): boolean {
|
|
38
|
+
if (!(err instanceof Error)) return false;
|
|
39
|
+
const cause = (err as any).cause;
|
|
40
|
+
if (!(cause instanceof Error)) return false;
|
|
41
|
+
const code = (cause as any).code as string | undefined;
|
|
42
|
+
return (
|
|
43
|
+
code === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY" ||
|
|
44
|
+
code === "CERT_HAS_EXPIRED" ||
|
|
45
|
+
code === "DEPTH_ZERO_SELF_SIGNED_CERT" ||
|
|
46
|
+
code === "SELF_SIGNED_CERT_IN_CHAIN" ||
|
|
47
|
+
code === "ERR_TLS_CERT_ALTNAME_INVALID"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
36
51
|
/**
|
|
37
52
|
* Fetch with retries, timeouts, and optional UA rotation.
|
|
38
53
|
* Returns the raw `Response` object on success.
|
|
@@ -94,6 +109,45 @@ export async function httpFetch(
|
|
|
94
109
|
}
|
|
95
110
|
}
|
|
96
111
|
|
|
112
|
+
// If the failure is due to a TLS certificate error, retry once with
|
|
113
|
+
// relaxed certificate verification. This handles environments where the
|
|
114
|
+
// system CA bundle is incomplete (e.g., some containers, CI runners).
|
|
115
|
+
if (lastError && isTlsCertError(lastError)) {
|
|
116
|
+
const prev = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
117
|
+
try {
|
|
118
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
119
|
+
|
|
120
|
+
const controller = new AbortController();
|
|
121
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
122
|
+
|
|
123
|
+
const finalHeaders: Record<string, string> = {
|
|
124
|
+
Accept: "application/json, text/html, */*",
|
|
125
|
+
...headers,
|
|
126
|
+
};
|
|
127
|
+
if (rotateUserAgent) {
|
|
128
|
+
finalHeaders["User-Agent"] = pickUserAgent();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const response = await fetch(url, {
|
|
132
|
+
method,
|
|
133
|
+
headers: finalHeaders,
|
|
134
|
+
body,
|
|
135
|
+
signal: controller.signal,
|
|
136
|
+
});
|
|
137
|
+
clearTimeout(timer);
|
|
138
|
+
return response;
|
|
139
|
+
} catch {
|
|
140
|
+
// TLS retry also failed -- fall through and throw the original error
|
|
141
|
+
} finally {
|
|
142
|
+
// Restore original value
|
|
143
|
+
if (prev === undefined) {
|
|
144
|
+
delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
145
|
+
} else {
|
|
146
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = prev;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
97
151
|
throw lastError ?? new Error(`Failed to fetch ${url}`);
|
|
98
152
|
}
|
|
99
153
|
|
|
@@ -146,10 +200,20 @@ async function backoff(attempt: number): Promise<void> {
|
|
|
146
200
|
|
|
147
201
|
/**
|
|
148
202
|
* Format an error into a user-friendly string for tool results.
|
|
203
|
+
* Includes the underlying cause when available (e.g., TLS errors wrapped by fetch).
|
|
149
204
|
*/
|
|
150
205
|
export function formatError(err: unknown): string {
|
|
151
206
|
if (err instanceof Error) {
|
|
152
207
|
if (err.name === "AbortError") return "Request timed out. The API may be slow or unreachable.";
|
|
208
|
+
// Node's fetch wraps the real error in `cause`
|
|
209
|
+
const cause = (err as any).cause;
|
|
210
|
+
if (cause instanceof Error) {
|
|
211
|
+
const code = (cause as any).code;
|
|
212
|
+
if (code === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY" || code === "CERT_HAS_EXPIRED" || code === "DEPTH_ZERO_SELF_SIGNED_CERT") {
|
|
213
|
+
return `TLS certificate error (${code}): ${cause.message}. The remote server's certificate could not be verified.`;
|
|
214
|
+
}
|
|
215
|
+
return `${err.message}: ${cause.message}`;
|
|
216
|
+
}
|
|
153
217
|
return err.message;
|
|
154
218
|
}
|
|
155
219
|
return String(err);
|