{
  "markdown": "<!-- mcp-name: io.github.shigechika/eos-mcp -->\n\n# eos-mcp\n\nEnglish | [日本語](README.ja.md)\n\nMCP server for Arista EOS device operations via eAPI.\n\nExposes EOS show commands, running-config retrieval, configuration push\n(via configure session with commit timer), and tech-support collection\nto MCP-compatible AI assistants.\n\nDocumentation: <https://shigechika.github.io/eos-mcp/>\n\n## Installation\n\n```bash\npip install eos-mcp\n```\n\n## Configuration\n\nCopy `config.ini.example` to `~/.config/eos-mcp/config.ini` and fill in credentials:\n\n```ini\n[DEFAULT]\nusername = admin\npassword = yourpassword\ntransport = https\nverify = false\n\n[switch1.example.com]\ntags = main,dc1\n\n[switch2.example.com]\ntags = main,dc1\n```\n\nConfig file discovery order:\n1. `EOS_MCP_CONFIG` environment variable\n2. `./config.ini` (current directory)\n3. `~/.config/eos-mcp/config.ini`\n\n(Individual MCP tool calls may also override the path via a `config_path`\nparameter.)\n\n### Write operations\n\nThree tools change device state through a guarded path:\n\n| Tool | API call | Gated by |\n|---|---|---|\n| `push_config` | Opens a `configure session <name>`, stages `config_lines`, then either `show session-config diffs` + `abort` (`dry_run=True`, the default) or `commit timer HH:MM:SS` (`dry_run=False`) — eAPI JSON-RPC Command API | The eAPI account's own EOS privilege level: it must be able to enter `configure session` mode (effectively privilege 15 / enable access). `dry_run=True` by default means an accidental call without an explicit `dry_run=False` only shows a diff and aborts. |\n| `confirm_config_session` | `configure session <name> commit` — finalizes a pending commit-timer session started by `push_config` | Same EOS account privilege requirement as `push_config`. |\n| `abort_config_session` | `configure session <name> abort` — discards a pending session | Same EOS account privilege requirement as `push_config`. |\n\nGive the `config.ini` account for a device a lower-privilege, show-only role\nand these three tools fail against the EOS API instead of writing; every\nread-only tool for that device keeps working.\n\n**`run_command`, `run_commands`, `run_command_batch`, and\n`run_commands_batch` are not restricted to `show ...` commands**, despite\nbeing documented and grouped as command runners. Nothing in the server\nvalidates or whitelists the command text — it is passed to the eAPI Command\nAPI verbatim — so these tools can execute arbitrary enable-mode EOS\ncommands, including `configure terminal ...` or `reload`, on any configured\ndevice (a single host, or fleet-wide via `tags` in the `_batch` variants).\nThis is gated by the same EOS account privilege as `push_config`, but\nwithout `push_config`'s `dry_run` / commit-timer safety net — a de facto\nsecond write path worth remembering when deciding how privileged a device's\n`config.ini` account should be.\n\n## Usage\n\n### Claude Code (plugin)\n\nThis repository doubles as a single-plugin marketplace, so Claude Code can\ninstall the server for you:\n\n```\n/plugin marketplace add shigechika/eos-mcp\n/plugin install eos-mcp@eos-mcp\n```\n\nThe plugin launches `uvx eos-mcp` and reads `EOS_MCP_CONFIG`, the same\nvariable described in [Configuration](#configuration). Leave it unset and\nthe server falls through to its normal discovery order (`./config.ini`,\nthen `~/.config/eos-mcp/config.ini`). `/plugin install` only wires up the\nserver process — it cannot create the `config.ini` file or the per-device\neAPI credentials it holds; that file must already exist on the machine\nrunning the plugin before any tool but `health_check` will succeed.\n\n`uvx` must be on the `PATH` of the process that runs Claude Code — a login\nshell usually has it, but a GUI-launched app may not; install\n[uv](https://docs.astral.sh/uv/) system-wide if the plugin fails to start.\n\n### Claude Code (manual)\n\nIn `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"eos-mcp\": {\n      \"type\": \"stdio\",\n      \"command\": \"eos-mcp\"\n    }\n  }\n}\n```\n\nAdd `\"env\": { \"EOS_MCP_CONFIG\": \"...\" }` only if `config.ini` is not at one\nof the default discovery locations above.\n\n### Claude Desktop\n\nAdd the same entry to `claude_desktop_config.json`.\n\n### From a shell\n\n```bash\n# Verify config and list devices\neos-mcp --check\n\n# Test connectivity to a specific host\neos-mcp --check --check-host switch1.example.com\n\n# Start MCP server (stdio transport)\neos-mcp\n```\n\n## Tools\n\n| Tool | Description |\n|---|---|\n| `health_check` | Report server version and config status (lightweight; does NOT connect to devices) |\n| `get_router_list` | List registered devices (optional tag filter) |\n| `get_device_facts` | Return structured facts for one device (model, serial, EOS version, uptime, memory) |\n| `get_device_facts_batch` | Return device facts for multiple devices in parallel |\n| `get_version` | Return EOS version string (quick connectivity check) |\n| `run_command` | Run a single enable-mode command on one device |\n| `run_commands` | Run multiple enable-mode commands on one device |\n| `run_command_batch` | Run an enable-mode command on multiple devices in parallel |\n| `run_commands_batch` | Run multiple enable-mode commands on multiple devices in parallel |\n| `get_config` | Retrieve running-config |\n| `get_config_diff` | Show config diff vs rollback checkpoint |\n| `list_config_sessions` | List configure sessions and their state |\n| `push_config` | Push config via configure session (dry_run=True by default) |\n| `confirm_config_session` | Confirm a pending commit timer session |\n| `abort_config_session` | Abort a pending session |\n| `collect_tech_support` | Collect show tech-support output |\n| `daily_brief` | Health check (environment, errdisabled, uptime, MLAG, recent syslog alerts) across multiple devices |\n\n## Development\n\n### Live smoke test\n\nUnit tests check logic against fixtures; they cannot tell you that a tool has\nstopped returning real data. `scripts/smoke_test.py` runs **every registered\ntool** against the configured devices and fails on empty, malformed or error\nanswers:\n\n```bash\n# uses the same inventory file as the server (EOS_MCP_CONFIG)\nuv run python scripts/smoke_test.py\nuv run python scripts/smoke_test.py --only facts --traceback\n```\n\n- **Read-only.** `push_config`, `confirm_config_session` and\n  `abort_config_session` are skipped by name, and a test enforces that.\n  `collect_tech_support` is skipped too — it changes nothing, but it is minutes\n  of device CPU for an answer no assertion would read. The command-running\n  tools are exercised with `show version`: they accept enable-mode commands in\n  general, and a smoke test must not be the thing that types one that matters.\n- **No payloads in the report.** Tool names and statuses only; error text is\n  redacted too, since every error here is prefixed with the device it came from\n  and the payloads are configuration.\n- **Nothing estate-specific in the specs.** The device the per-host tools need\n  is discovered at run time from the configured inventory, and skipped when it\n  is empty. Two tests keep it that way: one refuses those parameters as\n  literals, the other bans anything address-shaped anywhere in the file,\n  because this repository is public.\n- Every probe refuses the `Error (<host>): ...` line these tools return in\n  place of raising — otherwise an unreachable device would read as a\n  successful call.\n- CI enforces the cheap half: a tool registered without a probe spec fails the\n  build (`tests/test_smoke_probes.py`), so adding a tool forces the question\n  \"how would we know it works?\".\n- `scripts/smoke_harness.py` is the engine and holds no EOS knowledge: it is\n  kept identical across the servers that share it, so fix engine bugs once and\n  sync the file rather than patching this copy.\n\n## Requirements\n\n- Python >= 3.10\n- Arista EOS with eAPI enabled (`management api http-commands`)\n- Network access to port 443 (HTTPS) on target devices\n\n## License\n\nApache-2.0",
  "bytes": 7868,
  "sha": "f2556fb68fff78ff6f04eed498a29ec0690fbf5b2d477b93f5e9bbc6f0aa38d6",
  "repo_slug": "shigechika/eos-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_shigechika_eos_mcp_e96a2949/readme"
}