UNPKG

octagon-financials-mcp

Version:

MCP server for Financial Analysis. Provides specialized AI-powered financial statement analysis, ratio calculations, and analysts' estimates with over 8,000 public companies coverage and historical data dating back to 2018.

115 lines (114 loc) 5.06 kB
#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import dotenv from "dotenv"; import { readFile } from "fs/promises"; import OpenAI from "openai"; import path from "path"; import { fileURLToPath } from "url"; import { z } from "zod"; // Get package.json info const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const packageJsonPath = path.join(__dirname, "..", "package.json"); const packageJsonContent = await readFile(packageJsonPath, "utf8"); const packageInfo = JSON.parse(packageJsonContent); // Load environment variables dotenv.config(); // Check for required environment variables const OCTAGON_API_KEY = process.env.OCTAGON_API_KEY; const OCTAGON_API_BASE_URL = process.env.OCTAGON_API_BASE_URL || "https://api.octagonagents.com/v1"; if (!OCTAGON_API_KEY) { console.error("Error: OCTAGON_API_KEY is not set in the environment variables"); console.error("Please set the OCTAGON_API_KEY environment variable or use 'env OCTAGON_API_KEY=your_key npx -y octagon-financials-mcp'"); process.exit(1); } // Initialize OpenAI client with Octagon API const octagonClient = new OpenAI({ apiKey: OCTAGON_API_KEY, baseURL: OCTAGON_API_BASE_URL, defaultHeaders: { "User-Agent": `${packageInfo.name}/${packageInfo.version} (Node.js/${process.versions.node})` }, }); // Create MCP server const server = new McpServer({ name: packageInfo.name, version: packageInfo.version, }); // Helper function to process streaming responses async function processStreamingResponse(stream) { let fullResponse = ""; let citations = []; try { // Process the streaming response for await (const chunk of stream) { // For Chat Completions API if (chunk.choices && chunk.choices[0]?.delta?.content) { fullResponse += chunk.choices[0].delta.content; // Check for citations in the final chunk if (chunk.choices[0]?.finish_reason === "stop" && chunk.choices[0]?.citations) { citations = chunk.choices[0].citations; } } // For Responses API if (chunk.type === "response.output_text.delta") { fullResponse += chunk.text?.delta || ""; } } return fullResponse; } catch (error) { console.error("Error processing streaming response:", error); throw error; } } // Define a schema for the 'prompt' parameter that all tools will use const promptSchema = z.object({ prompt: z.string().describe("Your natural language query or request for the agent"), }); // Financial Data Agent server.tool("octagon-financials-agent", "[PUBLIC MARKET INTELLIGENCE] Specialized agent for public companies' financial statement analysis, financial ratio calculations, and analysts' estimates. Capabilities: Analyze financial statements including income statements, balance sheets, cash flow statements, product segments, geographic segments, analysts' financial estimates, calculate financial metrics, growth rates, compare ratios across companies, and evaluate performance indicators and operational efficiency. Best for: Deep financial analysis and comparison of company financial performance. Example queries: 'Extract quarterly revenue growth rates for Microsoft over the past 2 years', 'Compare the gross margins, operating margins, and net margins of Apple, Microsoft, and Google over the last 3 years', 'Analyze Tesla's cash flow statements from 2021 to 2023 and calculate free cash flow trends', 'Show me Amazon's capex to operating cash flow ratio for the past 3 years','What is NVDA's cash conversion cycle trend over the past 8 quarters?'.", { prompt: z.string().describe("Your natural language query or request for the agent"), }, async ({ prompt }) => { try { const response = await octagonClient.chat.completions.create({ model: "octagon-financials-agent", messages: [{ role: "user", content: prompt }], stream: true, metadata: { tool: "mcp" } }); const result = await processStreamingResponse(response); return { content: [ { type: "text", text: result, }, ], }; } catch (error) { console.error("Error calling Financials agent:", error); return { isError: true, content: [ { type: "text", text: `Error: Failed to process financial data query. ${error}`, }, ], }; } }); // Start the server with stdio transport async function main() { try { const transport = new StdioServerTransport(); await server.connect(transport); } catch (error) { process.exit(1); } } main();