MCP Prometheus
Acesse métricas e consultas do Prometheus por meio de interfaces MCP padronizadas.
Documentação
MCP Prometheus
Um servidor MCP (Model Context Protocol) para Prometheus e Mimir, escrito em Go. Implantado no cluster na Giant Swarm para dar a assistentes de IA acesso autenticado e multi-tenant à infraestrutura de métricas.
O que ele faz
O MCP Prometheus expõe 18 ferramentas MCP somente leitura que encapsulam a API HTTP do Prometheus: consultas PromQL instantâneas e por intervalo, descoberta de métricas/rótulos/séries, informações de alvos e runtime, estatísticas do TSDB, regras de alerta e exemplares.
Quando implantado com OAuth habilitado, ele atua como um Servidor de Autorização OAuth 2.1 completo (com suporte a Dex/OIDC ou Google), para que clientes MCP se autentiquem no servidor antes de qualquer chamada de ferramenta. O servidor então resolve os IDs de tenant Mimir do usuário autenticado e os aplica em todas as consultas.
Conteúdo
- Arquitetura
- Instalação
- Referência de configuração
- Modos de transporte
- Autenticação OAuth 2.1
- Multi-tenancy
- Ferramentas disponíveis
- Implantação Kubernetes (Helm)
- Desenvolvimento
Arquitetura
MCP Client (Claude, muster, …)
│ OAuth 2.1 + MCP over HTTP
▼
┌──────────────────────────────────┐
│ mcp-prometheus │
│ │
│ ┌────────────┐ ┌─────────────┐ │
│ │ OAuth 2.1 │ │ MCP Tools │ │
│ │ server │ │ (PromQL, │ │
│ │ (mcp-oauth)│ │ labels, …)│ │
│ └─────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ ┌─────▼──────┐ ┌──────▼──────┐ │
│ │ Dex OIDC │ │ Tenancy │ │
│ │ provider │ │ resolver │ │
│ └────────────┘ └──────┬──────┘ │
└─────────────────────────┼────────┘
│
┌───────────────┴──────────────┐
│ │
┌──────▼───────┐ ┌───────▼──────┐
│ GrafanaOrg │ │ Prometheus │
│ CRDs (k8s) │ │ / Mimir │
└──────────────┘ └──────────────┘
O servidor escuta em duas portas:
:8080— endpoints MCP + OAuth (servidos aos clientes):9091— observabilidade:/metrics,/healthz,/readyz(somente interno)
Instalação
Binários pré-compilados
Baixe a versão mais recente na página de releases.
A partir do código-fonte
git clone https://github.com/giantswarm/mcp-prometheus.git
cd mcp-prometheus
go build -o mcp-prometheus ./...
Kubernetes (Helm)
Consulte Implantação Kubernetes (Helm).
Referência de configuração
Toda a configuração é feita por meio de variáveis de ambiente.
Conexão Prometheus
| Variável | Padrão | Descrição |
|---|---|---|
PROMETHEUS_URL | — | URL base do Prometheus/Mimir |
PROMETHEUS_USERNAME | — | Nome de usuário para autenticação básica |
PROMETHEUS_PASSWORD | — | Senha para autenticação básica |
PROMETHEUS_TOKEN | — | Token Bearer |
PROMETHEUS_ORGID | — | ID de org/tenant Mimir padrão |
PROMETHEUS_TLS_SKIP_VERIFY | false | Ignorar verificação TLS (somente desenvolvimento) |
PROMETHEUS_TLS_CA_CERT | — | Caminho para certificado CA PEM |
OAuth 2.1
| Variável | Padrão | Descrição |
|---|---|---|
MCP_OAUTH_ISSUER | obrigatório | URL base pública deste servidor (ex.: https://mcp.example.com) |
MCP_OAUTH_ENCRYPTION_KEY | — | Chave AES-256-GCM base64 de 32 bytes para criptografia de tokens (openssl rand -base64 32) |
MCP_OAUTH_PROVIDER | dex | Provedor de identidade: dex ou google (consulte as tabelas de provedores abaixo) |
OAUTH_REDIRECT_URL | obrigatório | URL de callback registrada no provedor (ex.: https://mcp.example.com/oauth/callback). O DEX_REDIRECT_URL legado ainda é respeitado quando este não está definido |
MCP_OAUTH_ALLOW_PUBLIC_REGISTRATION | false | Permitir registro dinâmico de clientes não autenticados (somente desenvolvimento/MCP Inspector) |
MCP_OAUTH_ALLOW_PRIVATE_URLS | false | Permitir descoberta OIDC contra Dex em IPs privados/internos (consulte abaixo); somente dex |
OAUTH_TRUSTED_AUDIENCES | — | IDs de clientes separados por vírgula confiáveis para encaminhamento de token SSO |
OAUTH_STORAGE | memory | Armazenamento de tokens: memory ou valkey |
VALKEY_URL | — | Endereço Valkey/Redis (obrigatório quando OAUTH_STORAGE=valkey) |
VALKEY_PASSWORD | — | Senha de autenticação Valkey |
VALKEY_TLS_ENABLED | false | Habilitar TLS para Valkey |
VALKEY_KEY_PREFIX | mcp: | Prefixo do namespace de chaves |
Provedor Dex OIDC (MCP_OAUTH_PROVIDER=dex)
| Variável | Padrão | Descrição |
|---|---|---|
DEX_ISSUER_URL | obrigatório | URL do emissor Dex (ex.: https://dex.mc.example.io) |
DEX_CLIENT_ID | obrigatório | ID do cliente OAuth registrado no Dex |
DEX_CLIENT_SECRET | obrigatório | Segredo do cliente OAuth |
DEX_REDIRECT_URL | — | Alias legado de OAUTH_REDIRECT_URL; usado quando este não está definido |
DEX_CA_FILE | — | Arquivo CA PEM para verificar TLS para endpoints Dex e JWKS (instalações com CA privada). Adicionado sobre o armazenamento de confiança do sistema |
Provedor Google (MCP_OAUTH_PROVIDER=google)
| Variável | Padrão | Descrição |
|---|---|---|
GOOGLE_CLIENT_ID | obrigatório | ID do cliente OAuth do cliente OAuth do Google Cloud (….apps.googleusercontent.com) |
GOOGLE_CLIENT_SECRET | obrigatório | Segredo do cliente OAuth desse cliente |
Os endpoints de descoberta, token e JWKS do Google são públicos, portanto DEX_CA_FILE e
MCP_OAUTH_ALLOW_PRIVATE_URLS não se aplicam (são ignorados com um aviso).
Os tokens de ID do Google não carregam a declaração groups: combine este provedor com
modo de tenancy none ou uma lista estática de tenants para todos os usuários.
Tenancy
| Variável | Padrão | Descrição |
|---|---|---|
TENANCY_STATIC_GROUP_MAP | — | Mapa JSON de grupo Dex → lista de IDs de tenant Mimir (modo estático) |
O modo de tenancy é uma flag: --tenancy-mode grafana-organization|static|none (consulte Multi-tenancy).
Observabilidade
| Variável | Padrão | Descrição |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | — | Endpoint HTTP OTLP para rastreamento (sem operação se não definido) |
OTEL_SERVICE_NAME | mcp-prometheus | Nome do serviço nos rastreamentos |
Modos de transporte
Inicie o servidor com serve --transport <mode>:
| Modo | Flag | Caso de uso |
|---|---|---|
stdio | --transport stdio | Clientes desktop locais (Claude Desktop, MCP Inspector) |
sse | --transport sse | Clientes SSE legados |
streamable-http | --transport streamable-http | Produção no cluster (padrão) |
OAuth requer sse ou streamable-http.
# Local stdio (no OAuth)
./mcp-prometheus serve
# In-cluster HTTP with OAuth
./mcp-prometheus serve --transport streamable-http --http-addr :8080 --enable-oauth
Autenticação OAuth 2.1
O MCP Prometheus implementa OAuth 2.1 (RFC 9700) usando mcp-oauth com o
provedor de identidade da plataforma upstream: Dex (padrão) ou Google, selecionado com MCP_OAUTH_PROVIDER.
O fluxo, os endpoints e o manuseio de tokens são idênticos para ambos; apenas o login upstream e as
variáveis de ambiente específicas do provedor diferem.
Endpoints
| Caminho | Método | Finalidade |
|---|---|---|
/.well-known/oauth-authorization-server | GET | Metadados do servidor OAuth (RFC 8414) |
/.well-known/protected-resources | GET | Metadados do recurso protegido |
/oauth/authorize | GET | Endpoint de autorização (redireciona para o provedor de identidade) |
/oauth/callback | GET | Callback do provedor de identidade (OAUTH_REDIRECT_URL) |
/oauth/token | POST | Troca de tokens |
/oauth/register | POST | Registro dinâmico de clientes (RFC 7591) |
/oauth/revoke | POST | Revogação de tokens |
Fluxo OAuth completo
MCP Client mcp-prometheus Dex OIDC
│ │ │
│ 1. GET /.well-known/… │ │
│──────────────────────────>│ │
│ server metadata │ │
│<──────────────────────────│ │
│ │ │
│ 2. POST /oauth/register │ │
│──────────────────────────>│ │
│ client_id + secret │ │
│<──────────────────────────│ │
│ │ │
│ 3. GET /oauth/authorize │ │
│──────────────────────────>│ │
│ │ 4. redirect to Dex │
│ │───────────────────────>│
│<──────────────────────────────────────────────────│
│ browser: Dex login UI │ │
│ (user authenticates) │ │
│ │ │
│ │ 5. callback + code │
│ │<───────────────────────│
│ │ │
│ 6. POST /oauth/token │ │
│──────────────────────────>│ │
│ access_token + refresh │ │
│<──────────────────────────│ │
│ │ │
│ 7. MCP tool call │ │
│ Authorization: Bearer … │ │
│──────────────────────────>│ │
│ │ 8. validate token │
│ │ resolve tenants │
│ │ forward to Mimir │
O token de acesso é um JWT de curta duração assinado pelo mcp-prometheus e validado em todas as requisições. A rotação de refresh tokens está habilitada — cada atualização emite um novo refresh token.
Armazenamento de tokens
memory(padrão): em processo, perdido na reinicialização. Adequado para implantações de réplica única e desenvolvimento.valkey: backend Redis/Valkey de nível de produção. Obrigatório para implantações com múltiplas réplicas.
Permitir URLs privadas
Quando DEX_ISSUER_URL usa um nome DNS interno que resolve para um IP privado (faixa RFC-1918),
a proteção SSRF embutida no cliente de descoberta OIDC rejeitaria a conexão.
Defina MCP_OAUTH_ALLOW_PRIVATE_URLS=true para injetar um cliente HTTP que permita conexões com IPs privados
para descoberta OIDC. A verificação TLS ainda é aplicada.
MCP_OAUTH_ALLOW_PRIVATE_URLS=true
DEX_ISSUER_URL=https://dex.mc.my-cluster.example.io # resolves to 10.x.x.x
No Helm: app.oauth.allowPrivateURLs: true
CA privada (DEX_CA_FILE)
Quando o Dex é servido com um certificado de uma CA privada/interna (ex.: clusters de gerenciamento
privados), a verificação TLS falha com x509: certificate signed by unknown authority.
Aponte DEX_CA_FILE para um arquivo CA PEM para adicionar essa CA sobre o armazenamento de confiança do sistema.
O pool verifica a conexão do provedor Dex (descoberta OIDC, fluxo de código, userinfo),
o endpoint JWKS do token de ID encaminhado e os endpoints JWKS de emissores confiáveis.
DEX_CA_FILE=/etc/ssl/certs/dex-ca/ca.crt
No Helm, referencie um Secret contendo o certificado CA:
app:
oauth:
dexCASecret:
name: mcp-prometheus-dex-ca
key: ca.crt
Encaminhamento de token SSO (trustedAudiences)
Quando usuários se conectam por meio de um agregador MCP upstream (ex.: muster) que já os autenticou, o agregador pode encaminhar o token de ID do usuário do IdP da plataforma diretamente, em vez de iniciar um novo fluxo OAuth.
Configure OAUTH_TRUSTED_AUDIENCES com uma lista separada por vírgulas dos IDs de cliente OAuth do agregador:
OAUTH_TRUSTED_AUDIENCES=muster-client,my-aggregator
O mcp-prometheus irá:
- Detectar que o público do token recebido corresponde a um ID de cliente confiável
- Verificar a assinatura do token contra o endpoint JWKS do provedor (Dex ou Google)
- Aceitar o token e prosseguir com a resolução de tenant
Os tokens devem ainda ser originados do emissor do provedor configurado. Com o provedor Google, liste o ID do cliente OAuth do Google da plataforma (aquele com o qual o muster autentica usuários) aqui.
Multi-tenancy
Quando o OAuth está habilitado, toda chamada de ferramenta é limitada aos IDs de tenant Mimir permitidos do usuário autenticado.
O usuário pode passar um parâmetro explícito org_id; o servidor o valida contra seus tenants permitidos.
Se nenhum org_id for fornecido, todos os tenants permitidos são injetados como um seletor multi-tenant Mimir separado por pipe.
Três modos de resolução estão disponíveis, selecionados com --tenancy-mode (ou app.tenancy.mode no Helm):
grafana-organization (padrão), static e none.
Modo GrafanaOrganization (padrão)
--tenancy-mode grafana-organization
Lê recursos personalizados GrafanaOrganization da API Kubernetes.
Cada CR declara quais grupos Dex têm acesso (spec.rbac) e quais IDs de tenant Mimir mapeiam para ele (spec.tenants).
apiVersion: observability.giantswarm.io/v1alpha1
kind: GrafanaOrganization
metadata:
name: team-platform
spec:
rbac:
- groupName: github-org:team-platform # Dex group from LDAP/GitHub
tenants:
- prod-eu-west
- prod-us-east
Quando um usuário se autentica:
- O servidor lê a declaração
groupsdo token Dex do usuário - Ele busca todos os CRs
GrafanaOrganizationonde qualquer grupo emspec.rbaccorresponde - Ele coleta todos os IDs de tenant de
spec.tenantsnos CRs correspondentes - Os resultados são armazenados em cache por conjunto de grupos por 60 segundos
O chart Helm cria um ClusterRole + ClusterRoleBinding concedendo get, list, watch em grafanaorganizations.observability.giantswarm.io quando este modo está ativo.
Modo estático
--tenancy-mode static
Nenhum acesso à API Kubernetes é necessário. Os tenants são configurados estaticamente.
Todos os usuários: mesmos tenants para todos
# All authenticated users get these tenant IDs
--static-tenants=prod-eu,prod-us
Helm:
app:
tenancy:
mode: static
static:
tenants: "prod-eu,prod-us"
Mapeamento de grupos: atribuição de tenant por grupo
Quando TENANCY_STATIC_GROUP_MAP está definido (ou app.tenancy.static.groups no Helm), os IDs de tenant são resolvidos por grupo:
TENANCY_STATIC_GROUP_MAP='{"team-ops":["prod-eu","prod-us"],"team-dev":["staging"]}'
Helm:
app:
tenancy:
mode: static
static:
groups:
team-ops:
- prod-eu
- prod-us
team-dev:
- staging
Os tenants permitidos do usuário são a união de todos os tenants de seus grupos Dex.
Modo None (Prometheus de tenant único)
--tenancy-mode none
Para um Prometheus simples de tenant único (sem Mimir, sem X-Scope-OrgID). O OAuth ainda
autentica todo chamador — requisições não autenticadas são rejeitadas, tokens encaminhados são
validados e a identidade está disponível para auditoria — mas nenhum tenant é derivado da
identidade e nenhum cabeçalho de tenant é injetado. Um parâmetro explícito de ferramenta org_id ou
PROMETHEUS_ORGID é repassado literalmente. O chart não cria ClusterRole neste modo.
Este é o modo a ser usado com o provedor Google (tokens do Google não têm a declaração groups)
e sempre que o mcp-prometheus estiver atrás do muster na frente de um único Prometheus.
Helm:
app:
tenancy:
mode: none
Ferramentas disponíveis
Todas as ferramentas aceitam parâmetros opcionais prometheus_url e org_id para substituições por chamada.
Execução de consultas
| Ferramenta | Descrição |
|---|---|
mcp_prometheus_execute_query | Consulta instantânea PromQL |
mcp_prometheus_execute_range_query | Consulta por intervalo PromQL com start, end, step |
As ferramentas de consulta aceitam: timeout, limit, stats, lookback_delta, unlimited.
Métricas e descoberta
| Ferramenta | Descrição |
|---|---|
mcp_prometheus_get_metric_metadata | Metadados para uma métrica específica |
mcp_prometheus_list_label_names | Todos os nomes de rótulos |
mcp_prometheus_list_label_values | Valores para um rótulo específico |
mcp_prometheus_find_series | Encontrar séries por seletores de rótulos |
Alvos e informações do sistema
| Ferramenta | Descrição |
|---|---|
mcp_prometheus_get_targets | Lista de alvos e saúde |
mcp_prometheus_get_build_info | Informações de build/versão |
mcp_prometheus_get_runtime_info | Informações de runtime |
mcp_prometheus_get_flags | Flags de runtime |
mcp_prometheus_get_config | Configuração do Prometheus |
mcp_prometheus_get_tsdb_stats | Estatísticas de cardinalidade do TSDB |
mcp_prometheus_check_ready | Verificação de prontidão (/-/ready), funciona com Mimir |
Alertas e regras
| Ferramenta | Descrição |
|---|---|
mcp_prometheus_get_alerts | Alertas ativos |
mcp_prometheus_get_alertmanagers | Descoberta do AlertManager |
mcp_prometheus_get_rules | Regras de gravação e alertas |
get_rules aceita os filtros de GET /api/v1/rules, aplicados no lado do servidor pelo Prometheus ou pelo
ruler do Mimir: type (alert ou record), rule_name, rule_group, file (o namespace de regras
do Mimir) e exclude_alerts. Os seletores de rótulos (match[]) não são expostos porque o ruler do Mimir
os ignora. No Mimir, passe org_id — a API do ruler rejeita requisições sem um tenant.
Avançado
| Ferramenta | Descrição |
|---|---|
mcp_prometheus_query_exemplars | Consultas de exemplares para correlação de traces |
mcp_prometheus_get_targets_metadata | Metadados de métricas por alvo |
Resultados grandes de consultas são truncados automaticamente com orientação para a IA refinar sua consulta.
Implantação no Kubernetes (Helm)
Mínimo (sem OAuth)
app:
env:
- name: PROMETHEUS_URL
value: "http://mimir-gateway.monitoring:8080/prometheus"
- name: PROMETHEUS_ORGID
value: "my-tenant"
Produção com OAuth + locação GrafanaOrganization
app:
server:
transport: streamable-http
oauth:
enabled: true
dexClientSecret: "..." # stored in K8s Secret
encryptionKey: "..." # openssl rand -hex 32
storage:
type: valkey
valkey:
url: "valkey:6379"
trustedAudiences:
- muster-client
tenancy:
mode: grafana-organization
env:
- name: MCP_OAUTH_ISSUER
value: "https://mcp-prometheus.mc.example.io"
- name: DEX_ISSUER_URL
value: "https://dex.mc.example.io"
- name: DEX_CLIENT_ID
value: "mcp-prometheus"
- name: DEX_REDIRECT_URL
value: "https://mcp-prometheus.mc.example.io/oauth/callback"
- name: PROMETHEUS_URL
value: "http://mimir-gateway.monitoring:8080/prometheus"
Provedor Google + Prometheus de tenant único atrás do muster
O IdP da plataforma é o Google, o muster encaminha o token de ID do Google do usuário
(auth.forwardToken: true), e não há tenants do Mimir para resolver.
app:
oauth:
enabled: true
provider: google
redirectURL: "https://mcp-prometheus.example.io/oauth/callback"
google:
clientID: "1234567890-abc.apps.googleusercontent.com" # this server's OAuth client
googleClientSecret: "..." # or existingSecret with key GOOGLE_CLIENT_SECRET
encryptionKey: "..." # openssl rand -base64 32
trustedAudiences:
- "1234567890-platform.apps.googleusercontent.com" # the platform client muster logs in with
tenancy:
mode: none
env:
- name: MCP_OAUTH_ISSUER
value: "https://mcp-prometheus.example.io"
- name: PROMETHEUS_URL
value: "http://prometheus-operated.monitoring:9090"
Produção com OAuth + mapeamento de grupo estático
app:
oauth:
enabled: true
dexClientSecret: "..."
encryptionKey: "..."
tenancy:
mode: static
static:
groups:
team-ops:
- prod-eu
- prod-us
team-dev:
- staging
Dex privado (DNS interno)
Quando DEX_ISSUER_URL resolve para um IP privado:
app:
oauth:
enabled: true
allowPrivateURLs: true # enables private-IP OIDC discovery
dexClientSecret: "..."
encryptionKey: "..."
Armazenamento de tokens Valkey (multi-réplica)
app:
oauth:
storage:
type: valkey
valkey:
url: "valkey.default:6379"
password: ""
tlsEnabled: false
keyPrefix: "mcp-prometheus:"
Desenvolvimento
Estrutura do projeto
mcp-prometheus/
├── cmd/ # CLI (serve, version)
├── internal/
│ ├── oauth/ # OAuth 2.1 setup (Config, NewHandler)
│ ├── server/ # ServerContext, PrometheusConfig
│ ├── tenancy/ # TenancyResolver, GrafanaOrg + static modes
│ ├── tools/prometheus/ # 18 MCP tool registrations
│ └── observability/ # /metrics, /healthz, /readyz, OTel
├── helm/mcp-prometheus/ # Helm chart
├── go.mod
└── README.md
Build e testes
go build -o mcp-prometheus ./...
go test ./...
Convenções de código
- Cada pacote tem um
doc.go - Cobertura de testes unitários de 80%+ em código novo
- Execute
goimports -w . && go fmt ./...antes de commitar - Arquivos mantidos abaixo de 500 linhas; GoDoc em todos os membros exportados