Skip to main content
Glama

firewalla-mcp-server

A read-only Model Context Protocol (MCP) server that lets Claude audit your Firewalla configuration and network security posture via the Firewalla MSP API.

Read-only by design. This server cannot block/unblock devices, create or modify rules, pause services, or make any changes to your Firewalla. It only observes.

What it does

Exposes 8 tools that Claude can use to inspect your Firewalla — devices on your network, active rules, security alarms, network flows, and block/allow target lists.

Related MCP server: mcp-infra-readonly

Example prompts

Security audits

These prompts treat Claude as a network security professional conducting a structured review of your Firewalla configuration. They work best in Claude Desktop or Claude Code where the Firewalla MCP tools are available.

Full network security audit:

You are a senior network security engineer conducting a comprehensive audit of my home network. Using the Firewalla MCP tools, perform the following review and present your findings in a structured report with severity ratings (Critical / High / Medium / Low / Informational):

  1. Device inventory — Pull the complete device list. Flag any devices with unrecognized MAC vendors, devices not being monitored, or unexpected router-class devices that could indicate a rogue access point.

  2. Rule audit — Review all block/allow rules. Identify any allow rules that are overly permissive (broad scope, inbound direction, no device restriction). Flag rules with zero hit counts that may be stale.

  3. Alarm review — Search recent alarms grouped by type and severity. Identify any patterns (repeated alarms from the same device, alarms from unexpected countries, alarms targeting devices that shouldn't have external exposure).

  4. Target list coverage — Review which block lists are active. Assess whether the current list configuration provides adequate coverage against common threat categories (malware, C2, phishing, cryptomining, newly registered domains).

Conclude with a prioritized list of recommended actions I should take to improve my network security posture.

Firewall rule gap analysis:

Act as a firewall policy analyst. Pull all of my Firewalla rules and the complete device list, then cross-reference them. I need you to identify: (1) devices that have no rules scoped to them at all — are they relying entirely on global rules, and is that intentional? (2) allow rules that grant inbound access — what devices do they target and is the scope appropriately narrow? (3) block rules that have never fired (hit count = 0) — are they stale or is the threat they guard against simply not present? Present your findings as a table for each category with your assessment and recommended action.

Suspicious traffic investigation:

I want to investigate whether any devices on my network are communicating with unexpected external destinations. Search my recent network flows for any traffic to regions outside the US that was NOT blocked by Firewalla. Group the results by device and destination country. For any device that shows unblocked traffic to unusual regions, cross-reference it against my device list to identify what the device is, then check if there are any alarms associated with it. Summarize your findings with a risk assessment for each flagged device.

Quick queries

These are shorter prompts for everyday monitoring and spot checks:

  • "List all devices on my network and flag any that have an unknown MAC vendor or aren't being monitored by Firewalla."

  • "Show me all allow rules on my Firewalla. Are any of them scoped too broadly?"

  • "What are the top alarm types firing on my network right now? Group them by type and give me a count."

  • "Check which Firewalla block lists I have active and how many entries each one has. Am I missing any important categories?"

  • "Search for any blocked flows in the last 24 hours and group them by destination country. Which countries are showing up the most?"

  • "Pull my Firewalla box info — is it online, what firmware version is it running, and how many active alarms are there right now?"

Tools

Tool

Description

firewalla_list_boxes

Discover Firewalla boxes on the MSP account (model, firmware, online status, device/rule/alarm counts)

firewalla_list_devices

Inventory all devices on the network (IP, MAC vendor, device type, online status, monitoring flag)

firewalla_search_flows

Search network flows with query filters, grouping, and cursor pagination

firewalla_search_alarms

Search active security alarms with query filters, grouping, and cursor pagination

firewalla_get_alarm

Fetch full detail for a single alarm by box + alarm ID

firewalla_list_rules

Audit configured block/allow rules (action, direction, target, scope, hit count)

firewalla_list_target_lists

List block/allow target lists (Firewalla-managed and user-defined)

firewalla_get_target_list

Fetch metadata for a single target list by ID

All tools support response_format: "json" | "markdown" and are annotated readOnlyHint: true.

Prerequisites

  1. A Firewalla box linked to an MSP account. Even standalone (non-fleet) boxes use the MSP API — it's the only supported public API.

  2. An MSP personal access token. Generate one at:

    • Log in to your MSP portal at https://<your-subdomain>.firewalla.net

    • Go to Account Settings → Personal Access Tokens

    • Create a new token and save it somewhere secure

    For detailed setup instructions, see Getting Started with the Firewalla MSP API.

  3. Node.js 18+

Install

git clone https://github.com/productengineered/firewalla-mcp.git
cd firewalla-mcp
npm install
npm run build

Configuration

The server reads two environment variables:

Variable

Description

Example

FIREWALLA_MSP_DOMAIN

Your MSP subdomain (no https://, no trailing slash)

yourname.firewalla.net

FIREWALLA_MSP_TOKEN

Personal access token from MSP Account Settings

fwtoken_abc123...

For local development, copy .env.example to .env and fill in your values:

cp .env.example .env
# edit .env with your real values

Usage with Claude Desktop

Add to your claude_desktop_config.json (usually at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "firewalla": {
      "command": "node",
      "args": ["/absolute/path/to/firewalla-mcp/dist/index.js"],
      "env": {
        "FIREWALLA_MSP_DOMAIN": "yourname.firewalla.net",
        "FIREWALLA_MSP_TOKEN": "your-token-here"
      }
    }
  }
}

Note: Claude Desktop launches with a minimal PATH. If node isn't found, use the absolute path to your Node.js binary (e.g. the output of which node).

Restart Claude Desktop after editing the config.

Usage with Claude Code

claude mcp add-json --scope user firewalla '{
  "type": "stdio",
  "command": "node",
  "args": ["/absolute/path/to/firewalla-mcp/dist/index.js"],
  "env": {
    "FIREWALLA_MSP_DOMAIN": "yourname.firewalla.net",
    "FIREWALLA_MSP_TOKEN": "your-token-here"
  }
}'

Verify with:

claude mcp list
# firewalla: ... - ✓ Connected

New Claude Code sessions will have firewalla_* tools available automatically.

Development

# Source env for local dev
set -a; source .env; set +a

# Run with auto-reload
npm run dev

# Build
npm run build

# Test with MCP Inspector
npx @modelcontextprotocol/inspector --cli node dist/index.js --method tools/list

Firewalla API documentation

License

MIT

Available Tools

8 tools
firewalla_get_alarmGet Firewalla AlarmA
Read-onlyIdempotent

Fetch the full detail of a single alarm by gid (box id) + aid (alarm id). Use this after firewalla_search_alarms to drill into one event.

Args:

  • gid (string, required): Box id (from firewalla_list_boxes).

  • aid (string, required): Alarm id (from firewalla_search_alarms).

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns the full alarm record, which may include device, remote endpoint, category, timestamps, and any alarm-type-specific detail fields the MSP API surfaces.

Inputs: gid (required), aid (required), response_format.

firewalla_get_target_listGet Firewalla Target ListA
Read-onlyIdempotent

Fetch the metadata for a single target list by id.

MSP API limitation: For Firewalla-managed lists (owner="firewalla"), the MSP API does NOT return individual target entries — it returns the summary plus the aggregate count. User-created lists may include a targets array; if so, we surface it.

Use this to answer:

  • "What's the block mode / source / type of list X?"

  • "When was list X last updated?"

  • "How big is list X?" (use the count / targetCount field)

Do NOT use this to answer:

  • "Is domain example.com on list X?" — the entries aren't returned.

  • "Give me the first N entries of list X." — same reason.

Args:

  • id (string, required): Target-list id (from firewalla_list_target_lists).

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns: { id, name, owner, type?, source?, blockMode?, notes?, lastUpdated?, count?: number, // summary count reported by the API targetCount: number, // same as count, or actual targets.length when present targets?: string[] // only populated for user-created lists (rare) }

Inputs: id (required), response_format.

firewalla_list_boxesList Firewalla BoxesA
Read-onlyIdempotent

Discover the Firewalla boxes linked to this MSP account. This is the entry point for every audit — the returned gid is required by other tools.

Use this to answer:

  • "Is my box online and reporting in?"

  • "What firmware version is it running?"

  • "How many active devices, rules, alarms are there right now?"

Args:

  • group (string, optional): Filter to a specific group id.

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns: { count: number, boxes: Array<{ gid: string, // box id — save this, other tools need it name: string, model: string, // e.g. "gold_plus" mode: string, // routing mode version: string, // firmware online: boolean, publicIP?: string, lastSeen?: number, // epoch seconds — not always populated license?: string, location?: string, deviceCount: number, ruleCount: number, alarmCount: number, // currently-active alarms group?: { id, name } }> }

Audit framing:

  • Offline box → can't observe current state; surface it.

  • High alarmCount → follow up with firewalla_search_alarms.

  • publicIP exposed unexpectedly → investigate with firewalla_search_flows.

Inputs: group, response_format.

firewalla_list_devicesList Firewalla DevicesA
Read-onlyIdempotent

Inventory every device Firewalla tracks — the "who's on my network right now" primitive.

Use this to answer:

  • "Are there any unknown/rogue devices on my network?"

  • "Which devices aren't being monitored?"

  • "What's the MAC vendor breakdown across my network?"

  • "Any router-class devices I didn't expect?"

Args:

  • box (string, optional): Filter to devices on a specific box gid.

  • online_only (boolean, optional): Drop offline devices client-side.

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns: { count: number, // devices after client-side filtering total: number, // devices returned by the API (pre-filter) devices: Array<{ id: string, // typically MAC gid: string, // box the device is attached to name: string, ip: string, mac?: string, macVendor?: string, ipReserved?: boolean, online: boolean, network?: { id, name }, deviceType?: string, // e.g. "phone", "computer", "iot" isRouter?: boolean, isFirewalla?: boolean, monitoring?: boolean, // false = device excluded from monitoring totalDownload?: number, // bytes (lifetime) totalUpload?: number }> }

Audit framing:

  • Unknown macVendor → possible squatter or spoofed MAC.

  • monitoring=false → device is excluded from Firewalla's visibility; review whether that's intentional.

  • Unexpected isRouter=true → shadow router on the LAN.

  • ipReserved=false on a server that should have a static lease → risk of address drift.

Inputs: box, online_only, response_format.

firewalla_list_rulesList Firewalla RulesA
Read-onlyIdempotent

Audit configured block / allow rules. Read-only — this tool does NOT pause, resume, create, or modify rules.

Use this to answer:

  • "Do I have any allow rules that bypass Firewalla's default blocks?"

  • "Which rules haven't fired in 90 days (candidates to remove)?"

  • "Are my block rules scoped to the right device/group?"

  • "Any rules with action=allow and broad scope?"

Args:

  • query (string, optional): Firewalla query-grammar filter (pass-through). Examples: action:allow, status:paused, target.type:domain.

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns: { count: number, rules: Array<{ id: string, gid: string, action: string, // "block" | "allow" | "time_limit" | … direction?: string, // "outbound" | "inbound" | "bidirection" status?: string, // "active" | "paused" | "disabled" target: { type, value, dnsOnly?, port? }, scope?: { type?, value? }, notes?: string, hit?: { count?, lastHitTs? }, ts?: number, updateTs?: number }> }

Audit framing:

  • action=allow with scope=global → overly permissive, investigate.

  • status=paused with no notes → someone disabled a rule and didn't document why.

  • hit.count=0 & old updateTs → stale rule, candidate for removal.

Inputs: query, response_format.

firewalla_list_target_listsList Firewalla Target ListsA
Read-onlyIdempotent

List the block/allow target lists available on this MSP account — both Firewalla-managed ("global") and user-defined.

Use this to answer:

  • "Which block lists is Firewalla enforcing against?"

  • "Have I added any custom target lists, and what are their owners?"

  • "What categories (ad, tracker, malware, …) are covered?"

This endpoint returns summaries (including target count per list); call firewalla_get_target_list for the actual targets array.

Args:

  • owner (string, optional): Filter by owner (e.g. 'global').

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns: { count: number, // number of target lists targetLists: Array<{ id: string, name: string, owner: string, // "global" | user id type?: string, // e.g. "ad", "tracker", "malware", "custom" source?: string, // upstream feed source (Firewalla-managed lists) count?: number, // number of entries in the list blockMode?: string, // e.g. "dns" | "ip" beta?: boolean, notes?: string, lastUpdated?: number }> }

Audit framing:

  • Custom lists (owner != global) without notes → undocumented intent.

  • blockMode=dns only, but target includes raw IPs → mismatch, investigate.

  • Zero-count list → may be stale / never populated.

Inputs: owner, response_format.

firewalla_search_alarmsSearch Firewalla AlarmsA
Read-onlyIdempotent

Search active Firewalla alarms with the MSP query grammar. This is the primary tool for "what security events are happening right now?" audits.

Use this to answer:

  • "Any alarms from devices not in a known group?"

  • "How many alarms of type X in the last 24h, grouped by device?"

  • "Which remote countries are triggering the most alarms?"

  • "Any alarms relating to a specific device (by MAC)?"

Args:

  • query (string, optional): Firewalla query grammar. Examples: type:1, device.mac:AA:BB:CC:DD:EE:FF, remote.country:CN, ts:>1700000000.

  • group_by (string, optional): e.g. device, type, remote.country.

  • sort_by (string, optional): e.g. ts:desc (default), ts:asc.

  • limit (number, 1–500, default 200).

  • cursor (string, optional): pagination cursor from a prior response.

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns: { count: number, // items in this page next_cursor?: string, // echo back to fetch the next page alarms: Array<{ aid, gid, type, ts, message, status?, device?: { id?, name?, ip? }, remote?: { ip?, country?, name?, region?, category? } }> }

Audit framing:

  • Alarm from an unknown MAC (device.id not in firewalla_list_devices) → rogue device.

  • Repeated alarms to the same remote.country → likely a single piece of malware, check firewalla_list_rules.

  • When counts get big, use group_by=type first for a birds-eye view, then drill.

Inputs: query, group_by, sort_by, limit, +2 more.

firewalla_search_flowsSearch Firewalla FlowsA
Read-onlyIdempotent

Search network flows observed by Firewalla with the MSP query grammar. Use this to inspect what's actually happening on the wire.

Use this to answer:

  • "Any outbound flows to region:CN that were NOT blocked?"

  • "Top talkers by download volume over the last 24h?"

  • "Which devices have made the most connections to blocklisted categories?"

  • "Are there any inbound flows from the public internet that shouldn't exist?"

  • "Flows from device X in the last hour?"

Args:

  • query (string, optional): Firewalla query grammar. Examples: blocked:true, region:CN, direction:inbound, device.mac:AA:BB:CC:DD:EE:FF, category:malware, ts:>1700000000, combined with AND/OR.

  • group_by (string, optional): e.g. device, device,destination, region.

  • sort_by (string, optional): e.g. ts:desc (default), download:desc.

  • limit (number, 1–500, default 200).

  • cursor (string, optional): pagination cursor from a prior response.

  • response_format ('markdown' | 'json'): Output format (default: markdown).

Returns: { count: number, // items in this page next_cursor?: string, flows: Array<{ ts, gid, protocol, direction, block?, blockType?, download?, upload?, total?, duration?, count?, device?: { id, ip?, name?, network? }, source?: { id?, ip?, name?, port? }, destination?: { id?, ip?, name?, port? }, // Flow-level classification fields (NOT nested under destination): country?, region?, domain?, category? }> }

Audit framing:

  • Start broad with sort_by=download:desc to find top bandwidth users.

  • Narrow with query when you've found a device/region of interest.

  • block=false flows to a category:malware destination = missed block, investigate rules.

  • Use group_by for aggregates; use limit=50 or so for fine-grained review.

Inputs: query, group_by, sort_by, limit, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.6/5.0

    Scored across 8 tools

    Disambiguation5/5

    Each tool has a distinct purpose targeting specific Firewalla resources: list_* tools fetch collections, get_* tools retrieve single items, and search_* tools query with filters. There is no overlap in functionality; for example, firewalla_get_alarm and firewalla_search_alarms serve complementary drill-down and overview roles without ambiguity.

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern with the prefix 'firewalla_' and snake_case throughout. Verbs are clear and standardized: 'list' for collections, 'get' for single items, and 'search' for filtered queries. This predictability makes it easy to understand each tool's intent at a glance.

    Tool Count5/5

    With 8 tools, the server is well-scoped for network security auditing. It covers essential resources (boxes, devices, rules, alarms, flows, target lists) without being overwhelming. Each tool earns its place by addressing a distinct aspect of Firewalla monitoring, fitting the domain's complexity appropriately.

    Completeness4/5

    The toolset provides comprehensive read-only coverage for auditing Firewalla MSP data, including inventory, rules, alarms, and network flows. Minor gaps exist, such as no tools for modifying rules or managing devices, but these are consistent with an audit-focused server, and agents can work around this by using the provided search and list tools effectively.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Read-only MCP server that allows AI assistants to query and monitor KVM Fleet devices, audit logs, and console sessions through the official REST API.
      5
      13 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      A read-only MCP server that gives Claude safe access to Kubernetes clusters, enabling listing, describing, and monitoring resources without mutation risks and with secret masking.
      1
      MIT