Skip to main content
Glama

platform-mcp

用于 sonar-prod 集群基础设施服务的 MCP 服务器 —— Argo CD、Vault 和 Keycloak —— 支持 SSO 登录(Argo/Vault 用 GitLab,Keycloak 用 FreeIPA)。

为什么

编辑器中的代理需要访问 Argo CD、Vault 和 Keycloak,但不能给它服务账号:审计中会出现一个通用账号而不是具体的人,而且权限会比任何特定开发者的权限都宽。

这个包安装在本地,通过浏览器进行常规 SSO 登录。之后它以登录用户的名义执行命令:审计日志中可以看到真实登录名,权限恰好是群组成员身份所赋予的。

每个服务只有一个工具 —— argocd_execvault_execkeycloak_exec,接受命令行参数。底层是官方 CLI(argocdvaultkcadm),所以它们能做的这里都能做。新增服务只需实现一个接口。

Related MCP server: mcp-read-only-argocd

安装

第 1 步:访问包仓库

只需要做一次,对所有下面的方式都适用:包放在这个 GitLab 项目的 npm registry 中,而不是公共 npm。获取一个具有 read_package_registry 权限的令牌(个人访问令牌或项目的 deploy token),然后添加到 ~/.npmrc

@sonar:registry=https://git.sonar-corp.ru/api/v4/projects/98/packages/npm/
//git.sonar-corp.ru/api/v4/projects/98/packages/npm/:_authToken=<ваш gitlab токен>

第 2 步:连接到编辑器

Claude Code 和 Cursor —— 用插件。 仓库本身就是插件目录,所以两条命令就够了:

/plugin marketplace add https://github.com/K-manankov/platform-mcp.git
/plugin install platform-mcp

地址是 GitHub 而不是 GitLab,这不是笔误 —— 参见为什么插件目录在 GitHub 上

Argo CD、Vault 和 Keycloak 的地址已经写在插件里了 —— 无需配置。更新会自动到达:插件通过 npx -y 启动服务器,也就是说总是最新发布的版本。更新插件本身 —— /plugin marketplace update

Claude Desktop 不安装这种格式的插件,所以那里需要手动配置。全局安装包:

npm install -g @sonar/platform-mcp

然后添加到 claude_desktop_config.json(Settings → Developer → Edit Config)。node 和服务器路径必须是绝对路径:macOS 上的 GUI 应用不继承 shell 的 PATH。用 which nodewhich platform-mcp 命令查看自己的路径:

{
  "mcpServers": {
    "platform": {
      "command": "/opt/homebrew/bin/node",
      "args": ["/opt/homebrew/lib/node_modules/@sonar/platform-mcp/dist/index.js"],
      "env": {
        "ARGOCD_BASE_URL": "https://argocd.infra.sonar-corp.ru",
        "VAULT_ADDR": "https://vault.infra.sonar-corp.ru",
        "KEYCLOAK_BASE_URL": "https://auth.infra.sonar-corp.ru",
        "PLATFORM_MCP_INSECURE": "true"
      }
    }
  }
}

Argo CD、Vault 和 Keycloak 在任何一个方案中都不需要单独安装:服务器会在首次调用时自动下载所需版本的 CLI(参见CLI 从哪里来)。kcadm 需要机器上有 Java 17+

为什么插件目录在 GitHub 上

Claude Desktop 只从 GitHub 连接插件目录。另外,我们的 GitLab 在内网中,外部根本无法访问,所以它连 git.sonar-corp.ru 都够不到。

因此源代码留在 GitLab,而在 github.com/K-manankov/platform-mcp 配置了受保护分支的镜像。受保护的只有一个分支 —— main,每次推送时它都会同步到 GitHub。没有反向同步:修改只在 GitLab 中进行,GitHub 副本只是为了安装插件而存在。

镜像本身不会泄露任何多余信息 —— 那里是同一个公共 npm 包和内部服务地址,而这些地址反正只能从内网解析。仓库中没有也不应该有密钥:访问令牌由服务器保存在 ~/.config/platform-mcp/ 中,包仓库令牌由每个人自己在 ~/.npmrc 中配置。

修改后更新已安装的插件:

/plugin marketplace update sonar-infra
/plugin update platform-mcp

登录

需要 VPN:argocd.infra.sonar-corp.ruvault.infra.sonar-corp.ruauth.infra.sonar-corp.ru 这些名称只能从内网解析。从外部它们会被公共通配符 *.infra.sonar-corp.ru 捕获,请求会静默地跑到别处 —— 检查 dig +short argocd.infra.sonar-corp.ru 应该返回 192.168.88.106

最简单的登录方式就是直接在对话中:让代理调用 argocd_loginvault_loginkeycloak_login,打开给出的链接并完成登录。无需重启编辑器。

如果包已全局安装,也可以从终端做同样的事:

export ARGOCD_BASE_URL=https://argocd.infra.sonar-corp.ru
export VAULT_ADDR=https://vault.infra.sonar-corp.ru
export KEYCLOAK_BASE_URL=https://auth.infra.sonar-corp.ru
export PLATFORM_MCP_INSECURE=true   # пока нет настоящих сертификатов, см. TLS

platform-mcp login             # во все настроенные сервисы подряд
platform-mcp login keycloak    # только в один

浏览器会打开:Argo CD 和 Vault 是 GitLab SSO,Keycloak 是 master realm 中的 FreeIPA(客户端 platform-mcp-cli,参见 infra 中的 bootstrap)。会话会存放在 ~/.config/platform-mcp/ 中,权限为 0600,对所有编辑器共享:登录一次,处处可用。

在 SSH 或 devcontainer 中(没有浏览器):

platform-mcp login --no-browser

需要在自己机器上打开输出中的链接;此时端口 8085(Argo CD)、8250(Vault)或 8280(Keycloak)必须转发到运行命令的主机上。

以 Vault 管理员身份登录

常规登录进入 oidc 挂载点,策略根据子群组成员身份授予。存储库的完整权限位于单独的 oidc-admin 挂载中,只有 infra/k8s 组的 Owner 才能获得 —— 原因在 platform/vault-config/40-groups.yaml 中有描述:

VAULT_OIDC_MOUNT=oidc-admin platform-mcp login vault

配置

不需要修改任何东西 —— 地址已经写在插件里了。

Cursor. Plugins → Configure 中的 platform-mcp:Argo CD、Vault 和 Keycloak 的 URL、PLATFORM_MCP_INSECURE,以及 Vault OIDC 挂载(oidc —— 常规登录,oidc-admin —— infra/k8s Owner 的完整权限)。默认值与 sonar-prod 集群一致。

Claude Code 和手动配置。 如果需要不同的设置(自己的实例、oidc-admin、自定义禁止项),可以在编辑器配置中用环境变量覆盖,或者放到 ~/.config/platform-mcp/config.json 中:

{
  "argocdUrl": "https://argocd.infra.sonar-corp.ru",
  "vaultUrl": "https://vault.infra.sonar-corp.ru",
  "keycloakUrl": "https://auth.infra.sonar-corp.ru",
  "vaultOidcMount": "oidc",
  "policy": {
    "requireConfirmation": true,
    "denyVaultPaths": ["kv/infra/"]
  }
}

只需设置至少一个服务的地址 —— 其余服务只是不会出现在工具列表中。

如果会话不存在或已过期,工具会返回清晰的错误,代理可以直接在对话中调用 argocd_login / vault_login / keycloak_login —— 无需重启编辑器。这些工具会打开浏览器并立即返回链接,不等待登录完成:人走 SSO 流程需要几分钟,而 MCP 客户端的请求超时通常只有 60 秒。结果通过单独的 *_auth_status 调用检查。

命令

platform-mcp                    # MCP-сервер поверх stdio (так его запускает редактор)
platform-mcp login [сервис]     # интерактивный вход, --no-browser для headless
platform-mcp status [сервис]    # кто вошёл и до какого момента действует токен
platform-mcp logout [сервис]    # удалить сохранённую сессию

服务是 argocdvaultkeycloak;不带服务时命令应用于所有已配置的服务。

工具

每个服务:<服务>_exec<服务>_login<服务>_auth_status<服务>_logout

argocd_execvault_execkeycloak_exec 接受 args —— 命令行参数数组:

argocd_exec { "args": ["app", "list", "-o", "json"] }
argocd_exec { "args": ["app", "sync", "team-a-api"] }
vault_auth_status   # сначала: username, role, policies
vault_exec  { "args": ["token", "lookup"] }
vault_exec  { "args": ["kv", "list", "kv/teams"] }
vault_exec  { "args": ["kv", "get", "kv/teams/team-a/postgres"] }
keycloak_exec { "args": ["get", "realms"] }
keycloak_exec { "args": ["get", "users", "-r", "sonar-prod", "-q", "username=alice"] }

对于 Vault,从 vault_auth_status 开始:通过 policies 可以立即看出是否有 KV 访问权限。["token","lookup"] 是 CLI 的标准写法(不是 lookup-self)。普通 OIDC 用户的 sys/mounts 经常返回 403 —— 不要用它做发现。kv list 的 exit code 2 通常表示"为空或没有 list ACL",而不是"需要尝试其他挂载"。

参数始终以数组形式传递,绝不拼接成字符串:不经过 shell,所以参数中的 ;$(...) 只是普通文本。

地址和令牌由服务器注入。覆盖它们的标志(Argo CD 的 --server--auth-token--config--core;Vault 的 -address-tls-skip-verify;Keycloak 的 --server--config--no-config)被禁止 —— 否则子进程环境中的工作令牌可能被发送到其他主机。

危险操作的确认

只读命令立即执行。对于 Argo CD 和 Vault,其他所有操作都需要用户确认。

任何未被识别为只读的命令都被视为变更操作:动词列表是封闭的且偏向安全,所以不认识的命令会进入确认流程,而不是绕过它。

如果客户端支持 MCP elicitation,会出现常规对话框。如果不支持 —— 使用备用方案:第一次调用返回后果描述和一次性令牌,第二次调用携带该令牌执行操作。令牌有效期 5 分钟,并绑定到具体参数,所以"确认了一个,执行了另一个"不可能发生,代理也无法自行编造令牌。

Keycloak 是例外:变更立即执行,但会在给代理的响应中添加 warning —— 配置通过 CR/operator 管理,通过 kcadm 的手动修改可能会在 sync 时被 operator 覆盖。优先使用 Git 中的清单。

完全禁止的操作:

  • 登录和退出(argocd loginvault loginkcadm config …)—— 会话由服务器自己管理;

  • 不会结束的命令:vault server|agent|proxy|monitorargocd app logs --follow

  • argocd admin —— 管理 Argo CD 本身;

  • vault operator seal|step-down|init|rekey|generate-root|migrate —— 其中任何一个失败都会让整个存储库宕掉;

  • 修改 Argo CD 基础设施应用(argocdvaultkeycloakcert-manageringress-nginx、……):它们通过 merge request 从 Git 部署,而不是通过与代理的对话。可以读取它们。

列表可在 config.json 中配置(policy.denyApplicationspolicy.denyVaultPaths)。

这是防止代理出错的保护,而不是安全边界。infra/k8s 群组成员本来就是 Argo CD 管理员(g, infra/k8s, role:admin),可以通过 UI 做同样的事。真正限制权限只能通过 argocd-rbac-cm 中的角色分离和 Vault 策略实现。

密钥不会进入模型上下文

密钥值会从响应中剔除,而键名和元数据保留:

  • Vault —— kv get、KV 路径上的 readunwrap 中的值。kv listkv metadata getpolicy readsys/mounts 的响应不受影响:那里没有密钥,剔除会让它们变得无用。

  • Argo CD —— Secret 资源中的 datastringData,包括 Argo CD 以 JSON 字符串形式返回清单的 manifestliveStatetargetState 字段内部。base64 不是加密。

绕过路径已被封死:vault kv get -field=password 会绕过 JSON 直接打印裸值,而 -format=table 没有可剔除的对象 —— 两者都会被拒绝并附上说明。

如果确实需要在对话中看到值:

export PLATFORM_MCP_ALLOW_SECRET_VALUES=true

这是有意识的 opt-in:之后密钥内容会发送给模型提供商。默认情况下请直接在 Vault 中查看密钥。

另外:超过 100 KB 的响应会被截断并提示如何缩小请求范围,输出会被标记为来自集群的数据 —— 清单、注解和日志是人写的,代理不应执行其中遇到的指令。

argocd、vault 和 kcadm 从哪里来

服务器不是通过自写的 REST 客户端工作,而是通过官方 CLI:Argo CD 根本没有 Node 客户端,Vault 的官方客户端是 Go 库和同一个二进制文件,Keycloak Admin API 是发行版中的 kcadm。功能完整度与 CLI 相同。

不需要手动安装:

  1. 如果 argocd / vault / kcadmkcadm.sh)已经在 PATH 中 —— 使用现有的,不下载任何东西。

  2. 否则在首次调用时从官方发布页(github.com/argoproj/argo-cdreleases.hashicorp.comgithub.com/keycloak/keycloak)下载固定版本,适配当前平台。对于 Keycloak —— 整个发行版 zip(约 170 MB):kcadm 是 Java 脚本,而不是独立的 Go 二进制文件。

  3. 在解压和 chmod +x 之前校验校验和。 没有这一步,一切都只是"从网上下载并执行"。

  4. 文件放在 ~/.config/platform-mcp/bin/ 中并后续复用。

kcadm 需要机器上有 Java 17+PATH 中的 javaJAVA_HOME)。没有的话服务器会返回清晰的错误。

下载发生在首次使用时,而不是在 postinstall 中:postinstall 脚本被普遍禁用(npm ci --ignore-scripts),安装会静默地不完整。

版本固定在 src/config.ts 中,与集群中部署的版本一致(Argo CD v3.4.5、Vault 2.0.3、Keycloak 26.6.4)。集群升级时需要在这里同步更新。

TLS

argocd.infra.sonar-corp.ruvault.infra.sonar-corp.ruauth.infra.sonar-corp.ru 目前没有真正的证书:Ingress 中没有指定证书密钥,所以 ingress-nginx 返回自己的默认自签名证书(CN=Kubernetes Ingress Controller Fake Certificate,SAN ingress.local)。

在这种情况下,需要显式 opt-in:

export PLATFORM_MCP_INSECURE=true

它会对 Node 禁用证书校验(OIDC 登录),并在每次启动时打印警告。连接仍然是加密的,但服务器身份未得到确认,而访问令牌会经过这条通道传输。kcadm 在配置中没有 truststore 时会启用跳过证书验证(stderr CLI 中会有警告)。

NODE_EXTRA_CA_CERTS 在这里帮不上忙:证书的 SAN(ingress.local)与主机名不匹配,因此即使有受信任的根 CA,主机名校验也会失败。

发布正式证书后需要移除该选项。如果证书由内部 CA 签发,只需指定根证书即可——环境变量会继承给子 CLI:

export NODE_EXTRA_CA_CERTS=/path/to/internal-ca.pem   # для самого сервера (Node)
export SSL_CERT_FILE=/path/to/internal-ca.pem         # для argocd и vault (Go)

工作原理

редактор ──stdio──▶ platform-mcp ──argv+env──▶ argocd ──▶ Argo CD
                    (OIDC, политика,  vault  ──▶ Vault
                     вырезание секретов) kcadm ──▶ Keycloak

Argo CD。 登录方式为通过 Dex 的 Authorization Code + PKCE。使用的是 public 客户端 argo-cd-cli,Argo CD 会在 Dex 中自动注册它,同时注册 redirect URI http://localhost:8085/auth/callback,因此无需修改 argocd-cm 即可完成安装。Argo CD 接受的是 id_token 而非 access_token 作为 Bearer——后者的 Dex 令牌是不透明的,API 服务器无法校验。令牌通过 refresh token 刷新。

CLI 以 --grpc-web 启动:ingress-nginx 将普通 HTTP/1.1 代理到 argocd-serverconfigs.params.server.insecure: true),纯 gRPC 无法到达它。

Vault。 流程更简单:不需要 PKCE,因为用代码换令牌的是 Vault 本身——OAuth 应用的密钥就存储在 Vault 中。客户端只需在 http://localhost:8250/oidc/callback 上启动一个 listener(该地址已预先写入 allowedRedirectURIs),并返回 codestateclient_noncestate 参数由 Vault 自己生成并放入下发的链接中——重定向校验时就从那里取用。只要 renewable 为真,令牌就通过 auth/token/renew-self 续期。

Keycloak。 通过 master realm 中的 public 客户端 platform-mcp-cli 使用 Authorization Code + PKCE(在 bootstrap 中一次性创建,redirect 为 http://localhost:8280/oidc/callback)。登录方式为 FreeIPA。access_token(Admin API)会放入会话中。在 kcadm 之前,服务器会将私有的 kcadm.config 写入 ~/.config/platform-mcp/——而不是公共的 ~/.keycloak/kcadm.config

令牌仅通过环境变量(Argo/Vault)或私有配置文件(Keycloak)传递给子进程:如果放在 argv 中,用户的所有进程都能在 ps 里看到。环境变量不会整体继承——CLI 只获得它需要的内容,不包含相邻服务的密钥。

会话存储在自己的文件中,而不是 ~/.config/argocd/config~/.vault-token~/.keycloak/kcadm.config:提供方在刷新时会轮换令牌,如果使用公共文件,终端中的普通 CLI 和这个服务器会互相使对方的会话失效。

开发

npm install
npm run build
npm test

测试覆盖了命令分类与禁止规则、密钥脱敏、一次性确认令牌、启动 CLI 时无 shell,以及自研的 ZIP 解包器(之所以需要它,是因为 HashiCorp 以压缩包形式分发 vault,而 Node 没有内置解包器)。

插件

该仓库既是插件目录,也是插件本身:

.claude-plugin/marketplace.json      каталог для Claude Code
.cursor-plugin/marketplace.json      каталог для Cursor
plugins/platform-mcp/
  .claude-plugin/plugin.json         манифест для Claude Code
  .cursor-plugin/plugin.json         манифест для Cursor
  .mcp.json                          сервер для Claude Code — ПЛОСКАЯ карта
  mcp.json                           тот же сервер для Cursor — с обёрткой mcpServers

服务器描述以两种形式重复,这并非疏忽。Claude Code 将 .mcp.json 读取为扁平的「名称 → 服务器」映射:如果使用 mcpServers 包装,它会静默地不加载服务器——插件已安装并显示为启用,但不会出现任何工具。而 Cursor 则从自己 plugin.json 中的 mcpServers 按路径读取文件,可用的插件都使用带包装的形式。command/argsenv 键一致;Cursor 的 env 值是 ${VAR} 占位符(plugin.json 中的 variables 模式,UI 中的 Configure),Claude 的则是字面默认值。npm run check:manifests 确保两种形式不会分叉。

服务器代码不会复制到插件中:两个文件都通过 npx 运行已发布的包,因此插件只包含几个小文件,服务器变更时无需重新构建。

推送前可以通过本地路径挂载目录来验证更改:

/plugin marketplace add /путь/к/platform-mcp
/plugin install platform-mcp

发布

CI(.gitlab-ci.yml)会在打上 vX.Y.Z 格式的标签时自动将包发布到该项目的 GitLab npm registry,认证使用内置的 CI_JOB_TOKEN,CI 中不需要个人令牌。

版本在插件清单中重复出现,需要在那里同步提升:

npm version <major|minor|patch> --no-git-tag-version   # только package.json
# поправить version в обоих plugins/platform-mcp/*/plugin.json
npm run check:manifests                                # сверить
git commit -am "0.X.Y" && git tag v0.X.Y && git push --follow-tags

不一致会被 CI 捕获:test 任务会核对三个清单中的版本以及两份服务器描述的一致性,publish 任务则核对标签版本与 package.json。否则,当服务器更新后,用户的插件仍会显示为「未变更」:Claude Code 和 Cursor 都根据插件的 version 决定是否更新。

插件无需单独发布到任何地方:推送到 main 会通过受保护分支的镜像同步到 GitHub,用户通过 /plugin marketplace update 获取更新。请注意,插件是从分支而非标签安装的:一旦修改进入 main,所有用户立即可用——即使版本尚未打标签发布。

F
license - not found
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
    A
    quality
    D
    maintenance
    An MCP (Model Context Protocol) server that integrates with the ArgoCD API, enabling AI assistants and large language models to manage ArgoCD applications and resources through natural language interactions.
    10
    12
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    A secure MCP server providing read-only access to Argo CD instances using browser session cookies, enabling querying of applications, projects, clusters, and repositories.
    14
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    A Model Context Protocol (MCP) server that enables secure execution of shell commands with a dynamic approval system, audit logging, and command revocation.
    41
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • Go MCP server for GitLab: 2 dynamic tools reach 1000+ REST/GraphQL actions. Free/CE, no paid tier.

  • MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2

  • A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready

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/K-manankov/platform-mcp'

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