Skip to main content
Glama

claude-project — netmiko MCP 서버 + 스킬

복사하여 바로 사용할 수 있는 프로젝트로, AI 에이전트에게 SSH를 통해 라우터, 스위치, 방화벽에 대한 읽기 전용 액세스를 Model Context Protocol을 통해 제공합니다.

이 프로젝트는 두 가지 구성 요소와 그 연결을 제공합니다:

  • mcps/mcp_server_netmiko.py — 자체 포함된 MCP 서버. 10개의 도구, 모든 명령은 운영자가 정의한 허용/차단 목록에 대해 검증되며, 출력은 ntc-templates로 JSON으로 파싱되고, 모든 시도에 대해 실패 시 닫히는 감사 추적이 제공됩니다.

  • .claude/skills/netmiko/SKILL.md — 에이전트에게 언제 해당 도구를 사용해야 하는지, 각 플랫폼의 CLI 방언이 어떻게 생겼는지, 그리고 거부를 읽는 방법을 가르치는 스킬입니다.

여기 있는 어떤 것도 장치에 쓰기를 수행하지 않습니다. 허용 목록은 기본 차단(default-deny)입니다 — 비어 있으면 아무것도 허용하지 않으며, 차단 측은 항상 허용 측보다 우선합니다.

발생하는 모든 일은 감사 추적에 기록되며, netmiko.query_audit_trail을 통해 대화 중에 질문할 수 있습니다: "SW-CORE-01에서 날짜별로 수행된 모든 작업", "마지막 6개 작업", "이번 주에 거부된 명령". 이 프로젝트에는 UI가 없으므로, 해당 도구가 유일하게 감사 추적을 읽는 방법입니다.

저자 및 출처

이 프로젝트의 저자는 Ed Scrimaglia입니다 — edgardo.scrimaglia@gmail.com, Octupus. 서버, 스킬, 구성 모델 및 문서는 그의 작업이며, Niko 에이전트를 위해 작성되어 독립 프로젝트로 패키징되었습니다.

이 프로젝트는 포크에서 시작되었으며, 그 기원을 숨기지 않고 인정합니다: 출발점은 Kirk Byers의 작업이었고, 프로젝트는 그것을 훨씬 넘어 성장했습니다. 현재 여기에 있는 것 — 진실 공급원(Source of Truth) 기반 인벤토리, 자격 증명 해결, 세 가지 배포 방식, 출력 페이지 매김, 감사 추적, 스킬 및 이 문서 — 은 상류(upstream)에서 온 것이 아닙니다.

Kirk Byers의 두 상류 프로젝트:

  • Netmiko — 장치와 실제 통신을 수행하는 다중 벤더 SSH 라이브러리.

  • netmiko_mcp — 이 프로젝트가 포크된 MCP 서버. 그 중 한 부분은 거의 원래대로 남아 있습니다: 보안 핵심(명령 검증, 글로브 처리, 허용/차단 비대칭)은 상류 패치를 계속 diff할 수 있도록 의도적으로 충실하게 포팅되었습니다. 이는 엔지니어링 결정이었으며, 나머지 작업의 한계가 아닙니다.

Related MCP server: Network MCP Server

Niko에 관하여

이 서버는 Niko(Neural Intelligence Knowledge Orchestrator AI 에이전트, Octupus의 Ed Scrimaglia가 구축)를 위해 작성되었습니다. Niko는 여러 MCP 서버 — 진실 공급원 서버, 이 서버, Jira, 이메일 전송, 파일 생성 등 — 를 앞세워 운영자가 평범한 언어로 질문하면 부동산 정보로부터 답변을 받을 수 있게 합니다: SoT는 있어야 하는 것, 장치 자체는 실제로 있는 것을 제공합니다.

Niko 내부에서는 동일한 파일이 약간 다르게 실행되며, 이는 코드의 몇 가지 사항을 설명하므로 알아두는 것이 좋습니다:

  • 서버는 루프백(loopback)에서 HTTP로, 각각 하나의 포트를 사용하여 실행되며, mcps/mcp_config.jsonurl / transport / local / env로 선언됩니다 — 아래 설명된 동일한 두 축 구성이 Niko 고유 형식으로 표현됩니다.

  • 설치는 파일 복사가 아닌 앱을 통해 이루어집니다: 업로드가 검증되고, 종속성은 코드 자체에서 해결되며, 실패한 설치는 서버의 절반을 남기지 않고 롤백됩니다.

이러한 각 통합은 대체(fallback)가 있는 선택적 임포트이므로, niko를 설치할 필요가 없습니다. 네 가지가 있으며, 임포트 실패 시 각각의 저하(degrade) 방식은 다음과 같습니다:

Import

독립형 대체(fallback)

niko.srvclass_logging.MCPLogging

60

NIKO_AVAILABLE = False; 서버가 자체 logging을 구성합니다.

niko.niko_paths.NikoPaths

68

None; 경로는 NETMIKO_MCP_* 변수에서 가져오며, 이것이 이 프로젝트가 명시적으로 설정하는 이유입니다.

niko.srvclass_logging.SyncedConcurrentTimedRotatingFileHandler

436

FailClosedFileHandler — 여전히 실패 시 닫히지만, 멀티 프로세스에 안전하지는 않습니다.

niko.srvclass_list_budget.apply_budget_to_payload

2709

페이로드를 변경하지 않고 반환하는 no-op입니다.

Niko 외부에서는 중요한 것이 손실되지 않습니다: 동시 핸들러는 여기서 발생하지 않는 여러 프로세스-하나의 파일 문제를 해결하며, 목록 예산은 자체 컨텍스트 회계가 있는 에이전트를 위해 긴 페이로드를 자릅니다. 하나의 파일, 두 개의 집, 포크 없음.

Fedele은 Niko의 진실 공급원(SoT)이며, 따라서 SoT 변수가 NetBox 인스턴스를 가리키더라도 FEDELE_ 접두사를 가지는 이유입니다.

라이선스

이 프로젝트 자체 코드는 MIT입니다 — LICENSE를 참조하세요.

이는 파생 작업이므로 두 개의 라이선스가 적용되며 두 파일이 함께 제공됩니다:

라이선스

파일

이 프로젝트의 코드, 문서 및 스킬

MIT

LICENSE

ktbyers/netmiko_mcp에서 포팅된 부분

Apache-2.0

LICENSE-APACHE-2.0

NOTICE에는 Apache-2.0 §4(b)가 요구하는 저자 표시 및 수정 사항 명세가 포함되어 있습니다. Netmiko는 일반적인 MIT 종속성입니다: 임포트되었으며, 벤더링되지 않았고, 재배포할 것이 없습니다.


레이아웃

claude-project/
├── .mcp.json                     # declares the server (project scope)
├── .env.example                  # → copy to .env with the SSH credentials
├── .claude/skills/netmiko/
│   └── SKILL.md                  # one directory per skill, file named SKILL.md
├── mcps/
│   └── mcp_server_netmiko.py     # NOT at the root: the server reads ../.env
├── config/netmiko/
│   ├── commands.yml              # allow/deny list — without it, a 16-command fallback applies
│   └── inventory.yml             # inventory in netmiko_tools format
├── logs/                         # netmiko-mcp.log + netmiko-audit.jsonl
├── mcpr/netmiko/                 # created on demand (0700): large outputs
├── LICENSE  LICENSE-APACHE-2.0  NOTICE
└── pyproject.toml

협상 불가능한 두 가지 규칙:

  1. 스킬은 .claude/skills/<name>/SKILL.md에 있어야 합니다. Claude Code는 skills/netmiko.md를 읽지 않습니다: 디렉토리와 정확한 파일 이름이 필요합니다.

  2. 서버는 루트가 아닌 mcps/에 있어야 합니다. PARENT_DIR.py를 포함하는 디렉토리의 상위 디렉토리이며(mcp_server_netmiko.py:62), 여기서 .env를 가져옵니다. 서버가 루트에 있으면 .env는 프로젝트의 한 단계 위에서 조회됩니다.

실행하기

uv venv --python 3.12
uv pip install -r <(uv pip compile pyproject.toml)   # or: uv sync
cp .env.example .env && $EDITOR .env                 # SSH credentials
# .mcp.json needs no editing: its paths are project-relative
claude                                               # approve the project server

세션 내에서: /mcp는 10개의 도구를 나열하고, /skills는 스킬이 로드되었는지 확인합니다. 네트워크에 접촉하지 않고 먼저 확인:

netmiko MCP가 시행하는 명령 정책은 무엇인가요?


세 가지 변형

인벤토리가 어디에서 오는지와 자격 증명이 어디에서 오는지는 독립적인 두 축입니다. 이것이 하나의 서버로 세 가지 배포를 가능하게 하며, 서버가 그 사이를 이동하기 위해 수정될 필요가 없는 이유입니다: 두 개의 환경 변수가 결정합니다.

인벤토리

자격 증명

필요한 것

사용 시기

A — SoT 모든 것

Fedele

Fedele

API 토큰 + Fernet 키

SoT가 권위적이며 이미 장치 자격 증명을 보유하고 있을 때

B — SoT 인벤토리, 로컬 자격 증명

Fedele 또는 NetBox

.env

API 토큰

SoT는 있지만 자격 증명 플러그인이 없을 때. 일반적인 시작점

C — 자체 포함

로컬 YAML

.env

외부 필요 없음

실험실, 폐쇄망, 데모, 또는 SoT가 다운되었을 때의 저하 모드

netmiko.get_metadata는 실제로 실행 중인 것을 보고합니다 — 설정 파일에서 추정하지 마세요:

{
  "inventory": {"backend": "fedele", "scope_filter": {"tag": "lab"}, "available": true},
  "credential_source": "env",
  "device_types_in_inventory": ["cisco_ios", "huawei_vrp", "…"]
}

A — Fedele을 진실 공급원으로, 자격 증명 포함

에이전트는 장치를 이름으로 요청합니다; 서버는 호출 시점에 SoT에 대해 주소, 플랫폼 및 자격 증명을 해결합니다. 이 프로젝트에는 장치 정보가 전혀 없습니다: SoT에 장치를 추가하면 다음 호출 시 수정이나 재시작 없이 접근 가능합니다.

// .mcp.json → env
"NETMIKO_MCP_INVENTORY_TYPE": "fedele",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "fedele",
"NETMIKO_MCP_FEDELE_GROUP_SOURCE": "tags",        // tags | device_roles | sites
"NETMIKO_MCP_FEDELE_DEVICE_FILTER": "tag=lab",    // the scope filter — read the warning
"NETMIKO_MCP_FEDELE_CACHE_TTL": "60"
# .env
FEDELE_URL=https://fedele.example.com
FEDELE_TOKEN=<API token>
FEDELE_CREDENTIALS_KEY=<Fernet key of the fedele_credentials plugin>

파일: 필수 사항은 없습니다. commands.yml권장됩니다 — 없으면 내장된 대체 정책이 적용됩니다. 로컬 인벤토리는 관련되지 않으며, NETMIKO_USERNAME / NETMIKO_PASSWORD도 없습니다; credential_source=fedele인 경우 NETMIKO_SECRET무시됩니다 — enable 비밀번호도 SoT에서 가져옵니다.

자격 증명 조회가 작동하는 방식, 세 단계:

GET dcim/devices/?name=<name>                          → device.id
GET plugins/credentials/devicecredentials/?device=<id> → credential id
GET plugins/credentials/networkcredentials/<id>/       → username + encrypted password
                                                          decrypted locally with the Fernet key

이 변형을 선택하기 전에 알아야 할 사항:

  • Fernet 키는 전체 보안 경계입니다. 서버 메모리에서 장치 비밀번호를 복호화합니다. 비밀번호 자체처럼 취급하세요.

  • FEDELE_CREDENTIALS_KEY가 없어도 서버는 시작되지만, 모든 도구가 누락된 변수를 명시하는 동일한 Startup Error를 반환합니다. 조용히 실패하지 않고 크게 실패합니다.

  • 범위 필터를 설정하세요. NETMIKO_MCP_FEDELE_DEVICE_FILTER가 없으면 인벤토리는 SoT가 알고 있는 전체 장치이며, 이는 에이전트가 접근할 수 있는 전체 장치 집합이기도 합니다. 서버는 누락 시 경고를 기록합니다; 필터는 쿼리 구문, tag=lab&status=active를 사용합니다.

  • primary_ip가 없거나, platform이 없거나, 플랫폼이 Netmiko device_type이 아닌 장치는 인벤토리에서 제외됩니다 — SoT는 카메라, 출입증 리더기 및 섀시도 인벤토리합니다. 제외는 카운트되고 보고되므로, 에이전트가 하위 집합에 대해 "이것들이 모든 장치입니다"라고 주장하지 않습니다.

  • 회로 차단기(circuit breaker)가 있습니다: 전송 오류 또는 5xx 후에 클라이언트는 30초 동안 SoT 호출을 중단합니다. SoT가 다운된 상태에서 40개 장치에 대한 그룹 명령은 40번이 아닌 한 번 실패합니다.

B — 인벤토리는 SoT에서, 자격 증명은 .env에서

하나의 변수만 바꾸면 A와 동일합니다:

"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",
# .env
FEDELE_URL=https://sot.example.com
FEDELE_TOKEN=<API token>
NETMIKO_USERNAME=<service account>
NETMIKO_PASSWORD=<password>
NETMIKO_SECRET=<enable password, if any device asks for it>

동적 인벤토리 — 그 자체로 가치 있는 부분 — 를 자격 증명 플러그인과 Fernet 키 없이 얻을 수 있습니다. 모든 장치에 대해 하나의 서비스 계정이 사용됩니다.

NetBox, 또는 NetBox 형태의 모든 SoT

인벤토리 백엔드는 NetBox REST 방언을 사용하므로, NetBox 자체가 이 변형에서 수정 없이 작동합니다:

백엔드가 호출하는 것

읽는 것

dcim/devices/

장치 목록, 범위 필터로 필터링되고 페이지 매김됨

extras/tags/, dcim/device-roles/, dcim/sites/

FEDELE_GROUP_SOURCE가 선택하는 것 중 하나가 장치 그룹이 됩니다

device.primary_ip.address

SSH 호스트, 마스크 제거됨

device.platform.name

Netmiko device_type, CLASS_MAPPER에 대해 검증됨

FEDELE_URL을 NetBox 인스턴스로 지정하고(생략하면 /api가 추가됨), FEDELE_TOKEN을 NetBox API 토큰으로 지정합니다 — 클라이언트는 NetBox가 기대하는 Authorization: Token … 헤더로 인증합니다. 변수는 FEDELE_ 접두사를 유지합니다; 이는 명명 유산일 뿐, 제품 요구 사항이 아닙니다.

NetBox가 기본적으로 충족하지 못하는 한 가지 요구 사항: platform.name은 정확히 Netmiko device_type 이어야 합니다 — cisco_ios, arista_eos, huawei_vrp, juniper_junos. "Cisco IOS 15.2"라는 이름의 플랫폼은 device_type이 아니므로, 이를 가진 모든 장치는 인벤토리에서 제외됩니다. NetBox에서 플랫폼 이름을 바꾸거나 제외를 수용하세요. 제외는 보고됩니다.

자격 증명은 NetBox가 다루지 않는 부분입니다: plugins/credentials/… 엔드포인트는 Fedele의 플러그인에 속합니다. 일반 NetBox의 경우 변형 A는 사용할 수 없습니다 — B를 유지하세요.

C — 자체 포함: SoT 전혀 없음

모든 것이 이 프로젝트에 있습니다. 외부 서비스에 전혀 접촉하지 않습니다.

// .mcp.json → env
"NETMIKO_MCP_INVENTORY_TYPE": "yaml",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",
"NETMIKO_MCP_INVENTORY_FILE": "/abs/path/claude-project/config/netmiko/inventory.yml"
# .env
NETMIKO_USERNAME=<service account>
NETMIKO_PASSWORD=<password>
NETMIKO_SECRET=<enable password, if any device asks for it>

파일: inventory.yml은 여기서 필수입니다 — 장치가 존재하는 유일한 곳입니다. commands.yml은 권장되며 필수는 아닙니다. 인벤토리는 netmiko_tools 형식입니다 — 이름과 연결 데이터의 평면 매핑에 그룹 키가 추가됩니다:

CORE-RTR-01:
  device_type: cisco_xr        # must be a Netmiko device_type, verbatim
  host: 192.0.2.11

CORE-SW-01:
  device_type: arista_eos
  host: 192.0.2.21

core:                          # a group is a list of device names
- CORE-RTR-01
- CORE-SW-01

이 프로젝트가 제공하는 파일은 예제 데이터입니다: RFC 5737 문서 범위의 12개 가상 장치, 7개 그룹, 그리고 허용 목록에 언급된 모든 CLI 방언이 포함되도록 선택된 플랫폼입니다. 실제 환경으로 교체하세요.

이것은 이 프로젝트가 구성된 상태로 제공하는 방식이며, 저하 모드이기도 합니다: SoT가 다운되면 두 개의 변수와 재시작으로 flavor-A 또는 flavor-B 배포를 여기로 이동합니다. 필요해지기 전에 연습해볼 가치가 있습니다.

비용은 파일이 오래된다는 점입니다. 상위 저장소의 scripts/export_inventory.py가 SoT에서 이를 재생성합니다; 정기적으로 실행하세요. 6개월 전의 주소를 담은 백업 인벤토리는 백업이 없는 것보다 더 나쁩니다, 운영 중에 알게 되기 때문입니다.

세 가지 모두에서 동일한 부분

명령 정책, 감사 추적, 출력 페이지 매김 및 도구 표면은 flavor 간에 변경되지 않습니다. 에이전트가 보는 계약은 동일하며, 이것이 스킬에 flavor별 변형이 필요하지 않은 이유입니다.

commands.yml은 권장되며 필수는 아닙니다

서버는 이것 없이도 실행됩니다. 파일이 없으면 모든 것을 거부하지도 않고 시작을 거부하지도 않습니다: 16개의 읽기 전용 명령으로 구성된 내장 폴백이 작동합니다 — show version, show ip interface brief, display version 및 Junos/VRP 등가물입니다. 이는 의도적입니다. 빈 정책은 서버가 여전히 정상이라고 보고하는 동안 모든 명령을 거부할 것이며, 운영자에게는 "정책을 작성한 사람이 없다"보다는 "장치가 거부했다"로 읽힙니다. 폴백은 시작 시 공지되며, netmiko.get_command_policypolicy_source: "fallback"을 보고하고, 모든 감사된 시도는 출처를 포함합니다.

따라서 파일은 설치 단계가 아닌 정책 결정입니다: 폴백을 사용하면 첫 시도에 서버를 실행할 수 있으며, 보수적인 기본값 대신 환경의 자체 정책을 원할 때 commands.yml을 작성합니다. 선택하지 않은 정책을 모르는 상태로 가질 수는 없습니다 — 서버는 요청할 때마다 어떤 정책이 적용 중인지 알려줍니다.


.mcp.json 파일

프로젝트 루트의 .mcp.json이 프로젝트에 대한 MCP 서버를 선언합니다. Claude Code는 파일을 처음 볼 때 승인을 요청하며, 파일은 커밋되도록 설계되었습니다: 팀 전체가 동일한 서버를 사용하는 방법입니다.

동일한 서버 정의에 대해 두 가지 다른 범위가 존재합니다:

범위

위치

보는 사람

project

프로젝트 루트의 .mcp.json

프로젝트를 여는 모든 사람 (승인 후)

user

~/.claude.json

해당 사용자의 모든 프로젝트, 해당 머신에서

local

~/.claude.json, 프로젝트 경로별 키

해당 사용자만, 해당 프로젝트에서만

claude mcp add --scope project netmiko -- /path/to/python /path/to/server.pyproject 항목을 자동으로 작성합니다; JSON을 수동으로 편집해도 동일합니다.

파일 구조

{
  "mcpServers": {           // ← the top-level key. Not "servers", not "mcp".
    "netmiko": {            // ← the server name; it becomes the tool prefix
      ...                   //    mcp__netmiko__<tool>
    }
  }
}

서버 이름은 단순한 장식이 아닙니다: Claude Code는 각 도구를 mcp__<서버-이름>__<도구-이름>으로 노출합니다. netmiko라는 이름과 서버가 등록하는 netmiko.get_metadata 도구를 사용하면 Claude가 실제로 보는 도구는 mcp__netmiko__netmiko.get_metadata입니다. /mcp를 실행하여 정확한 이름을 확인한 후 allowed-tools 목록이나 권한 규칙에 작성하세요.

필드 참조

필드

전송 방식

의미

type

둘 다

"stdio" (생략 시 기본값), "http", 또는 "sse"

command

stdio

실행할 실행 파일. 절대 경로 — cwd를 가정하지 마세요

args

stdio

인수 목록, 각 요소는 별도

env

stdio

자식 프로세스의 환경. 상속된 환경 위에 병합됨

url

http / sse

전체 엔드포인트 URL, 경로 포함

headers

http / sse

추가 요청 헤더, 일반적으로 Authorization

값은 환경 확장을 지원합니다: ${VAR}${VAR:-default}. 커밋된 파일에서 토큰을 유지하는 데 유용합니다:

"headers": { "Authorization": "Bearer ${NETMIKO_MCP_TOKEN}" }

전송 방식 1 — stdio (이 프로젝트가 사용하는 방식)

Claude Code는 서버를 자식 프로세스로 실행하고 stdin/stdout을 통해 JSON-RPC로 통신합니다. 포트에서 수신 대기하지 않으며, 네트워크에서 접근할 수 없고, 프로세스 수명은 세션과 동일합니다. 이는 SSH 자격 증명을 보유하는 서버에 적합한 기본값입니다.

{
  "mcpServers": {
    "netmiko": {
      "type": "stdio",
      "command": "${CLAUDE_PROJECT_DIR:-.}/.venv/bin/python",
      "args": ["${CLAUDE_PROJECT_DIR:-.}/mcps/mcp_server_netmiko.py"],
      "env": {
        "NETMIKO_MCP_INVENTORY_TYPE": "yaml",
        "NETMIKO_MCP_INVENTORY_FILE": "${CLAUDE_PROJECT_DIR:-.}/config/netmiko/inventory.yml",
        "NETMIKO_MCP_COMMAND_FILE": "${CLAUDE_PROJECT_DIR:-.}/config/netmiko/commands.yml",
        "NETMIKO_MCP_CREDENTIAL_SOURCE": "env",
        "NETMIKO_MCP_SAVE_OUTPUT_DIR": "${CLAUDE_PROJECT_DIR:-.}/mcpr/netmiko",
        "NETMIKO_MCP_AUDIT_LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/logs/netmiko-audit.jsonl",
        "LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/logs/netmiko-mcp.log",
        "LOG_LEVEL": "INFO"
      }
    }
  }
}

주의할 두 가지 사항:

  • 하드코딩된 경로 없음, 작업 디렉토리는 신뢰할 수 있는 것이 아닙니다. ${CLAUDE_PROJECT_DIR:-.}는 파일을 그대로 커밋 가능하게 유지합니다; 다음 섹션이 전체 설명이며, 명백한 해석이 틀리기 때문입니다.

  • 서버는 stdout에 쓰면 안 됩니다. stdout은 프로토콜 채널이며, 한 줄의 잘못된 출력이 세션을 중단시킵니다. 로깅은 stderr와 LOG_FILE의 순환 파일(5 MB × 3, 0600으로 생성 — DEBUG 수준에서 이 파일은 장치 출력을 포함)로 이동합니다. Niko 내부에서는 동일한 변수가 MCPLogging에 의해 처리됩니다.

${CLAUDE_PROJECT_DIR:-.}의 출처

하나의 문자열에 두 가지 별개의 것: 구문과 변수.

구문. ${VAR}${VAR:-default}는 POSIX 매개변수 대체입니다("VAR 사용; 설정되지 않았거나 비어 있으면 default 사용"). 그러나 셸이 관여하지 않습니다 — JSON 파일은 셸을 통과하지 않습니다. Claude Code는 파일을 읽을 때 command, args, env, urlheaders에서 직접 확장을 구현합니다. 이는 해당 클라이언트의 규칙이며 MCP 사양의 일부가 아닙니다: 다른 클라이언트는 이를 구현하지 않을 수 있으며(비-Claude 에이전트 참조, 경로가 리터럴이어야 함), VS Code는 자체 표기법 ${workspaceFolder}를 사용합니다.

변수. CLAUDE_PROJECT_DIR은 Claude Code가 프로젝트 루트로 설정하며, 훅이 받는 것과 동일한 값입니다. 안정적입니다 — --add-dir로 세션 중간에 추가 작업 디렉토리를 부여해도 이동하지 않습니다.

직관에 반하는 부분이자 :-.이 장식이 아닌 이유: Claude Code는 해당 변수를 자신의 환경이 아닌, 실행하는 서버의 환경에 설정합니다. 그러나 확장은 실행 전에 Claude Code의 환경에서 발생하며, 여기서 변수는 존재하지 않습니다. 따라서 순수한 ${CLAUDE_PROJECT_DIR}은 아무것도 확장되지 않고 /config/netmiko/inventory.yml을 남겨 파일 시스템 루트의 절대 경로가 됩니다.

따라서 프로젝트 범위의 .mcp.json에서 기본값은 일부 예외 상황의 폴백이 아닙니다: 매번 사용되는 값입니다. 프로세스에 도달하는 것은 ./config/netmiko/inventory.yml입니다. 유일한 예외는 플러그인이 제공하는 MCP 구성입니다 — 여기서 Claude Code는 변수를 직접 대체하며 기본값이 필요하지 않습니다.

이것이 서버의 처리를 강제합니다. 상대 경로는 자식 프로세스의 cwd를 기준으로 해석되며, cwd는 클라이언트의 선택이지 프로젝트의 선택이 아닙니다. 따라서 resolve_project_path(): 모든 상대 경로 설정은 설정이 로드될 때 PARENT_DIRmcps/의 상위 디렉토리이자 .env가 있는 동일한 루트 — 에 고정됩니다. 어디서든 시작된 세션은 config/netmiko/를 찾고, validate_startup()은 파일이 없을 때 절대 파일을 지정합니다. ~는 여전히 운영자의 홈 디렉토리를 의미하며, 프로젝트 내부의 파일이 아닙니다.

변수는 문서가 의도한 방식대로 서버 내부에서 읽을 때(os.environ["CLAUDE_PROJECT_DIR"]) 여전히 유용하며, 여기서 설정됩니다. 이 서버는 필요하지 않습니다: PARENT_DIR__file__에서 파생되므로 클라이언트에 전혀 의존하지 않습니다 — HTTP 전송 방식에서 아무도 해당 변수를 설정하지 않아 특별한 처리가 필요 없는 것과 같은 이유입니다.

출처: Claude Code — MCP, 로컬 stdio 서버 추가.mcp.json의 환경 변수 확장 섹션.

전송 방식 2 — HTTP (스트리밍 가능 HTTP)

Claude Code가 지원하며, 다른 MCP 클라이언트도 지원합니다. 서버가 다른 곳에서 실행될 때 사용하는 전송 방식입니다: 다른 호스트, 컨테이너, 여러 에이전트가 공유하는 서비스, 또는 Claude가 아닌 에이전트.

서버 파일은 항상 __main__ 가드 아래에서 mcp.run(transport="stdio")를 호출하므로, HTTP는 FastMCP CLI를 통해 제공됩니다 — 코드 변경 없음:

.venv/bin/fastmcp run mcps/mcp_server_netmiko.py \
  --transport http --host 127.0.0.1 --port 8123
# endpoint: http://127.0.0.1:8123/mcp/

NETMIKO_MCP_* 변수는 더 이상 클라이언트 구성의 일부가 아닙니다: 서버 프로세스는 사용자가 시작하므로 해당 환경(셸 내보내기, systemd 유닛, 컨테이너의 environment: 블록)에 속합니다.

클라이언트 측:

{
  "mcpServers": {
    "netmiko": {
      "type": "http",
      "url": "http://127.0.0.1:8123/mcp/",
      "headers": {
        "Authorization": "Bearer ${NETMIKO_MCP_TOKEN}"
      }
    }
  }
}

또는 동등하게 claude mcp add --transport http netmiko http://127.0.0.1:8123/mcp/.

--transport sse"type": "sse"도 작동합니다; SSE는 더 오래된 원격 전송 방식이며 스트리밍 가능 HTTP로 전환하지 않은 클라이언트를 위해 유지됩니다.

보안. FastMCP CLI는 인증 없이 이를 제공합니다: 포트에 접근하는 사람은 서버 환경의 자격 증명을 사용하여 인벤토리의 모든 장치에 대해 show 명령을 실행할 수 있습니다. 로컬 테스트의 경우 127.0.0.1에 바인딩하고, 공유되는 경우 TLS를 종료하고 Authorization 헤더를 확인하는 리버스 프록시 뒤에 배치하세요. 위의 headers 블록은 클라이언트가 보내는 것이며, 프록시가 이를 확인해야 합니다.

비-Claude 에이전트

여기에 표시된 mcpServers 객체는 사실상의 표준 형태입니다: Claude Code, Claude Desktop, Cursor 및 Windsurf는 모두 stdio에 대해 동일한 세 필드(command / args / env)와 원격에 대해 동일한 두 필드(url / headers)를 읽습니다. 항목을 복사하는 것은 일반적으로 그대로 작동합니다.

복사하기 전에 확인할 가치가 있는 알려진 차이점:

  • VS Code"mcpServers" 대신 최상위 "servers" 키와 함께 mcp.json을 사용하며, "type"을 명시적으로 명시해야 합니다.

  • 일부 클라이언트는 ${VAR} 확장을 구현하지 않습니다; 이 경우 값은 리터럴이어야 하며, 이는 커밋된 파일에 토큰을 붙여넣는 것보다 HTTP 전송 방식과 프록시를 사용해야 하는 이유입니다.

  • 구성 파일이 전혀 없는 에이전트도 HTTP 엔드포인트와 직접 통신할 수 있습니다 — URL과 Authorization 헤더가 전체 계약입니다.

env 블록

NETMIKO_MCP_* 항목은 모든 YAML 구성 파일보다 우선합니다. Niko 외부에는 NikoPaths가 없으므로 기본값은 ~/commands.yml~/.netmiko_mcp_tmp로 폴백되기 때문에 명시적으로 설정됩니다.

여기의 모든 경로는 프로젝트 루트를 기준으로 작성될 수 있습니다: 서버는 설정이 로드될 때 상대 값을 PARENT_DIR에 고정하므로, 실행된 프로세스의 cwd가 인벤토리나 감사 추적의 위치를 결정하지 않습니다. 절대 경로나 ~는 그대로 사용됩니다.

Variable

기본값

용도

NETMIKO_MCP_INVENTORY_TYPE

netmiko_tools

yaml (로컬 파일) 또는 fedele (SoT)

NETMIKO_MCP_INVENTORY_FILE

(netmiko-tools 조회)

유형이 yaml일 때 인벤토리 경로

NETMIKO_MCP_CREDENTIAL_SOURCE

env

env (.env 읽기) 또는 fedele

NETMIKO_MCP_FEDELE_GROUP_SOURCE

tags

그룹을 정의하는 항목: tags, device_roles, sites

NETMIKO_MCP_FEDELE_DEVICE_FILTER

(없음)

범위 필터, tag=lab&status=active. 없으면 전체 자산을 대상으로 함

NETMIKO_MCP_FEDELE_CACHE_TTL

60

SoT 확인 캐시 (초 단위)

NETMIKO_MCP_COMMAND_FILE

Niko 외부 ~/commands.yml

허용/차단 목록

NETMIKO_MCP_ALLOW_PIPE

false

명령어에서 파이프 사용 가능

NETMIKO_MCP_SSH_CONFIG_FILE

(없음)

OpenSSH ssh_config. 점프 호스트에 필수 — Netmiko는 자체적으로 ~/.ssh/config를 읽지 않음

NETMIKO_MCP_MAX_WORKERS

10

그룹 명령어의 동시 연결 수

NETMIKO_MCP_SAVE_OUTPUT_DIR

Niko 외부 ~/.netmiko_mcp_tmp

대용량 출력 버퍼

NETMIKO_MCP_SAVE_THRESHOLD

1000

이 줄 수를 초과하면 출력을 인라인 대신 파일로 저장

NETMIKO_MCP_AUDIT_LOG_FILE

(상위 README 참조)

감사 추적 (JSON, 실패 시 차단). 에이전트에게 netmiko.query_audit_trail로 읽도록 요청

NETMIKO_MCP_CONFIG

~/.netmiko-mcp.yml

동일한 설정을 담은 YAML 구성 파일 경로

LOG_FILE / LOG_LEVEL

Niko.log / INFO

운영 로그: stderr는 항상 출력되며, 이 로테이션 파일 (5 MB × 3, 0600)에도 기록. LOG_LEVEL은 기본값이 명시되어 있어 필요한 곳에서 조정 가능 — DEBUG로 설정하면 장치 출력이 로그에 기록됨

자격 증명은 여기서 설정하지 않습니다. NETMIKO_USERNAME, NETMIKO_PASSWORD, NETMIKO_SECRETFEDELE_* 변수는 <project-root>/.env에서 읽어오므로, 커밋된 JSON 파일에 절대 포함되지 않습니다. 우선 순위: env 블록에 있는 값이 .env의 값을 조용히 덮어씁니다 — 각 변수는 정확히 한 곳에서 정의하세요.

그 외 모든 변수는 상위 저장소의 README에 문서화되어 있습니다.

작동 확인

claude mcp list          # netmiko: ✓ connected

세션 내에서 /mcp는 도구 목록을 보여주고, /skills는 스킬이 로드되었음을 확인합니다. 적용 중인 정책을 물어보면 netmiko.get_command_policy가 읽고 있는 파일 이름을 알려주거나, "fallback"을 보고합니다. 이는 파일을 찾지 못해 기본 내장 명령어 16개로 실행 중임을 의미합니다.


작성자: Ed Scrimaglia edgardo.scrimaglia@gmail.com — 마지막 업데이트: 2026-08-18.

A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides AI assistants with direct access to multi-vendor network devices for tasks like configuration management, health checks, and topology discovery through 35 specialized tools. It enables natural language control over platforms including Cisco, Juniper, and Nokia using SSH, NETCONF, and SNMP protocols.
    11
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with Cisco IOS-XE network devices over SSH using structured tools. Provides read and write capabilities for network management with built-in validation and security.
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables read-only querying and diagnostics of Fortigate firewalls via SSH, providing security analysis, traffic monitoring, and configuration inspection through natural language.
    MIT

View all related MCP servers

Related MCP Connectors

  • Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.

  • Read-only CVE intelligence, remediation playbooks, and agent setup guides. Not a scanner.

  • Read-only bank access for your AI agent. Connects Claude, ChatGPT, Cursor, Gemini, Codex.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/escrimaglia/netmiko-sot_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server