Skip to main content
Glama
modellers

ConsignCloud MCP Server

by modellers

calculate_account_metrics

Calculate vendor account metrics including balance, inventory value, sales revenue, and commission owed for consignment business analysis.

Instructions

Calculate comprehensive metrics for a specific vendor/consignor account including current balance, inventory value, items available/sold, total sales revenue, and commission owed.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
account_idYesAccount ID (required)
date_fromNoFilter by items/sales created on or after this date (ISO 8601: YYYY-MM-DD)
date_toNoFilter by items/sales created on or before this date (ISO 8601: YYYY-MM-DD)
inventory_typeNoFilter by inventory type

Implementation Reference

  • src/server.ts:381-398 (registration)
    Tool registration in createTools() function, defining name, description, and input schema for calculate_account_metrics.
    {
      name: 'calculate_account_metrics',
      description: 'Calculate comprehensive metrics for a specific vendor/consignor account including current balance, inventory value, items available/sold, total sales revenue, and commission owed.',
      inputSchema: {
        type: 'object',
        properties: {
          account_id: { type: 'string', description: 'Account ID (required)' },
          date_from: { type: 'string', description: 'Filter by items/sales created on or after this date (ISO 8601: YYYY-MM-DD)' },
          date_to: { type: 'string', description: 'Filter by items/sales created on or before this date (ISO 8601: YYYY-MM-DD)' },
          inventory_type: {
            type: 'string',
            enum: ['consignment', 'buy_outright', 'retail'],
            description: 'Filter by inventory type'
          },
        },
        required: ['account_id'],
      },
    },
  • MCP server dispatch handler case that invokes the client-side calculateAccountMetrics implementation.
    case 'calculate_account_metrics':
      return { content: [{ type: 'text', text: JSON.stringify(await client.calculateAccountMetrics(args as any), null, 2) }] };
  • Primary handler function in ConsignCloudClient that executes the core logic: fetches data via API calls, performs client-side filtering/aggregation, calculates metrics, and formats output.
    async calculateAccountMetrics(params: {
      account_id: string;
      date_from?: string;
      date_to?: string;
      inventory_type?: string;
    }): Promise<AccountMetricsResult> {
      const { account_id, date_from, date_to, inventory_type } = params;
      const filters: string[] = [`account_id=${account_id}`];
    
      if (date_from) filters.push(`date_from=${date_from}`);
      if (date_to) filters.push(`date_to=${date_to}`);
      if (inventory_type) filters.push(`inventory_type=${inventory_type}`);
    
      // Fetch account details
      const account = await this.getAccount(account_id);
    
      // Fetch all items for this account
      let allItems: Item[] = [];
      let cursor: string | null = null;
      const itemQueryParams: Record<string, any> = { limit: 100, account: account_id };
      if (inventory_type) itemQueryParams.inventory_type = inventory_type;
    
      do {
        if (cursor) itemQueryParams.cursor = cursor;
        const response = await this.listItems(itemQueryParams);
        allItems = allItems.concat(response.data);
        cursor = response.next_cursor;
      } while (cursor);
    
      // Calculate inventory metrics
      let inventoryValue = 0;
      let itemsAvailable = 0;
      let itemsSold = 0;
    
      for (const item of allItems) {
        const quantity = item.quantity || 1;
        if (item.status === 'sold') {
          itemsSold += quantity;
        } else if (item.status === 'available') {
          inventoryValue += item.tag_price * quantity;
          itemsAvailable += quantity;
        }
      }
    
      // Fetch sales for this account (items sold by this consignor)
      let totalSalesRevenue = 0;
      let commissionOwed = 0;
    
      // Fetch all sales (no date filter - API doesn't support it)
      let allSales: Sale[] = [];
      cursor = null;
      const salesQueryParams: Record<string, any> = { limit: 100 };
      // NOTE: date_from/date_to NOT sent to API (not supported) - will filter client-side
    
      do {
        if (cursor) salesQueryParams.cursor = cursor;
        const response = await this.listSales(salesQueryParams);
        allSales = allSales.concat(response.data);
        cursor = response.next_cursor;
      } while (cursor);
    
      // Apply client-side date filtering (API doesn't support this)
      if (date_from || date_to) {
        allSales = allSales.filter(sale => {
          if (!sale.created) return false;
          const saleDate = new Date(sale.created);
          if (date_from && saleDate < new Date(date_from)) return false;
          if (date_to && saleDate > new Date(date_to)) return false;
          return true;
        });
      }
    
      // Calculate sales revenue for items from this account
      for (const sale of allSales) {
        if (sale.status === 'completed' && sale.items) {
          for (const saleItem of sale.items) {
            // Check if this sale item belongs to our account
            const matchingItem = allItems.find(i => i.id === saleItem.item);
            if (matchingItem) {
              const itemRevenue = saleItem.price || 0;
              totalSalesRevenue += itemRevenue;
              // Calculate commission based on split
              commissionOwed += Math.round(itemRevenue * matchingItem.split);
            }
          }
        }
      }
    
      return {
        account_id: account.id,
        account_name: [account.first_name, account.last_name].filter(Boolean).join(' ') || account.company || account.number,
        current_balance: account.balance,
        current_balance_formatted: this.formatAmount(account.balance),
        inventory_value: inventoryValue,
        inventory_value_formatted: this.formatAmount(inventoryValue),
        items_available: itemsAvailable,
        items_sold: itemsSold,
        total_sales_revenue: totalSalesRevenue,
        total_sales_revenue_formatted: this.formatAmount(totalSalesRevenue),
        commission_owed: commissionOwed,
        commission_owed_formatted: this.formatAmount(commissionOwed),
        filters_applied: filters,
        currency: this.currency,
        locale: this.locale,
      };
    }
  • Input schema/parameter validation definition for the tool.
    inputSchema: {
      type: 'object',
      properties: {
        account_id: { type: 'string', description: 'Account ID (required)' },
        date_from: { type: 'string', description: 'Filter by items/sales created on or after this date (ISO 8601: YYYY-MM-DD)' },
        date_to: { type: 'string', description: 'Filter by items/sales created on or before this date (ISO 8601: YYYY-MM-DD)' },
        inventory_type: {
          type: 'string',
          enum: ['consignment', 'buy_outright', 'retail'],
          description: 'Filter by inventory type'
        },
      },
      required: ['account_id'],
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It describes what metrics are calculated but doesn't mention whether this is a read-only operation, if it requires specific permissions, how it handles date ranges, or what format the results come in. For a metrics calculation tool with 4 parameters and no annotations, this leaves significant behavioral questions unanswered.

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

Conciseness4/5

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

The description is a single, efficient sentence that packs substantial information about what metrics are calculated. It's appropriately sized for the tool's complexity, though it could be slightly more structured by separating the metric list for better readability.

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

Completeness3/5

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

For a metrics calculation tool with 4 parameters, no annotations, and no output schema, the description is adequate but has clear gaps. It explains what's calculated but not how results are returned, what permissions are needed, or how it differs from sibling tools. The 100% schema coverage helps, but behavioral context is incomplete.

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?

The schema has 100% description coverage, so parameters are well-documented in the schema itself. The description mentions date filtering ('including current balance...') which aligns with date_from/date_to parameters, but doesn't add meaningful semantic context beyond what's already in the schema descriptions. Baseline 3 is appropriate when schema does the heavy lifting.

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?

The description clearly states the tool calculates comprehensive metrics for a specific vendor/consignor account and lists the specific metrics included (current balance, inventory value, items available/sold, total sales revenue, commission owed). It distinguishes from obvious siblings like calculate_inventory_value and calculate_sales_totals by being more comprehensive, though it doesn't explicitly name them.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like calculate_inventory_value, calculate_sales_totals, or get_account_stats. It doesn't mention prerequisites, dependencies, or scenarios where this tool is preferred over other metrics-related tools.

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/modellers/mcp-consigncloud'

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