Skip to main content
Glama

Stock Market MCP Server

by MCP-100
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js'; import axios from 'axios'; const API_KEY = 'UM3APW59708M49EH'; const BASE_URL = 'https://www.alphavantage.co/query'; class StockMarketServer { private server: Server; private axiosInstance; constructor() { this.server = new Server( { name: 'stock-market', version: '0.1.0', }, { capabilities: { resources: {}, tools: {}, }, } ); this.axiosInstance = axios.create({ baseURL: BASE_URL, params: { apikey: API_KEY, }, }); this.setupToolHandlers(); // Error handling this.server.onerror = (error) => console.error('[MCP Error]', error); process.on('SIGINT', async () => { await this.server.close(); process.exit(0); }); } private setupToolHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'get_ticker_price', description: 'Get current price for a stock ticker', inputSchema: { type: 'object', properties: { symbol: { type: 'string', description: 'Stock ticker symbol' } }, required: ['symbol'] } }, { name: 'get_market_report', description: 'Generate US market report/briefing', inputSchema: { type: 'object', properties: {} } }, { name: 'get_financial_statement', description: 'Get financial statements for a company', inputSchema: { type: 'object', properties: { symbol: { type: 'string', description: 'Stock ticker symbol' }, statement: { type: 'string', enum: ['income', 'balance', 'cashflow'], description: 'Type of financial statement' } }, required: ['symbol', 'statement'] } }, { name: 'get_company_overview', description: 'Get company overview and key metrics', inputSchema: { type: 'object', properties: { symbol: { type: 'string', description: 'Stock ticker symbol' } }, required: ['symbol'] } } ], })); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { switch (request.params.name) { case 'get_ticker_price': return await this.handleGetTickerPrice(request.params.arguments); case 'get_market_report': return await this.handleGetMarketReport(); case 'get_financial_statement': { if (!request.params.arguments || typeof request.params.arguments !== 'object') { throw new McpError(ErrorCode.InvalidParams, 'Invalid arguments'); } const args = request.params.arguments as { statement: 'income' | 'balance' | 'cashflow'; symbol: string }; return await this.handleGetFinancialStatement(args); } case 'get_company_overview': { if (!request.params.arguments || typeof request.params.arguments !== 'object') { throw new McpError(ErrorCode.InvalidParams, 'Invalid arguments'); } const args = request.params.arguments as { symbol: string }; return await this.handleGetCompanyOverview(args); } default: throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`); } } catch (error) { if (axios.isAxiosError(error)) { return { content: [{ type: 'text', text: `API error: ${error.response?.data?.['Error Message'] || error.message}` }], isError: true }; } throw error; } }); } private async handleGetTickerPrice(args: any) { const response = await this.axiosInstance.get('', { params: { function: 'TIME_SERIES_INTRADAY', symbol: args.symbol, interval: '1min', outputsize: 'compact' } }); const latestData = response.data['Time Series (1min)']; const latestTimestamp = Object.keys(latestData)[0]; const price = latestData[latestTimestamp]['1. open']; return { content: [{ type: 'text', text: JSON.stringify({ symbol: args.symbol, price: price, timestamp: latestTimestamp }, null, 2) }] }; } private async handleGetMarketReport() { const response = await this.axiosInstance.get('', { params: { function: 'MARKET_STATUS' } }); return { content: [{ type: 'text', text: JSON.stringify(response.data, null, 2) }] }; } private async handleGetFinancialStatement(args: { statement: 'income' | 'balance' | 'cashflow'; symbol: string }) { if (!args || typeof args !== 'object' || !args.statement || !['income', 'balance', 'cashflow'].includes(args.statement)) { throw new McpError(ErrorCode.InvalidParams, 'Invalid statement parameter'); } if (!args.symbol || typeof args.symbol !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Invalid symbol parameter'); } const functionMap = { income: 'INCOME_STATEMENT', balance: 'BALANCE_SHEET', cashflow: 'CASH_FLOW' }; const response = await this.axiosInstance.get('', { params: { function: functionMap[args.statement], symbol: args.symbol } }); return { content: [{ type: 'text', text: JSON.stringify(response.data, null, 2) }] }; } private async handleGetCompanyOverview(args: { symbol: string }) { const response = await this.axiosInstance.get('', { params: { function: 'OVERVIEW', symbol: args.symbol } }); return { content: [{ type: 'text', text: JSON.stringify(response.data, null, 2) }] }; } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('Stock Market MCP server running on stdio'); } } const server = new StockMarketServer(); server.run().catch(console.error);

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MCP-100/stock-market-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server