Skip to main content
Glama
amittell

firewalla-mcp-server

get_flow_insights

Analyze network traffic by content category to identify bandwidth usage, top content types, and blocked traffic patterns for security monitoring.

Instructions

Get category-based flow analysis including top content categories, bandwidth consumers, and blocked traffic. Ideal for answering questions like "what porn sites were accessed" or "what social media was used". Replaces time-based trends with actionable insights.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
periodNoTime period for analysis (default: 24h)24h
categoriesNoFilter to specific content categories (optional)
include_blockedNoInclude blocked traffic analysis (default: false)

Implementation Reference

  • The GetFlowInsightsHandler class implements the core logic for the 'get_flow_insights' tool. It validates parameters (period, categories, include_blocked), calls the Firewalla API via firewalla.getFlowInsights, processes the response with normalization and formatting, and returns a unified response structure.
    export class GetFlowInsightsHandler extends BaseToolHandler {
      name = 'get_flow_insights';
      description =
        'Get category-based flow analysis including top content categories, bandwidth consumers, and blocked traffic. Replaces time-based trends with actionable insights for networks with high flow volumes. Ideal for answering questions like "what porn sites were accessed" or "what social media was used".';
      category = 'analytics' as const;
    
      constructor() {
        super({
          enableGeoEnrichment: false, // Already contains aggregated data
          enableFieldNormalization: true,
          additionalMeta: {
            data_source: 'flow_insights',
            entity_type: 'category_flow_analysis',
            supports_geographic_enrichment: false,
            supports_field_normalization: true,
            standardization_version: '2.0.0',
          },
        });
      }
    
      async execute(
        _args: ToolArgs,
        firewalla: FirewallaClient
      ): Promise<ToolResponse> {
        try {
          const periodValidation = ParameterValidator.validateEnum(
            _args?.period,
            'period',
            ['1h', '24h', '7d', '30d'],
            false,
            '24h'
          );
          const categoriesValidation = ParameterValidator.validateArray(
            _args?.categories,
            'categories',
            {
              required: false,
            }
          );
    
          // Validate allowed category values if provided
          const allowedCategories = [
            'ad',
            'edu',
            'games',
            'gamble',
            'intel',
            'p2p',
            'porn',
            'private',
            'social',
            'shopping',
            'video',
            'vpn',
          ];
    
          if (categoriesValidation.isValid && categoriesValidation.sanitizedValue) {
            const categories = categoriesValidation.sanitizedValue as string[];
            const invalidCategories = categories.filter(
              cat => !allowedCategories.includes(cat)
            );
            if (invalidCategories.length > 0) {
              categoriesValidation.isValid = false;
              categoriesValidation.errors = [
                `Invalid categories: ${invalidCategories.join(', ')}`,
              ];
            }
          }
          const includeBlockedValidation = ParameterValidator.validateBoolean(
            _args?.include_blocked,
            'include_blocked',
            false
          );
    
          const validationResult = ParameterValidator.combineValidationResults([
            periodValidation,
            categoriesValidation,
            includeBlockedValidation,
          ]);
    
          if (!validationResult.isValid) {
            return this.createErrorResponse(
              'Parameter validation failed',
              ErrorType.VALIDATION_ERROR,
              undefined,
              validationResult.errors
            );
          }
    
          const period = periodValidation.sanitizedValue as
            | '1h'
            | '24h'
            | '7d'
            | '30d';
          const categories = categoriesValidation.sanitizedValue as
            | string[]
            | undefined;
          const includeBlocked = includeBlockedValidation.sanitizedValue as boolean;
    
          const startTime = Date.now();
    
          const insights = await withToolTimeout(
            async () =>
              firewalla.getFlowInsights(period, {
                categories,
                includeBlocked,
              }),
            this.name
          );
    
          // Format response for better readability
          const unifiedResponseData = {
            period,
            analysis_time: getCurrentTimestamp(),
    
            // Category breakdown with human-readable formatting
            content_categories: insights.categoryBreakdown.map(cat => ({
              category: cat.category,
              flow_count: cat.count,
              total_bytes: cat.bytes,
              total_mb: Math.round((cat.bytes / 1048576) * 100) / 100,
              top_domains: cat.topDomains.map(dom => ({
                domain: dom.domain,
                visits: dom.count,
                bandwidth_mb: Math.round((dom.bytes / 1048576) * 100) / 100,
              })),
            })),
    
            // Top bandwidth consumers
            top_bandwidth_devices: insights.topDevices.map(dev => ({
              device: dev.device,
              total_bandwidth_mb:
                Math.round((dev.totalBytes / 1048576) * 100) / 100,
              category_usage: dev.categories.map(cat => ({
                category: cat.category,
                bandwidth_mb: Math.round((cat.bytes / 1048576) * 100) / 100,
              })),
            })),
    
            // Blocked traffic summary if requested
            ...(insights.blockedSummary && {
              blocked_traffic: {
                total_blocked_flows: insights.blockedSummary.totalBlocked,
                blocked_by_category: insights.blockedSummary.byCategory,
              },
            }),
    
            // Summary statistics
            summary: {
              total_categories: insights.categoryBreakdown.length,
              total_bandwidth_gb:
                Math.round(
                  (insights.categoryBreakdown.reduce(
                    (sum, cat) => sum + cat.bytes,
                    0
                  ) /
                    1073741824) *
                    100
                ) / 100,
              most_active_category:
                insights.categoryBreakdown[0]?.category || 'none',
              top_bandwidth_consumer: insights.topDevices[0]?.device || 'none',
            },
          };
    
          const executionTime = Date.now() - startTime;
          return this.createUnifiedResponse(unifiedResponseData, {
            executionTimeMs: executionTime,
          });
        } catch (error: unknown) {
          const errorMessage =
            error instanceof Error ? error.message : 'Unknown error';
          return this.createErrorResponse(
            `Failed to get flow insights: ${errorMessage}`,
            ErrorType.API_ERROR,
            {
              period: _args?.period || '24h',
              categories: _args?.categories || 'all',
              troubleshooting:
                'Check if Firewalla API is accessible and flow data is available',
            }
          );
        }
      }
    }
  • Registration of the GetFlowInsightsHandler instance in the ToolRegistry during automatic tool registration.
    this.register(new GetFlowInsightsHandler());
  • MCP tool schema definition in server.ts, specifying the inputSchema with parameters period (enum), categories (array of allowed categories), and include_blocked (boolean) for the get_flow_insights tool.
      name: 'get_flow_insights',
      description:
        'Get category-based flow analysis including top content categories, bandwidth consumers, and blocked traffic. Ideal for answering questions like "what porn sites were accessed" or "what social media was used". Replaces time-based trends with actionable insights.',
      inputSchema: {
        type: 'object',
        properties: {
          period: {
            type: 'string',
            enum: ['1h', '24h', '7d', '30d'],
            description: 'Time period for analysis (default: 24h)',
            default: '24h',
          },
          categories: {
            type: 'array',
            items: {
              type: 'string',
              enum: [
                'ad',
                'edu',
                'games',
                'gamble',
                'intel',
                'p2p',
                'porn',
                'private',
                'social',
                'shopping',
                'video',
                'vpn',
              ],
            },
            description:
              'Filter to specific content categories (optional)',
          },
          include_blocked: {
            type: 'boolean',
            description:
              'Include blocked traffic analysis (default: false)',
            default: false,
          },
        },
        required: [],
      },
    },
  • Import statement for GetFlowInsightsHandler from './handlers/analytics.js' in the ToolRegistry file.
    GetFlowInsightsHandler,

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