Skip to main content
Glama
JohnGilligan2

trmm-action-mcp

README.md
# trmm-action-mcp

A **gated, allow-listed action server** for Tactical RMM. Unlike the read-only
[`trmm-mcp`](../TrmmMCPServer) server, this one *can* act on endpoints — but only
by running a **vetted, read-only audit** from a fixed catalog. There is
deliberately **no** tool to run arbitrary code and **no** tool to delete, edit,
reboot, or uninstall anything.

Built for a small group of senior engineers (e.g. the approved engineers) to run
audits like "list Domain Admins on EF-DC01" from Claude.

## Why it's safe — six independent guardrails

1. **Identity** — reachable only by the named senior engineers.
2. **Network** — nginx allows only Anthropic's connector egress IPs (+ your IPs).
3. **Bearer** — shared secret between the edge and this backend.
4. **Restricted tools** — only `list_agents`, `list_audits`, `run_audit`.
5. **Allow-listed audits** — `run_audit` runs only vetted read-only scripts in
   [`catalog.py`](trmm_action_mcp/catalog.py); no arbitrary-code path exists.
6. **Scoped TRMM key** — the [`claude-actions`](docs/TRMM_ROLE.md) role can
   Send-Command + read, nothing else. Every run is TRMM-audit-logged.

"Can't delete stuff" is a guarantee here (allow-listed catalog + no delete tools +
scoped key), not a hope — see the note in `catalog.py`.

## Tools

| Tool | Kind | What it does |
|------|------|--------------|
| `trmm_list_agents` | read | Find the agent to target (filter by client/site/type/platform/status/hostname). |
| `trmm_list_audits` | read | The catalog of runnable audits (the only scripts `run_audit` will execute). |
| `trmm_run_audit` | **action** | Run ONE vetted audit on ONE agent; returns its output. `readOnlyHint:false`. |

## Audit catalog (v1)

`privileged_groups` (DC), `local_admins`, `local_users`, `disk_space`, `os_info`,
`installed_software`, `services_not_running`, `pending_reboot`, `hotfixes`,
`logged_on_users`, `bitlocker`, `network_config`. All read-only. Add more by
vetting a new entry in `catalog.py`.

## Configuration

| Variable | Required | Description |
|----------|----------|-------------|
| `TRMM_API_URL` | ✅ | TRMM API base URL (`api.` subdomain). |
| `TRMM_ACTION_API_KEY` | ✅ | The **scoped** `claude-actions` key (Send-Command + read only). |
| `TRMM_MCP_TRANSPORT` | — | `stdio` (default) or `http`. |
| `TRMM_MCP_AUTH_TOKEN` | http only | Shared bearer between edge and backend. |
| `TRMM_MCP_HOST` / `PORT` / `PATH` | — | Default `0.0.0.0` / `8090` / `/mcp` (in Docker). |
| `TRMM_TIMEOUT` / `TRMM_VERIFY_SSL` / `TRMM_MAX_RETRIES` | — | Tuning. |

## Run

```bash
python -m venv .venv && .venv\Scripts\activate   # or source .venv/bin/activate
pip install -r requirements.txt
# stdio (local dev): set TRMM_API_URL + TRMM_ACTION_API_KEY, then:
python -m trmm_action_mcp
```

## Deploy (gated, remote)

See **[docs/DEPLOY.md](docs/DEPLOY.md)** (Docker + nginx Anthropic-IP allowlist +
identity options) and **[docs/TRMM_ROLE.md](docs/TRMM_ROLE.md)** (the scoped key).
The senior-engineer path that works today is **Claude Code/Desktop + bearer behind
the nginx allowlist**; per-user Entra SSO for claude.ai web/mobile is best done via
Cloudflare Access (see the read-only project) — DEPLOY.md explains the trade-offs.

## Relationship to trmm-mcp

Separate project, separate key, separate deploy on purpose: the read-only server
stays incapable of acting, and this one stays incapable of anything but vetted
audits.

Maintenance

ActivityMaintained
ResponsivenessNo issues