get-stock-alerts
Monitor stock price movements and receive alerts when a specified symbol crosses your set percentage threshold for tracking investment opportunities.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| symbol | Yes | Stock symbol (e.g., IBM, AAPL) | |
| threshold | No | Percentage threshold for price movement alerts (default: 5) |
Implementation Reference
- src/index.ts:87-116 (registration)Registration of the 'get-stock-alerts' MCP tool, including input schema and thin wrapper handler that delegates to getStockAlerts helper.server.tool( 'get-stock-alerts', { symbol: z.string().describe('Stock symbol (e.g., IBM, AAPL)'), threshold: z .number() .optional() .describe('Percentage threshold for price movement alerts (default: 5)'), }, async ({ symbol, threshold = 5 }) => { try { const alerts = await getStockAlerts(symbol, threshold); return { content: [{ type: 'text', text: alerts }], }; } catch (error) { return { content: [ { type: 'text', text: `Error generating stock alerts: ${ error instanceof Error ? error.message : String(error) }`, }, ], isError: true, }; } }, );
- src/alphaVantage.ts:104-169 (handler)Core implementation of getStockAlerts: fetches recent daily stock data via Alpha Vantage API, computes day-over-day percentage changes, and generates alerts for movements exceeding the threshold.export async function getStockAlerts(symbol: string | string[], threshold: number = 5): Promise<string> { try { // Ensure symbol is a string, not an array const symbolStr = Array.isArray(symbol) ? symbol[0] : symbol; // Get daily stock data for analysis const url = `${BASE_URL}?function=TIME_SERIES_DAILY&symbol=${symbolStr}&outputsize=compact&apikey=${API_KEY}`; const response = await axios.get(url); if (response.data['Error Message']) { throw new Error(response.data['Error Message']); } const timeSeries = response.data['Time Series (Daily)']; if (!timeSeries) { throw new Error('No time series data found in the response'); } // Get dates sorted from newest to oldest const dates = Object.keys(timeSeries).sort().reverse(); if (dates.length < 2) { return `Not enough historical data available for ${symbolStr} to generate alerts.`; } let alerts = `Stock Alerts for ${symbolStr.toUpperCase()} (${threshold}% threshold):\n\n`; let alertCount = 0; // Analyze the last 10 days (or less if not available) const daysToAnalyze = Math.min(10, dates.length - 1); for (let i = 0; i < daysToAnalyze; i++) { const currentDate = dates[i]; const previousDate = dates[i + 1]; const currentClose = parseFloat(timeSeries[currentDate]['4. close']); const previousClose = parseFloat(timeSeries[previousDate]['4. close']); // Calculate percentage change const percentChange = ((currentClose - previousClose) / previousClose) * 100; const absPercentChange = Math.abs(percentChange); // Check if change exceeds threshold if (absPercentChange >= threshold) { const direction = percentChange >= 0 ? 'increased' : 'decreased'; alerts += `${currentDate}: Price ${direction} by ${absPercentChange.toFixed( 2, )}% from ${previousClose} to ${currentClose}\n`; alertCount++; } } if (alertCount === 0) { alerts += `No significant price movements (>=${threshold}%) detected in the last ${daysToAnalyze} trading days.\n`; } return alerts; } catch (error) { if (axios.isAxiosError(error)) { throw new Error(`API request failed: ${error.message}`); } throw error; } }
- src/index.ts:89-95 (schema)Zod schema for input validation of the get-stock-alerts tool: requires stock symbol, optional percentage threshold (default 5).{ symbol: z.string().describe('Stock symbol (e.g., IBM, AAPL)'), threshold: z .number() .optional() .describe('Percentage threshold for price movement alerts (default: 5)'), },