关于 Oxidized MCP
Oxidized MCP 是面向需要检查和管理 Oxidized 网络设备备份的 AI 助手的 Python MCP 服务。它整合设备与备份健康状态查询、配置搜索、版本历史、差异查看及可选的备份操作。
主要功能
- 01列出并筛选网络设备
- 02检查备份健康状况和过期设备
- 03读取并搜索设备配置
- 04浏览版本并比较配置差异
- 05触发备份并重新加载节点列表
适用场景
- 01按名称或 IP 查找设备
- 02识别失败或过期的备份
- 03按文本或模式搜索配置
- 04查看不同版本间的配置变化
MCP 相关
该服务将 Oxidized 设备、备份、配置、历史记录和操作功能作为 MCP 工具提供。它支持 stdio、HTTP SSE 和 HTTP Streamable 传输,并提供只读模式及可选的 bearer token 身份验证。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx oxidized-mcpOXIDIZED_URLOxidized web base URL (e.g., http://localhost:8888)OXIDIZED_USERNAMEHTTP Basic auth username (e.g., for a reverse proxy in front of oxidized-web)OXIDIZED_PASSWORD密钥HTTP Basic auth passwordOXIDIZED_VERIFY_SSLVerify SSL certificates (true/false)OXIDIZED_TIMEOUTRequest timeout in secondsOXIDIZED_SEARCH_TIMEOUTTimeout in seconds for configuration searches (oxidized-web reads every stored configuration)OXIDIZED_REDACT_NODE_VARSRedact node vars (may contain device credentials) in tool outputREAD_ONLY_MODEEnable read-only mode to restrict write operationsOXIDIZED_DISABLED_TAGSComma-separated list of tags to disable tools forLOG_LEVELLogging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)RATE_LIMIT_ENABLEDEnable rate limitingRATE_LIMIT_MAX_REQUESTSMaximum requests per rate limit windowRATE_LIMIT_WINDOW_MINUTESRate limit window in minutesTOOL_SEARCH_ENABLEDEnable FastMCP tool search transformTOOL_SEARCH_STRATEGYTool search strategy (bm25 or regex)TOOL_SEARCH_MAX_RESULTSMaximum tool search results returned by search_toolsMCP_HTTP_PORTPort for HTTP server (default: 8000)MCP_TRANSPORTMCP transport type: stdio, sse, or http (alias: streamable-http)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
11收录的工具列表 · 更新于 5 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group | any | 否 | 仅包含此组中的节点——名称必须与 list_nodes 显示的名称完全匹配且区分大小写(例如 'core');'default' 表示选择没有组的节点 |
| limit | integer | 否 | 最多返回节点数 |
| model | any | 否 | 仅包含此 Oxidized 型号的节点(例如 'IOS'、'JunOS'、'RouterOS');内置型号名称不区分大小写 |
| offset | integer | 否 | 要跳过的匹配节点数量 |
| status | any | 否 | 仅包含上次运行状态为此值的节点(例如 'success'、'no_connection'、'fail'、'never') |
| name_contains | any | 否 | 仅包含名称、全名或 IP 中包含此文本的节点(不区分大小写) |
详细介绍
Oxidized MCP 服务是一个基于 Python 的 Model Context Protocol(MCP)服务,可让 AI 助手访问 Oxidized,这是一款网络设备配置备份工具。它通过 oxidized-web REST API 与其通信,可列出设备、检查备份健康状况、读取和搜索设备配置、浏览配置历史并查看差异,以及将备份加入队列。它支持只读模式、基于标签的工具筛选,以及适用于 HTTP 传输的 Bearer 令牌身份验证。
✨ 功能
核心功能
- 按组、型号和最近备份状态列出并筛选受管理设备
- 通过部分名称、完整名称(
group/name)或 IP 地址查找设备 - 汇总备份健康状况:备份失败、从未备份的设备以及过期备份
- 读取任意设备最近一次备份的配置;大型配置支持分页
- 使用正则表达式或字面文本搜索所有配置,并返回匹配行及上下文
配置历史
- 列出设备存储的配置版本(git 输出)
- 读取设备在任意版本下的配置(完整 oid 或短前缀)
- 比较两个版本,或仅查看最近的更改,并以统一差异格式显示
操作
- 立即将设备备份加入队列;可选提供提交消息和作者
- 从来源重新加载节点列表(router.db、SQL、HTTP 等)
- 只读模式会隐藏所有操作,便于安全监控
高级功能
- 默认会在工具输出中隐藏节点变量(通常包含设备凭据)
- 为反向代理后的 oxidized-web 提供 HTTP Basic 身份验证
- 速率限制、SSL/TLS 验证和可配置超时
- 基于标签的工具筛选,以及可选的工具搜索转换
- 适用于 HTTP 传输的 Bearer 令牌身份验证
🚀 安装
前提条件
- Python 3.11 至 3.15
- 正在运行且已启用 oxidized-web 的 Oxidized 实例
- 若要查看版本历史和差异:Oxidized 的
git(或gitcrypt)输出
从 PyPI 快速安装
开始使用最简单的方法是从 PyPI 安装:
# Using UV (recommended)
uvx oxidized-mcp
# Or using pip
pip install oxidized-mcp
运行服务前,请记得为 Oxidized 实例配置环境变量:
# Create environment configuration
export OXIDIZED_URL=http://localhost:8888
详情请访问:https://pypi.org/project/oxidized-mcp/
从源代码安装
- 克隆仓库:
git clone https://github.com/mhajder/oxidized-mcp.git
cd oxidized-mcp
- 安装依赖项:
# Using UV (recommended)
uv sync
# Or using pip
pip install -e .
- 配置环境变量:
cp .env.example .env
# Edit .env with your Oxidized URL (and Basic auth credentials if needed)
- 运行服务:
# Using UV (recommended)
uv run oxidized-mcp
# Or using the installed command directly
oxidized-mcp
开发环境设置
如需使用其他工具进行开发:
# Clone and install with development dependencies
git clone https://github.com/mhajder/oxidized-mcp.git
cd oxidized-mcp
uv sync --group dev
# Run tests
uv run pytest
# Run with coverage
uv run pytest --cov=src/
# Run linting and formatting
uv run ruff check .
uv run ruff format .
# Run type checking
uv run ty check .
# Setup prek hooks
uv run prek install
🔧 配置
环境变量
# Oxidized Connection Details
# Base URL of oxidized-web (include the url_prefix if one is configured).
# A query string (?...) is rejected; use the Basic auth settings below, or
# percent-encode special characters in credentials put in the URL.
OXIDIZED_URL=http://localhost:8888
# Optional HTTP Basic auth, e.g. for a reverse proxy in front of oxidized-web
# OXIDIZED_USERNAME=
# OXIDIZED_PASSWORD=
# SSL Configuration
OXIDIZED_VERIFY_SSL=true
OXIDIZED_TIMEOUT=30
# Timeout for search_configs (oxidized-web reads every configuration)
OXIDIZED_SEARCH_TIMEOUT=300
# Redact node vars (often device credentials) in tool output
OXIDIZED_REDACT_NODE_VARS=true
# Read-Only Mode
# Set READ_ONLY_MODE true to disable operations (trigger_node_backup, reload_nodes)
READ_ONLY_MODE=false
# Disabled Tags
# Comma-separated list of tags to disable tools for (empty by default)
# Example: OXIDIZED_DISABLED_TAGS=search,diff
OXIDIZED_DISABLED_TAGS=
# Logging Configuration
LOG_LEVEL=INFO
# Rate Limiting (requests per minute)
# Set RATE_LIMIT_ENABLED true to enable rate limiting
RATE_LIMIT_ENABLED=false
RATE_LIMIT_MAX_REQUESTS=60
RATE_LIMIT_WINDOW_MINUTES=1
# Tool Search Transform (Optional)
# Set TOOL_SEARCH_ENABLED true to replace full tool listings with search_tools + call_tool
TOOL_SEARCH_ENABLED=false
# Search strategy: bm25 (natural language) or regex (pattern match)
TOOL_SEARCH_STRATEGY=bm25
# Maximum number of tools returned by search_tools
TOOL_SEARCH_MAX_RESULTS=5
# Sentry Error Tracking (Optional)
# Set SENTRY_DSN to enable error tracking and performance monitoring
# SENTRY_DSN=https://[email protected]/6789
# Optional Sentry configuration
# SENTRY_TRACES_SAMPLE_RATE=1.0
# SENTRY_SEND_DEFAULT_PII=false
# SENTRY_ENVIRONMENT=production
# SENTRY_RELEASE=1.2.3
# SENTRY_PROFILE_SESSION_SAMPLE_RATE=1.0
# SENTRY_PROFILE_LIFECYCLE=trace
# SENTRY_ENABLE_LOGS=true
# MCP Transport Configuration
# Transport type: 'stdio' (default), 'sse' (Server-Sent Events), or 'http' (HTTP Streamable)
# 'streamable-http' is accepted as an alias for 'http'. Any other value stops
# the server at startup.
# MCP_TRANSPORT=stdio
# HTTP Transport Settings (used when MCP_TRANSPORT=sse or MCP_TRANSPORT=http)
# Host to bind the HTTP server (default: 127.0.0.1)
# MCP_HTTP_HOST=127.0.0.1
# Port to bind the HTTP server (default: 8000)
# MCP_HTTP_PORT=8000
# Optional bearer token for authentication (leave empty for no auth)
# MCP_HTTP_BEARER_TOKEN=
Sentry 错误跟踪与监控(可选)
该服务可选支持 Sentry,用于错误跟踪、性能监控和调试。Sentry 集成完全可选,仅在完成配置后才会初始化。
安装
如需启用 Sentry 监控,请安装可选依赖:
# Using UV (recommended)
uv sync --extra sentry
配置
在 .env 文件中设置 SENTRY_DSN 环境变量以启用 Sentry:
# Required: Sentry DSN for your project
SENTRY_DSN=https://[email protected]/6789
# Optional: Performance monitoring sample rate (0.0-1.0, default: 1.0)
SENTRY_TRACES_SAMPLE_RATE=1.0
# Optional: Include personally identifiable information (default: false).
# Keep it off: with the MCP integration it records tool results, which are
# full device configurations including secrets.
SENTRY_SEND_DEFAULT_PII=false
# Optional: Environment name (e.g., "production", "staging")
SENTRY_ENVIRONMENT=production
# Optional: Release version (auto-detected from package if not set)
SENTRY_RELEASE=1.2.2
# Optional: Profiling - continuous profiling sample rate (0.0-1.0, default: 1.0)
SENTRY_PROFILE_SESSION_SAMPLE_RATE=1.0
# Optional: Profiling - lifecycle mode for profiling (default: "trace")
# Options: "all", "continuation", "trace"
SENTRY_PROFILE_LIFECYCLE=trace
# Optional: Enable log capture as breadcrumbs and events (default: true)
SENTRY_ENABLE_LOGS=true
功能
启用后,Sentry 会自动捕获:
- 异常与错误:包含完整上下文的所有未处理异常
- 性能指标:请求/响应时间和跟踪记录
- MCP 集成:详细的 MCP 服务活动和交互
- 日志与面包屑:用于调试的应用日志和事件轨迹
- 上下文数据:环境、客户端信息和请求参数
获取 Sentry DSN
- 在 sentry.io 创建免费账户
- 创建一个新的 Python 项目
- 从项目设置中复制 DSN
- 将其设置在
.env文件中
禁用 Sentry
Sentry 完全可选。如果不设置 SENTRY_DSN,服务将正常运行,不会集成 Sentry,也不会收集任何监控数据。
🧰 可用工具
节点工具
list_nodes:列出设备,可按组、型号、上次运行状态、名称/IP 子字符串筛选,并支持分页;组和型号由 Oxidized 自行筛选(/nodes/<group|model>/<value>.json),因此不会完整传输大型设备清单get_node:获取单台设备的详细信息和最近一次备份运行情况(接受名称或 IP)find_nodes:按部分名称、完整名称或 IP 查找设备,优先返回精确匹配项get_backup_stats:备份健康状况摘要——按状态、组和型号统计数量,提供成功率、失败/从未备份/备份过期的设备信息;也可仅针对某个组或型号
配置工具
get_node_config:获取设备最近一次备份的配置(按名称或 IP),并按行分页(offset/max_lines)search_configs:在所有配置中搜索正则表达式或字面文本;返回匹配行及行号,并可选包含上下文
版本历史工具
需要使用 Oxidized 的 git 或 gitcrypt 输出。
list_node_versions:列出存储的配置版本(oid、日期、作者、消息),按时间从新到旧排列get_node_version:获取指定版本的配置(完整 oid 或唯一前缀),并按行分页diff_node_versions:比较两个版本并生成统一差异;默认比较最近一次变更
操作工具
当 READ_ONLY_MODE=true 时隐藏。
trigger_node_backup:将设备的即时备份加入队列;可选记录提交消息和作者reload_nodes:从数据源重新加载整个节点列表(不提供逐节点重新加载:oxidized-web 的/reload?node=X会用匹配的节点替换整个内存中的节点列表)
🔒 安全与防护功能
只读模式
服务支持只读模式,可禁用所有写操作,以便安全地进行监控:
READ_ONLY_MODE=true
启用后,只会公开标记为 read-only 的工具:trigger_node_backup 和 reload_nodes 会被隐藏,而所有节点、配置和历史工具仍可用。
基于标签筛选工具
可通过设置要禁用的标签来停用特定类别的工具:
OXIDIZED_DISABLED_TAGS=search,diff
可用标签包括:
node- 节点列表和查询工具(以及备份/重新加载操作)stats- 备份健康统计信息config- 配置读取工具search- 配置搜索和节点搜索工具version- 版本历史工具diff- 版本差异工具backup- 备份触发操作reload- 节点列表重新加载操作read-only- 所有不会更改 Oxidized 状态的工具
速率限制
服务器支持速率限制,以控制 API 使用量并防止滥用。启用后,会使用滑动窗口算法按客户端限制请求。
在 .env 文件中设置以下环境变量即可启用速率限制:
RATE_LIMIT_ENABLED=true
RATE_LIMIT_MAX_REQUESTS=60 # Maximum requests allowed per window
RATE_LIMIT_WINDOW_MINUTES=1 # Window size in minutes
如果将 RATE_LIMIT_ENABLED 设为 true,服务器将应用速率限制中间件。根据环境需要调整 RATE_LIMIT_MAX_REQUESTS 和 RATE_LIMIT_WINDOW_MINUTES。启用速率限制时,两者都必须至少为 1;关闭时则不会读取这两个变量。
大型工具集的工具搜索
对于包含大量工具的服务,FastMCP 工具搜索可以减少提示词大小。
启用后,list_tools 会返回两个合成工具:
search_tools:查找匹配的工具并返回其完整架构call_tool:按名称执行已发现的任意工具
使用以下设置启用:
TOOL_SEARCH_ENABLED=true
TOOL_SEARCH_STRATEGY=bm25 # bm25 or regex
TOOL_SEARCH_MAX_RESULTS=8 # optional, default is 5
bm25 支持自然语言查询,而 regex 使用 pattern
输入进行确定性匹配。
启用工具搜索后,任何其他 TOOL_SEARCH_STRATEGY 值都会导致服务器在启动时停止,且 TOOL_SEARCH_MAX_RESULTS 必须至少为 1。
工具搜索遵循现有的可见性控制(只读模式和 已禁用的标签)。
SSL/TLS 配置
服务器支持 SSL 证书验证和自定义超时设置:
OXIDIZED_VERIFY_SSL=true # Enable SSL certificate verification
OXIDIZED_TIMEOUT=30 # Request timeout in seconds
上游身份验证
oxidized-web 本身不提供身份验证,通常会通过带有 HTTP Basic 身份验证的反向代理发布。设置这两个变量,即可在每个请求中发送 Basic 身份验证信息:
OXIDIZED_USERNAME=oxidized
OXIDIZED_PASSWORD=your-password
节点变量脱敏
来自 Oxidized 源(router.db、SQL、HTTP)的节点变量通常包含各设备的凭据,而 oxidized-web 会从 /nodes.json 返回未脱敏的变量。除非选择退出,否则服务器会将每个变量值替换为 <redacted>(保留键名):
OXIDIZED_REDACT_NODE_VARS=false
传输配置
服务器支持多种传输协议,以适用于不同的部署场景:
STDIO 传输(默认)
默认传输使用标准输入/输出进行通信。这非常适合本地使用,以及与通过 stdin/stdout 通信的工具集成:
MCP_TRANSPORT=stdio
HTTP SSE 传输(服务器发送事件)
对于基于网络的部署,可以使用 HTTP 和服务器发送事件。这使得 MCP 服务可通过 HTTP 访问,并支持实时流式传输:
MCP_TRANSPORT=sse
MCP_HTTP_HOST=127.0.0.1 # Localhost
MCP_HTTP_PORT=8000 # Port to listen on
MCP_HTTP_BEARER_TOKEN=your-secret-token # Optional authentication token
使用带有 bearer token 的 SSE 传输时,客户端必须在请求中包含该 token:
curl -H "Authorization: Bearer your-secret-token" http://localhost:8000/sse
HTTP Streamable 传输
HTTP Streamable 传输通过 HTTP 实现通信,并支持请求/响应流式传输。这非常适合 Web 集成,以及需要 HTTP 端点的工具:
MCP_TRANSPORT=http
MCP_HTTP_HOST=127.0.0.1 # Localhost
MCP_HTTP_PORT=8000 # Port to listen on
MCP_HTTP_BEARER_TOKEN=your-secret-token # Optional authentication token
使用带有 bearer token 的 Streamable 传输时:
curl -H "Authorization: Bearer your-secret-token" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
http://localhost:8000/mcp
注意:HTTP 传输需要正确的 JSON-RPC 格式,其中包含 jsonrpc 和 id 字段。某些操作还可能需要服务器先进行会话初始化。
健康检查端点
两种 HTTP 传输(sse 和 http)都提供 GET /health,服务器正在处理请求时会返回 200 ok。
该端点无需 bearer token,也不会联系 Oxidized,因此 Oxidized 中断不会导致 MCP 服务被标记为不健康。
Docker 镜像的 HEALTHCHECK 使用此端点:
curl http://localhost:8000/health
📝 Oxidized 注意事项
- 版本历史(
list_node_versions、get_node_version、diff_node_versions)需要使用git或gitcrypt输出。使用file输出时,Oxidized 不会报告任何版本。 - 分组:节点名称应保持唯一。工具接受可选的
group参数以区分节点;省略该参数时,get_node_config和历史工具会自动查找分组(使用 git 输出的single_repo时,分组会成为存储路径的一部分,因此 oxidized-web 要求提供该参数)。没有分组的节点会显示为default组,传回default时则会视为“无分组”。search_configs与list_nodes使用相同方式筛选分组(精确匹配)。trigger_node_backup不接受分组,因为 Oxidized 仅按节点名称或 IP 将备份加入队列。 - 筛选大型清单:
list_nodes/get_backup_stats中的group和model由 Oxidized 本身筛选。分组必须完全匹配(区分大小写,与list_nodes显示的一致),因此拼错分组会返回空结果,而不是下载整个清单。内置模型名称不区分大小写(ios和IOSXE别名都会作为IOS发送,名称来自 Oxidized 的模型目录);自定义模型必须拼写完全正确。任一筛选条件都不会回退到下载整个清单。 - 搜索分两步进行:oxidized-web 的
conf_search会查找匹配的设备(它会在服务端读取每个配置,因此大型部署中可能较慢),然后只获取这些设备的配置以提取匹配行。max_nodes限制获取数量;从未备份过的节点(其占位文本可能匹配)会被跳过,且不计入数量。服务端步骤使用OXIDIZED_SEARCH_TIMEOUT(默认 300 s),而不是OXIDIZED_TIMEOUT。模式会在服务端逐行作为 Ruby 正则表达式运行,在本地逐行作为 Python 正则表达式运行,因此请使用常见语法。 - 备份为异步操作:
trigger_node_backup会将设备移至队列首位。请通过get_node检查结果。 - 错误:对于未知节点名称,oxidized-web 会返回 HTTP 500。在
RACK_ENV=production环境下运行时,具体原因会被隐藏,因此节点路由返回 500 时会附带提示,说明节点名称可能未知。
🐳 使用 Docker
GitHub Packages 上提供了 Docker 镜像,便于部署。
docker pull ghcr.io/mhajder/oxidized-mcp:latest
docker run --rm -p 8000:8000 \
-e OXIDIZED_URL=http://oxidized:8888 \
-e MCP_HTTP_BEARER_TOKEN=your-secret-token \
ghcr.io/mhajder/oxidized-mcp:latest
该镜像默认使用端口 8000 上的 HTTP Streamable 传输(http://localhost:8000/mcp)。
🤝 参与贡献
欢迎贡献。请参阅 CONTRIBUTING.md,了解开发环境设置、检查项和提交消息格式;报告 Bug 和功能请求时,请使用问题模板。
发现安全问题?请按照 SECURITY.md 中的说明私下报告。
📜 许可证
MIT License——详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。