Skip to main content
Glama
dun999

FinSight

analyze_report

Analyze investment portfolios with comprehensive risk assessment, diversification scoring, stress testing, and rebalancing recommendations to optimize performance and manage exposure.

Instructions

Full report — all 8 modules in one call: risk + rebalance + diversification + stress_test (10 scenarios) + var_cvar + factor_exposure + correlation + market_regime. Includes ExecutiveSummary: overall score (0-100), grade (A-F), key strengths, key risks, top recommendations. Most cost-effective option for comprehensive analysis. Costs $0.10 USDC.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
holdingsYes
profileNoRisk profile — affects rebalance targets and scoring. Default: balanced.
benchmarkReturnNoAnnual benchmark return for Sharpe calculation, e.g. 0.08 = 8%. Default: 0.08.
riskFreeRateNoAnnual risk-free rate for Sortino and VaR excess return, e.g. 0.05 = 5%. Default: 0.05.
rebalanceMethodNoPortfolio construction method for rebalance recommendations. Default: profile.
marketIndicatorsNoOptional macro indicators — improves market regime detection confidence to HIGH when 3+ provided.

Implementation Reference

  • The handler for the '/analyze/report' endpoint, which maps to the "analyze_report" tool/feature. It validates the request, handles payment, checks for cached results, and calls generateFullReport.
    app.post('/analyze/report', validate, charge('0.05'), async (c) => {
      try {
        const portfolio = c.get('portfolio')
    
        // Cache: return previously computed result for identical portfolios (30s TTL).
        // Uses stableJSON() instead of JSON.stringify() to ensure key order in the
        // input object does not produce different cache keys for identical portfolios.
        if (c.env.CACHE) {
          const keyBytes = await crypto.subtle.digest(
            'SHA-256',
            new TextEncoder().encode(stableJSON(portfolio)),
          )
          const cacheKey = 'report:' + Array.from(new Uint8Array(keyBytes))
            .map((b) => b.toString(16).padStart(2, '0'))
            .join('')
    
          const cached = await c.env.CACHE.get(cacheKey).catch(() => null)
          if (cached) {
            c.res.headers.set('X-Cache', 'HIT')
            return c.json({ ...JSON.parse(cached), ...{ warnings: c.get('warnings') ?? [], request_id: c.get('requestId') ?? 'unknown' } })
          }
    
          const result = generateFullReport(portfolio, c.get('returnSeries'))
          await c.env.CACHE.put(cacheKey, JSON.stringify(result), { expirationTtl: 30 }).catch(() => undefined)
          c.res.headers.set('X-Cache', 'MISS')
          return c.json(withMeta(c, result))
        }
    
        return c.json(withMeta(c, generateFullReport(portfolio, c.get('returnSeries'))))
      } catch (err) {
        console.error(err)
        return internalError(c)
      }
    })
  • The core implementation logic for generating the full report, which aggregates data from various other analyze modules.
    export function generateFullReport(
      portfolio: Portfolio,
      returnSeries?: Record<string, number[]>,
    ): FullReport {
      const risk            = analyzeRisk(portfolio, returnSeries)
      const rebalance       = analyzeRebalance(portfolio)
      const diversification = analyzeDiversification(portfolio)
      const stressTest      = analyzeStressTest(portfolio, returnSeries)
      const varCvar         = analyzeVaR(portfolio)
      const factorExposure  = analyzeFactorExposure(portfolio, returnSeries)
      const correlation     = analyzeCorrelation(portfolio, returnSeries)
      const marketRegime    = analyzeMarketRegime(portfolio)
      const executiveSummary = computeExecutiveSummary(
        risk, diversification, correlation, factorExposure, stressTest, portfolio,
      )
    
      return {
        risk,
        rebalance,
        diversification,
        stressTest,
        varCvar,
        factorExposure,
        correlation,
        marketRegime,
        executiveSummary,
        generatedAt: new Date().toISOString(),
        version: '3.1.0',
      }
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and successfully discloses critical behavioral traits: the $0.10 USDC cost, that stress_test runs 10 scenarios, and the ExecutiveSummary output structure. However, it omits standard operational details like whether the operation is read-only, idempotent, or rate-limited.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence is information-dense: module enumeration, output description (score/grade/recommendations), cost-effectiveness claim, and pricing. The list format for 8 modules and ExecutiveSummary components maximizes scannability with zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of output schema, the description adequately compensates by detailing the ExecutiveSummary structure (0-100 score, A-F grade, strengths/risks/recommendations). It also lists all 8 sub-modules covered. Minor gap: it doesn't explicitly state that individual tools exist for each module, though this is strongly implied.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 83% (high), establishing a baseline of 3. The description does not explicitly discuss parameter semantics (e.g., explaining the holdings array structure or profile enum), but the schema comprehensively documents auto-population rules for tickers and weight constraints, making additional description text unnecessary.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states this generates a 'Full report' combining all 8 analysis modules (risk, rebalance, diversification, etc.), explicitly distinguishing it from individual sibling tools like analyze_risk or analyze_stress. The verb-resource combination ('analyze' implied by context + 'report') is specific and comprehensive.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies the comprehensive use case by listing all 8 constituent modules and stating this is the 'most cost-effective option for comprehensive analysis.' However, it lacks explicit guidance on when NOT to use this (e.g., 'use individual analysis tools if you only need specific metrics') or clear prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/dun999/finsight-mpp'

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