Skip to main content
Glama
mod-us

Modus MCP Server

Official
by mod-us

modus_get_sales_breakdown

Analyze sales performance with hiring and capacity metrics, including revenue gaps and hiring needs, for any period type (quarter, year, or custom range).

Instructions

Get comprehensive sales breakdown with hiring/capacity analysis including targets, capacity, attrition impact, and quarterly waterfall metrics. Returns month-by-month capacity projections with revenue gaps and hiring needs. The period type is auto-detected: use quarter for quarterly analysis, year for annual, or startDate/endDate for custom ranges.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
periodNoPeriod type (optional - auto-detected): YTD, QUARTER, YEAR, CUSTOM_RANGE, LAST_12_MONTHS, NEXT_12_MONTHS
yearNoYear to analyze (e.g., 2025). Required for QUARTER, YEAR, or YTD periods.
quarterNoQuarter number (1-4). When specified, automatically uses QUARTER period.
startDateNoStart date (YYYY-MM-DD). When specified with endDate, automatically uses CUSTOM_RANGE period.
endDateNoEnd date (YYYY-MM-DD). When specified with startDate, automatically uses CUSTOM_RANGE period.
scenarioIdNoOptional scenario ID to analyze

Implementation Reference

  • Tool registration with name, description, and input/output schema definition
    {
      name: "modus_get_sales_breakdown",
      description:
        "Get comprehensive sales breakdown with hiring/capacity analysis including targets, capacity, attrition impact, and quarterly waterfall metrics. Returns month-by-month capacity projections with revenue gaps and hiring needs. The period type is auto-detected: use quarter for quarterly analysis, year for annual, or startDate/endDate for custom ranges.",
      inputSchema: {
        type: "object",
        properties: {
          period: {
            type: "string",
            description: "Period type (optional - auto-detected): YTD, QUARTER, YEAR, CUSTOM_RANGE, LAST_12_MONTHS, NEXT_12_MONTHS",
            enum: ["YTD", "QUARTER", "YEAR", "CUSTOM_RANGE", "LAST_12_MONTHS", "NEXT_12_MONTHS"],
          },
          year: {
            type: "number",
            description: "Year to analyze (e.g., 2025). Required for QUARTER, YEAR, or YTD periods.",
          },
          quarter: {
            type: "number",
            description: "Quarter number (1-4). When specified, automatically uses QUARTER period.",
          },
          startDate: {
            type: "string",
            description: "Start date (YYYY-MM-DD). When specified with endDate, automatically uses CUSTOM_RANGE period.",
          },
          endDate: {
            type: "string",
            description: "End date (YYYY-MM-DD). When specified with startDate, automatically uses CUSTOM_RANGE period.",
          },
          scenarioId: {
            type: "number",
            description: "Optional scenario ID to analyze",
          },
        },
      },
    },
  • Input schema defining parameters: period type, year, quarter, startDate, endDate, scenarioId
        type: "object",
        properties: {
          period: {
            type: "string",
            description: "Period type (optional - auto-detected): YTD, QUARTER, YEAR, CUSTOM_RANGE, LAST_12_MONTHS, NEXT_12_MONTHS",
            enum: ["YTD", "QUARTER", "YEAR", "CUSTOM_RANGE", "LAST_12_MONTHS", "NEXT_12_MONTHS"],
          },
          year: {
            type: "number",
            description: "Year to analyze (e.g., 2025). Required for QUARTER, YEAR, or YTD periods.",
          },
          quarter: {
            type: "number",
            description: "Quarter number (1-4). When specified, automatically uses QUARTER period.",
          },
          startDate: {
            type: "string",
            description: "Start date (YYYY-MM-DD). When specified with endDate, automatically uses CUSTOM_RANGE period.",
          },
          endDate: {
            type: "string",
            description: "End date (YYYY-MM-DD). When specified with startDate, automatically uses CUSTOM_RANGE period.",
          },
          scenarioId: {
            type: "number",
            description: "Optional scenario ID to analyze",
          },
        },
      },
    },
  • Handler function that executes 'modus_get_sales_breakdown': parses args, auto-detects period type, calls API, computes summary, returns response
    case "modus_get_sales_breakdown": {
      const { period, year, quarter, startDate, endDate, scenarioId } = args || {};
      const params = new URLSearchParams();
    
      // Auto-detect period type based on provided parameters if not explicitly set
      let finalPeriod = period;
      if (!finalPeriod) {
        if (startDate && endDate) {
          finalPeriod = "CUSTOM_RANGE";
        } else if (quarter) {
          finalPeriod = "QUARTER";
        } else if (year) {
          finalPeriod = "YEAR";
        } else {
          finalPeriod = "YTD";
        }
      }
    
      params.append("period", finalPeriod);
      if (year) params.append("year", year.toString());
      if (quarter) params.append("quarter", quarter.toString());
      if (startDate) params.append("startDate", startDate);
      if (endDate) params.append("endDate", endDate);
      if (scenarioId) params.append("scenarioId", scenarioId.toString());
    
      response = await modusApi.get(`/api/sales/sales-breakdown?${params.toString()}`);
      const data = response.data;
    
      // Add summary statistics
      const summary = {
        totalRevenueGap: calculateTotalGap(data.quarterlyCapacityDetails),
        totalHeadcount: (data.totalHeadcount?.current || 0) + (data.totalHeadcount?.tbh || 0),
        currentHeadcount: data.totalHeadcount?.current || 0,
        plannedHires: data.totalHeadcount?.tbh || 0,
        averageAttritionImpact: calculateAvgAttrition(data),
        quartersAtRisk: countQuartersAtRisk(data.quarterlyCapacityDetails),
      };
    
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify({ summary, data }, null, 2),
          },
        ],
      };
    }
  • Helper function calculateTotalGap: sums gap values from quarterlyCapacityDetails
    function calculateTotalGap(quarterlyDetails) {
      if (!quarterlyDetails || !Array.isArray(quarterlyDetails)) return 0;
      return quarterlyDetails.reduce((sum, q) => sum + (q.gap || 0), 0);
    }
  • Helper function calculateAvgAttrition: averages non-zero attrition impacts across quarters
    function calculateAvgAttrition(data) {
      if (!data.quarterlyCapacityDetails || !Array.isArray(data.quarterlyCapacityDetails)) return 0;
      const impacts = data.quarterlyCapacityDetails
        .map((q) => q.attritionImpact || 0)
        .filter((impact) => impact > 0);
      return impacts.length > 0 ? impacts.reduce((sum, i) => sum + i, 0) / impacts.length : 0;
    }
Behavior3/5

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

No annotations provided, so description must cover behavioral traits. It explains auto-detection of period type, which is helpful, but does not disclose other traits like read-only nature, permissions, or data freshness. Since it is a get tool, it is likely safe, but this is not explicitly stated.

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?

Two sentences: first clearly states purpose and output, second explains key parameter behavior. No redundant information. Every sentence earns its place.

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 no output schema, the description provides a reasonable overview of return values (month-by-month capacity projections, revenue gaps, hiring needs). However, it lacks details on data structure or format, and does not compare to sibling tools. For a tool with 6 parameters and no output schema, it is fairly complete but could be enhanced.

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

Parameters4/5

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

Input schema has 100% coverage (all parameters described). The description adds value by explaining auto-detection logic (e.g., specifying quarter sets period to QUARTER), which clarifies parameter interactions beyond the schema.

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

Purpose4/5

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

Description clearly states the tool retrieves a comprehensive sales breakdown with specific metrics (targets, capacity, attrition impact, quarterly waterfall). However, it does not explicitly differentiate from sibling tools like modus_get_quarterly_capacity, which may overlap.

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

Usage Guidelines3/5

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

Description implies usage for comprehensive analysis but provides no explicit guidance on when to use this tool versus alternatives. No exclusions or when-not-to-use instructions are given.

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/mod-us/modus-mcp-server'

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