Nginx UI 的 MCP 模块:为 AI Agent 提供 Nginx 配置管理与服务控制接口
【免费下载链接】nginx-uiYet another WebUI for Nginx项目地址: https://gitcode.com/gh_mirrors/ngi/nginx-ui
MCP(Model Context Protocol,模型上下文协议)是 Nginx UI 提供的一组特殊接口,让 AI Agent、LLM 与自动化脚本能够直接读写 Nginx 配置文件、执行 reload/restart 等运维操作并获取服务运行状态。本文以 docs/guide/mcp.md 为主体,结合 mcp/ 目录下的 Go 实现,完整讲解 MCP 模块的接口、认证、工具清单与调用方式,帮助读者掌握如何让 AI 安全地管理 Nginx。
MCP 模块整体概览
从官方文档与源码结构来看,Nginx UI 的 MCP 模块分为两大功能域:
- 配置文件管理:围绕 Nginx 配置文件的读取、创建、修改、重命名、目录创建、历史记录与启用等操作,详见 docs/guide/mcp-config.md;
- Nginx 服务管理:查询 Nginx 状态、平滑重载配置、重启服务,详见 docs/guide/mcp-nginx.md。
模块由mcp目录组织,入口 mcp/register.go 在初始化时依次调用config.Init()与nginx.Init()完成工具注册;两个子目录分别对应上述两大功能域。MCP 服务端本体位于 internal/mcp/server.go,它基于mark3labs/mcp-go构建了一个名为"Nginx"、版本"1.0.0"的 MCP Server,并启用了资源能力(Resource Capabilities)与日志、恢复等特性。
接口与传输方式
MCP 接口挂载在/mcp路径,并通过SSE(Server-Sent Events)提供流式传输。路由注册见 mcp/router.go:
/mcp—— SSE 主端点;/mcp_message—— 客户端向服务器发送消息的端点。
两个端点都依次经过IPWhiteList(IP 白名单)、mcpAuthRequired(认证)与authorizeMCPToolRequest(工具级权限分类)三道中间件,最终交由internalmcp.ServeHTTP处理。SSE 端点与消息端点的具体配置定义在 internal/mcp/server.go 中。
认证与访问令牌
MCP 接口不对外开放,调用方必须先持有有效凭据。官方文档要求在Preferences > Access Tokens(偏好设置 > 访问令牌)中创建服务令牌(Service Token),并授予客户端所需的最小 MCP 作用域:
mcp:read:允许访问 Resources 与只读工具;mcp:write:允许调用变更类(mutating)工具,且包含mcp:read的全部权限。
作用域常量定义在 model/mcp_service_token.go,前端创建入口为 app/src/views/preference/tabs/AccessTokens.vue,对应的 API 封装在 app/src/api/service_token.ts 中(支持创建、列出、轮换与撤销,令牌名称最长 64 字符)。
令牌格式与传递方式
服务令牌以nui_pat_前缀开头,格式为nui_pat_<publicID>_<secret>,通过Authorization请求头发送:
Authorization: Bearer nui_pat_...从 internal/mcp/service_token.go 的实现可以确认:publicID 为 12 字节随机数经 base64url 编码(16 个字符),secret 为 32 字节随机数编码(43 个字符),由 HMAC-SHA256 派生验证器(verifier)校验,验证密钥通过 HKDF 从CryptoSettings.Secret与NodeSettings.InstanceID派生。令牌验证时还会检查revoked_at撤销标记与expires_at过期时间,并更新last_used_at(service_token.go)。
安全要点(来自文档与实现):
- 令牌只显示一次:创建后立即保存到密码管理器,并尽可能设置过期时间;
- 拒绝 URL 查询参数传凭据:避免令牌通过日志与浏览器历史泄露,认证中间件会直接拒绝携带
node_secret查询参数的请求(mcp/router.go); - 除服务令牌外,
mcpAuthRequired还兼容普通用户令牌(短令牌/长令牌)以及旧式X-Node-Secret头认证,详见 mcp/router.go。
工具级作用域控制
authorizeMCPToolRequest中间件会根据请求体中的工具名动态判定所需作用域(mcp/router.go):
- 只读工具集
readOnlyMCPTools:nginx_config_base_path、nginx_config_get、nginx_config_history、nginx_config_list、nginx_status; - 写工具集
writeMCPTools:nginx_config_add、nginx_config_enable、nginx_config_mkdir、nginx_config_modify、nginx_config_rename、reload_nginx、restart_nginx。
classifyMCPRequest的默认策略是fail-closed(失败即关闭):无法识别的新增工具一律按写作用域处理(mcp/router.go),确保新加入的变更类工具在明确归类前始终处于写权限与安全会话检查的保护之下。当使用写工具且请求由服务令牌认证时,还会额外校验令牌是否具备mcp:write作用域。
Resources 与 Tools 两种能力
按文档定义,MCP 向 AI 客户端暴露两类能力:
- Resources(资源):只读信息,例如 Nginx 的运行状态。服务端在创建时启用了资源能力(internal/mcp/server.go),并且实现中预留了
Resource注册结构(server.go); - Tools(工具):可执行操作,例如重启 Nginx、修改配置文件。
值得一提的实现细节是 internal/mcp/context.go:IsServiceTokenRequest用于识别当前请求是否由服务令牌认证,处理器可据此在返回资源时剔除凭据类敏感字段,而交互式管理员仍能看到完整响应。
配置文件管理工具(9 个)
配置文件管理子模块注册了 9 个工具(mcp/config/register.go),全部以nginx_config_为前缀。重要约定:所有路径操作都相对于 Nginx 配置根路径(base path),工具内部通过config.ResolveConfPath/config.ResolveAbsoluteOrRelativeConfPath解析并做路径包含校验,防止越出配置目录(如config_enable.go中的IsUnderDirectory检查)。
nginx_config_base_path —— 获取配置根路径
无参数,返回 Nginx 配置根目录(mcp/config/config_base_path.go):
{ "tool": "nginx_config_base_path", "parameters": {} }示例响应:
{ "base_path": "/etc/nginx" }nginx_config_list —— 列出配置文件
参数:relative_path(相对路径)、filter_by_name(按名称过滤,可选)。实现调用config.GetConfigList并对文件名做子串匹配过滤(mcp/config/config_list.go):
{ "tool": "nginx_config_list", "parameters": { "relative_path": "/etc/nginx/conf.d" } }示例响应:
{ "files": [ { "name": "default.conf", "is_dir": false, "path": "/etc/nginx/conf.d/default.conf" }, { "name": "example.conf", "is_dir": false, "path": "/etc/nginx/conf.d/example.conf" } ] }nginx_config_get —— 读取配置文件内容
参数:relative_path(必填)。返回内容的同时附带文件元数据与集群同步设置(mcp/config/config_get.go):
{ "tool": "nginx_config_get", "parameters": { "path": "/etc/nginx/conf.d/default.conf" } }nginx_config_add —— 新增配置文件
参数:name(必填)、content(必填)、base_dir(基础目录)、overwrite(是否覆盖已存在文件)、sync_node_ids(同步到的节点 ID 数组)。实现流程值得注意(mcp/config/config_add.go):
- 对目标路径与内容执行语法校验
ValidateConfigFile; - 若文件已存在且
overwrite=false,返回ErrFileAlreadyExists; - 持有 apply 锁,通过
config.FileTransaction写入文件,随后执行写入 → 配置测试(nginx -t)→ reload的完整链路;测试或重载失败会触发回滚(RollbackError+tx.Rollback),被 Nginx 拒绝的文件绝不会残留在磁盘上; - 成功后写数据库并调用
config.SyncToRemoteServer向集群节点同步。
nginx_config_modify —— 修改已有配置文件
参数:relative_path(必填)、content(必填)、sync_overwrite(同步时是否覆盖)、sync_node_ids。修改前同样执行语法校验,并通过config.Save落盘、自动生成历史备份(mcp/config/config_modify.go):
{ "tool": "nginx_config_modify", "parameters": { "path": "/etc/nginx/conf.d/default.conf", "content": "server {\n listen 80;\n server_name example.com;\n location / {\n root /usr/share/nginx/html;\n index index.html;\n }\n}" } }nginx_config_rename —— 重命名文件或目录
参数:base_path、orig_name(必填)、new_name(必填)、sync_node_ids。重命名会同步更新配置表(configs)、备份表(config_backups)以及 LLM 会话表(llm_sessions)中的记录;若重命名的是目录,则批量更新该目录下所有记录(mcp/config/config_rename.go)。新旧名称相同时直接返回"无需变更"。
nginx_config_mkdir —— 创建配置目录
参数:base_path、folder_name(必填),以 0755 权限创建目录(mcp/config/config_mkdir.go)。
nginx_config_history —— 查询配置变更历史
参数:filepath(必填)。从config_backups表按文件路径查询,按 ID 倒序返回(mcp/config/config_history.go)。配置文件的每次修改都会自动备份,可借此回滚——对应文档"配置修改自动备份,可通过历史功能恢复"的说明。
nginx_config_enable —— 启用配置(创建软链接)
参数:name(必填)、base_dir(源目录,默认sites-available)、overwrite(是否覆盖已存在的启用配置)。实现(mcp/config/config_enable.go)在sites-enabled下为sites-available中的文件创建符号链接,随后执行nginx -t配置测试与 reload;任何一步失败都会回滚删除刚创建的软链接,避免无效配置在下次启动时破坏 Nginx:
{ "tool": "nginx_config_enable", "parameters": { "name": "my-site.conf", "base_dir": "sites-available", "overwrite": false } }示例响应:
{ "status": "success", "message": "Site enabled and Nginx reloaded successfully", "source": "/etc/nginx/sites-available/my-site.conf", "destination": "/etc/nginx/sites-enabled/my-site.conf" }Nginx 服务管理工具(3 个)
服务管理子模块注册了 3 个工具(mcp/nginx/register.go),让 AI 无需命令行即可完成服务级操作。
nginx_status —— 查询运行状态
无参数,返回running(是否运行)、message(最近一次控制命令输出)、level(日志级别)三个字段(mcp/nginx/status.go)。当上次执行结果出错时直接返回错误结果。
reload_nginx —— 平滑重载配置
执行 Nginx 平滑重载(graceful reload),返回命令输出(mcp/nginx/reload.go)。
restart_nginx —— 重启 Nginx 服务
执行优雅重启(graceful restart),同样返回命令输出;出错时返回ToolResultError(mcp/nginx/restart.go)。
典型使用场景
按官方文档,MCP 模块主要服务于以下四类场景:
- AI 驱动的 Nginx 配置管理:让 LLM 直接读取、校验、修改站点配置,再通过 reload 生效;
- 与自动化运维工具集成:把 Nginx 的配置与状态管理能力暴露给 Ansible 等自动化链路;
- 第三方系统对接 Nginx UI:外部系统通过标准 MCP 协议获得统一的配置与服务控制入口;
- 为自动化脚本提供机器可读 API:以 JSON 请求/响应替代脆弱的命令行解析。
安全与可靠性设计小结
结合文档与源码,MCP 模块在安全与可靠性上有几个值得关注的设计:
- 最小权限:令牌作用域区分
mcp:read/mcp:write,写工具默认需要写作用域与安全会话检查; - fail-closed 分类:未识别的工具名默认按写作用域处理,防止新工具绕过权限(mcp/router.go);
- 写后验证与回滚:新增、启用配置都遵循"写入 → nginx -t → reload → 失败回滚"的事务式流程,杜绝坏配置存活;
- 凭据保护:令牌仅通过
Authorization头传递,拒绝 URL 参数携带凭据;服务令牌实现采用 HMAC 验证器并支持轮换、撤销与过期; - 测试保障:路由层测试验证了
/mcp与/mcp_message在无认证时返回 403(mcp/router_test.go),internal/mcp/service_token_test.go与 mcp/config/config_validation_test.go 分别覆盖令牌与配置校验逻辑。
对开发者而言,接入 Nginx UI 的 MCP 只需三步:在Preferences > Access Tokens创建带最小作用域的nui_pat_令牌 → 在 MCP 客户端中把 Server 地址配置为http(s)://<host>/mcp并设置Authorization: Bearer nui_pat_...→ 即可通过 SSE 会话调用上述 12 个工具完成 Nginx 的配置管理与服务控制。
【免费下载链接】nginx-uiYet another WebUI for Nginx项目地址: https://gitcode.com/gh_mirrors/ngi/nginx-ui
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考