data-aggregator-mcp 1.0.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.
Files changed (58) hide show
  1. package/README.md +336 -0
  2. package/dist/index.d.ts +14 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +333 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/tools/exchange.d.ts +15 -0
  7. package/dist/tools/exchange.d.ts.map +1 -0
  8. package/dist/tools/exchange.js +195 -0
  9. package/dist/tools/exchange.js.map +1 -0
  10. package/dist/tools/news.d.ts +20 -0
  11. package/dist/tools/news.d.ts.map +1 -0
  12. package/dist/tools/news.js +175 -0
  13. package/dist/tools/news.js.map +1 -0
  14. package/dist/tools/public-data.d.ts +24 -0
  15. package/dist/tools/public-data.d.ts.map +1 -0
  16. package/dist/tools/public-data.js +262 -0
  17. package/dist/tools/public-data.js.map +1 -0
  18. package/dist/tools/scraper.d.ts +19 -0
  19. package/dist/tools/scraper.d.ts.map +1 -0
  20. package/dist/tools/scraper.js +185 -0
  21. package/dist/tools/scraper.js.map +1 -0
  22. package/dist/tools/stocks.d.ts +14 -0
  23. package/dist/tools/stocks.d.ts.map +1 -0
  24. package/dist/tools/stocks.js +172 -0
  25. package/dist/tools/stocks.js.map +1 -0
  26. package/dist/tools/weather.d.ts +15 -0
  27. package/dist/tools/weather.d.ts.map +1 -0
  28. package/dist/tools/weather.js +172 -0
  29. package/dist/tools/weather.js.map +1 -0
  30. package/dist/types.d.ts +160 -0
  31. package/dist/types.d.ts.map +1 -0
  32. package/dist/types.js +3 -0
  33. package/dist/types.js.map +1 -0
  34. package/dist/utils/cache.d.ts +45 -0
  35. package/dist/utils/cache.d.ts.map +1 -0
  36. package/dist/utils/cache.js +88 -0
  37. package/dist/utils/cache.js.map +1 -0
  38. package/dist/utils/http.d.ts +39 -0
  39. package/dist/utils/http.d.ts.map +1 -0
  40. package/dist/utils/http.js +103 -0
  41. package/dist/utils/http.js.map +1 -0
  42. package/dist/utils/rate-limiter.d.ts +34 -0
  43. package/dist/utils/rate-limiter.d.ts.map +1 -0
  44. package/dist/utils/rate-limiter.js +95 -0
  45. package/dist/utils/rate-limiter.js.map +1 -0
  46. package/package.json +42 -0
  47. package/src/index.ts +461 -0
  48. package/src/tools/exchange.ts +241 -0
  49. package/src/tools/news.ts +238 -0
  50. package/src/tools/public-data.ts +325 -0
  51. package/src/tools/scraper.ts +217 -0
  52. package/src/tools/stocks.ts +205 -0
  53. package/src/tools/weather.ts +216 -0
  54. package/src/types.ts +184 -0
  55. package/src/utils/cache.ts +103 -0
  56. package/src/utils/http.ts +156 -0
  57. package/src/utils/rate-limiter.ts +114 -0
  58. package/tsconfig.json +19 -0
@@ -0,0 +1,262 @@
1
+ /**
2
+ * query_public_data - Miscellaneous public API queries.
3
+ *
4
+ * Sub-commands:
5
+ * - wikipedia : Get a Wikipedia article summary
6
+ * - ip_geolocation : Look up geographic info for an IP address
7
+ * - dns_lookup : DNS record lookup for a domain
8
+ * - expand_url : Expand a shortened URL to its final destination
9
+ *
10
+ * All APIs used are free and require no API keys.
11
+ */
12
+ import { cache, TTL } from "../utils/cache.js";
13
+ import { rateLimiter } from "../utils/rate-limiter.js";
14
+ import { httpGetJson, httpFetch, formatError } from "../utils/http.js";
15
+ import { resolve } from "node:dns/promises";
16
+ // ─── Wikipedia Summary ─────────────────────────────────────────────────────
17
+ async function fetchWikipediaSummary(query, language = "en") {
18
+ // Use the Wikipedia REST API summary endpoint
19
+ const encoded = encodeURIComponent(query.replace(/\s+/g, "_"));
20
+ const url = `https://${language}.wikipedia.org/api/rest_v1/page/summary/${encoded}`;
21
+ await rateLimiter.acquire("wikipedia");
22
+ const data = await httpGetJson(url);
23
+ if (data.type === "disambiguation") {
24
+ return {
25
+ title: data.title ?? query,
26
+ extract: `This is a disambiguation page. ${data.extract ?? "Multiple meanings exist for this term."}`,
27
+ url: data.content_urls?.desktop?.page ?? `https://${language}.wikipedia.org/wiki/${encoded}`,
28
+ thumbnail: data.thumbnail?.source,
29
+ timestamp: new Date().toISOString(),
30
+ };
31
+ }
32
+ if (!data.extract) {
33
+ throw new Error(`No Wikipedia article found for "${query}". Try a different search term.`);
34
+ }
35
+ return {
36
+ title: data.title ?? query,
37
+ extract: data.extract,
38
+ url: data.content_urls?.desktop?.page ?? `https://${language}.wikipedia.org/wiki/${encoded}`,
39
+ thumbnail: data.thumbnail?.source,
40
+ timestamp: new Date().toISOString(),
41
+ };
42
+ }
43
+ // ─── IP Geolocation ────────────────────────────────────────────────────────
44
+ async function fetchIpGeolocation(ip) {
45
+ // ip-api.com is free for non-commercial use, no key required
46
+ const target = ip ?? ""; // empty string = caller's IP
47
+ const url = `http://ip-api.com/json/${target}?fields=status,message,country,countryCode,regionName,city,lat,lon,timezone,isp,query`;
48
+ await rateLimiter.acquire("ipgeo");
49
+ const data = await httpGetJson(url);
50
+ if (data.status !== "success") {
51
+ throw new Error(data.message ?? `Geolocation failed for IP "${ip ?? "self"}"`);
52
+ }
53
+ return {
54
+ ip: data.query,
55
+ country: data.country,
56
+ countryCode: data.countryCode,
57
+ region: data.regionName,
58
+ city: data.city,
59
+ latitude: data.lat,
60
+ longitude: data.lon,
61
+ timezone: data.timezone,
62
+ isp: data.isp,
63
+ };
64
+ }
65
+ // ─── DNS Lookup ────────────────────────────────────────────────────────────
66
+ async function fetchDnsRecords(domain, recordType) {
67
+ await rateLimiter.acquire("dns");
68
+ const type = recordType.toUpperCase();
69
+ let records = [];
70
+ try {
71
+ switch (type) {
72
+ case "A": {
73
+ const result = await resolve(domain, "A");
74
+ records = result;
75
+ break;
76
+ }
77
+ case "AAAA": {
78
+ const result = await resolve(domain, "AAAA");
79
+ records = result;
80
+ break;
81
+ }
82
+ case "MX": {
83
+ const result = await resolve(domain, "MX");
84
+ records = result.map((r) => `${r.priority} ${r.exchange}`);
85
+ break;
86
+ }
87
+ case "TXT": {
88
+ const result = await resolve(domain, "TXT");
89
+ records = result.map((r) => r.join(""));
90
+ break;
91
+ }
92
+ case "NS": {
93
+ const result = await resolve(domain, "NS");
94
+ records = result;
95
+ break;
96
+ }
97
+ case "CNAME": {
98
+ const result = await resolve(domain, "CNAME");
99
+ records = result;
100
+ break;
101
+ }
102
+ case "SOA": {
103
+ const result = await resolve(domain, "SOA");
104
+ const soa = result;
105
+ records = [
106
+ `nsname=${soa.nsname} hostmaster=${soa.hostmaster} serial=${soa.serial}`,
107
+ ];
108
+ break;
109
+ }
110
+ default:
111
+ throw new Error(`Unsupported record type: ${type}. Supported: A, AAAA, MX, TXT, NS, CNAME, SOA`);
112
+ }
113
+ }
114
+ catch (err) {
115
+ if (err.code === "ENODATA" || err.code === "ENOTFOUND") {
116
+ records = [];
117
+ }
118
+ else {
119
+ throw err;
120
+ }
121
+ }
122
+ return {
123
+ domain,
124
+ type,
125
+ records,
126
+ };
127
+ }
128
+ // ─── URL Expander ──────────────────────────────────────────────────────────
129
+ async function expandUrl(shortUrl) {
130
+ await rateLimiter.acquire("generic");
131
+ // Follow redirects by making a HEAD request
132
+ const response = await httpFetch(shortUrl, {
133
+ method: "GET",
134
+ maxRetries: 1,
135
+ timeoutMs: 10_000,
136
+ rotateUserAgent: true,
137
+ });
138
+ return {
139
+ originalUrl: shortUrl,
140
+ expandedUrl: response.url,
141
+ statusCode: response.status,
142
+ contentType: response.headers.get("content-type") ?? undefined,
143
+ };
144
+ }
145
+ export async function queryPublicData(args) {
146
+ try {
147
+ const { command } = args;
148
+ switch (command) {
149
+ case "wikipedia": {
150
+ const query = args.query;
151
+ if (!query) {
152
+ return {
153
+ content: [
154
+ { type: "text", text: 'The "query" parameter is required for Wikipedia lookups.' },
155
+ ],
156
+ isError: true,
157
+ };
158
+ }
159
+ const cacheKey = `wiki:${query.toLowerCase()}:${args.language ?? "en"}`;
160
+ const cached = cache.get(cacheKey);
161
+ if (cached) {
162
+ return {
163
+ content: [
164
+ { type: "text", text: JSON.stringify({ ...cached, cached: true }, null, 2) },
165
+ ],
166
+ };
167
+ }
168
+ const summary = await fetchWikipediaSummary(query, args.language);
169
+ cache.set(cacheKey, summary, TTL.PUBLIC);
170
+ return {
171
+ content: [{ type: "text", text: JSON.stringify(summary, null, 2) }],
172
+ };
173
+ }
174
+ case "ip_geolocation": {
175
+ const cacheKey = `ipgeo:${args.ip ?? "self"}`;
176
+ const cached = cache.get(cacheKey);
177
+ if (cached) {
178
+ return {
179
+ content: [
180
+ { type: "text", text: JSON.stringify({ ...cached, cached: true }, null, 2) },
181
+ ],
182
+ };
183
+ }
184
+ const geo = await fetchIpGeolocation(args.ip);
185
+ cache.set(cacheKey, geo, TTL.PUBLIC);
186
+ return {
187
+ content: [{ type: "text", text: JSON.stringify(geo, null, 2) }],
188
+ };
189
+ }
190
+ case "dns_lookup": {
191
+ const domain = args.domain;
192
+ if (!domain) {
193
+ return {
194
+ content: [
195
+ { type: "text", text: 'The "domain" parameter is required for DNS lookups.' },
196
+ ],
197
+ isError: true,
198
+ };
199
+ }
200
+ const recordType = args.recordType ?? "A";
201
+ const cacheKey = `dns:${domain.toLowerCase()}:${recordType}`;
202
+ const cached = cache.get(cacheKey);
203
+ if (cached) {
204
+ return {
205
+ content: [
206
+ { type: "text", text: JSON.stringify({ ...cached, cached: true }, null, 2) },
207
+ ],
208
+ };
209
+ }
210
+ const records = await fetchDnsRecords(domain, recordType);
211
+ cache.set(cacheKey, records, TTL.PUBLIC);
212
+ return {
213
+ content: [{ type: "text", text: JSON.stringify(records, null, 2) }],
214
+ };
215
+ }
216
+ case "expand_url": {
217
+ const url = args.url;
218
+ if (!url) {
219
+ return {
220
+ content: [
221
+ { type: "text", text: 'The "url" parameter is required for URL expansion.' },
222
+ ],
223
+ isError: true,
224
+ };
225
+ }
226
+ const cacheKey = `url:${url}`;
227
+ const cached = cache.get(cacheKey);
228
+ if (cached) {
229
+ return {
230
+ content: [
231
+ { type: "text", text: JSON.stringify({ ...cached, cached: true }, null, 2) },
232
+ ],
233
+ };
234
+ }
235
+ const info = await expandUrl(url);
236
+ cache.set(cacheKey, info, TTL.PUBLIC);
237
+ return {
238
+ content: [{ type: "text", text: JSON.stringify(info, null, 2) }],
239
+ };
240
+ }
241
+ default:
242
+ return {
243
+ content: [
244
+ {
245
+ type: "text",
246
+ text: `Unknown sub-command: "${command}". Available commands: wikipedia, ip_geolocation, dns_lookup, expand_url`,
247
+ },
248
+ ],
249
+ isError: true,
250
+ };
251
+ }
252
+ }
253
+ catch (err) {
254
+ return {
255
+ content: [
256
+ { type: "text", text: `Error in public data query: ${formatError(err)}` },
257
+ ],
258
+ isError: true,
259
+ };
260
+ }
261
+ }
262
+ //# sourceMappingURL=public-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-data.js","sourceRoot":"","sources":["../../src/tools/public-data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * fetch_webpage - Structured web scraping.
3
+ *
4
+ * Fetches a URL and returns structured JSON with:
5
+ * - Page title
6
+ * - Meta description
7
+ * - Headings hierarchy
8
+ * - Main text content (HTML stripped)
9
+ * - Selected content via CSS-selector-like path (basic support)
10
+ * - Links found on the page
11
+ *
12
+ * Uses rotating User-Agent strings for basic anti-scraping.
13
+ */
14
+ import type { ToolResult } from "../types.js";
15
+ export declare function fetchWebpage(args: {
16
+ url: string;
17
+ selector?: string;
18
+ }): Promise<ToolResult>;
19
+ //# sourceMappingURL=scraper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scraper.d.ts","sourceRoot":"","sources":["../../src/tools/scraper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,aAAa,CAAC;AAqI3D,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,UAAU,CAAC,CA+DtB"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * fetch_webpage - Structured web scraping.
3
+ *
4
+ * Fetches a URL and returns structured JSON with:
5
+ * - Page title
6
+ * - Meta description
7
+ * - Headings hierarchy
8
+ * - Main text content (HTML stripped)
9
+ * - Selected content via CSS-selector-like path (basic support)
10
+ * - Links found on the page
11
+ *
12
+ * Uses rotating User-Agent strings for basic anti-scraping.
13
+ */
14
+ import { cache, TTL } from "../utils/cache.js";
15
+ import { rateLimiter } from "../utils/rate-limiter.js";
16
+ import { httpGetText, formatError } from "../utils/http.js";
17
+ // ─── Basic HTML Parsing Helpers ────────────────────────────────────────────
18
+ // We do simple regex-based extraction to avoid heavy deps like cheerio.
19
+ function extractTag(html, tag) {
20
+ const re = new RegExp(`<${tag}[^>]*>([\\s\\S]*?)</${tag}>`, "i");
21
+ const m = html.match(re);
22
+ return m ? stripHtml(m[1]).trim() : "";
23
+ }
24
+ function extractMetaContent(html, name) {
25
+ // Match both name="..." and property="..."
26
+ const re = new RegExp(`<meta\\s+(?:[^>]*?(?:name|property)\\s*=\\s*["']${name}["'][^>]*?content\\s*=\\s*["']([^"']*)["']|[^>]*?content\\s*=\\s*["']([^"']*)["'][^>]*?(?:name|property)\\s*=\\s*["']${name}["'])`, "i");
27
+ const m = html.match(re);
28
+ return (m?.[1] ?? m?.[2] ?? "").trim();
29
+ }
30
+ function extractHeadings(html) {
31
+ const headings = [];
32
+ const re = /<(h[1-6])[^>]*>([\s\S]*?)<\/\1>/gi;
33
+ let match;
34
+ while ((match = re.exec(html)) !== null) {
35
+ const level = parseInt(match[1].charAt(1), 10);
36
+ const text = stripHtml(match[2]).trim();
37
+ if (text)
38
+ headings.push({ level, text });
39
+ }
40
+ return headings;
41
+ }
42
+ function extractLinks(html, baseUrl) {
43
+ const links = [];
44
+ const re = /<a\s+[^>]*href\s*=\s*["']([^"'#]+)["'][^>]*>([\s\S]*?)<\/a>/gi;
45
+ let match;
46
+ const seen = new Set();
47
+ while ((match = re.exec(html)) !== null) {
48
+ let href = match[1].trim();
49
+ const text = stripHtml(match[2]).trim();
50
+ if (!text || !href)
51
+ continue;
52
+ // Resolve relative URLs
53
+ try {
54
+ href = new URL(href, baseUrl).href;
55
+ }
56
+ catch {
57
+ continue;
58
+ }
59
+ if (!seen.has(href)) {
60
+ seen.add(href);
61
+ links.push({ text: text.slice(0, 200), href });
62
+ }
63
+ if (links.length >= 50)
64
+ break;
65
+ }
66
+ return links;
67
+ }
68
+ function stripHtml(html) {
69
+ return html
70
+ .replace(/<script[\s\S]*?<\/script>/gi, " ")
71
+ .replace(/<style[\s\S]*?<\/style>/gi, " ")
72
+ .replace(/<[^>]+>/g, " ")
73
+ .replace(/&nbsp;/gi, " ")
74
+ .replace(/&amp;/gi, "&")
75
+ .replace(/&lt;/gi, "<")
76
+ .replace(/&gt;/gi, ">")
77
+ .replace(/&quot;/gi, '"')
78
+ .replace(/&#39;/gi, "'")
79
+ .replace(/\s+/g, " ")
80
+ .trim();
81
+ }
82
+ function extractMainContent(html) {
83
+ // Try to find <main>, <article>, or role="main" first
84
+ const mainPatterns = [
85
+ /<main[^>]*>([\s\S]*?)<\/main>/i,
86
+ /<article[^>]*>([\s\S]*?)<\/article>/i,
87
+ /<div[^>]*role\s*=\s*["']main["'][^>]*>([\s\S]*?)<\/div>/i,
88
+ ];
89
+ for (const pattern of mainPatterns) {
90
+ const match = html.match(pattern);
91
+ if (match) {
92
+ const text = stripHtml(match[1]);
93
+ if (text.length > 100)
94
+ return text.slice(0, 10_000);
95
+ }
96
+ }
97
+ // Fall back to stripping the body
98
+ const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
99
+ const body = bodyMatch ? bodyMatch[1] : html;
100
+ return stripHtml(body).slice(0, 10_000);
101
+ }
102
+ /**
103
+ * Very basic CSS-selector-like content extraction.
104
+ * Supports: tag, .class, #id (single selector only).
105
+ */
106
+ function extractBySelector(html, selector) {
107
+ let pattern;
108
+ if (selector.startsWith("#")) {
109
+ const id = selector.slice(1);
110
+ pattern = new RegExp(`<([a-z][a-z0-9]*)\\s+[^>]*id\\s*=\\s*["']${id}["'][^>]*>([\\s\\S]*?)<\\/\\1>`, "i");
111
+ }
112
+ else if (selector.startsWith(".")) {
113
+ const cls = selector.slice(1);
114
+ pattern = new RegExp(`<([a-z][a-z0-9]*)\\s+[^>]*class\\s*=\\s*["'][^"']*\\b${cls}\\b[^"']*["'][^>]*>([\\s\\S]*?)<\\/\\1>`, "i");
115
+ }
116
+ else {
117
+ // Plain tag name
118
+ pattern = new RegExp(`<${selector}[^>]*>([\\s\\S]*?)<\\/${selector}>`, "i");
119
+ }
120
+ const match = html.match(pattern);
121
+ if (!match)
122
+ return "";
123
+ // The captured content is in group 2 for id/class patterns, group 1 for tag
124
+ const content = match[2] ?? match[1] ?? "";
125
+ return stripHtml(content).slice(0, 10_000);
126
+ }
127
+ // ─── Public handler ────────────────────────────────────────────────────────
128
+ export async function fetchWebpage(args) {
129
+ try {
130
+ const url = args.url.trim();
131
+ // Validate URL
132
+ try {
133
+ new URL(url);
134
+ }
135
+ catch {
136
+ return {
137
+ content: [{ type: "text", text: `Invalid URL: "${url}"` }],
138
+ isError: true,
139
+ };
140
+ }
141
+ const cacheKey = `scrape:${url}:${args.selector ?? ""}`;
142
+ const cached = cache.get(cacheKey);
143
+ if (cached) {
144
+ return {
145
+ content: [
146
+ { type: "text", text: JSON.stringify({ ...cached, cached: true }, null, 2) },
147
+ ],
148
+ };
149
+ }
150
+ await rateLimiter.acquire("generic");
151
+ const html = await httpGetText(url, {
152
+ rotateUserAgent: true,
153
+ headers: {
154
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
155
+ "Accept-Language": "en-US,en;q=0.5",
156
+ },
157
+ });
158
+ const result = {
159
+ url,
160
+ title: extractTag(html, "title"),
161
+ metaDescription: extractMetaContent(html, "description") ||
162
+ extractMetaContent(html, "og:description"),
163
+ headings: extractHeadings(html),
164
+ mainContent: extractMainContent(html),
165
+ links: extractLinks(html, url),
166
+ timestamp: new Date().toISOString(),
167
+ };
168
+ if (args.selector) {
169
+ result.selectedContent = extractBySelector(html, args.selector);
170
+ }
171
+ cache.set(cacheKey, result, TTL.SCRAPE);
172
+ return {
173
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
174
+ };
175
+ }
176
+ catch (err) {
177
+ return {
178
+ content: [
179
+ { type: "text", text: `Error scraping webpage: ${formatError(err)}` },
180
+ ],
181
+ isError: true,
182
+ };
183
+ }
184
+ }
185
+ //# sourceMappingURL=scraper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scraper.js","sourceRoot":"","sources":["../../src/tools/scraper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;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;AAG5D,8EAA8E;AAC9E,wEAAwE;AAExE,SAAS,UAAU,CAAC,IAAY,EAAE,GAAW;IAC3C,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,uBAAuB,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY,EAAE,IAAY;IACpD,2CAA2C;IAC3C,MAAM,EAAE,GAAG,IAAI,MAAM,CACnB,mDAAmD,IAAI,wHAAwH,IAAI,OAAO,EAC1L,GAAG,CACJ,CAAC;IACF,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,QAAQ,GAAsC,EAAE,CAAC;IACvD,MAAM,EAAE,GAAG,mCAAmC,CAAC;IAC/C,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,IAAI;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,OAAe;IACjD,MAAM,KAAK,GAAqC,EAAE,CAAC;IACnD,MAAM,EAAE,GAAG,+DAA+D,CAAC;IAC3E,IAAI,KAAK,CAAC;IACV,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxC,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;YAAE,SAAS;QAE7B,wBAAwB;QACxB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE;YAAE,MAAM;IAChC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI;SACR,OAAO,CAAC,6BAA6B,EAAE,GAAG,CAAC;SAC3C,OAAO,CAAC,2BAA2B,EAAE,GAAG,CAAC;SACzC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,sDAAsD;IACtD,MAAM,YAAY,GAAG;QACnB,gCAAgC;QAChC,sCAAsC;QACtC,0DAA0D;KAC3D,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;YAClC,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,QAAgB;IACvD,IAAI,OAAe,CAAC;IAEpB,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,OAAO,GAAG,IAAI,MAAM,CAClB,4CAA4C,EAAE,gCAAgC,EAC9E,GAAG,CACJ,CAAC;IACJ,CAAC;SAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,OAAO,GAAG,IAAI,MAAM,CAClB,wDAAwD,GAAG,yCAAyC,EACpG,GAAG,CACJ,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,iBAAiB;QACjB,OAAO,GAAG,IAAI,MAAM,CAAC,IAAI,QAAQ,yBAAyB,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,4EAA4E;IAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAGlC;IACC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAE5B,eAAe;QACf,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,GAAG,EAAE,CAAC;gBAC1D,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,GAAG,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACxD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAc,QAAQ,CAAC,CAAC;QAChD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBAC7E;aACF,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAErC,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE;YAClC,eAAe,EAAE,IAAI;YACrB,OAAO,EAAE;gBACP,QAAQ,EAAE,iEAAiE;gBAC3E,iBAAiB,EAAE,gBAAgB;aACpC;SACF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAgB;YAC1B,GAAG;YACH,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;YAChC,eAAe,EACb,kBAAkB,CAAC,IAAI,EAAE,aAAa,CAAC;gBACvC,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,CAAC;YAC5C,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC;YAC/B,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC;YACrC,KAAK,EAAE,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC;YAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,eAAe,GAAG,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClE,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAExC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,2BAA2B,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE;aACtE;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * query_stocks - Fetch stock and crypto market data.
3
+ *
4
+ * Free data sources:
5
+ * - CoinGecko API (crypto, no key required)
6
+ * - Yahoo Finance v8 unofficial API (stocks, no key required)
7
+ * - Alpha Vantage (stocks, optional key via ALPHA_VANTAGE_KEY env)
8
+ */
9
+ import type { ToolResult } from "../types.js";
10
+ export declare function queryStocks(args: {
11
+ symbol: string;
12
+ type?: "stock" | "crypto" | "auto";
13
+ }): Promise<ToolResult>;
14
+ //# sourceMappingURL=stocks.d.ts.map
@@ -0,0 +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;AAoIvE,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"}