Skip to main content
Glama
josuekongolo

CompanyIQ MCP Server

by josuekongolo
financial_analysis.ts8.31 kB
import { z } from 'zod'; import { CompanyDatabase } from '../database/db.js'; import { RiskAnalyzer } from '../analytics/risk_analyzer.js'; import { BrregClient } from '../apis/brreg.js'; import { RegnskapClient } from '../apis/regnskap.js'; const FinancialAnalysisSchema = z.object({ org_nr: z.string().describe("Organisasjonsnummer"), include_risk_assessment: z.boolean().default(true).describe("Inkluder konkursrisikoanalyse"), auto_fetch: z.boolean().default(true).describe("Automatisk hent regnskapsdata hvis ikke i database") }); export async function analyzeFinancials(args: unknown, db: CompanyDatabase, brreg: BrregClient) { const params = FinancialAnalysisSchema.parse(args); const company = await db.getCompany(params.org_nr); if (!company) { return { content: [{ type: "text" as const, text: `Fant ikke selskap med org.nr ${params.org_nr}` }] }; } let financialHistory = await db.getFinancialHistory(params.org_nr, 10); // Auto-fetch if no data and auto_fetch enabled if (financialHistory.length === 0 && params.auto_fetch) { console.error('📊 No financial data in database, triggering FULL AUTO-SCRAPE...'); console.error('🤖 This will download ALL available years automatically...'); console.error('⏳ Please wait 2-5 minutes for complete automation...'); try { // Use the browser scraper to get ALL years const { BrowserScraper } = await import('../scraper/browser_scraper.js'); const openaiApiKey = process.env.OPENAI_API_KEY; if (!openaiApiKey) { console.error('⚠️ OPENAI_API_KEY not set - PDF extraction may be limited'); } const scraper = new BrowserScraper(openaiApiKey, params.org_nr); const allYears = await scraper.getAllFinancialYears(params.org_nr); console.error(`✅ Auto-scraper completed! Got ${allYears.length} years`); // Save all years to database for (const yearData of allYears) { if (yearData.revenue !== null || yearData.profit !== null) { try { await db.insertFinancialSnapshot({ org_nr: params.org_nr, year: yearData.year, revenue: yearData.revenue, profit: yearData.profit, assets: yearData.assets, equity: yearData.equity, employees: null, source: yearData.source }); } catch (e) { // Might already exist, ignore } } } // Re-fetch from database financialHistory = await db.getFinancialHistory(params.org_nr, 10); console.error(`✅ Database now has ${financialHistory.length} years of financial data`); } catch (error) { console.error('⚠️ Auto-scrape failed, trying simple API fetch...'); // Fallback to simple API fetch const regnskapClient = new RegnskapClient(); const financialData = await regnskapClient.getExtractedFinancials(params.org_nr); if (financialData) { await db.insertFinancialSnapshot({ org_nr: financialData.org_nr, year: financialData.year, revenue: financialData.revenue, profit: financialData.profit, assets: financialData.assets, equity: financialData.equity, employees: null, source: 'regnskapsregisteret_api' }); financialHistory = await db.getFinancialHistory(params.org_nr, 10); } } } if (financialHistory.length === 0) { // Do basic risk assessment even without financial data const basicRisk = { overallScore: company.bankrupt ? 100 : company.under_liquidation ? 70 : 30, bankruptcyRisk: company.bankrupt ? 100 : company.under_liquidation ? 70 : 30, factors: [ company.bankrupt ? '⚠️ Selskapet er konkurs' : '', company.under_liquidation ? '⚠️ Selskapet er under avvikling' : '', !company.bankrupt && !company.under_liquidation ? '✅ Ingen konkursindikasjoner' : '', company.employees_count ? `👥 ${company.employees_count} ansatte` : '⚠️ Ingen registrerte ansatte' ].filter(f => f), recommendation: company.bankrupt ? 'KRITISK - Unngå' : company.under_liquidation ? 'HØY RISIKO' : 'Ingen finansdata tilgjengelig' }; return { content: [{ type: "text" as const, text: ` 💰 RISIKOANALYSE: ${company.name} ⚠️ VIKTIG: Ingen regnskapsdata tilgjengelig i CompanyIQ. Brønnøysund Enhetsregisteret API gir IKKE tilgang til: - Omsetning (revenue) - Resultat (profit) - Eiendeler (assets) - Egenkapital (equity) 📊 BASERT PÅ TILGJENGELIG DATA: - Organisasjonsnummer: ${params.org_nr} - Status: ${company.bankrupt ? '🔴 KONKURS' : company.under_liquidation ? '⚠️ UNDER AVVIKLING' : '✅ Aktiv'} - Ansatte: ${company.employees_count || 'Ikke registrert'} - Bransje: ${company.nace_description || 'Ukjent'} - Siste innsendte årsregnskap: ${(company as any).last_updated || 'Ukjent'} ⚠️ RISIKOVURDERING (Begrenset): Risikoscore: ${basicRisk.overallScore}/100 Anbefaling: ${basicRisk.recommendation} Faktorer: ${basicRisk.factors.join('\n')} 💡 FOR FULL FINANSIELL ANALYSE: Bruk kommersielle tjenester som: - Proff.no (https://proff.no) - Komplett regnskapsdata - Bisnode - Kredittrating og finansdata - Manuell nedlasting fra Brønnøysund ℹ️ CompanyIQ er best til markedsintelligens, ikke finansiell due diligence. ` }] }; } let riskAssessment = null; if (params.include_risk_assessment) { const riskAnalyzer = new RiskAnalyzer(); riskAssessment = riskAnalyzer.assessBankruptcyRisk(company, financialHistory); // Save to database await db.insertRiskScore({ org_nr: params.org_nr, overall_score: riskAssessment.overallScore, bankruptcy_risk: riskAssessment.bankruptcyRisk, growth_score: 50, stability_score: 50, financial_health_score: 100 - riskAssessment.bankruptcyRisk, factors: riskAssessment.factors }); } const latest = financialHistory[0] as any; const report = ` 💰 FINANSIELL ANALYSE: ${company.name} 📊 SISTE REGNSKAPSÅR (${latest.year}): ${latest.revenue ? `- Omsetning: ${(latest.revenue / 1000000).toFixed(1)}M NOK` : ''} ${latest.profit ? `- Resultat: ${(latest.profit / 1000000).toFixed(1)}M NOK` : ''} ${latest.assets ? `- Eiendeler: ${(latest.assets / 1000000).toFixed(1)}M NOK` : ''} ${latest.equity ? `- Egenkapital: ${(latest.equity / 1000000).toFixed(1)}M NOK` : ''} ${latest.employees ? `- Ansatte: ${latest.employees}` : ''} ${financialHistory.length > 1 ? ` 📈 HISTORIKK (${financialHistory.length} år): ${financialHistory.map((f: any) => `${f.year}: ${f.revenue ? (f.revenue / 1000000).toFixed(1) + 'M NOK' : 'N/A'}` ).join(' | ')} ` : ''} ${riskAssessment ? ` ⚠️ RISIKOVURDERING: Samlet risikoscore: ${riskAssessment.overallScore}/100 Anbefaling: ${riskAssessment.recommendation} Faktorer: ${riskAssessment.factors.join('\n')} ` : ''} 📋 DATAKILDE: ${financialHistory.map((f: any) => { if (f.source === 'openai_vision_extraction') return '✅ Ekstrahert fra offisielle årsregnskap (PDF) via AI'; if (f.source === 'regnskapsregisteret_api') return '✅ Hentet fra Regnskapsregisteret API'; return '⚠️ Estimert data'; }).filter((v: string, i: number, a: string[]) => a.indexOf(v) === i).join('\n')} 📥 LAST NED ÅRSREGNSKAP (PDF): 🔗 https://virksomhet.brreg.no/nb/oppslag/enheter/${params.org_nr} Slik laster du ned: 1. Åpne lenken over 2. Skroll ned til "Årsregnskap" seksjonen 3. Klikk "Vis alle" for å se alle år 4. Klikk "Innsendt årsregnskap" for året du vil laste ned Tilgjengelige år i database: ${financialHistory.map((f: any) => `${f.year} - ${f.source === 'openai_vision_extraction' ? 'AI-ekstrahert' : f.source === 'regnskapsregisteret_api' ? 'API' : f.source}`).join('\n')} 💡 KOMPLETT REGNSKAPSDATA: CompanyIQ ekstraherer automatisk finansielle nøkkeltall fra offisielle årsregnskap ved hjelp av AI-drevet PDF-analyse. For mer detaljerte balansetall og noteopplysninger: - Last ned fullstendig årsregnskap fra Brønnøysund - Bruk kommersielle tjenester (Proff.no, Bisnode) for kredittvurdering `; return { content: [{ type: "text" as const, text: report }] }; }

Latest Blog Posts

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/josuekongolo/companyiq-mcp'

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