Skip to main content
Glama
amittell

firewalla-mcp-server

resume_rule

Reactivate a paused firewall rule to restore its security function and network protection.

Instructions

Resume a previously paused firewall rule, restoring it to active state

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
rule_idYesRule ID to resume
boxYesBox GID for context (required by API)

Implementation Reference

  • ResumeRuleHandler class containing the execute method that implements the resume_rule tool logic: validates rule_id, checks current rule status to prevent redundant operations, calls firewalla.resumeRule(ruleId), formats unified response with success status and execution time.
    export class ResumeRuleHandler extends BaseToolHandler {
      name = 'resume_rule';
      description =
        'Resume a previously paused firewall rule. Requires rule_id parameter.';
      category = 'rule' as const;
    
      constructor() {
        super({
          enableGeoEnrichment: false, // No IP fields in rule operations
          enableFieldNormalization: true,
          additionalMeta: {
            data_source: 'rule_operations',
            entity_type: 'rule_resume_operation',
            supports_geographic_enrichment: false,
            supports_field_normalization: true,
            standardization_version: '2.0.0',
          },
        });
      }
    
      async execute(
        args: ToolArgs,
        firewalla: FirewallaClient
      ): Promise<ToolResponse> {
        try {
          // Parameter validation with enhanced rule ID format checking
          const ruleIdValidation = ParameterValidator.validateRuleId(
            args?.rule_id,
            'rule_id'
          );
    
          if (!ruleIdValidation.isValid) {
            return createErrorResponse(
              this.name,
              'Parameter validation failed',
              ErrorType.VALIDATION_ERROR,
              undefined,
              ruleIdValidation.errors
            );
          }
    
          const ruleId = ruleIdValidation.sanitizedValue as string;
    
          // Check rule status before attempting to resume it
          const statusCheck = await checkRuleStatus(ruleId, this.name, firewalla);
    
          if (!statusCheck.exists) {
            return statusCheck.errorResponse!;
          }
    
          // Prevent redundant resume operations
          if (statusCheck.isActive) {
            return createErrorResponse(
              this.name,
              'Rule is already active and does not need to be resumed',
              ErrorType.API_ERROR,
              {
                rule_id: ruleId,
                current_status: statusCheck.status,
                already_active: true,
              },
              [
                'Rule is already in an active state',
                'Use get_network_rules to verify current rule status',
                'If the rule is not working as expected, check rule configuration instead',
                'Use pause_rule if you want to temporarily disable the rule',
              ]
            );
          }
    
          // Provide helpful context for non-paused rules
          if (!statusCheck.isPaused) {
            logger.warn(
              `Rule ${ruleId} has status '${statusCheck.status}' - resuming may not activate it as expected`,
              {
                tool: 'resume_rule',
                rule_id: ruleId,
                current_status: statusCheck.status,
                warning: 'rule_not_paused',
              }
            );
          }
    
          const result = await withToolTimeout(
            async () => firewalla.resumeRule(ruleId),
            this.name
          );
    
          const startTime = Date.now();
    
          const unifiedResponseData = {
            success: SafeAccess.getNestedValue(result as any, 'success', false),
            message: SafeAccess.getNestedValue(
              result,
              'message',
              'Rule resume completed'
            ),
            rule_id: ruleId,
            action: 'resume_rule',
          };
    
          const executionTime = Date.now() - startTime;
          return this.createUnifiedResponse(unifiedResponseData, {
            executionTimeMs: executionTime,
          });
        } catch (error: unknown) {
          if (error instanceof TimeoutError) {
            return createTimeoutErrorResponse(
              this.name,
              error.duration,
              10000 // Default timeout
            );
          }
    
          const errorMessage =
            error instanceof Error ? error.message : 'Unknown error occurred';
          return this.createErrorResponse(`Failed to resume rule: ${errorMessage}`);
        }
      }
    }
  • Registration of the ResumeRuleHandler instance in the ToolRegistry constructor's registerHandlers method.
    this.register(new ResumeRuleHandler());
  • Input schema definition for the resume_rule tool provided in the static ListToolsRequestSchema response, specifying required rule_id and box parameters.
      name: 'resume_rule',
      description:
        'Resume a previously paused firewall rule, restoring it to active state',
      inputSchema: {
        type: 'object',
        properties: {
          rule_id: {
            type: 'string',
            description: 'Rule ID to resume',
          },
          box: {
            type: 'string',
            description: 'Box GID for context (required by API)',
          },
        },
        required: ['rule_id', 'box'],
      },
    },
  • checkRuleStatus utility function used by ResumeRuleHandler (and PauseRuleHandler) to validate rule existence, check current status (active/paused), and prevent redundant operations before calling the resume API.
    async function checkRuleStatus(
      ruleId: string,
      toolName: string,
      firewalla: FirewallaClient
    ): Promise<RuleStatusInfo> {
      try {
        // First check if the rule exists
        const existenceCheck = await validateRuleExists(
          ruleId,
          toolName,
          firewalla
        );
        if (!existenceCheck.exists) {
          return {
            exists: false,
            status: 'not_found',
            isPaused: false,
            isActive: false,
            errorResponse: existenceCheck.errorResponse,
          };
        }
    
        // Get the specific rule details to check its status
        const rulesResponse = await firewalla.getNetworkRules(`id:${ruleId}`, 1);
        const rules = SafeAccess.getNestedValue(
          rulesResponse,
          'results',
          []
        ) as any[];
    
        if (rules.length === 0) {
          return {
            exists: false,
            status: 'not_found',
            isPaused: false,
            isActive: false,
            errorResponse: createErrorResponse(
              toolName,
              'Rule not found in current rule set',
              ErrorType.API_ERROR,
              { rule_id: ruleId }
            ),
          };
        }
    
        const rule = rules[0];
        const status = SafeAccess.getNestedValue(
          rule,
          'status',
          'unknown'
        ) as string;
        const resumeTs = SafeAccess.getNestedValue(rule, 'resumeTs', undefined) as
          | number
          | undefined;
    
        // Determine if rule is paused or active
        const isPaused: boolean =
          status === 'paused' ||
          status === 'disabled' ||
          Boolean(resumeTs && resumeTs > Date.now() / 1000);
        const isActive: boolean = status === 'active' || status === 'enabled';
    
        return {
          exists: true,
          status,
          isPaused,
          isActive,
          resumeAt: resumeTs ? new Date(resumeTs * 1000).toISOString() : undefined,
        };
      } catch (error) {
        return {
          exists: false,
          status: 'error',
          isPaused: false,
          isActive: false,
          errorResponse: createErrorResponse(
            toolName,
            `Failed to check rule status: ${error instanceof Error ? error.message : 'Unknown error'}`,
            ErrorType.API_ERROR,
            { rule_id: ruleId }
          ),
        };
      }
    }

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