Several FortiGates
Manage several FortiGates from one forti-mcp with a profile per device, --profile and the per-request profile field.
Several FortiGates
One forti-mcp serves every FortiGate in the forti home. Each device is a profile in
~/.forti/config.json, with its own host, credentials, certificates and mode. The model picks a
device per request with the profile field; --profile sets the device used when a request names
none.
A profile per device
Create a profile for each FortiGate with the forti CLI. Profile names are 1 to 64 letters, digits,
- and _.
1forti configure --profile fw01 --host fw01.example.net --api-key-stdin --default < fw01.key2forti profile copy fw01 fw02 && forti profile set fw02 host=fw02.example.net3forti configure --profile fw02 --api-key-stdin < fw02.key4forti profile list
forti profile copy copies the settings but no secrets, so the copy gets its own API key from
forti configure. Other profile commands:
| Command | What it does |
|---|---|
forti profile default NAME | Makes NAME the default profile |
forti profile mode [NAME] MODE | Sets a profile's mode: read-only, guarded or autonomous |
forti profile set NAME key=value... | Changes settings such as port, vdom or ca_bundle without contacting the device |
forti profile rename OLD NEW | Renames a profile with its stored secrets and certificates |
forti cert create --profile NAME | Makes a client certificate for that profile in ~/.forti/certs/NAME/ |
forti-mcp reads config.json once, at the first request that needs it, and keeps it for the life
of the process. After adding or changing a profile, start a new agent session so the client starts
forti-mcp again.
How a request picks its device
forti_discover, forti_read and forti_plan accept a profile field. A request uses:
- the
profileit names; - else the registration's
--profile; - else the default profile of the forti home (
forti profile default); - else the only profile, when there is exactly one.
With several profiles and no default, a request that names none fails with a config error that
says so. forti_apply takes only a plan_id: a stored plan already names its profile.
The model learns the devices from forti_discover:
1{"what": "devices"}2{"what": "capabilities", "profile": "fw02"}
devices lists every profile with host, port and mode (never a secret) and reports the default in
meta.default_profile. After that, the model names the device in each request:
1{"resource": "firewall/address", "profile": "fw02", "fields": ["name", "subnet"], "count": 50}2{"profile": "fw02", "operations": [{"op": "create", "resource": "firewall/address",3 "object": {"name": "web", "subnet": "192.0.2.10 255.255.255.255"}}]}
Read and plan results name the profile they used in meta.profile.
A default device for a registration
--profile in the client entry sets step 2 above. forti install mcp writes it for you:
1forti install mcp --client all --scope workspace --profile fw01
The tools' schemas then name that profile as the default, so the model sees which device it gets when it names none.
A registration with --profile fw01 can still reach every other profile in the forti home by
naming it. What limits each device is its profile's mode and the FortiOS account's privileges
(Safety and modes).
A mode per device
Each profile has its own mode, so one workspace can hold a production FortiGate in read-only or
guarded mode next to a lab device in autonomous mode:
1forti profile mode fw01 guarded2forti profile mode lab autonomous
forti_discover reports each profile's mode, and forti_plan says what apply will do in it. A
guarded plan on one device is approved with forti plan approve <id> like any other; the plan id
already identifies the device.