yahoo-finance WebMCP
Browser tool configuration for yahoo-finance
URL Pattern: ^https?://finance\.yahoo\.com(/.*)?$
Allowed Extra Domains: finance.yahoo.com, query1.finance.yahoo.com
Tools (1)
yahoo_finance_quote()
Yahoo Finance 股票行情
Parameters
symbol
string
required
- Stock ticker symbol, e.g. AAPL, MSFT, TSLA
JavaScript Handler
(params) => {
const run = async function(args) {
if (!args.symbol) return {error: 'Missing argument: symbol', hint: 'Please provide a stock ticker symbol, e.g. AAPL'};
var symbol = args.symbol.toUpperCase().trim();
// Try v7 quote API first
var url = 'https://query1.finance.yahoo.com/v7/finance/quote?symbols=' + encodeURIComponent(symbol);
var resp;
var data;
try {
resp = await fetch(url, {
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Accept': 'application/json'
}
});
if (resp.ok) {
data = await resp.json();
var results = data && data.quoteResponse && data.quoteResponse.result;
if (results && results.length > 0) {
var q = results[0];
return formatQuote(q);
}
}
} catch(e) {
// v7 failed (likely CORS), fall through to alternatives
}
// Fallback: try v8 chart API
try {
var chartUrl = 'https://query1.finance.yahoo.com/v8/finance/chart/' + encodeURIComponent(symbol) + '?interval=1d&range=1d';
resp = await fetch(chartUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Accept': 'application/json'
}
});
if (resp.ok) {
data = await resp.json();
var chart = data && data.chart && data.chart.result && data.chart.result[0];
if (chart) {
return formatChart(chart, symbol);
}
}
} catch(e) {
// v8 also failed, fall through
}
// Fallback: scrape from Yahoo Finance page via page context
try {
var pageUrl = 'https://finance.yahoo.com/quote/' + encodeURIComponent(symbol) + '/';
resp = await fetch(pageUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Accept': 'text/html'
}
});
if (resp.ok) {
var html = await resp.text();
// Try to extract JSON data embedded in the page
var jsonMatch = html.match(/root\.App\.main\s*=\s*(\{.*?\});\s*\n/);
if (jsonMatch) {
var appData = JSON.parse(jsonMatch[1]);
var stores = appData && appData.context && appData.context.dispatcher && appData.context.dispatcher.stores;
if (stores && stores.QuoteSummaryStore && stores.QuoteSummaryStore.price) {
var price = stores.QuoteSummaryStore.price;
return {
symbol: symbol,
name: price.shortName || price.longName || symbol,
price: price.regularMarketPrice && price.regularMarketPrice.raw,
change: price.regularMarketChange && price.regularMarketChange.raw,
changePercent: price.regularMarketChangePercent && price.regularMarketChangePercent.raw
? (price.regularMarketChangePercent.raw * 100).toFixed(2) + '%' : null,
currency: price.currency,
exchange: price.exchangeName,
marketState: price.marketState,
url: pageUrl
};
}
}
// Try to extract from newer page format (FinanceConfigStore or similar)
var titleMatch = html.match(/<title>([^<]+)<\/title>/);
var priceMatch = html.match(/data-testid="qsp-price"[^>]*>([^<]+)</);
var changeMatch = html.match(/data-testid="qsp-price-change"[^>]*>([^<]+)</);
var changePctMatch = html.match(/data-testid="qsp-price-change-percent"[^>]*>([^<]+)</);
if (priceMatch) {
return {
symbol: symbol,
name: titleMatch ? titleMatch[1].split('(')[0].trim() : symbol,
price: priceMatch[1].replace(/,/g, ''),
change: changeMatch ? changeMatch[1] : null,
changePercent: changePctMatch ? changePctMatch[1] : null,
source: 'page-scrape',
url: pageUrl
};
}
return {error: 'Could not parse quote data from page', symbol: symbol, url: pageUrl};
}
} catch(e) {
// All methods failed
}
return {error: 'Failed to fetch quote for ' + symbol, hint: 'All API methods failed. The symbol may be invalid or Yahoo Finance may be blocking requests.'};
function formatQuote(q) {
return {
symbol: q.symbol,
name: q.shortName || q.longName || q.symbol,
price: q.regularMarketPrice,
change: q.regularMarketChange != null ? q.regularMarketChange.toFixed(2) : null,
changePercent: q.regularMarketChangePercent != null ? q.regularMarketChangePercent.toFixed(2) + '%' : null,
open: q.regularMarketOpen,
high: q.regularMarketDayHigh,
low: q.regularMarketDayLow,
prevClose: q.regularMarketPreviousClose,
volume: q.regularMarketVolume,
marketCap: formatLargeNumber(q.marketCap),
pe: q.trailingPE != null ? q.trailingPE.toFixed(2) : null,
eps: q.epsTrailingTwelveMonths != null ? q.epsTrailingTwelveMonths.toFixed(2) : null,
week52High: q.fiftyTwoWeekHigh,
week52Low: q.fiftyTwoWeekLow,
avgVolume: q.averageDailyVolume3Month,
currency: q.currency,
exchange: q.fullExchangeName || q.exchange,
marketState: q.marketState,
quoteType: q.quoteType,
url: 'https://finance.yahoo.com/quote/' + q.symbol + '/'
};
}
function formatChart(chart, sym) {
var meta = chart.meta || {};
var indicators = chart.indicators;
var quoteData = indicators && indicators.quote && indicators.quote[0];
var timestamps = chart.timestamp || [];
var lastIdx = timestamps.length - 1;
var currentPrice = meta.regularMarketPrice || (quoteData && quoteData.close && quoteData.close[lastIdx]);
var prevClose = meta.previousClose || meta.chartPreviousClose;
var change = (currentPrice != null && prevClose != null) ? (currentPrice - prevClose) : null;
var changePct = (change != null && prevClose) ? ((change / prevClose) * 100) : null;
return {
symbol: meta.symbol || sym,
name: meta.shortName || meta.longName || sym,
price: currentPrice != null ? Number(currentPrice.toFixed(2)) : null,
change: change != null ? change.toFixed(2) : null,
changePercent: changePct != null ? changePct.toFixed(2) + '%' : null,
open: quoteData && quoteData.open ? quoteData.open[0] : null,
high: quoteData && quoteData.high ? Math.max.apply(null, quoteData.high.filter(function(v) { return v != null; })) : null,
low: quoteData && quoteData.low ? Math.min.apply(null, quoteData.low.filter(function(v) { return v != null; })) : null,
prevClose: prevClose,
volume: meta.regularMarketVolume || (quoteData && quoteData.volume ? quoteData.volume[lastIdx] : null),
currency: meta.currency,
exchange: meta.exchangeName,
marketState: meta.marketState,
source: 'chart-api',
url: 'https://finance.yahoo.com/quote/' + (meta.symbol || sym) + '/'
};
}
function formatLargeNumber(v) {
if (v == null) return null;
if (v >= 1e12) return (v / 1e12).toFixed(2) + 'T';
if (v >= 1e9) return (v / 1e9).toFixed(2) + 'B';
if (v >= 1e6) return (v / 1e6).toFixed(2) + 'M';
if (v >= 1e3) return (v / 1e3).toFixed(2) + 'K';
return v.toString();
}
};
return run(params || {});
}
🔌 Chrome MCP Server Extension
Use these tools with Claude, ChatGPT, and other AI assistants.
How to Use WebMCP
WebMCP tools are designed for browser extensions or automation frameworks. The browser extension matches the current URL against the pattern and executes the JavaScript handler when the tool is invoked.
API Endpoint:
GET /api/webmcp/match?url=https://www.yahoo-finance.com/...