{
  "markdown": "# talos-mcp\n\n[![CI](https://github.com/Nosmoht/talos-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/Nosmoht/talos-mcp-server/actions/workflows/ci.yml)\n[![Release](https://img.shields.io/github/v/release/Nosmoht/talos-mcp-server?sort=semver)](https://github.com/Nosmoht/talos-mcp-server/releases)\n[![Go Reference](https://pkg.go.dev/badge/github.com/Nosmoht/talos-mcp-server.svg)](https://pkg.go.dev/github.com/Nosmoht/talos-mcp-server)\n[![codecov](https://codecov.io/gh/Nosmoht/talos-mcp-server/graph/badge.svg)](https://codecov.io/gh/Nosmoht/talos-mcp-server)\n[![Go Report Card](https://goreportcard.com/badge/github.com/Nosmoht/talos-mcp-server)](https://goreportcard.com/report/github.com/Nosmoht/talos-mcp-server)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Nosmoht/talos-mcp-server/badge)](https://scorecard.dev/viewer/?uri=github.com/Nosmoht/talos-mcp-server)\n[![License](https://img.shields.io/github/license/Nosmoht/talos-mcp-server)](LICENSE)\n\nAn MCP server that exposes Talos Linux cluster management to AI agents (Claude Code, OpenAI Codex, and any MCP-compatible client). Instead of pasting `talosctl` output into chat, the agent calls structured tools that return machine-readable JSON directly from the Talos gRPC API — zero token cost for intermediate output.\n\nConnects to your cluster via the native Talos gRPC API using the same mTLS credentials as `talosctl` (`~/.talos/config`).\n\n## Installation\n\n**Via npm** (no Go required, Linux/macOS, amd64/arm64):\n\n```bash\nnpx talos-mcp\n```\n\n**Via npm (global install)** for persistent invocation from `$PATH`:\n\n```bash\nnpm install -g talos-mcp\n```\n\nInstalls the binary as `<npm-prefix>/bin/talos-mcp`. Verify with:\n\n```bash\nwhich talos-mcp        # path\ntalos-mcp --version    # version + commit hash\nnpm list -g talos-mcp  # npm's view of the installed version\n```\n\nUpgrade to the latest published release:\n\n```bash\nnpm install -g talos-mcp@latest\n```\n\nNew releases appear on npmjs.com within minutes of every `feat:` / `fix:` / `perf:` (or breaking) merge to `main` — see [CONTRIBUTING.md § Post-merge release pipeline](./CONTRIBUTING.md#post-merge-release-pipeline) for the mechanism.\n\n**Download binary** (Linux/macOS, amd64/arm64):\n\nDownload the latest release from [GitHub Releases](https://github.com/Nosmoht/talos-mcp-server/releases), extract, and place the binary in your `$PATH`.\n\n**Build from source** (requires Go 1.21+):\n\n```bash\ngit clone https://github.com/Nosmoht/talos-mcp-server\ncd talos-mcp\ngo build -o talos-mcp ./cmd/talos-mcp\n```\n\n## Configuration\n\nReads `~/.talos/config` by default (the same file `talosctl` uses). Override via environment variables:\n\n| Variable | Default | Description |\n|---|---|---|\n| `TALOSCONFIG` | `~/.talos/config` | Path to talosconfig file |\n| `TALOS_CONTEXT` | active context | Context name to use |\n| `TALOS_ENDPOINTS` | from config | Comma-separated endpoint overrides |\n| `TALOS_MCP_READ_ONLY` | `false` | Set to `true` to disable all mutating tools at startup |\n| `TALOS_MCP_HTTP_ADDR` | (unset) | If set (e.g. `:8080`), serve Streamable HTTP instead of stdio |\n| `TALOS_MCP_AUTH_TOKEN` | (unset) | Required bearer token when HTTP mode is active |\n| `TALOS_MCP_ALLOWED_NODES` | (unset) | Comma-separated IPs, hostnames, and CIDR ranges permitted as tool targets. Unset allows all. |\n| `TALOS_MCP_ALLOWED_PATHS` | *(all)* | Comma-separated path prefixes allowed for `talos_read_file` and `talos_list_files` (e.g. `/etc,/proc`). Defense-in-depth only — checks run on the MCP server host and do **not** resolve symlinks on the remote Talos node, so a symlink under an allowed prefix that points elsewhere is not detected. |\n| `TALOS_MCP_SKIP_VERSION_CHECK` | `false` | Set to `true` to bypass upgrade path validation (e.g. for factory images or custom tags) |\n| `TALOS_MCP_ENABLE_INSECURE` | `false` | Unlock `insecure=true` on `talos_apply_config` / `talos_get` / `talos_version` / `talos_meta`. Bypasses mTLS — REQUIRES `TALOS_MCP_INSECURE_ALLOWED_NODES`. |\n| `TALOS_MCP_INSECURE_ALLOWED_NODES` | (unset) | Comma-separated IPs / CIDRs permitted as maintenance-mode endpoints. Required when `TALOS_MCP_ENABLE_INSECURE=true`. Refused: `0.0.0.0/0`, `::/0`, IPv4 mask `<16`, IPv6 mask `<48`. |\n| `TALOS_MCP_META_PRIVILEGED_KEYS` | *(none)* | Comma-separated META keys (decimal or `0x`-prefixed hex) that `talos_meta` is allowed to write/delete beyond `UserReserved1/2/3`. |\n| `TALOS_MCP_SAFETY_PROFILE` | (unset) | `conservative` / `standard` / `expert` preset that seeds gating flags. `expert` enables `EnableInsecure`. |\n| `TALOS_MCP_RATE_LIMIT` | `10` | HTTP mode: token-bucket refill rate (requests/second, float) |\n| `TALOS_MCP_RATE_BURST` | `20` | HTTP mode: token-bucket burst capacity (int) |\n| `TALOS_MCP_MAX_BODY_SIZE` | `4194304` | HTTP mode: max POST request body size in bytes (4 MiB default) |\n| `TALOS_MCP_MAX_CONCURRENT` | `20` | HTTP mode: max concurrent POST handlers (fail-fast 503 on overload) |\n| `TALOS_MCP_SUBSCRIPTION_RATE` | `1s` | Minimum interval between delivered `resources/updated` notifications per `(session, URI)` pair (Go duration, e.g. `500ms`) |\n| `TALOS_MCP_SUBSCRIPTION_BURST` | `3` | Initial notification burst per `(session, URI)` before the rate kicks in |\n\n## Compatibility\n\nThis server is tested against Talos Linux v1.9.x through v1.13.x.\n\n| talos-mcp | Talos Linux | machinery SDK |\n|-----------|-------------|---------------|\n| v0.x (current) | v1.9.0 – v1.13.x | v1.13.4 |\n\nThe server logs a startup warning if the connected cluster's Talos version is outside the tested range. All 19 gRPC methods used have been stable since Talos v1.9.\n\n### Upgrade path validation\n\nThe `talos_upgrade` tool validates that the target version follows Talos's supported upgrade path — at most one minor version at a time (e.g. v1.11.x → v1.12.x). Upgrades that skip minor versions are rejected with an error.\n\nIf your image uses a custom or factory tag (e.g. `factory.talos.dev/...` or `:latest`) the tag cannot be parsed and validation is skipped automatically. To bypass validation explicitly, set `TALOS_MCP_SKIP_VERSION_CHECK=true`.\n\n## Client Setup\n\n### Claude Code\n\nAdd to your project's `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"talos\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"talos-mcp\"]\n    }\n  }\n}\n```\n\nOr globally in `~/.claude.json` under `\"mcpServers\"`. If you prefer a local binary, replace `\"command\": \"npx\"` with the path to the binary.\n\n### Claude Desktop\n\nAdd to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"talos\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"talos-mcp\"]\n    }\n  }\n}\n```\n\n### OpenAI Codex\n\nAdd to `.codex/config.toml` (project) or `~/.codex/config.toml` (global):\n\n```toml\n[mcp_servers.talos]\ncommand = \"npx\"\nargs = [\"-y\", \"talos-mcp\"]\n\n[mcp_servers.talos.env]\nTALOSCONFIG = \"/path/to/talosconfig\"\n```\n\n### Generic MCP client\n\nThe server speaks the [MCP protocol](https://modelcontextprotocol.io) over stdio:\n\n```bash\n./talos-mcp\n```\n\n## Tools\n\n<!-- inventory:tools:start -->\n### Read-only\n\n| Tool | Description |\n|---|---|\n| `talos_resource_definitions` | List all available resource types and their aliases. Call this first to discover what can be queried. |\n| `talos_get` | Get or list any COSI resource by type (e.g. `MachineStatus`, `Member`, `NodeAddress`, `Service`). Supports maintenance-mode (`insecure=true` + `endpoint`). |\n| `talos_version` | Get Talos version info from target nodes. Supports maintenance-mode (`insecure=true` + `endpoint`). |\n| `talos_services` | List all Talos services and their current state (running, stopped, health). |\n| `talos_containers` | List containers in a namespace (default: `k8s.io` for Kubernetes containers). |\n| `talos_processes` | List running processes on target nodes. |\n| `talos_health` | Check cluster health (etcd, Kubernetes API, node readiness). Supports `control_plane_nodes` / `worker_nodes` override. |\n| `talos_logs` | Fetch recent service logs (last N lines, no follow). |\n| `talos_dmesg` | Read kernel ring buffer messages. |\n| `talos_events` | Fetch recent Talos runtime events (service changes, config changes). |\n| `talos_etcd` | Query etcd cluster: `members` (default) or `status`. |\n| `talos_etcd_snapshot` | Stream an etcd snapshot to a local file path. |\n| `talos_list_files` | List files and directories on a node filesystem. |\n| `talos_read_file` | Read file contents from a node filesystem. |\n| `talos_validate` | Validate a machine config (YAML/JSON) offline — no cluster connection. |\n\n### Mutating\n\nThese tools modify cluster state and have explicit safety guards.\n\n| Tool | Description | Guards |\n|---|---|---|\n| `talos_service_action` | Start, stop, or restart a Talos service (note: restarting `etcd` is not supported by the Talos API). | `confirm=true` required |\n| `talos_reboot` | Reboot target nodes. Supports `mode`: `default`, `powercycle`, `force`. | `confirm=true` required; `nodes` must be explicit |\n| `talos_upgrade` | Upgrade Talos on target nodes. Supports `preserve` (default `true`), `stage`, `force`, `reboot_mode`. | `confirm=true` required; `nodes` and `image` required |\n| `talos_rollback` | Roll back the last upgrade on target nodes. | `confirm=true` required; `nodes` must be explicit |\n| `talos_patch_config` | Apply a targeted machine config patch (strategic-merge or RFC 6902 JSON Patch). | `dry_run` defaults to `true`; `confirm=true` required when `dry_run=false` |\n| `talos_reset` | Wipe and factory-reset target nodes (irreversible). | `confirm=true` required; `nodes` must be explicit |\n| `talos_apply_config` | Apply a complete machine config to a single node. Supports maintenance-mode (`insecure=true` + `endpoint`) for fresh-node bootstrap. | `dry_run` defaults to `true`; `confirm=true` required when `dry_run=false` |\n| `talos_meta` | Read, write, or delete META partition key/value pairs. Supports maintenance-mode (`insecure=true` + `endpoint`). | `write`/`delete` require `confirm=true`; non-`UserReserved*` keys require enumeration in `TALOS_MCP_META_PRIVILEGED_KEYS` |\n\nAll tools accept an optional `nodes` field (list of node IPs or hostnames). When omitted, the active context from talosconfig is used.\n\n#### Maintenance-mode (`--insecure`) operations\n\n`talos_apply_config`, `talos_get`, `talos_version`, and `talos_meta` accept an `insecure=true` flag that targets a node in maintenance mode (booted but not yet configured). The transport is TLS-encrypted but bypasses mTLS — there is no client certificate and (by default) no server-certificate verification. This is required for bootstrapping fresh nodes (`talosctl apply-config --insecure` equivalent).\n\n- **Operator opt-in required.** Set `TALOS_MCP_ENABLE_INSECURE=true` (or use the `expert` safety profile). Without it, every `insecure=true` call is refused.\n- **Endpoint allowlist required.** Set `TALOS_MCP_INSECURE_ALLOWED_NODES` to a comma-separated list of permitted maintenance-mode IPs / CIDRs. The startup is aborted if it is missing or contains `0.0.0.0/0`, `::/0`, an IPv4 mask `<16`, or an IPv6 mask `<48`. Use `/28` or narrower in production.\n- **Endpoint must be a bare IP.** No hostnames, no `host:port`, no scheme, no IPv6 zone. Link-local (incl. `169.254.169.254` IMDS), loopback, multicast, and unspecified addresses are rejected.\n- **MITM mitigation via TOFU pinning.** Pass `cert_fingerprint=<64-hex>` (server SHA-256 fingerprint, copied from the Talos console banner) to enable leaf-cert verification. Without it, the connection is MITMable by anyone on-path between the MCP server and the target node.\n- **META write/delete safelist.** `talos_meta` write/delete is restricted to `meta.UserReserved1`/`2`/`3`. Privileged keys (`Upgrade`, `StateEncryptionConfig`, …) must be enumerated in `TALOS_MCP_META_PRIVILEGED_KEYS` (per-key, not a blanket flag).\n<!-- inventory:tools:end -->\n\n### Prompts\n\n<!-- inventory:prompts:start -->\n| Prompt | Description |\n|---|---|\n| `diagnose-node` | Guided diagnosis workflow for a single node. |\n| `investigate-etcd` | Focused investigation of an etcd cluster anomaly. |\n| `debug-service` | Service-specific diagnostic workflow (kubelet, containerd, etcd, …). |\n| `pre-upgrade-checklist` | Pre-flight verification before a Talos upgrade. |\n| `apply-config` | Guided flow for applying a machine config patch (registered only when `TALOS_MCP_READ_ONLY` is unset). |\n<!-- inventory:prompts:end -->\n\n### Resources and Subscriptions\n\n<!-- inventory:resources:start -->\n\nThe server exposes Talos COSI resources as MCP resources:\n\n- `talos://cluster/version` — static cluster version info.\n- `talos://cluster/resource-definitions` — discover resource types.\n- `talos://{node}/resource/{namespace}/{type}[/{id}]` — list or get COSI resources on a specific node.\n\nMCP clients that implement `resources/subscribe` (Claude Desktop, Cursor) receive `notifications/resources/updated` whenever the underlying resource changes — no polling required. Subscriptions are backed by the Talos COSI `Watch` / `WatchKindAggregated` streams and honour the same `TALOS_MCP_ALLOWED_NODES` allowlist as reads.\n\nSubscribable resource types (canonical names):\n\n- `MachineStatuses.runtime.talos.dev` (`MachineStatus`)\n- `Members.cluster.talos.dev` (`Member`)\n- `NodeAddresses.net.talos.dev` (`NodeAddress`)\n- `Services.v1alpha1.talos.dev` (`Service`)\n\nAliases resolve to the canonical type before the allowlist check, so a client subscribing to `talos://{node}/resource/runtime/ms/...` (alias for `MachineStatus`) succeeds. Other COSI types reject with `resource type %q is not subscribable`. Static `talos://cluster/*` URIs are not subscribable (no COSI backing).\n\nDelivery is rate-limited per `(session, URI)` via `TALOS_MCP_SUBSCRIPTION_RATE` / `TALOS_MCP_SUBSCRIPTION_BURST`; over-rate events are dropped and the client re-reads the resource to catch up. The initial `Bootstrapped` event is intentionally not forwarded — the client is expected to call `resources/read` once after subscribe for initial state.\n<!-- inventory:resources:end -->\n\n## Security Model\n\n### Trust Boundaries\n\n```\nMCP Client (Claude Code / Codex)\n        │  stdio / JSON-RPC\n        ▼\n   talos-mcp  ◄── reads TALOSCONFIG (~/.talos/config)\n        │  gRPC + mTLS\n        ▼\n  Talos API (each node)\n        │\n        ▼\n    Node OS\n```\n\n**Data flow warning:** Tool responses flow directly into the LLM's context window and are sent to the LLM provider. Anything a tool returns — node IPs, hostnames, service configurations, kernel logs, file contents — becomes part of the prompt sent over the network. Do not use this server with clusters containing data you would not be comfortable sending to your LLM provider.\n\n**Talos RBAC is server-side enforced.** The credentials in your talosconfig determine what operations are permitted on each node. talos-mcp cannot bypass Talos RBAC — a request that the API rejects will fail with an error, not silently succeed.\n\n### Tool Classification and Minimum Required RBAC Role\n\n| Tool | RBAC minimum |\n|---|---|\n| `talos_resource_definitions`, `talos_get`, `talos_version`, `talos_services`, `talos_containers`, `talos_processes`, `talos_health`, `talos_logs`, `talos_dmesg`, `talos_events`, `talos_list_files`, `talos_read_file` | `os:reader` |\n| `talos_etcd`, `talos_service_action`, `talos_reboot`, `talos_upgrade`, `talos_rollback` | `os:operator` |\n| `talos_patch_config` | `os:admin` |\n\n### Safety Mechanisms\n\n| Mechanism | How it works |\n|---|---|\n| Read-only mode | `TALOS_MCP_READ_ONLY=true` registers only read-only tools at startup; mutating tools are never exposed to the LLM |\n| Path allowlist | `TALOS_MCP_ALLOWED_PATHS=/etc,/proc` restricts `talos_read_file` and `talos_list_files` to specified prefixes. **Defense-in-depth, not a hard boundary:** the check is local to the MCP server — symlinks on the remote Talos node that resolve outside an allowed prefix are not detected. |\n| Confirm gates | Always require `confirm=true`: `talos_service_action`, `talos_reboot`, `talos_upgrade`, `talos_rollback`, `talos_reset`. Require `confirm=true` when `dry_run=false`: `talos_patch_config`, `talos_apply_config`. All enforced server-side. |\n| Preserve default | `talos_upgrade` defaults `preserve` to `true` (keep EPHEMERAL partition) — differs from `talosctl` default of `false` |\n| Dry-run default | `talos_patch_config` defaults to `dry_run=true`; applying requires both `dry_run=false` and `confirm=true` |\n| Audit logging | All mutating tool calls (`talos_service_action`, `talos_reboot`, `talos_upgrade`, `talos_rollback`, `talos_reset`, `talos_patch_config`, `talos_apply_config`) emit a structured log line to stderr: `AUDIT timestamp=<RFC3339> tool=<name> nodes=<list> args=<json>` (patch content is redacted) |\n\n### What Is Not in the Threat Model\n\n- **The LLM itself** — prompt injection, hallucinated tool arguments, and LLM provider data retention are outside the scope of this server\n- **The MCP client** — security of Claude Code, Codex, or other MCP clients is the responsibility of those projects\n- **Network path between talos-mcp and Talos nodes** — protected by mutual TLS using the credentials in your talosconfig\n\n### Least-Privilege Credential Setup\n\nCreate a dedicated talosconfig with minimal permissions for use with this server:\n\n**Read-only access (recommended for most use cases):**\n\n```bash\n# Generate a reader-only talosconfig\ntalosctl config new --roles=os:reader talosconfig-readonly\n```\n\nThen set `TALOSCONFIG=/path/to/talosconfig-readonly` and `TALOS_MCP_READ_ONLY=true` for maximum restriction. With this setup, the server exposes only read-only tools and the credentials cannot perform any mutating operations even if a tool were somehow bypassed.\n\n**Operator access (for service management, reboot, upgrade):**\n\n```bash\ntalosctl config new --roles=os:operator talosconfig-operator\n```\n\nThis covers all tools except `talos_patch_config` (which requires `os:admin`).\n\n**Full access (required for config patching):**\n\nUse your default talosconfig or generate one with `os:admin`. Reserve this for setups where config patch capability is explicitly needed.\n\n## Verifying Downloads\n\n### Checksums (integrity)\n\nEach release includes a `talos-mcp_<version>_checksums.txt` file with SHA-256 hashes of all archives. Verify the binary after downloading:\n\n```bash\n# Download archive and checksums\ncurl -LO https://github.com/Nosmoht/talos-mcp-server/releases/download/v<version>/talos-mcp_<version>_linux_amd64.tar.gz\ncurl -LO https://github.com/Nosmoht/talos-mcp-server/releases/download/v<version>/talos-mcp_<version>_checksums.txt\n\n# Verify\nsha256sum --check --ignore-missing talos-mcp_<version>_checksums.txt\n```\n\nThis detects corruption or truncated downloads. It does not protect against a compromised release pipeline.\n\n### GitHub Artifact Attestations (SLSA L2 provenance)\n\nEach release includes a GitHub-native build provenance attestation that cryptographically links the binary to the specific commit and workflow run that produced it:\n\n```bash\ngh attestation verify talos-mcp_<version>_linux_amd64.tar.gz \\\n  --repo Nosmoht/talos-mcp-server\n```\n\nThis requires the [GitHub CLI](https://cli.github.com/). A passing verification means the artifact was produced by the official release workflow in this repository, not a third-party build.\n\n### npm Package Provenance\n\nThe npm package is published with provenance attestation:\n\n```bash\nnpm audit signatures\n```\n\nA passing result means the package was published by the official GitHub Actions release workflow via OIDC trusted publishing.\n\n## Development\n\n```bash\n# Build\ngo build -o talos-mcp ./cmd/talos-mcp\n\n# Test\ngo test -race ./...\n\n# Lint (requires golangci-lint v2)\ngolangci-lint run\n\n# Format check\ngofmt -l .\n```\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 19755,
  "sha": "8abf35797cf3aea0cbdb50f6fa930f6e2595f14fc75b119adea0bb5296a4fd54",
  "repo_slug": "nosmoht/talos-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_nosmoht_talos_mcp_server_fe91eb81/readme"
}