platform-mcp
platform-mcp
用于 sonar-prod 集群基础设施服务的 MCP 服务器 —— Argo CD、Vault 和 Keycloak —— 支持 SSO 登录(Argo/Vault 用 GitLab,Keycloak 用 FreeIPA)。
为什么
编辑器中的代理需要访问 Argo CD、Vault 和 Keycloak,但不能给它服务账号:审计中会出现一个通用账号而不是具体的人,而且权限会比任何特定开发者的权限都宽。
这个包安装在本地,通过浏览器进行常规 SSO 登录。之后它以登录用户的名义执行命令:审计日志中可以看到真实登录名,权限恰好是群组成员身份所赋予的。
每个服务只有一个工具 —— argocd_exec、vault_exec 和 keycloak_exec,接受命令行参数。底层是官方 CLI(argocd、vault、kcadm),所以它们能做的这里都能做。新增服务只需实现一个接口。
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 node 和 which 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.ru、vault.infra.sonar-corp.ru 和 auth.infra.sonar-corp.ru 这些名称只能从内网解析。从外部它们会被公共通配符 *.infra.sonar-corp.ru 捕获,请求会静默地跑到别处 —— 检查 dig +short argocd.infra.sonar-corp.ru 应该返回 192.168.88.106。
最简单的登录方式就是直接在对话中:让代理调用 argocd_login、vault_login 或 keycloak_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 [сервис] # удалить сохранённую сессию服务是 argocd、vault 或 keycloak;不带服务时命令应用于所有已配置的服务。
工具
每个服务:<服务>_exec、<服务>_login、<服务>_auth_status、<服务>_logout。
argocd_exec、vault_exec 和 keycloak_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 login、vault login、kcadm config …)—— 会话由服务器自己管理;不会结束的命令:
vault server|agent|proxy|monitor、argocd app logs --follow;argocd admin—— 管理 Argo CD 本身;vault operator seal|step-down|init|rekey|generate-root|migrate—— 其中任何一个失败都会让整个存储库宕掉;修改 Argo CD 基础设施应用(
argocd、vault、keycloak、cert-manager、ingress-nginx、……):它们通过 merge request 从 Git 部署,而不是通过与代理的对话。可以读取它们。
列表可在 config.json 中配置(policy.denyApplications、policy.denyVaultPaths)。
这是防止代理出错的保护,而不是安全边界。
infra/k8s群组成员本来就是 Argo CD 管理员(g, infra/k8s, role:admin),可以通过 UI 做同样的事。真正限制权限只能通过argocd-rbac-cm中的角色分离和 Vault 策略实现。
密钥不会进入模型上下文
密钥值会从响应中剔除,而键名和元数据保留:
Vault ——
kv get、KV 路径上的read和unwrap中的值。kv list、kv metadata get、policy read、sys/mounts的响应不受影响:那里没有密钥,剔除会让它们变得无用。Argo CD ——
Secret资源中的data和stringData,包括 Argo CD 以 JSON 字符串形式返回清单的manifest、liveState、targetState字段内部。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 相同。
不需要手动安装:
如果
argocd/vault/kcadm(kcadm.sh)已经在PATH中 —— 使用现有的,不下载任何东西。否则在首次调用时从官方发布页(
github.com/argoproj/argo-cd、releases.hashicorp.com、github.com/keycloak/keycloak)下载固定版本,适配当前平台。对于 Keycloak —— 整个发行版 zip(约 170 MB):kcadm是 Java 脚本,而不是独立的 Go 二进制文件。在解压和
chmod +x之前校验校验和。 没有这一步,一切都只是"从网上下载并执行"。文件放在
~/.config/platform-mcp/bin/中并后续复用。
kcadm 需要机器上有 Java 17+(PATH 中的 java 或 JAVA_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.ru、vault.infra.sonar-corp.ru 和 auth.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 ──▶ KeycloakArgo 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-server(configs.params.server.insecure: true),纯 gRPC 无法到达它。
Vault。 流程更简单:不需要 PKCE,因为用代码换令牌的是 Vault 本身——OAuth 应用的密钥就存储在 Vault 中。客户端只需在 http://localhost:8250/oidc/callback 上启动一个 listener(该地址已预先写入 allowedRedirectURIs),并返回 code、state 和 client_nonce。state 参数由 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/args 和 env 键一致;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,所有用户立即可用——即使版本尚未打标签发布。
Maintenance
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
- AlicenseAqualityDmaintenanceAn 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.1012MIT
- AlicenseAqualityBmaintenanceA secure MCP server providing read-only access to Argo CD instances using browser session cookies, enabling querying of applications, projects, clusters, and repositories.14MIT
- AlicenseNot gradedqualityFmaintenanceA Model Context Protocol (MCP) server that enables secure execution of shell commands with a dynamic approval system, audit logging, and command revocation.41Apache 2.0
- AlicenseNot gradedqualityAmaintenanceMCP server for interacting with GitLab API, supporting dynamic tool selection and enterprise-grade security.10MIT
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
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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