Skip to main content
Glama
limtsi

Cisco FMC MCP Server

by limtsi
README.md
# Cisco FMC MCP Server

An MCP server exposing Cisco Secure Firewall Management Center (FMC)
operations over streamable HTTP, built as the demo target for Cisco AI
Defense controlling MCP tool calls in-path.

> **New to this project?** See [`docs/user_guide.md`](docs/user_guide.md)
> for a step-by-step walkthrough: setting up your Python environment,
> pointing the server at your FMC, and connecting the Claude Desktop app.
> The sections below assume familiarity and go faster.

## Setup

1. Copy `.env.example` to `.env` and fill in your FMC host, a dedicated
   API-user's credentials, and a value for `MCP_AUTH_TOKEN` (the shared
   secret clients must send as `Authorization: Bearer <token>`).
2. Set `MCP_ALLOWED_HOSTS`/`MCP_ALLOWED_ORIGINS` to match how this server
   will actually be addressed (e.g. the hostname AI Defense uses to reach
   it) — the SDK's DNS-rebinding protection denies every host by default.
3. Use a dedicated FMC API user, not a shared GUI admin account: FMC does
   not allow the same user to be logged into the API and the GUI at once.
   Grant that user the minimum role needed: the 8 read-only tools need only
   read access to devices, policies, and objects; the 3 write tools
   additionally need permission to create network objects, create/modify
   access control rules, and deploy policy changes -- a role like
   "Access Admin" (or an equivalent covering network-object and
   access-policy read/write plus deployment) is the practical minimum if
   the write tools will be used, while a read-only role suffices if they
   will not be.
4. Run locally: `pip install -e ".[dev]"` then `fmc-mcp-server`.
5. Run via Docker: `docker compose up --build`.

## Putting Cisco AI Defense in front

Point AI Defense (or any in-path proxy enforcing its policies) at this
server's `http://<host>:8765/mcp` endpoint. This server's own bearer-token
check is a baseline control independent of AI Defense — it means the
server is never accidentally left open before AI Defense is wired in.

## Tools

| Tool | Risk | Description |
|---|---|---|
| `list_devices` | read-only | Managed FTD devices, model, health status |
| `get_device` | read-only | Full detail for one device |
| `list_access_policies` | read-only | Access control policies |
| `get_deployment_status` | read-only | Pending-changes status for a device |
| `search_access_rules` | read-only | Search rules in a policy |
| `find_rules_by_ip_or_fqdn` | read-only | Reverse lookup: rules referencing an IP/FQDN |
| `search_network_objects` | read-only | Search host/network/FQDN objects |
| `list_security_zones` | read-only | Security zones |
| `create_network_object` | **write** | Create a host/network/FQDN object |
| `create_access_rule` | **write** | Append a rule to a policy |
| `deploy_policy` | **write, most consequential** | Push pending changes to live devices |

Every tool declares standard MCP `ToolAnnotations` (`readOnlyHint`,
`destructiveHint`, `idempotentHint`) so a policy layer like AI Defense can
key off that metadata rather than tool names.

## Testing

`pytest -v` runs the full suite (`FMCClient` auth/refresh/pagination, every
tool against mocked FMC responses, the bearer middleware, and the assembled
server). A manual smoke test against a real/lab FMC via
`npx @modelcontextprotocol/inspector` is recommended before treating the
server as demo-ready.

## Security notes

- `FMC_VERIFY_SSL=false` is an explicit, lab-only opt-out — production
  deployments must supply a trusted certificate or CA bundle.
- Credentials and tokens are never logged; audit log entries redact any
  sensitive-looking argument keys.
- The three write tools exist specifically so the AI Defense demo has real
  actions worth blocking. Consider removing or further gating them for any
  non-demo deployment.