FortiManager MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| LOG_LEVEL | No | Logging level (e.g., DEBUG, INFO, WARNING). | INFO |
| DEFAULT_ADOM | No | Default Administrative Domain (ADOM) for operations. | root |
| FMG_TOOL_MODE | No | Tool loading mode: 'full' or 'dynamic'. | full |
| MCP_AUTH_TOKEN | No | Bearer token for HTTP authentication (optional). | |
| MCP_SERVER_HOST | No | Bind address for HTTP mode. | 127.0.0.1 |
| MCP_SERVER_MODE | No | MCP transport mode: 'http', 'stdio', or 'auto'. | auto |
| MCP_SERVER_PORT | No | Port for HTTP mode. | 8000 |
| FMG_POLICY_SAFETY | No | Policy safety mode: 'strict', 'warn', 'disabled'. | strict |
| FMG_SCRIPT_SAFETY | No | Script safety mode: 'strict', 'disabled'. | strict |
| FORTIMANAGER_HOST | Yes | FortiManager hostname or IP address. | |
| MCP_ALLOWED_HOSTS | No | List of allowed Host headers (JSON array string). | |
| FORTIMANAGER_TIMEOUT | No | Request timeout in seconds. | 30 |
| FORTIMANAGER_PASSWORD | No | Password for authentication. | |
| FORTIMANAGER_USERNAME | No | Username for authentication (alternative to API token). | |
| FORTIMANAGER_API_TOKEN | No | API token for authentication (recommended). | |
| FORTIMANAGER_VERIFY_SSL | No | Enable SSL verification for FortiManager connection. | true |
| FORTIMANAGER_MAX_RETRIES | No | Maximum number of retry attempts. | 3 |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| health_checkA | Check FortiManager MCP server health and connection status. |
| list_device_vdomsA | List VDOMs for a specific device. Virtual Domains (VDOMs) are independent virtual instances within a FortiGate device, each with its own configuration. Args: device: Device name adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") Returns: dict: VDOM list with keys: - status: "success" or "error" - count: Number of VDOMs - vdoms: List of VDOM objects with name, status, etc. - message: Error message if failed Example: >>> result = await list_device_vdoms("FGT-HQ", "root") >>> for vdom in result['vdoms']: ... print(f"VDOM: {vdom['name']}") |
| get_device_statusA | Get device status including connection and config sync status. Returns status information for all devices or a specific device:
Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") device: Specific device name (optional, returns all if not specified) Returns: dict: Device status with keys: - status: "success" or "error" - count: Number of devices - devices: List of device status objects - message: Error message if failed Example: >>> # Get all device status >>> result = await get_device_status("root") >>> for dev in result['devices']: ... print(f"{dev['name']}: {dev['conn_status_str']}") |
| search_devicesA | Search for devices with filters. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") name_filter: Filter by device name (partial match) platform_filter: Filter by platform type (e.g., "FortiGate-VM") os_version_filter: Filter by OS version (e.g., "7.4") connection_status: Filter by status ("up" or "down") Returns: dict: Search results with keys: - status: "success" or "error" - count: Number of matching devices - devices: List of matching device objects - message: Error message if failed Example: >>> # Find all FortiGate VMs >>> result = await search_devices(platform_filter="FortiGate-VM") |
| add_deviceA | Add a new device to FortiManager. Registers a device with FortiManager for central management. Can add either a real device (with IP) or a model device (with serial number). Args: adom: ADOM name where device will be added name: Device display name ip: Device IP address (for real device connection) serial_number: Device serial number (for model device or validation) admin_user: Admin username for device connection admin_pass: Admin password for device connection description: Device description platform: Platform type (default: "FortiGate-VM64") mgmt_mode: Management mode - "fmg" (FortiManager only), or "fmgfaz" (both) flags: Additional flags like ["create_task"] Returns: dict: Add result with keys: - status: "success" or "error" - device: Added device information - task_id: Task ID if run as background task - message: Error message if failed Example: >>> # Add a FortiGate with IP >>> result = await add_device( ... adom="root", ... name="FGT-Branch1", ... ip="192.168.1.1", ... admin_user="admin", ... admin_pass="password123" ... ) |
| add_model_deviceA | Add a model device for offline provisioning. Model devices allow pre-configuring policies and settings before the actual device connects to FortiManager. Useful for zero-touch provisioning workflows. Args: adom: ADOM name where device will be added name: Device display name serial_number: Device serial number (e.g., "FGVM020000123456") platform: Platform type (default: "FortiGate-VM64") os_version: FortiOS version (default: "7.0") description: Device description Returns: dict: Add result with keys: - status: "success" or "error" - device: Added device information - message: Status or error message Example: >>> result = await add_model_device( ... adom="root", ... name="FGT-NewBranch", ... serial_number="FGVM02TM12345678", ... platform="FortiGate-60F", ... os_version="7.4" ... ) |
| delete_deviceA | Delete a device from FortiManager. Removes a device registration. Does not affect the actual device or its configuration - only removes it from FortiManager management. WARNING: This operation cannot be undone. Args: adom: ADOM name where device is located device: Device name to delete flags: Additional flags like ["create_task"] Returns: dict: Delete result with keys: - status: "success" or "error" - task_id: Task ID if run as background task - message: Status or error message Example: >>> result = await delete_device("root", "FGT-OldBranch") >>> if result['status'] == 'success': ... print("Device removed from FortiManager") |
| add_devices_bulkA | Add multiple devices to FortiManager in bulk. Registers multiple devices at once for efficiency. Args: adom: ADOM name where devices will be added devices: List of device configurations. Each device dict can contain: - name: Device display name (required) - ip: Device IP address - sn: Serial number - adm_usr: Admin username - adm_pass: Admin password - desc: Description - platform_str: Platform type - os_ver: OS version flags: Additional flags like ["create_task"] Returns: dict: Bulk add result with keys: - status: "success" or "error" - added_count: Number of devices added - task_id: Task ID if run as background task - message: Error message if failed Example: >>> devices = [ ... {"name": "FGT-Site1", "ip": "10.0.1.1", "adm_usr": "admin", "adm_pass": "pass1"}, ... {"name": "FGT-Site2", "ip": "10.0.2.1", "adm_usr": "admin", "adm_pass": "pass2"}, ... ] >>> result = await add_devices_bulk("root", devices) |
| delete_devices_bulkA | Delete multiple devices from FortiManager in bulk. Removes multiple device registrations at once. WARNING: This operation cannot be undone. Args: adom: ADOM name where devices are located devices: List of device names to delete flags: Additional flags like ["create_task"] Returns: dict: Bulk delete result with keys: - status: "success" or "error" - deleted_count: Number of devices deleted - task_id: Task ID if run as background task - message: Error message if failed Example: >>> result = await delete_devices_bulk("root", ["FGT-Old1", "FGT-Old2"]) |
| update_deviceA | Update device properties. Modify device metadata like description and location. Args: adom: ADOM name device: Device name description: New device description latitude: GPS latitude for device location longitude: GPS longitude for device location Returns: dict: Update result with keys: - status: "success" or "error" - message: Status or error message Example: >>> result = await update_device( ... adom="root", ... device="FGT-HQ", ... description="Main headquarters firewall", ... latitude=37.7749, ... longitude=-122.4194 ... ) |
| reload_device_listA | Reload the device list from FortiManager database. Forces FortiManager to refresh its device cache. Useful after direct database changes or if device list appears stale. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") Returns: dict: Reload result with keys: - status: "success" or "error" - message: Status or error message |
| get_device_realtime_statusA | Get real-time status from a managed device. Queries the actual device through FortiManager proxy to get current system status including CPU, memory, and uptime. Args: adom: ADOM name device: Device name Returns: dict: Real-time status with keys: - status: "success" or "error" - data: Device status from FortiGate API - message: Error message if failed Example: >>> result = await get_device_realtime_status("root", "FGT-HQ") >>> print(f"Uptime: {result['data'].get('uptime')}") |
| get_device_interfacesA | Get interface information from a managed device. Queries the actual device through FortiManager proxy to get current interface configuration and status. Args: adom: ADOM name device: Device name Returns: dict: Interface information with keys: - status: "success" or "error" - data: Interface list from FortiGate API - message: Error message if failed Example: >>> result = await get_device_interfaces("root", "FGT-HQ") >>> for iface in result['data']: ... print(f"{iface['name']}: {iface.get('ip')}") |
| list_addressesA | List firewall address objects in an ADOM. Address objects define network entities (hosts, subnets, FQDNs) used in firewall policies. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") name_filter: Filter by name (partial match) type_filter: Filter by type ("ipmask", "fqdn", "iprange", "wildcard") Returns: dict: Address list with keys: - status: "success" or "error" - count: Number of addresses - addresses: List of address objects - message: Error message if failed Example: >>> # List all addresses >>> result = await list_addresses("root") |
| get_addressA | Get detailed information about a firewall address object. Args: adom: ADOM name name: Address object name Returns: dict: Address details with keys: - status: "success" or "error" - address: Full address configuration - message: Error message if failed |
| create_address_subnetA | Create a subnet/network address object. Args: adom: ADOM name name: Address object name subnet: IP/netmask (e.g., "10.0.0.0/24" or "10.0.0.0 255.255.255.0") comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created address name - message: Status or error message Example: >>> result = await create_address_subnet( ... adom="root", ... name="LAN-Subnet", ... subnet="192.168.1.0/24", ... comment="Local network" ... ) |
| create_address_hostA | Create a host address object (single IP). Args: adom: ADOM name name: Address object name ip: Host IP address (e.g., "10.0.0.100") comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created address name - message: Status or error message Example: >>> result = await create_address_host( ... adom="root", ... name="WebServer", ... ip="192.168.1.100", ... comment="Production web server" ... ) |
| create_address_fqdnA | Create an FQDN (Fully Qualified Domain Name) address object. FQDN addresses are resolved dynamically by FortiGate. Args: adom: ADOM name name: Address object name fqdn: Domain name (e.g., "www.example.com") comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created address name - message: Status or error message Example: >>> result = await create_address_fqdn( ... adom="root", ... name="Google-DNS", ... fqdn="dns.google.com" ... ) |
| create_address_rangeA | Create an IP range address object. Args: adom: ADOM name name: Address object name start_ip: Start IP address end_ip: End IP address comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created address name - message: Status or error message Example: >>> result = await create_address_range( ... adom="root", ... name="DHCP-Pool", ... start_ip="192.168.1.100", ... end_ip="192.168.1.200" ... ) |
| update_addressA | Update an existing address object. Only specified fields will be updated. Args: adom: ADOM name name: Current address name new_name: New name (optional) subnet: New subnet for ipmask type (optional) fqdn: New FQDN for fqdn type (optional) comment: New comment (optional) Returns: dict: Update result with keys: - status: "success" or "error" - message: Status or error message |
| delete_addressA | Delete a firewall address object. WARNING: This will fail if the address is in use by policies or groups. Args: adom: ADOM name name: Address object name to delete Returns: dict: Delete result with keys: - status: "success" or "error" - message: Status or error message |
| list_address_groupsA | List firewall address groups in an ADOM. Address groups contain multiple address objects for easier policy management. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") name_filter: Filter by name (partial match) Returns: dict: Group list with keys: - status: "success" or "error" - count: Number of groups - groups: List of address group objects - message: Error message if failed |
| get_address_groupB | Get detailed information about an address group. Args: adom: ADOM name name: Address group name Returns: dict: Group details with keys: - status: "success" or "error" - group: Full group configuration including members - message: Error message if failed |
| create_address_groupA | Create an address group. Args: adom: ADOM name name: Group name members: List of address object names to include comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created group name - message: Status or error message Example: >>> result = await create_address_group( ... adom="root", ... name="Web-Servers", ... members=["WebServer1", "WebServer2", "WebServer3"], ... comment="Production web servers" ... ) |
| update_address_groupB | Update an address group. Args: adom: ADOM name name: Group name members: New member list (replaces existing) comment: New comment Returns: dict: Update result with keys: - status: "success" or "error" - message: Status or error message |
| delete_address_groupA | Delete an address group. WARNING: This will fail if the group is in use by policies. Args: adom: ADOM name name: Group name to delete Returns: dict: Delete result with keys: - status: "success" or "error" - message: Status or error message |
| list_servicesA | List custom service objects in an ADOM. Service objects define network protocols and ports used in policies. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") name_filter: Filter by name (partial match) protocol_filter: Filter by protocol ("TCP/UDP/SCTP", "ICMP", "IP") Returns: dict: Service list with keys: - status: "success" or "error" - count: Number of services - services: List of service objects - message: Error message if failed |
| get_serviceC | Get detailed information about a service object. Args: adom: ADOM name name: Service object name Returns: dict: Service details with keys: - status: "success" or "error" - service: Full service configuration - message: Error message if failed |
| create_service_tcp_udpA | Create a TCP/UDP/SCTP/UDP-Lite service object. Args: adom: ADOM name name: Service object name tcp_portrange: TCP port range (e.g., "80", "8080-8090", "80 443 8080") udp_portrange: UDP port range (e.g., "53", "500-502") sctp_portrange: SCTP port range (e.g., "3868", "2905-2907") udplite_portrange: UDP-Lite port range (e.g., "1234") comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created service name - message: Status or error message Example: >>> # Create HTTP/HTTPS service >>> result = await create_service_tcp_udp( ... adom="root", ... name="Custom-Web", ... tcp_portrange="80 443 8080", ... comment="Custom web ports" ... ) |
| create_service_icmpA | Create an ICMP service object. Args: adom: ADOM name name: Service object name icmp_type: ICMP type (0-255, optional for all types) icmp_code: ICMP code (0-255, optional) comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created service name - message: Status or error message Example: >>> # Create ping service (ICMP echo request) >>> result = await create_service_icmp( ... adom="root", ... name="Custom-Ping", ... icmp_type=8, ... comment="ICMP Echo Request" ... ) |
| update_serviceB | Update a service object. Args: adom: ADOM name name: Service name tcp_portrange: New TCP port range udp_portrange: New UDP port range comment: New comment Returns: dict: Update result with keys: - status: "success" or "error" - message: Status or error message |
| delete_serviceA | Delete a service object. WARNING: This will fail if the service is in use by policies. Args: adom: ADOM name name: Service name to delete Returns: dict: Delete result with keys: - status: "success" or "error" - message: Status or error message |
| list_service_groupsA | List service groups in an ADOM. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") name_filter: Filter by name (partial match) Returns: dict: Group list with keys: - status: "success" or "error" - count: Number of groups - groups: List of service group objects - message: Error message if failed |
| get_service_groupA | Get detailed information about a service group. Args: adom: ADOM name name: Service group name Returns: dict: Group details with keys: - status: "success" or "error" - group: Full group configuration including members - message: Error message if failed |
| create_service_groupA | Create a service group. Args: adom: ADOM name name: Group name members: List of service names to include comment: Optional comment Returns: dict: Create result with keys: - status: "success" or "error" - name: Created group name - message: Status or error message Example: >>> result = await create_service_group( ... adom="root", ... name="Web-Services", ... members=["HTTP", "HTTPS", "DNS"], ... comment="Common web services" ... ) |
| delete_service_groupA | Delete a service group. WARNING: This will fail if the group is in use by policies. Args: adom: ADOM name name: Group name to delete Returns: dict: Delete result with keys: - status: "success" or "error" - message: Status or error message |
| search_objectsA | Search across all firewall objects by name. Searches addresses, address groups, services, and service groups for objects matching the search term. Args: adom: ADOM name search_term: Search term (partial match) Returns: dict: Search results with keys: - status: "success" or "error" - addresses: Matching address objects - address_groups: Matching address groups - services: Matching service objects - service_groups: Matching service groups - total_count: Total matches - message: Error message if failed Example: >>> result = await search_objects("root", "web") |
| create_packageA | Create a new policy package. Policy packages contain firewall policies, security profiles, and other configurations to be deployed to managed devices. Args: adom: ADOM name name: Package name ngfw_mode: NGFW mode - "profile-based" (default) or "policy-based" central_nat: Enable central NAT (default: False) Returns: dict: Create result with keys: - status: "success" or "error" - package: Created package name - message: Status or error message Example: >>> result = await create_package( ... adom="root", ... name="Branch-Policy", ... ngfw_mode="profile-based" ... ) |
| delete_packageA | Delete a policy package. WARNING: This will delete the package and all its policies. This operation cannot be undone. Args: adom: ADOM name package: Package name to delete Returns: dict: Delete result with keys: - status: "success" or "error" - message: Status or error message |
| clone_packageA | Clone a policy package. Creates a copy of an existing package with all its policies. Args: adom: ADOM name package: Source package name new_name: Name for the cloned package Returns: dict: Clone result with keys: - status: "success" or "error" - package: New package name - message: Status or error message Example: >>> result = await clone_package( ... adom="root", ... package="default", ... new_name="default-copy" ... ) |
| assign_packageA | Assign a policy package to devices. Associates a policy package with specific devices/VDOMs. The package can then be installed to these devices. Args: adom: ADOM name package: Package name devices: Target devices [{"name": "FGT1", "vdom": "root"}, ...] Returns: dict: Assignment result with keys: - status: "success" or "error" - message: Status or error message Example: >>> result = await assign_package( ... adom="root", ... package="Branch-Policy", ... devices=[ ... {"name": "FGT-Branch1", "vdom": "root"}, ... {"name": "FGT-Branch2", "vdom": "root"} ... ] ... ) |
| list_firewall_policiesA | List firewall policies in a policy package. Args: adom: ADOM name package: Policy package name fields: Specific fields to return (optional) limit: Maximum number of policies to return (optional) offset: Starting position for pagination (default: 0) Returns: dict: Policy list with keys: - status: "success" or "error" - count: Number of policies returned - total: Total number of policies in package - policies: List of policy objects - message: Error message if failed Example: >>> # Get all policies >>> result = await list_firewall_policies("root", "default") |
| get_firewall_policyA | Get detailed information about a specific firewall policy. Args: adom: ADOM name package: Policy package name policyid: Policy ID number Returns: dict: Policy details with keys: - status: "success" or "error" - policy: Full policy configuration - message: Error message if failed Example: >>> result = await get_firewall_policy("root", "default", 1) >>> print(f"Policy name: {result['policy']['name']}") |
| create_firewall_policyA | Create a new firewall policy. Creates a firewall policy in the specified policy package. The policy won't be active until the package is installed to devices. Args: adom: ADOM name package: Policy package name name: Policy name srcintf: Source interfaces (e.g., ["internal"]) dstintf: Destination interfaces (e.g., ["wan1"]) srcaddr: Source addresses (e.g., ["all"]) dstaddr: Destination addresses (e.g., ["all"]) service: Services (e.g., ["ALL", "HTTP", "HTTPS"]) action: Policy action - "accept" or "deny" (default: "accept") schedule: Schedule object name (default: "always") nat: Enable NAT (default: False) logtraffic: Log mode - "all", "utm", or "disable" (default: "utm") status: Policy status - "enable" or "disable" (default: "enable") comments: Policy comments (optional) policyid: Specific policy ID (optional, auto-assigned if not set) Returns: dict: Create result with keys: - status: "success" or "error" - policyid: Created policy ID - message: Status or error message Example: >>> result = await create_firewall_policy( ... adom="root", ... package="default", ... name="Allow-Web-Traffic", ... srcintf=["internal"], ... dstintf=["wan1"], ... srcaddr=["LAN-Subnet"], ... dstaddr=["all"], ... service=["HTTP", "HTTPS"], ... action="accept", ... nat=True ... ) |
| update_firewall_policyA | Update an existing firewall policy. Only the specified fields will be updated; other fields remain unchanged. Args: adom: ADOM name package: Policy package name policyid: Policy ID to update name: New policy name (optional) srcintf: New source interfaces (optional) dstintf: New destination interfaces (optional) srcaddr: New source addresses (optional) dstaddr: New destination addresses (optional) service: New services (optional) action: New action - "accept" or "deny" (optional) schedule: New schedule (optional) nat: Enable/disable NAT (optional) logtraffic: New log mode (optional) status: New status (optional) comments: New comments (optional) global_label: Policy section label (optional) global_label_color: Policy section color ID 0-31 (optional) Returns: dict: Update result with keys: - status: "success" or "error" - policyid: Updated policy ID - message: Status or error message Example: >>> # Disable a policy >>> result = await update_firewall_policy( ... adom="root", ... package="default", ... policyid=10, ... status="disable" ... ) |
| delete_firewall_policyA | Delete a firewall policy. WARNING: This operation cannot be undone. Args: adom: ADOM name package: Policy package name policyid: Policy ID to delete Returns: dict: Delete result with keys: - status: "success" or "error" - message: Status or error message |
| delete_firewall_policies_bulkA | Delete multiple firewall policies at once. WARNING: This operation cannot be undone. Args: adom: ADOM name package: Policy package name policyids: List of policy IDs to delete Returns: dict: Delete result with keys: - status: "success", "partial", or "error" - deleted_count: Number of policies deleted - deleted: Policy IDs that were deleted - failed: Per-item failures [{"policyid", "message", "error_code"}, ...] - message: Status or error message Example: >>> result = await delete_firewall_policies_bulk( ... adom="root", ... package="default", ... policyids=[5, 6, 7, 8] ... ) |
| move_firewall_policyA | Move a firewall policy to a new position. Reorders a policy relative to another policy in the rule list. Policy order determines evaluation priority. Args: adom: ADOM name package: Policy package name policyid: Policy ID to move target_policyid: Reference policy ID position: Where to place - "before" or "after" (default: "before") Returns: dict: Move result with keys: - status: "success" or "error" - message: Status or error message Example: >>> # Move policy 10 before policy 5 >>> result = await move_firewall_policy( ... adom="root", ... package="default", ... policyid=10, ... target_policyid=5, ... position="before" ... ) |
| search_firewall_policiesA | Search firewall policies with filters. Args: adom: ADOM name package: Policy package name name_filter: Filter by policy name (partial match) srcaddr_filter: Filter by source address (partial match) dstaddr_filter: Filter by destination address (partial match) service_filter: Filter by service (partial match) action_filter: Filter by action ("accept" or "deny") status_filter: Filter by status ("enable" or "disable") Returns: dict: Search results with keys: - status: "success" or "error" - count: Number of matching policies - policies: List of matching policy objects - message: Error message if failed Example: >>> # Find all deny policies >>> result = await search_firewall_policies( ... adom="root", ... package="default", ... action_filter="deny" ... ) |
| get_policy_servicesA | Get services configured on a firewall policy with optional group resolution. Retrieves the service list from a firewall policy and optionally resolves each service/group into its detailed definition (ports, protocols, group members). Useful for policy hardening workflows where you need to compare actual traffic against configured services. Args: adom: ADOM name package: Policy package name policy_id: Policy ID number resolve: If True, resolve each service to its definition including port ranges and group members (default: True) Returns: dict: Service information with keys: - status: "success" or "error" - policy_id: The policy ID queried - policy_name: Name of the policy - service_names: List of raw service names from the policy - services: Resolved service details (if resolve=True) - message: Error message if failed Example: >>> # Get resolved services for policy 10 >>> result = await get_policy_services("root", "default", 10) |
| preview_installA | Preview installation changes before applying. Shows what configuration changes would be made to devices without actually installing the package. Use this to verify changes before deployment. Args: adom: ADOM name package: Policy package name (optional, preview device settings if None) devices: Target devices [{"name": "FGT1", "vdom": "root"}, ...] Returns: dict: Preview result with keys: - status: "success" or "error" - task_id: Task ID for retrieving preview results - message: Status or error message Example: >>> # Start preview >>> result = await preview_install( ... adom="root", ... package="default", ... devices=[{"name": "FGT-HQ", "vdom": "root"}] ... ) >>> # Wait for preview to complete, then get results >>> if result["status"] == "success": ... from fortimanager_mcp.tools.system_tools import wait_for_task ... await wait_for_task(result["task_id"]) ... preview = await get_preview_result(...) |
| get_preview_resultA | Get the result of an installation preview. Call this after preview_install() task completes to see the detailed configuration changes. Args: adom: ADOM name devices: Target devices [{"name": "FGT1", "vdom": "root"}, ...] Returns: dict: Preview results with keys: - status: "success" or "error" - preview: Preview data with configuration changes - message: Error message if failed |
| list_scriptsA | List CLI scripts in an ADOM. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") script_type: Filter by type (cli, tcl, cligrp, tclgrp, jinja) target: Filter by target (device_database, remote_device, adom_database) limit: Maximum number of scripts to return Returns: List of scripts with name, type, target, and description |
| get_scriptA | Get details of a specific CLI script. Args: adom: ADOM name name: Script name Returns: Script details including content |
| create_scriptB | Create a new CLI script. Args: adom: ADOM name name: Script name content: Script content (CLI commands) script_type: Script type - cli, tcl, cligrp, tclgrp, jinja (default: cli) target: Execution target (default: device_database) - device_database: Device Database - adom_database: Policy Package or ADOM Database - remote_device: Remote FortiGate Directly (via CLI) description: Script description Returns: Created script details |
| update_scriptA | Update an existing CLI script. Args: adom: ADOM name name: Script name to update content: New script content description: New description script_type: New script type target: New target Returns: Updated script details |
| delete_scriptB | Delete a CLI script. Args: adom: ADOM name name: Script name to delete Returns: Deletion result |
| execute_script_on_deviceA | Execute a CLI script on a specific device. The script must have target=remote_device to run directly on the device. Script execution creates a task that should be monitored for completion. IMPORTANT: Keep the session alive while script executes on remote devices. Args: adom: ADOM name script: Script name to execute device: Target device name Returns: Task ID for monitoring execution progress |
| execute_script_on_devicesB | Execute a CLI script on multiple devices. Args: adom: ADOM name script: Script name to execute devices: List of device names Returns: Task ID for monitoring execution progress |
| execute_script_on_device_groupA | Execute a CLI script on a device group. Args: adom: ADOM name script: Script name to execute group: Device group name Returns: Task ID for monitoring execution progress |
| execute_script_on_packageA | Execute a CLI script against a policy package or ADOM database. The script must have target=adom_database. This modifies the package/ADOM DB, not a live device. Args: adom: ADOM name script: Script name to execute package: Policy package name Returns: Task ID for monitoring execution progress |
| get_script_log_latestB | Get the latest script execution log. Args: adom: ADOM name device: Optional device name to filter logs Returns: Latest script execution log with content and execution time |
| get_script_log_summaryA | Get script execution log summary. Lists all script executions with log IDs for detailed retrieval. Args: adom: ADOM name device: Optional device name to filter logs Returns: List of script execution summaries with log_id, script_name, exec_time |
| get_script_log_outputA | Get specific script execution output by log ID. Log ID can be derived from task ID:
Args: adom: ADOM name log_id: Log ID from execution task or log summary device: Optional device name (required for device-specific logs) Returns: Script execution output content |
| list_sdwan_templatesA | List SD-WAN templates in an ADOM. SD-WAN templates define WAN interface configurations, performance SLAs, and traffic steering rules for SD-WAN deployments. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") limit: Maximum number of templates to return Returns: List of SD-WAN templates with name, type, and assigned devices |
| get_sdwan_templateA | Get details of a specific SD-WAN template. Args: adom: ADOM name name: SD-WAN template name Returns: SD-WAN template details including interfaces, SLAs, and rules |
| create_sdwan_templateB | Create a new SD-WAN template. Creates an empty SD-WAN template that can be configured with interfaces, SLAs, and routing rules. Args: adom: ADOM name name: SD-WAN template name description: Optional description Returns: Created SD-WAN template |
| delete_sdwan_templateB | Delete an SD-WAN template. Note: Template must not be assigned to any devices before deletion. Args: adom: ADOM name name: SD-WAN template name Returns: Deletion result |
| assign_sdwan_templateC | Assign an SD-WAN template to a device. Args: adom: ADOM name template: SD-WAN template name device: Device name to assign vdom: VDOM name (default: root) Returns: Assignment result |
| assign_sdwan_template_bulkB | Assign an SD-WAN template to multiple devices. Args: adom: ADOM name template: SD-WAN template name devices: List of devices [{"name": "dev1", "vdom": "root"}, ...] Returns: Assignment result |
| unassign_sdwan_templateB | Unassign an SD-WAN template from a device. Args: adom: ADOM name template: SD-WAN template name device: Device name to unassign vdom: VDOM name (default: root) Returns: Unassignment result |
| get_system_statusA | Get FortiManager system status and version information. Returns comprehensive system status including:
Returns: dict: System status with keys: - status: "success" or "error" - data: System status information - message: Error message if failed Example: >>> result = await get_system_status() >>> print(f"Version: {result['data']['Version']}") >>> print(f"Hostname: {result['data']['Hostname']}") |
| get_ha_statusA | Get FortiManager High Availability (HA) status. Returns HA cluster status including:
Returns: dict: HA status with keys: - status: "success" or "error" - data: HA status information - message: Error message if failed Example: >>> result = await get_ha_status() >>> print(f"HA Mode: {result['data']['mode']}") |
| list_adomsA | List all Administrative Domains (ADOMs) in FortiManager. ADOMs partition FortiManager into separate management domains, each with its own devices, policies, and configurations. Args: fields: Specific fields to return (optional, returns all if not specified) Returns: dict: ADOM list with keys: - status: "success" or "error" - count: Number of ADOMs - adoms: List of ADOM objects with name, desc, state, etc. - message: Error message if failed Example: >>> result = await list_adoms() >>> for adom in result["adoms"]: ... print(f"{adom['name']}: {adom.get('desc', 'No description')}") |
| get_adomA | Get detailed information about a specific ADOM. Args: name: ADOM name (e.g., "root", "customer-a") include_details: Include sub-objects (default: False) Returns: dict: ADOM details with keys: - status: "success" or "error" - adom: ADOM object with full configuration - message: Error message if failed Example: >>> result = await get_adom("root") >>> print(f"State: {result['adom']['state']}") |
| list_devicesA | List all managed devices in an ADOM. FortiManager manages FortiGate and other Fortinet devices. This lists all devices registered in the specified ADOM. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") fields: Specific fields to return (optional) Returns: dict: Device list with keys: - status: "success" or "error" - count: Number of devices - devices: List of device objects with name, ip, os_ver, etc. - message: Error message if failed Example: >>> result = await list_devices("root") >>> for device in result["devices"]: ... print(f"{device['name']}: {device.get('ip', 'N/A')}") |
| get_deviceA | Get detailed information about a specific managed device. Args: name: Device name adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") include_details: Include sub-objects like VDOMs (default: False) Returns: dict: Device details with keys: - status: "success" or "error" - device: Device object with full configuration - message: Error message if failed Example: >>> result = await get_device("FGT-HQ", "root") >>> print(f"Version: {result['device']['os_ver']}") >>> print(f"Platform: {result['device']['platform_str']}") |
| list_device_groupsA | List all device groups in an ADOM. Device groups organize managed devices for bulk operations like policy installation or configuration deployment. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") Returns: dict: Device groups with keys: - status: "success" or "error" - count: Number of groups - groups: List of device group objects - message: Error message if failed |
| list_tasksA | List all tasks in FortiManager. Tasks represent background operations like policy installation, device provisioning, and other long-running processes. Args: filter_state: Filter by task state (optional): - "pending": Not started - "running": Currently executing - "done": Completed - "error": Failed - "cancelling": Being cancelled - "cancelled": Cancelled Returns: dict: Task list with keys: - status: "success" or "error" - count: Number of tasks - tasks: List of task objects with id, state, progress, etc. - message: Error message if failed Example: >>> # Get all tasks >>> result = await list_tasks() |
| get_taskA | Get detailed status of a specific task. Args: task_id: Task ID number include_details: Include task line details (default: False) Returns: dict: Task details with keys: - status: "success" or "error" - task: Task object with id, state, progress, result, etc. - lines: Task line details (if include_details=True) - message: Error message if failed Example: >>> result = await get_task(12345) >>> print(f"State: {result['task']['state']}") >>> print(f"Progress: {result['task'].get('percent', 0)}%") |
| wait_for_taskA | Wait for a task to complete. Polls the task status until it completes or times out. Useful for waiting on installation or provisioning operations. Args: task_id: Task ID number timeout: Maximum wait time in seconds (default: 300, capped at 3600) poll_interval: Seconds between status checks (default: 5) Returns: dict: Final task status with keys: - status: "success" or "error" - task: Final task object - completed: Whether task completed (vs timeout) - message: Status or error message Example: >>> # Wait for policy installation >>> result = await wait_for_task(12345, timeout=600) >>> if result['completed']: ... print("Installation finished!") |
| list_packagesA | List all policy packages in an ADOM. Policy packages contain firewall policies, security profiles, and other configurations to be installed on managed devices. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") Returns: dict: Package list with keys: - status: "success" or "error" - count: Number of packages - packages: List of package objects - message: Error message if failed Example: >>> result = await list_packages("root") >>> for pkg in result["packages"]: ... print(f"{pkg['name']}: {pkg.get('type', 'policy')}") |
| get_packageA | Get detailed information about a policy package. Args: name: Package name adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") include_details: Include policies and settings (default: False) Returns: dict: Package details with keys: - status: "success" or "error" - package: Package object - message: Error message if failed |
| install_packageA | Install a policy package to managed devices. Deploys firewall policies and configurations from a policy package to the specified devices. This is an asynchronous operation - use wait_for_task() to monitor completion. By default (FMG_INSTALL_SAFETY=strict) a real install requires a verified preview first: run preview_install for the same ADOM, package, and devices, wait for its task to finish, then install. Each preview authorizes one install, and only while the package is unchanged — if the package was edited after the preview, the install is refused (preview_stale) and a fresh preview is required. Args: adom: ADOM name package: Policy package name devices: Target devices [{"name": "FGT1", "vdom": "root"}, ...] preview: If True, only preview changes without applying (default: False) Returns: dict: Installation result with keys: - status: "success" or "error" - task_id: Task ID for monitoring (if successful) - message: Status or error message Example: >>> # Install to single device >>> result = await install_package( ... adom="root", ... package="default", ... devices=[{"name": "FGT-HQ", "vdom": "root"}] ... ) >>> if result["status"] == "success": ... await wait_for_task(result["task_id"]) |
| install_device_settingsA | Install device settings only (without policy package). Deploys device-level configurations like interfaces, DNS, NTP without reinstalling the full policy package. Args: adom: ADOM name devices: Target devices [{"name": "FGT1", "vdom": "root"}, ...] Returns: dict: Installation result with keys: - status: "success" or "error" - task_id: Task ID for monitoring - message: Status or error message |
| lock_adomA | Lock an ADOM for editing (workspace mode). In workspace mode, ADOMs must be locked before making changes. This prevents conflicts from multiple administrators editing the same ADOM simultaneously. Args: adom: ADOM name to lock Returns: dict: Lock result with keys: - status: "success" or "error" - message: Status or error message Example: >>> result = await lock_adom("root") >>> if result["status"] == "success": ... # Make changes... ... await commit_adom("root") ... await unlock_adom("root") |
| unlock_adomA | Unlock an ADOM (workspace mode). Release the lock on an ADOM. Changes should be committed before unlocking to persist them. Args: adom: ADOM name to unlock Returns: dict: Unlock result with keys: - status: "success" or "error" - message: Status or error message |
| commit_adomA | Commit changes to an ADOM (workspace mode). Saves all pending changes made to the ADOM. Must be called before unlocking to persist changes. Args: adom: ADOM name to commit Returns: dict: Commit result with keys: - status: "success" or "error" - message: Status or error message |
| list_templatesA | List all provisioning templates in an ADOM. Returns all template types: IPsec, BGP, system, etc. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") limit: Maximum number of templates to return Returns: List of templates with name, type, and settings |
| get_templateB | Get details of a specific provisioning template. Args: adom: ADOM name name: Template name Returns: Template details including settings and scope |
| list_system_templatesA | List system templates (device profiles) in an ADOM. System templates configure device settings like DNS, NTP, logging, etc. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") limit: Maximum number to return Returns: List of system templates with name, type, and assigned devices |
| get_system_templateB | Get details of a specific system template. Args: adom: ADOM name name: System template name Returns: System template details including widgets and assigned devices |
| assign_system_templateB | Assign a system template to a device. Args: adom: ADOM name template: System template name device: Device name to assign vdom: VDOM name (default: root) Returns: Assignment result |
| assign_system_template_bulkB | Assign a system template to multiple devices. Args: adom: ADOM name template: System template name devices: List of devices [{"name": "dev1", "vdom": "root"}, ...] Returns: Assignment result |
| unassign_system_templateA | Unassign a system template from a device. Args: adom: ADOM name template: System template name device: Device name to unassign vdom: VDOM name (default: root) Returns: Unassignment result |
| list_cli_template_groupsA | List CLI template groups in an ADOM. CLI template groups contain CLI commands to be executed on devices. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") limit: Maximum number to return Returns: List of CLI template groups |
| get_cli_template_groupA | Get details of a CLI template group. Args: adom: ADOM name name: CLI template group name Returns: CLI template group details |
| create_cli_template_groupB | Create a new CLI template group. Args: adom: ADOM name name: CLI template group name description: Optional description Returns: Created CLI template group |
| delete_cli_template_groupB | Delete a CLI template group. Args: adom: ADOM name name: CLI template group name Returns: Deletion result |
| list_template_groupsA | List template groups in an ADOM. Template groups combine multiple templates (system, CLI, SD-WAN, etc.) into a single package for device assignment. Args: adom: ADOM name (default: from DEFAULT_ADOM env var, or "root") limit: Maximum number to return Returns: List of template groups |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
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/rstierli/fortimanager-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server