by alexgoller
Provides a programmable interface to Illumio Policy Compute Engine for workload management, label operations, traffic flow analysis, automated ringfencing, and infrastructure service identification.
Enables conversational AI and script‑based interactions with an Illumio PCE, allowing full CRUD of workloads, labels, IP lists, services, and rulesets, plus advanced traffic analysis and automated security policy creation.
uv sync.PCE_HOST, API_KEY, API_SECRET).illumio-mcp-http. In production, set OAuth variables (MCP_OAUTH_ISSUER, MCP_OAUTH_JWKS_URL, etc.). For development, use MCP_DEV_INSECURE=1.create-deny-rule tool.Q: Which Python version is required? A: Python 3.8 or newer.
Q: How is authentication handled?
A: The server validates OAuth 2.1 bearer tokens from a configured IdP. In dev mode you can bypass auth with MCP_DEV_INSECURE=1.
Q: What is the difference between per‑user and shared PCE modes? A: Per‑user stores a unique PCE API key for each authenticated user, enabling audit attribution on the PCE side. Shared uses a single service‑account key for all users, simplifying onboarding.
Q: Do I need to set up a keystore?
A: Only for per‑user mode. Provide a KEK (MCP_KEK) and optionally set MCP_KEYSTORE_PATH.
Q: How are mutating actions protected?
A: Tools marked as requiring confirmation return a confirm_required error. A client must request a single‑use confirm token via /confirm before re‑issuing the tool call.
Q: Can I run the server in a container?
A: Yes. Docker images are available on GHCR; run them with environment variables or an .env file as documented.
Q: Where are logs and audit data stored?
A: Health endpoints (/healthz, /readyz) are unauthenticated. Audit logs default to <keystore_dir>/audit.db; the keystore defaults to ./data/keys.db.
📚 Documentation site — installation, getting started, workflows, the full tool reference, and central deployment.
A Model Context Protocol (MCP) server that provides an interface to interact with Illumio PCE (Policy Compute Engine). This server enables programmatic access to Illumio workload management, label operations, traffic flow analysis, automated ringfencing, and infrastructure service identification.
Use conversational AI to talk to your PCE:
git clone https://github.com/alexgoller/illumio-mcp-server.git
cd illumio-mcp-server
uv sync
You should run this using the uv command, which makes it easier to pass in environment variables and run it in the background.
On MacOS: ~/Library/Application\ Support/Claude/claude_desktop_config.json
On Windows: %APPDATA%/Claude/claude_desktop_config.json
Add the following to the custom_settings section:
"mcpServers": {
"illumio-mcp": {
"command": "uv",
"args": [
"--directory",
"/path/to/illumio-mcp-server",
"run",
"illumio-mcp"
],
"env": {
"PCE_HOST": "your-pce-host",
"PCE_PORT": "your-pce-port",
"PCE_ORG_ID": "1",
"API_KEY": "api_key",
"API_SECRET": "api_secret"
}
}
}
}
The server runs over HTTP using the MCP Streamable HTTP transport (spec rev 2025-03-26) and validates OAuth 2.1 bearer tokens issued by your IdP. This is Phase 3a: identity is enforced; per-user PCE keys land in Phase 3b.
export MCP_PUBLIC_URL=https://mcp.illumio.example
export MCP_OAUTH_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0
export MCP_OAUTH_JWKS_URL=https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys
export MCP_OAUTH_AUDIENCE=https://mcp.illumio.example
export MCP_OAUTH_REQUIRED_SCOPE=illumio-mcp.use # default; override if needed
illumio-mcp-http --host 127.0.0.1 --port 8080
The server refuses to start without these env vars (unless MCP_DEV_INSECURE=1).
MCP clients discover the AS via the standard RFC 9728 endpoint:
GET /.well-known/oauth-protected-resource
Unauthenticated requests to /mcp return 401 with
WWW-Authenticate: Bearer resource_metadata="<URL>", which any spec-compliant
MCP client (Claude Desktop, ChatGPT, MCP Inspector) follows automatically to
run PKCE auth code flow against the configured AS.
MCP_DEV_INSECURE=1 illumio-mcp-http
The server logs a prominent warning. Do NOT use in production.
GET /healthz — livenessGET /readyz — readiness (Phase 3a returns the same as healthz; Phase 3b/c will add PCE + JWKS reachability)The HTTP server supports two ways to source PCE credentials, selected via
MCP_PCE_MODE:
| Mode | MCP_PCE_MODE |
PCE creds | Onboarding | PCE-side audit |
|---|---|---|---|---|
| Per-user (default) | per_user |
One PCE API key per authenticated user, encrypted in keystore | User registers via /setup page or register-pce-credentials tool |
PCE logs show the real human via per-user API key |
| Shared | shared |
One PCE service-account key from env (same as stdio) | None — works immediately for any authenticated user | PCE logs show the service account; the MCP audit log is the source of truth for "who did what" |
Choose per-user when:
Choose shared when:
/setup step)In shared mode, /setup is not mounted, the credential-management tools
(register-pce-credentials, delete-pce-credentials) refuse with a friendly
error, and MCP_KEK is not required. SSO + JWT + role-based authz + audit
log + confirm tokens all still apply identically.
# Shared mode — same env that stdio uses today, plus auth/role config
export MCP_PCE_MODE=shared
export PCE_HOST=https://your-pce.example.com
export PCE_PORT=8443
export PCE_ORG_ID=1
export API_KEY=your_pce_api_key_name
export API_SECRET=your_pce_api_key_secret
# (other auth/role env vars from earlier sections still apply)
illumio-mcp-http
Each authenticated user has their own PCE API key/secret stored in an encrypted SQLite keystore. PCE-side audit logs attribute correctly per human; revoking a user is a single tool call.
Additional env required when running with auth:
export MCP_KEK=$(python -c 'import os, base64; print(base64.b64encode(os.urandom(32)).decode())')
export MCP_KEYSTORE_PATH=/var/lib/illumio-mcp/keys.db # default: ./data/keys.db
The KEK is never stored next to the database. Loss of KEK = total loss of stored creds (intentional, fail-closed). For production, source MCP_KEK from KMS or Vault rather than the operator's shell.
Onboarding paths (either works):
/setup after authenticating; paste credentials in the form.register-pce-credentials tool; the only tool
available before credentials are registered.Other credential tools:
check-pce-credentials-status — does this user have credentials registered?delete-pce-credentials — remove this user's credentials.The server maps each user's IdP groups to one of three internal roles:
reader, operator, admin. Per-tool authorization is enforced by the
dispatcher using the roles metadata on each ToolSpec.
Configure group → role mapping via env (comma-separated):
# A user matching ANY of these groups gets that role; highest role wins.
export MCP_ROLE_GROUPS_ADMIN=sg-illumio-mcp-admin
export MCP_ROLE_GROUPS_OPERATOR=sg-illumio-mcp-operator,sg-illumio-mcp-admin
export MCP_ROLE_GROUPS_READER=sg-illumio-mcp-readonly,sg-illumio-mcp-operator,sg-illumio-mcp-admin
# Optional: fallback role when no group matches. Leave unset to refuse.
# export MCP_ROLE_DEFAULT=reader
Tool-by-tool defaults:
| Tool category | Roles allowed | Examples |
|---|---|---|
| Reads | reader, operator, admin | get-labels, get-workloads, get-traffic-flows |
| Writes | operator, admin | create-*, update-*, delete-* |
| Provisioning + bulk | admin | provision-policy, ringfence-batch |
A user without a matching role (and no MCP_ROLE_DEFAULT) receives a structured
forbidden_no_role error.
Every dispatcher decision (allow / deny / error) is written to a SQLite audit database. Schema and storage location:
# Defaults to <keystore_dir>/audit.db
export MCP_AUDIT_LOG_PATH=/var/lib/illumio-mcp/audit.db
Audit rows include (ts, sub, iss, tool, decision, reason, role, request_id)
— never tool arguments. The request_id matches the X-Request-Id
response header so external traces can be correlated.
Query examples:
-- Recent denied calls per user
SELECT ts, sub, tool, reason FROM audit_log
WHERE decision='denied'
ORDER BY ts DESC LIMIT 20;
-- Tool-call volume by user
SELECT sub, COUNT(*) FROM audit_log
WHERE ts > date('now', '-7 days')
GROUP BY sub ORDER BY 2 DESC;
Tools marked requires_confirm=True (currently provision-policy,
ringfence-batch, register-pce-credentials, delete-pce-credentials) require
a server-issued single-use confirm token in params._meta.confirm_token when
called over HTTP. Stdio mode is unaffected — the operator who launched the
process can call mutating tools directly.
Required env in auth mode:
export MCP_CONFIRM_HMAC_KEY=$(python -c 'import os, base64; print(base64.b64encode(os.urandom(32)).decode())')
# Optional:
# export MCP_CONFIRM_TTL_SECONDS=120
# export MCP_CONFIRM_JTI_PATH=/var/lib/illumio-mcp/jti.db
# export MCP_CONFIRM_FRESH_AUTH_SECONDS=300 # require JWT auth_time within 5 min
{"error": "confirm_required", "params_hash": "<sha256>", "message": "..."}
POST /confirm with the JWT and the params_hash:
curl -X POST https://mcp.illumio.example/confirm \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"tool":"provision-policy","params_hash":"<sha256>"}'
# → {"confirm_token": "...", "expires_in": 120}
params._meta.confirm_token.Tokens are single-use (replays return confirm_token_replay) and scoped
to (sub, tool, params_hash). Tampering with any field invalidates the token.
Set MCP_CONFIRM_FRESH_AUTH_SECONDS=300 to require the JWT's auth_time
claim to be within the last 5 minutes. Forces the user to re-authenticate
before minting a token — the strongest prompt-injection defense available
without an interactive session model. Requires the IdP to issue auth_time
(Entra and Okta both do for OIDC sign-in flows).
get-workloads — Retrieve workloads with optional filtering by name, hostname, IP, labels, and max resultscreate-workload — Create an unmanaged workload with name, IP addresses, and labelsupdate-workload — Update an existing workload's propertiesdelete-workload — Remove a workload from PCEget-labels — Retrieve labels with optional filtering by key, value, and max resultscreate-label — Create a new label with key-value pairupdate-label — Update an existing labeldelete-label — Remove a labelget-rulesets — Get rulesets with optional filtering by name, description, and enabled statuscreate-ruleset — Create a new ruleset with scopesupdate-ruleset — Update ruleset propertiesdelete-ruleset — Remove a rulesetcreate-deny-rule — Create a deny rule (regular or override deny) in a rulesetupdate-deny-rule — Update an existing deny ruledelete-deny-rule — Remove a deny ruleget-iplists — Get IP lists with optional filtering by name, description, FQDN, and max resultscreate-iplist — Create a new IP listupdate-iplist — Update an existing IP listdelete-iplist — Remove an IP listget-services — Get services with optional filtering by name, port, protocol, and max resultscreate-service — Create a new service definitionupdate-service — Update an existing servicedelete-service — Remove a serviceget-traffic-flows — Get detailed traffic flow data with filtering by date range, source/destination, service, policy decision, and moreget-traffic-flows-summary — Get aggregated traffic summaries grouped by app, env, port, and protocolcreate-ringfence — Automated app-to-app segmentation policy creation. Analyzes traffic flows to discover which remote apps communicate with a target app, then creates a ruleset with:
selective=true) — adds a deny rule blocking all inbound, with allow rules for known apps processed first. Gets you to enforcement faster than full enforcement mode.deny_consumer parameter):
any (default) — IP list Any (0.0.0.0/0) as consumer, deny only at destination. Safest.ams — All Workloads as consumer, deny pushed to every managed workload. Broader.ams_and_any — Both. Maximum coverage.already_allowed (traffic covered by existing policy, created for documentation) or newly_allowed (filling a policy gap). Summary shows how many remote apps are already covered vs need new rules.skip_allowed parameter — set to true to only create rules for traffic not yet covered by existing policy, producing minimal rulesets that fill gaps onlyidentify-infrastructure-services — Discover which apps are infrastructure services by analyzing traffic patterns. Builds an app-to-app communication graph and uses dual-pattern scoring to recognize two types of infrastructure:
Provider infra (AD, DNS, shared DB) — consumed by many apps, high in-degree, low out-degree. Consumer infra (monitoring, backup, log shipping) — connects out to many apps, high out-degree, low in-degree.
Two scores are computed per app, and the higher one wins:
| Score | Degree metric (40%) | Directionality (30%) | Betweenness (25%) | Volume (5%) |
|---|---|---|---|---|
| Provider | In-degree | Consumer ratio (in/total) | Betweenness centrality | Connection volume |
| Consumer | Out-degree | Producer ratio (out/total) | Betweenness centrality | Connection volume |
Mixed-traffic dampening: score *= 1 / (1 + min(in_degree, out_degree) * 0.3) — apps with both significant inbound AND outbound connections are business apps, not infrastructure. Pure directional apps (all in OR all out) get no penalty.
Non-production environments (staging, dev, etc.) receive a 50% score penalty since infrastructure services typically live in production.
Apps are classified into tiers:
Each result includes a dominant_pattern field ("provider" or "consumer") indicating which type of infrastructure the app resembles.
Why this matters: Infrastructure services are consumed by many apps OR connect out to many apps. If you ringfence apps without allowing infrastructure services first, you break dependencies. This tool tells you what to policy first.
provision-policy — Provision pending draft changes to move them from draft to active state. Can provision all pending changes or specific items by href. Includes change descriptions for audit trail.compare-draft-active — Compare draft vs active policy to preview what would change on provisioning. Shows created, updated, and deleted rulesets, rules, IP lists, and services.enforcement-readiness — Assess whether an app is ready for enforcement. Analyzes traffic flows, existing policy coverage, enforcement modes, and ringfence status. Returns a readiness score (0-100) with actionable recommendations:
ringfence-batch — Ringfence multiple apps at once. Optionally uses identify-infrastructure-services to auto-order apps by infrastructure score (infrastructure first, then standard apps). Supports dry-run mode to preview all changes before applying.get-workload-enforcement-status — Get enforcement mode status across workloads, grouped by app and environment. Shows counts per mode (idle, visibility_only, selective, full) and identifies apps with mixed enforcement states — a common issue during rollouts.get-policy-coverage-report — Generate a policy coverage report for an app showing what traffic is covered by existing rules vs what would be blocked. Breaks down by inbound/outbound, identifies uncovered services and remote apps, and provides an overall coverage percentage.find-unmanaged-traffic — Find traffic involving unmanaged workloads or IP addresses. These are sources/destinations without app/env labels, representing policy blind spots. Filters by direction (inbound/outbound/both) and connection count.detect-lateral-movement-paths — Detect potential lateral movement paths by analyzing app-to-app traffic patterns. Identifies articulation points (bridge nodes) whose compromise would provide access to otherwise disconnected app groups. Computes reachability from any starting app and traces multi-hop paths up to a configurable depth.compliance-check — Check policy compliance against frameworks (PCI-DSS, NIST 800-53, CIS Controls, or general best practices). Evaluates segmentation, enforcement modes, high-risk port exposure, and policy coverage. Returns a compliance score with per-check findings (PASS/FAIL/WARNING).get-events — Get PCE events with optional filtering by event type, severity, status, and result limitscheck-pce-connection — Verify PCE connectivity and credentialsThe project includes a comprehensive integration test suite that runs against a real PCE using the MCP protocol.
# Set up credentials in .env
cat > .env << EOF
PCE_HOST=your-pce-host
PCE_PORT=8443
PCE_ORG_ID=1
API_KEY=your-api-key
API_SECRET=your-api-secret
EOF
# Run all tests
uv run pytest tests/ -v
The test suite covers:
Understanding rule processing is essential for ringfencing:
In selective enforcement, the default is allow-all, so a deny rule is needed to make the ringfence effective. Known remote apps get allow rules (step 3) which are processed before the deny (step 4).
All the examples below were generated by Claude Desktop and with data obtained through this MCP server.
Detailed view of application communication patterns and dependencies
Analysis of traffic patterns between different application tiers
Overview dashboard showing key infrastructure metrics and status
Detailed analysis of infrastructure service communications
Comprehensive security analysis report
Security assessment findings for high-risk vulnerabilities
PCI compliance assessment findings
SWIFT compliance assessment findings
Overview of security remediation planning
Detailed steps for security remediation implementation
Management interface for IP lists
Overview of ruleset categories and organization
Configuration of application ruleset ordering
Detailed workload analysis and metrics
Identification and analysis of workload traffic patterns
Organization of PCE labels by type and category
Automatic inference of service roles based on traffic patterns
Analysis of top 5 traffic sources and destinations
Project implementation timeline and milestones
The ringfence-application prompt helps create security policies to isolate and protect applications by controlling inbound and outbound traffic.
Required Arguments:
application_name: Name of the application to ringfenceapplication_environment: Environment of the application to ringfenceFeatures:
The analyze-application-traffic prompt provides detailed analysis of application traffic patterns and connectivity.
Required Arguments:
application_name: Name of the application to analyzeapplication_environment: Environment of the application to analyzeAnalysis Features:
Step1: Click "Attach from MCP" button in the interface

Step 2: Choose from installed MCP servers

Step 3: Fill in required prompt arguments:

Step 4: Click Submit to send the configured prompt
This workflow enables automated context sharing between Illumio systems and Claude for application traffic analysis and ringfencing tasks.
The application is available as a Docker container from the GitHub Container Registry.
docker pull ghcr.io/alexgoller/illumio-mcp-server:latest
You can also use a specific version by replacing latest with a version number:
docker pull ghcr.io/alexgoller/illumio-mcp-server:1.0.0
To use the container with Claude Desktop, you'll need to:
~/.illumio-mcp.env) with your PCE credentials:PCE_HOST=your-pce-host
PCE_PORT=your-pce-port
PCE_ORG_ID=1
API_KEY=your-api-key
API_SECRET=your-api-secret
On MacOS (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"illumio-mcp-docker": {
"command": "docker",
"args": [
"run",
"-i",
"--init",
"--rm",
"-v",
"/Users/YOUR_USERNAME/tmp:/var/log/illumio-mcp",
"-e",
"DOCKER_CONTAINER=true",
"-e",
"PYTHONWARNINGS=ignore",
"--env-file",
"/Users/YOUR_USERNAME/.illumio-mcp.env",
"illumio-mcp:latest"
]
}
}
}
Make sure to:
YOUR_USERNAME with your actual username~/tmp)You can also run the container directly:
docker run -i --init --rm \
-v /path/to/logs:/var/log/illumio-mcp \
-e DOCKER_CONTAINER=true \
-e PYTHONWARNINGS=ignore \
--env-file ~/.illumio-mcp.env \
ghcr.io/alexgoller/illumio-mcp-server:latest
For development or testing, you can use Docker Compose:
version: '3'
services:
illumio-mcp:
image: ghcr.io/alexgoller/illumio-mcp-server:latest
init: true
volumes:
- ./logs:/var/log/illumio-mcp
environment:
- DOCKER_CONTAINER=true
- PYTHONWARNINGS=ignore
env_file:
- ~/.illumio-mcp.env
Then run:
docker-compose up
This project is licensed under the GPL-3.0 License. See the LICENSE file for details.
For support, please create an issue.
Please log in to share your review and rating for this MCP.
Explore related MCPs that share similar capabilities and solve comparable challenges
by chaitin
A self‑hosted web application firewall and reverse proxy that protects web applications from attacks and exploits by filtering, monitoring, and blocking malicious HTTP/S traffic.
by snyk
Scans installed AI agent components, MCP servers, and skill files for prompt‑injection, tool poisoning, toxic flows, hard‑coded secrets and other supply‑chain risks.
by OpenOSINT
Provides an AI‑driven OSINT workflow that lets users query a natural‑language REPL, CLI, web UI, or MCP server, automatically selecting and chaining 18 reconnaissance tools to collect, pivot, verify, and report public‑source intelligence.
by 2akouwu
Provides deterministic verification of AI‑generated claims against binary artifacts, ensuring every structural or behavioral assertion is grounded in the actual file and preserving verified state across context resets.
by safedep
Provides enterprise‑grade open source software supply chain security by scanning source code, dependencies, containers and SBOMs, detecting vulnerabilities and malicious packages, and enforcing policy as code.
by tufantunc
Provides controlled SSH access for LLM agents with command classification, policy‑based authorization, human‑in‑the‑loop approval, and immutable audit logging.
by semgrep
Offers an MCP server that lets LLMs, agents, and IDEs run Semgrep scans to detect security vulnerabilities in source code.
by KeyValueSoftwareSystems
Enables adversary emulation for AI agents, LLM applications, and MCP servers, letting teams test their AI systems against realistic attack scenarios.
by PortSwigger
Enables Burp Suite to communicate with AI clients via the Model Context Protocol, providing an MCP server and bundled stdio proxy.