返回市场
诺林远程管理MCP服务器

诺林远程管理MCP服务器

作者:yhvh-chen7 星标更新:2025-09-26

项目介绍

🌐 Nornir MCP 服务器

License: MIT

一个由NornirNAPALM驱动的FastMCP服务器,提供网络自动化工具。

该服务器充当桥梁,将Nornir/NAPALM网络操作作为MCP(大规模并发处理)工具公开,使其能够通过兼容的MCP客户端轻松访问。

✨ 主要特性

  • 并发与多厂商支持:利用Nornir进行设备清单管理和并发任务执行,并使用NAPALM支持多厂商。
  • 扩展工具集:提供超过20种工具,包括广泛的NAPALM获取器(如get_factsget_interfaces),执行命令(如pingtraceroute),以及设备清单管理(如list_all_hosts)。
  • 强大的输入验证:使用Pydantic模型来验证所有传入的数据,确保类型安全并防止无效输入引起的错误。
  • 安全命令执行:具有可配置的命令黑名单conf/blacklist.yaml),以防止意外或恶意执行危险命令,例如通过send_command工具执行的reloaderase startup-config
  • 容器化与快速:使用Docker 🐳 容器化,便于设置,并在容器中使用uv进行闪电般的Python依赖管理 ⚡。

🔧 先决条件

开始之前,请确保已安装以下内容:

⚙️ 配置

在运行服务器之前,您必须配置您的网络清单和设备凭证:

  1. 导航到项目中的conf/目录。
  2. 编辑hosts.yaml:定义您的网络设备,包括其管理IP地址、平台、凭证和组。
  3. 编辑groups.yaml:定义具有共享属性的设备组。
  4. 编辑defaults.yaml:设置默认凭证和连接选项。
    • ⚠️ 重要安全提示:对于生产环境,强烈建议使用Nornir的秘密管理功能,避免在YAML文件中存储明文凭证。
  5. 查看blacklist.yaml:根据您的安全策略自定义被阻止的命令和模式列表。

▶️ 运行服务器

配置完成后,您可以使用Docker Compose轻松运行服务器:

docker-compose up --build -d

此命令将在Docker容器中启动Nornir MCP服务器,主机机器上的8000端口可以访问它。容器现在使用run.py作为入口点,支持开发和生产模式。

要在本地运行服务器(不使用Docker),使用:

python run.py --dev

或者简单地:

python run.py

这将使用新的入口点逻辑在0.0.0.0:8000上启动服务器。

🔌 如何连接MCP客户端

该项目通过HTTP传输暴露FastMCP。服务器提供了两个有用的端点:

  • HTTP API端点: http://<host>:<port>/mcp
  • SSE端点(事件): http://<host>:<port>/sse

关于传输和客户端设置的注意事项:

  • MCP服务器本身是一个HTTP应用程序(FastAPI/Starlette),由Uvicorn提供服务。您应该使用支持streamable-http传输的客户端直接连接到/mcp(主要)端点。
  • 您不需要为了典型的HTTP或SSE客户端运行此项目的stdio模式。先前包含的关于以“stdio模式”运行服务器并通过Supergateway代理的说明对于此仓库的正常使用是不准确的。

示例MCP客户端JSON配置(HTTP/streamable-http):

{
  "name": "Nornir MCP (HTTP)",
  "url": "http://localhost:8000/mcp",
  "transport": "http"
}

🧠 提示(自定义提示函数)

此服务器支持注册返回消息列表(MCP提示格式)的自定义提示函数。提示允许您预定义MCP客户端或LLM驱动代理可以调用的命名提示。FastMCP API通过@server.prompt()装饰器公开了注册函数的功能。

关键特性:

  • 使用@server.prompt()注册同步或异步提示函数。
  • 可选地提供nametitledescription,使提示在MCP客户端中可发现。
  • 提示可以返回包含资源引用的结构化消息(用于返回文件内容或清单片段)。

如何添加提示(示例):

@server.prompt(name="list-host-names", title="列出主机名", description="从清单返回主机名的简短列表")
def prompt_list_hosts() -> list:
    hosts = nr_mgr.list_hosts()
    return [{"role": "user", "content": f"可用主机:{', '.join(h['device_name'] for h in hosts)}"}]

异步示例带资源:

@server.prompt()
async def show_topology() -> list:
    topo = await server.read_resource("resource://topology")
    return [{"role": "user", "content": {"type": "resource", "resource": topo}}]

使用说明:

  • 注册提示后,客户端可以通过MCP ListPrompts请求发现它们,并按名称调用它们。
  • 保持提示函数轻量级且确定性;避免在提示内部执行长时间运行的操作。如果需要从设备收集数据,请考虑注册一个工具并在提示中调用它,或者返回一个简短的资源引用,供客户端获取。

安全性:

  • 提示在服务器进程中运行;不要在提示函数中执行不安全的文件操作或执行不受信任的代码。

快速入门——Docker(推荐)

  1. 使用docker-compose构建并运行(从仓库根目录):
docker-compose up --build -d

这将在容器中启动服务器,默认情况下在8000端口上公开。

快速入门——本地

  1. 创建并激活虚拟环境。
& .venv\Scripts\Activate.ps1
# 或在Unix系统上:python -m venv .venv; source .venv/bin/activate
  1. 安装运行时依赖项(示例):
pip install -U pip
pip install nornir==3.5.0 nornir-napalm mcp[cli]==1.15.0 sse-starlette
  1. 在本地运行服务器(默认绑定到0.0.0.0:8000):
python run.py

或者使用uv(当使用包含的运行器时推荐):

uv run .\run.py

如果您需要更改主机/端口,请在运行run.py时使用--host--port标志。

资源由服务器提供

  • resource://inventory/hosts — 返回带有清理字段(名称、主机名、平台、组、数据)的主机JSON数组。敏感键如usernamepasswordsecret已被移除。
  • resource://inventory/hosts/{keyword} — 同样的输出,通过关键字(大小写不敏感)过滤,匹配名称、主机名、平台、组名或数据值。
  • resource://inventory/groups — 返回清理过的组映射。
  • resource://topology — 解析resources/topology.json
  • resource://cisco_ios_commands — 解析resources/cisco_ios_commands.json

如何添加自己的资源

  1. 编辑resources.py并添加一个名为resource_<name>的函数(例如,resource_my_tools)。
  2. 如果您的函数需要Nornir管理器,请接受一个名为nr_mgr的参数。
  3. 如果您希望自定义URI,请向RESOURCE_MAP添加条目;否则将使用默认URI resource://user/<name>

示例resources.py片段

def resource_my_static():
  return {"hello": "world"}

def resource_my_hosts(nr_mgr):
  # 返回一个可JSON序列化的主机列表
  return nr_mgr.list_hosts()

安全注意事项

  • 清单YAML文件可能包含凭证。对于生产环境,建议使用秘密管理(如Vault、环境变量或Nornir秘密插件)而不是明文YAML。
  • 服务器会从通过resource://inventory/*提供的资源中移除常见的敏感键(如usernamepasswordsecret)。

贡献

  • 对于更改,打开问题或PR。保持更改小,并在适当的地方包含测试。

许可证

  • MIT