1. Conduid
  2. Developer Tools
  3. Eos MCP Server
MCP server · Developer Tools

Eos MCP Server

MCP server for EOS using eAPI

Unclaimed Apache-2.0 devtools
34Low

Scored 10 days ago · breakdown

About Eos MCP Server

Eos MCP Server is an MCP server published by aristanetworks in the Developer Tools category: mCP server for EOS using eAPI.

The repository has 10 stars and 1 forks, with the last commit 16 days ago. Recent commit activity is the strongest signal that reported issues will get attention.

Install

From source
git clone https://github.com/aristanetworks/eos-mcp-server

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Eos MCP Server

Powered by Claude · Grounded in docs

I know everything about Eos MCP Server. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository 6 days ago. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • ✓License declaredUsable under a stated license.
  • ✓Tests presentA test suite exists in the repository.
  • ✓Dependencies pinnedA lockfile pins dependency versions.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.

1 check has not been run yet.

Releases

v0.6.1-betav0.6.1-beta
v0.6.0-betav0.6.0-beta
v0.5.3-betav0.5.3-beta
v0.5.1-betav0.5.1-beta
v0.5.0-betav0.5.0-beta

README

eos-mcp-server

npm version

Read-only MCP server for Arista EOS eAPI (JSON-RPC over HTTPS).

Beta status: this project is under active development. Support: best-effort only. This open source project is not currently supported by Arista TAC.

This server provides a set of read-only tools. It never exposes configuration-changing operations. The server can:

  • introspect its own runtime and inventory
  • list inventory hosts/groups
  • probe EOS device readiness
  • run show commands
  • retrieve bounded logging output for troubleshooting
  • collect a fixed set of device facts
  • retrieve running configuration

Security note: LLMs have occasionally tried to bypass the MCP server and make configuration changes through other means (for example, SSH). As a best practice, use AAA and scope the authentication credentials used by this server to read-only access.

Contents

What's included

Implemented MCP tools:

  • eos_get_server_info
  • eos_list_inventory
  • eos_probe_devices
  • eos_run_show
  • eos_show_logging
  • eos_get_facts
  • eos_get_running_config

Implemented local CLI commands:

  • serve
  • validate-inventory
  • print-server-info
  • probe

Requirements

  • Node.js 24+
  • Arista EOS devices reachable via eAPI over HTTPS
  • EOS 4.20 or later
  • Inventory in one of the supported YAML formats

Install and get started

The package is published on npm as @aristanetworks/eos-mcp-server. The package provides the eos-mcp-server command.

npx or global install?

Both run the same package. They differ in when the version changes and whether the npm registry must be reachable when the server starts.

Use When
npx -y @aristanetworks/eos-mcp-server You're trying the server out, or mainly run it from an MCP client. Nothing to install, and it picks up the latest release when it launches.
npx -y @aristanetworks/eos-mcp-server@<version> You want a reproducible setup, such as an MCP config shared with a team. Everyone runs the same version until you change it.
npm install -g @aristanetworks/eos-mcp-server You run the CLI often, want to control when upgrades happen, or the npm registry isn't always reachable. The command starts without a registry lookup and stays on one version until you run npm update -g.
.tgz from a GitHub release The machine can't reach the npm registry at all.

Run with npx (recommended)

No install step is needed. npx downloads the package on first use and caches it:

npx -y @aristanetworks/eos-mcp-server --help

The MCP client examples below use npx. -y skips npm's install confirmation prompt, which an MCP client can't answer. Without a version, npx checks the registry for the latest release each time it launches the server. To pin a specific release, append a version, for example @aristanetworks/eos-mcp-server@0.6.1-beta.

Or install globally

A global install puts eos-mcp-server on your PATH, starts without a registry lookup, and stays on the installed version until you update it:

npm install -g @aristanetworks/eos-mcp-server
eos-mcp-server --help

Update it later with npm update -g @aristanetworks/eos-mcp-server, or remove it with npm uninstall -g @aristanetworks/eos-mcp-server.

Prereleases are published under the next tag (@aristanetworks/eos-mcp-server@next). Each GitHub release also attaches the package as a .tgz, for offline installs: npm install -g ./aristanetworks-eos-mcp-server-<version>.tgz.

Upgrading from a .tgz install

Versions up to 0.6.1-beta were distributed as .tgz files under the unscoped package name eos-mcp-server. Both packages provide the same eos-mcp-server command, so remove the old package before switching to npm. Otherwise the global install can fail with a conflict, or the old version keeps running:

npm uninstall -g eos-mcp-server

Validate your inventory

Create an inventory, provide the device password, and validate connectivity:

export EOS_MCP_PASSWORD='replace-with-device-password'

npx -y @aristanetworks/eos-mcp-server validate-inventory --inventory inventory.yml
npx -y @aristanetworks/eos-mcp-server probe --inventory inventory.yml --target leaf1

With a global install, run eos-mcp-server in place of npx -y @aristanetworks/eos-mcp-server. The CLI usage examples later in this README use the shorter eos-mcp-server form.

See Quickstart for a complete inventory example and MCP client setup. For building or contributing from source, see the developer workflow.

Server config file

The server needs an inventory to start. At minimum, provide one of:

  • --inventory <path> directly, or
  • --config <path> pointing at a YAML config file that itself sets inventory: <path>

Beyond that minimum, a config file is optional — use one when you want to set additional options such as timeouts, request limits, or a default connection. CLI flags always override config-file values.

Example:

version: 1
inventory: ./inventory.yml
actor: lab-user
readTimeoutMs: 10000
overallOperationTimeoutMs: 30000
deviceConcurrency: 5
maxReadTargets: 50
maxShowCommandsPerRequest: 5
maxLoggingMessagesPerRequest: 1000
maxResponseSizeBytes: 1048576
eapiVersion: latest
secretEnvPrefixes:
  - EOS_MCP_
defaultConnection:
  ansibleUser: admin
  mcpPasswordEnv: EOS_MCP_PASSWORD
  mcpValidateCerts: false

Supported config fields:

  • inventory
  • actor
  • logFile
  • caFile
  • readTimeoutMs
  • overallOperationTimeoutMs
  • deviceConcurrency
  • maxReadTargets
  • maxShowCommandsPerRequest
  • maxLoggingMessagesPerRequest
  • maxResponseSizeBytes
  • eapiVersion
  • secretEnvPrefixes
  • defaultConnection.ansibleUser
  • defaultConnection.ansibleHttpapiPort
  • defaultConnection.mcpValidateCerts
  • defaultConnection.mcpPasswordEnv

readTimeoutMs applies to each device eAPI request. overallOperationTimeoutMs, when set, bounds the whole tool call and aborts in-flight device requests once the limit is reached. maxLoggingMessagesPerRequest caps eos_show_logging.message_count and defaults to 1000. maxResponseSizeBytes limits both the buffered HTTP response from each device and the final serialized result of device read operations. eapiVersion selects the eAPI JSON output schema sent as the runCmds version parameter: latest (the default) returns the current schema for each command, and 1 pins the original schema for consumers that depend on it. It only affects JSON output, so eos_get_running_config and eos_show_logging are unchanged.

actor and logFile are currently exposed only as sanitized runtime metadata; the server does not yet write an audit log.

defaultConnection.mcpPasswordEnv is a fallback password source. A host or inherited inventory value for mcp_password_env or ansible_password overrides it. Setting both mcp_password_env and ansible_password for the same host remains invalid.

Connect to an MCP client

These examples assume you have an inventory file (and optionally a server config file) ready. They launch the server with npx, so nothing needs to be installed first. If you installed globally, use eos-mcp-server as the command and drop -y @aristanetworks/eos-mcp-server from the arguments.

Generic stdio example

Point the server at just an inventory file:

{
  "mcpServers": {
    "eos": {
      "command": "npx",
      "args": [
        "-y",
        "@aristanetworks/eos-mcp-server",
        "serve",
        "--inventory",
        "/absolute/path/to/inventory.yml"
      ]
    }
  }
}

Or use a server config file if you want to set additional options:

{
  "mcpServers": {
    "eos": {
      "command": "npx",
      "args": [
        "-y",
        "@aristanetworks/eos-mcp-server",
        "serve",
        "--config",
        "/absolute/path/to/eos-mcp-server.yml"
      ]
    }
  }
}

If you built the project locally instead, use "command": "node" and put /absolute/path/to/eos-mcp-server/dist/index.js first in args, in place of -y and the package name.

Claude Code

With just an inventory file:

claude mcp add eos -- npx -y @aristanetworks/eos-mcp-server serve --inventory /absolute/path/to/inventory.yml

Or with a server config file for additional options:

claude mcp add eos -- npx -y @aristanetworks/eos-mcp-server serve --config /absolute/path/to/eos-mcp-server.yml

Add -s user before eos in either command to make the server available across all your projects instead of just the current one:

claude mcp add -s user eos -- npx -y @aristanetworks/eos-mcp-server serve --inventory /absolute/path/to/inventory.yml

Codex

Add the server to .codex/config.toml in a trusted project, or to ~/.codex/config.toml for all projects.

With just an inventory file:

[mcp_servers.eos]
command = "npx"
args = ["-y", "@aristanetworks/eos-mcp-server", "serve", "--inventory", "/absolute/path/to/inventory.yml"]
env_vars = ["EOS_MCP_PASSWORD"]

Or with a server config file for additional options:

[mcp_servers.eos]
command = "npx"
args = ["-y", "@aristanetworks/eos-mcp-server", "serve", "--config", "/absolute/path/to/eos-mcp-server.yml"]
env_vars = ["EOS_MCP_PASSWORD"]

serve is optional because it is the default command, but is shown explicitly here for clarity. After exporting the password, you can also add the server and pass its current value through with the Codex CLI:

export EOS_MCP_PASSWORD='replace-with-device-password'

codex mcp add eos \
  --env EOS_MCP_PASSWORD="$EOS_MCP_PASSWORD" \
  -- npx -y @aristanetworks/eos-mcp-server serve \
  --inventory /absolute/path/to/inventory.yml

The --env form stores the expanded value in the generated Codex configuration. To have Codex read the variable from its environment each time it starts the server, use env_vars = ["EOS_MCP_PASSWORD"] as in the TOML examples above.

Passing secrets to the MCP server

To export secrets in the environment that launches the MCP client use:

export EOS_MCP_PASSWORD='super-secret'

For Codex, env_vars = ["EOS_MCP_PASSWORD"] forwards that exported variable to the server. Other MCP clients may support per-server env blocks. Avoid committing secret values to client config files when possible.

Skills

The skills/ folder holds community-created skills for everyday network operations workflows. Each skill is a SKILL.md file that teaches an AI assistant, such as Claude Code or Codex, how to carry out one workflow with this server's read-only tools: which show commands to run, how to read the output, what to investigate next, and how to report results.

The current skills cover:

  • Health checks: BGP, EVPN and EVPN multicast, interfaces, Port-Channels/LACP, VLANs, routing tables and VRFs, IGMP snooping, and PIM.
  • Validation: ISIS Segment Routing, RFC 9721 EVPN IP mobility, and MCS/CVX configuration.
  • Troubleshooting: multicast flows that are missing, dropping, or corrupted; PTP grandmaster and connectivity problems; Segment Routing faults; and MCS mounts and agents.

See skills/README.md for the full list and for how to load the skills into Claude Code or Codex. Skills aren't included in the npm package, so clone this repository to use them.

Contribute a skill

If you have a workflow you run by hand, such as a check you do after a change window, a runbook for a recurring problem, or an audit for a feature your network depends on, consider contributing it as a skill so other network engineers can use it too.

  1. Add skills/<skill-name>/SKILL.md with name, description, trigger, and allowed-tools frontmatter. The existing skills are good templates.
  2. Keep it read-only, and keep it generic: no site-specific hostnames, group names, or inventory layouts.
  3. Document the EOS commands the skill runs, the JSON fields it relies on, and what to check when something looks wrong.
  4. Add a row for the skill to the table in skills/README.md.
  5. Open a pull request that changes only files under skills/.

Pull requests that touch only skills/ can be accepted without a contributor license agreement. They are licensed under Apache-2.0. See CONTRIBUTING.md for details, and Writing a new skill for the full guidelines. Improvements to existing skills are welcome too, such as coverage for another EOS feature, a better diagnostic drill-down, or a fix for output that changed between EOS releases.

Inventory formats

The server supports exactly one inventory file loaded at startup. The inventory is not watched for changes — to pick up inventory edits, restart the server. Most MCP clients will do this automatically when you restart the client or re-launch the MCP connection.

Supported formats:

  • canonical Ansible-style YAML
  • simplified YAML

Canonical inventories must have all as the only top-level key. Simplified inventories may use only version, vars, hosts, and groups at the top level. Unknown structural keys are rejected; unknown keys inside vars remain allowed.

Canonical Ansible-style example

all:
  children:
    eos:
      vars:
        ansible_user: admin
        ansible_network_os: eos
        mcp_password_env: EOS_MCP_PASSWORD
      hosts:
        leaf1:
          ansible_host: 192.0.2.11
        leaf2:
          ansible_host: 192.0.2.12

Simplified YAML example

version: 1
vars:
  ansible_user: admin
  mcp_password_env: EOS_MCP_PASSWORD

hosts:
  leaf1:
    ansible_host: 192.0.2.11
    ansible_network_os: eos
  leaf2:
    ansible_host: 192.0.2.12
    ansible_network_os: eos

groups:
  leafs:
    hosts: [leaf1, leaf2]

For an inventory where devices do not share a password, see example-inventories/multi-password.yaml. Each host sets its own mcp_password_env reference, so the actual passwords remain in the environment rather than in the inventory file. For example:

export EOS_MCP_SPINE1_PASSWORD='spine1-password'
export EOS_MCP_SPINE2_PASSWORD='spine2-password'
export EOS_MCP_LEAF1_PASSWORD='leaf1-password'
export EOS_MCP_LEAF2_PASSWORD='leaf2-password'

eos-mcp-server validate-inventory \
  --inventory example-inventories/multi-password.yaml
eos-mcp-server serve --inventory example-inventories/multi-password.yaml

The password environment variable name is resolved independently for each host. Host-level values override inherited group or global values, so devices can be queried together through the FABRIC, SPINES, or LEAFS targets while still using their individual credentials.

Important inventory rules

  • Targets must be inventory host or group names, not IP addresses.
  • Host/group names must match ^[A-Za-z0-9_.-]+$.
  • Duplicate YAML keys are rejected.
  • The simplified schema reserves all; do not define groups.all there.
  • Group graphs must be acyclic.
  • EOS eligibility comes from either:
    • ansible_network_os: eos
    • mcp_platform: arista_eos
  • mcp_read_allowed defaults to true for eligible EOS hosts. Set it to false — inherited like any other variable — to explicitly deny read access to a host or group.
  • Read operations fail closed if the resolved target contains ineligible or read-denied hosts.

Connection and authentication

Supported connection fields

The read path currently uses these effective fields:

  • ansible_host - device hostname/IP for HTTPS connection
  • ansible_httpapi_port - optional eAPI port, default 443
  • ansible_user - username
  • mcp_password_env - preferred password source, treated as an environment variable name
  • ansible_password - literal password source
  • mcp_validate_certs - optional boolean to disable TLS validation for a lab target; ansible_httpapi_validate_certs is also accepted as a fallback

Password source rules

Exactly one password source must resolve per EOS host:

  • mcp_password_env
  • ansible_password

Do not set both.

If you use mcp_password_env, the value must be the name of an environment variable, not the password itself.

Correct:

mcp_password_env: EOS_MCP_PASSWORD

Incorrect:

mcp_password_env: admin

The default allowed env var prefix is EOS_MCP_, so names like EOS_MCP_PASSWORD work by default.

Example:

export EOS_MCP_PASSWORD='replace-with-device-password'

TLS behavior

  • HTTPS only
  • certificate validation is on by default
  • optional custom CA bundle via config file caFile
  • per-target or inherited inventory override via mcp_validate_certs: false (or ansible_httpapi_validate_certs: false)

There is currently no CLI --insecure flag.

Disable cert validation for a lab inventory

all:
  children:
    eos:
      vars:
        ansible_user: admin
        ansible_network_os: eos
        mcp_password_env: EOS_MCP_PASSWORD
        mcp_validate_certs: false
      hosts:
        leaf1:
          ansible_host: 192.0.2.11

Prefer a CA bundle when possible

Server config:

inventory: inventory.yml
caFile: /path/to/ca.pem

CLI usage

If no subcommand is provided, the CLI defaults to serve. These examples use the globally installed eos-mcp-server command; with npx, run npx -y @aristanetworks/eos-mcp-server in its place.

serve

Start the MCP server over stdio.

eos-mcp-server serve --inventory inventory.yml
eos-mcp-server serve --config eos-mcp-server.yml

On startup, serve loads the inventory and validates startup connection requirements for EOS-eligible hosts.

validate-inventory

Validate the inventory file.

Default behavior performs:

  • inventory parsing and structural validation
  • effective inventory validation
  • startup-style connection validation for EOS-eligible hosts using the loaded config/default connection settings

Use --inventory-only to skip the startup connection checks.

print-server-info

Print the server's sanitized runtime/config summary.

eos-mcp-server print-server-info --inventory inventory.yml
eos-mcp-server print-server-info --config eos-mcp-server.yml --json

probe

Probe a host or group target using the same logic as the MCP tool.

eos-mcp-server probe --inventory inventory.yml --target leaf1
eos-mcp-server probe --inventory inventory.yml --target leafs --json

Human-readable example output:

Probe target: leaf1
Devices: 1/1 succeeded
- leaf1: success

MCP tool reference

eos_get_server_info

Returns a sanitized summary of server runtime, capabilities, limits, TLS/config posture, and inventory summary.

Input:

{}

eos_list_inventory

Returns a sanitized view of the loaded inventory.

Input:

{
  "include_ineligible": false
}

eos_probe_devices

Checks operational readiness for a host or group by contacting devices and running a harmless command.

Input:

{
  "target": "leaf1",
  "include_raw": false
}

eos_run_show

Runs one or more show commands.

Rules:

  • exactly one of command or commands
  • every command is trimmed, must be a single line, and must be show or begin with show
  • commands with CLI output modifiers or shell metacharacters such as |, >, <, ;, &, backticks, or $ are rejected before device contact
  • output_format is one of auto, json, text
  • include_raw optionally attaches each command's raw eAPI result entry as raw_entry inside command_results

Input examples:

{
  "target": "leaf1",
  "command": "show version",
  "output_format": "auto"
}
{
  "target": "leafs",
  "commands": ["show version", "show interfaces status"],
  "output_format": "json",
  "include_raw": false
}

eos_show_logging

Retrieves bounded EOS logging output for a host or group target. The tool always uses text output and generates show logging threshold <minimum_severity> <message_count>. minimum_severity is a threshold, so warnings includes warning and more urgent log messages. Defaults are minimum_severity: "warnings" and message_count: 100; message_count is capped by maxLoggingMessagesPerRequest.

Input example:

{
  "target": "leaf1",
  "minimum_severity": "warnings",
  "message_count": 100
}

Allowed severities are emergencies, alerts, critical, errors, warnings, notifications, informational, and debugging.

eos_get_facts

Collects a small, fixed core facts set from show version.

Input:

{
  "target": "leaf1",
  "include_raw": false
}

eos_get_running_config

Returns running config text for a host target, or for a group target when section is provided. Automatically enters enable mode via eAPI since show running-config requires privileged access. section is trimmed and must be a single-line EOS section selector without CLI output modifiers or shell metacharacters.

Input examples:

{
  "target": "leaf1"
}
{
  "target": "leafs",
  "section": "router bgp"
}

Common troubleshooting

Password env var ... does not match any allowed prefix

mcp_password_env must contain an environment variable name like EOS_MCP_PASSWORD, not the password itself.

Password env var ... is not set

Export the referenced environment variable before launching probe or serve.

Certificate validation failure

Use one of:

  • caFile in the server config to trust your lab CA
  • mcp_validate_certs: false (or ansible_httpapi_validate_certs: false) in inventory for a lab/dev target

There is no CLI TLS-disable flag today.

Unknown inventory target ...

Tool and CLI targets must be inventory names, not ansible_host IPs.

Group running-config request failed without section

For eos_get_running_config, group targets require a section value.

Command or section rejected as invalid

eos_run_show accepts only single-line show commands. eos_get_running_config.section must also be a single-line selector. Newlines, other control characters, CLI output modifiers, and shell metacharacters are rejected before any device contact.

Response too large

Read tools are bounded by maxResponseSizeBytes. The server rejects oversized device HTTP responses before buffering them fully, and also rejects oversized aggregate tool results with narrowing guidance. For eos_show_logging, reduce message_count, target fewer devices, or raise minimum_severity.

Policy denied when probing a device

Example:

eos-mcp-server probe --inventory clab/clab-testlab/ansible-inventory.yml --target clab-testlab-node1-1
Policy denied: target clab-testlab-node1-1 includes host(s) not permitted for read operations: clab-testlab-node1-1

This means the target resolved to at least one host that is either not marked as EOS eligible (ansible_network_os: eos or mcp_platform: arista_eos) or has mcp_read_allowed: false set.

EOS version compatibility

The read-path tools have been validated against EOS 4.34.3M. The minimum supported EOS version for read operations is 4.20, which is when eAPI JSON-RPC became stable and show commands reliably produce structured JSON output.

Design notes

  • inventory is the trust boundary
  • reads are fail-closed on ineligible or denied targets
  • the server exposes only documented read-only operations

Project docs

Additional design and planning docs in the docs/ directory:

  • docs/DESIGN.md — detailed design specification
  • docs/IMPLEMENTATION_PLAN.md — implemented scope and maintenance priorities
  • docs/CHECKPOINT.md — current implementation status
  • docs/CODE_WALKTHROUGH.md — source layout and module guide
  • docs/QUICKSTART.md — quick start tutorial
  • docs/EXAMPLES.md — inventory and usage examples

License

Copyright 2026 Arista Networks, Inc.

This project is licensed under the Apache License, Version 2.0. Apache-2.0 applies to each released version of this repository. Arista may offer later versions under additional or different terms, but cannot revoke the Apache-2.0 rights granted for versions already released under it.

README fetched from the repository 6 days ago. The original is authoritative.

Questions

About Eos MCP Server

How do I install Eos MCP Server?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Eos MCP Server safe to use with an AI agent?

Its trust score is 34 out of 100 (low). It passes 5 of the 5 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Eos MCP Server still maintained?

Yes — the last commit was 16 days ago. The repository has 10 stars and 1 forks and 3 open issues.