Skip to main content
Glama
amittell

firewalla-mcp-server

get_bandwidth_usage

Identify top bandwidth-consuming devices on your network by retrieving usage data for specified time periods to monitor and manage network traffic.

Instructions

Get top bandwidth consuming devices (convenience wrapper around get_device_status)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
periodYesTime period for bandwidth calculation
limitNoNumber of top devices to return
boxNoFilter devices under a specific Firewalla box

Implementation Reference

  • The primary handler class implementing the get_bandwidth_usage tool. Validates parameters (period enum ['1h','24h','7d','30d'], limit), calls firewalla.getBandwidthUsage(period, limit), processes results into structured bandwidth data per device (upload/download/total bytes/MB/GB), applies geo-enrichment on IP, and returns standardized paginated response.
    export class GetBandwidthUsageHandler extends BaseToolHandler {
      name = 'get_bandwidth_usage';
      description =
        'Get top bandwidth consuming devices by data usage. Requires limit and period parameters. Data is cached for 5 minutes for performance.';
      category = 'network' as const;
    
      constructor() {
        super({
          enableGeoEnrichment: true,
          enableFieldNormalization: true,
          additionalMeta: {
            data_source: 'bandwidth_usage',
            entity_type: 'device_bandwidth',
            supports_geographic_enrichment: true,
            supports_field_normalization: true,
            standardization_version: '2.0.0',
          },
        });
      }
    
      async execute(
        args: ToolArgs,
        firewalla: FirewallaClient
      ): Promise<ToolResponse> {
        try {
          // Parameter validation
          const periodValidation = ParameterValidator.validateEnum(
            args?.period,
            'period',
            ['1h', '24h', '7d', '30d'],
            true
          );
          const limitValidation = ParameterValidator.validateNumber(
            args?.limit,
            'limit',
            {
              required: false,
              defaultValue: 10,
              ...getLimitValidationConfig(this.name),
            }
          );
    
          const validationResult = ParameterValidator.combineValidationResults([
            periodValidation,
            limitValidation,
          ]);
    
          if (!validationResult.isValid) {
            return this.createErrorResponse(
              'Parameter validation failed',
              ErrorType.VALIDATION_ERROR,
              undefined,
              validationResult.errors
            );
          }
    
          const usageResponse = await withToolTimeout(
            async () =>
              firewalla.getBandwidthUsage(
                periodValidation.sanitizedValue as string,
                limitValidation.sanitizedValue as number
              ),
            this.name
          );
    
          // Ensure we have results and validate count vs requested limit
          const results = usageResponse.results || [];
          const requestedLimit = limitValidation.sanitizedValue as number;
    
          // Note: if we get fewer results than requested, this may be due to
          // insufficient data rather than an error
    
          const startTime = Date.now();
    
          // Process bandwidth usage data
          const bandwidthData = SafeAccess.safeArrayMap(results, (item: any) => ({
            device_id: SafeAccess.getNestedValue(item, 'device_id', 'unknown'),
            device_name: SafeAccess.getNestedValue(
              item,
              'device_name',
              'Unknown Device'
            ),
            ip: SafeAccess.getNestedValue(item, 'ip', 'unknown'),
            bytes_uploaded: SafeAccess.getNestedValue(item, 'bytes_uploaded', 0),
            bytes_downloaded: SafeAccess.getNestedValue(
              item,
              'bytes_downloaded',
              0
            ),
            total_bytes: SafeAccess.getNestedValue(item, 'total_bytes', 0),
            total_mb:
              Math.round(
                ((SafeAccess.getNestedValue(item, 'total_bytes', 0) as number) /
                  (1024 * 1024)) *
                  100
              ) / 100,
            total_gb:
              Math.round(
                ((SafeAccess.getNestedValue(item, 'total_bytes', 0) as number) /
                  (1024 * 1024 * 1024)) *
                  100
              ) / 100,
          }));
    
          // Apply geographic enrichment for IP addresses
          const enrichedBandwidthData = await this.enrichGeoIfNeeded(
            bandwidthData,
            ['ip']
          );
    
          const unifiedResponseData = {
            period: periodValidation.sanitizedValue,
            top_devices: results.length,
            requested_limit: requestedLimit,
            bandwidth_usage: enrichedBandwidthData,
          };
    
          const executionTime = Date.now() - startTime;
          return this.createUnifiedResponse(unifiedResponseData, {
            executionTimeMs: executionTime,
          });
        } catch (error: unknown) {
          // Handle timeout errors specifically
          if (error instanceof TimeoutError) {
            return createTimeoutErrorResponse(
              this.name,
              error.duration,
              10000 // Default timeout from timeout-manager
            );
          }
    
          const errorMessage =
            error instanceof Error ? error.message : 'Unknown error occurred';
          return this.createErrorResponse(
            `Failed to get bandwidth usage: ${errorMessage}`,
            ErrorType.API_ERROR,
            { originalError: errorMessage }
          );
        }
      }
    }
  • Registration of the GetBandwidthUsageHandler in the central ToolRegistry during construction in registerHandlers() method.
    this.register(new GetBandwidthUsageHandler()); // wrapper around get_device_status
  • Tool schema definition exposed via MCP listTools request, defining input parameters, types, enum for period, limits, and required fields.
      name: 'get_bandwidth_usage',
      description:
        'Get top bandwidth consuming devices (convenience wrapper around get_device_status)',
      inputSchema: {
        type: 'object',
        properties: {
          period: {
            type: 'string',
            description: 'Time period for bandwidth calculation',
            enum: ['1h', '24h', '7d', '30d'],
          },
          limit: {
            type: 'number',
            description: 'Number of top devices to return',
            minimum: 1,
            maximum: 500,
            default: 10,
          },
          box: {
            type: 'string',
            description: 'Filter devices under a specific Firewalla box',
          },
        },
        required: ['period'],
      },
    },
  • Import of GetBandwidthUsageHandler from './handlers/network.js' in registry.ts
    GetBandwidthUsageHandler,
  • Configuration of rate limits and categorization for the get_bandwidth_usage tool in limits.ts, classifying it under moderate tools.
    get_bandwidth_usage: STANDARD_LIMITS.BANDWIDTH_ANALYSIS,
Behavior2/5

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

No annotations are provided, so the description carries full burden. It mentions being a 'convenience wrapper,' hinting at simplified behavior, but fails to disclose critical traits: whether it's read-only, how it handles errors, rate limits, authentication needs, or the format of returned data (e.g., list of devices with bandwidth metrics). This leaves significant gaps for an agent.

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?

The description is a single, efficient sentence that front-loads the core purpose and adds clarifying context without waste. Every word earns its place, making it easy to parse quickly.

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

Completeness2/5

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

Given no annotations and no output schema, the description is incomplete. It lacks details on behavioral traits (e.g., safety, data format) and output values, which are crucial for a tool with parameters and potential data retrieval. The mention of being a wrapper adds some context but doesn't compensate for these gaps.

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 100%, so the schema fully documents parameters (period, limit, box). The description adds no parameter-specific semantics beyond implying it returns 'top bandwidth consuming devices,' which aligns with the schema but doesn't provide additional context like how 'top' is determined or interaction between parameters.

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's purpose: 'Get top bandwidth consuming devices' specifies the verb (get) and resource (bandwidth consuming devices). It distinguishes from the sibling 'get_device_status' by noting it's a convenience wrapper, though it doesn't explicitly differentiate from other bandwidth-related tools (none listed).

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?

The description implies usage by referencing 'get_device_status' as an alternative, suggesting this is a simplified version. However, it lacks explicit guidance on when to use this tool versus other bandwidth or device-related tools (e.g., get_simple_statistics, search_devices), and does not mention prerequisites or exclusions.

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/amittell/firewalla-mcp-server'

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