Quando o número de servidores MCP chegou a seis e a equipe a dez, a frase "simplesmente execute npx localmente" deixou de funcionar. Nem todos querem instalar o Node.js, os gerentes não têm Docker e o arquivo claude_desktop_config.json local começa a se assemelhar a um cofre de segredos de todos os sistemas.
Percorri o caminho do MCP remoto → execução local → Docker → Kubernetes com um único Helm chart e autenticação JWT via Envoy. Vou contar o que encontrei, o que funcionou e o que ainda precisa ser resolvido.
Nível 1: MCP Remoto – Quando o Fornecedor Facilita para Você
A primeira experiência com o MCP foi extremamente simples. Adicionei atlassian-mcp-server ao Claude como um MCP remoto, passei pela autenticação e pude usá-lo. Tudo parecia bastante simples e acessível, a Atlassian forneceu a capacidade de conexão e autenticação.
json{ "mcpServers": { "atlassian": { "type": "http", "url": "https://mcp.atlassian.com/v1/sse" } } }
Nível 2: Execução Local – Primeiros Compromissos
Em seguida, quis conectar meu IDE ao Kubernetes. Aqui, as coisas ficaram mais complicadas, porque o Kubernetes não fornece acesso via MCP "out of the box". Tive que instalar dependências:
json{ "mcpServers": { "kubernetes": { "command": "npx", "args": ["-y", "kubernetes-mcp-server@latest"] } } }
Funcionou, mas um servidor precisa de Node.js, outro precisa de Python e uvx, e um terceiro precisa de um binário Go. O "zoológico" de runtimes na máquina de trabalho se multiplica com cada novo MCP. Não quero sobrecarregar meu computador de trabalho com isso, especialmente porque nem sou desenvolvedor.
Nível 3: Docker – Isolamento Sem Dor
O próximo passo lógico são os containers. Cada servidor MCP com seu próprio runtime, sem lixo no host:
json{ "mcpServers": { "grafana": { "command": "docker", "args": [ "run", "--rm", "-i", "-e", "GRAFANA_URL", "-e", "GRAFANA_SERVICE_ACCOUNT_TOKEN", "grafana/mcp-grafana", "-t", "stdio" ], "env": { "GRAFANA_URL": "https://grafana.example.com", "GRAFANA_SERVICE_ACCOUNT_TOKEN": "<token>" } } } }
Poderíamos ter parado por aqui. Para soluções SaaS, usar seu MCP remoto. Para soluções auto-hospedadas, execute localmente em um container. Para um engenheiro em uma máquina, é suficiente. Mas quando dez pessoas precisam disso, surgem perguntas:
- Os tokens de sistemas de produção estão espalhados pelos laptops.
- Workflows automatizados (n8n, CI/CD) também precisam de acesso ao MCP – e eles funcionam remotamente.
- Gerentes e analistas querem usar ferramentas de IA, mas não estão dispostos a lidar com
docker run.
Tudo isso levou a uma conclusão: os servidores MCP precisam ser movidos para uma infraestrutura compartilhada.
Nível 4: Kubernetes – Deploy Centralizado
Inicialmente, a ideia era simples: implantar servidores MCP remotos no circuito interno da sua infraestrutura. Aqui, podemos pelo menos restringir o acesso por meio de uma VPN corporativa.
Qualquer pessoa que tenha trabalhado em uma tarefa semelhante já se deparou com a questão de como organizar o acesso a um servidor que recebe dados via stdin remotamente. Por exemplo, mcp-digitalocean.
É aqui que soluções como o MCP Proxy entram em jogo, que podem estabelecer comunicação entre HTTP e stdin. Como os servidores MCP são principalmente serviços stateless homogêneos (se você desativar as notificações sobre alterações em ferramentas e prompts), é conveniente executá-los no Kubernetes.
O esquema se parece com isto: um cliente (Claude Desktop, IDE, n8n) acessa o API Gateway via HTTPS. O Gateway encaminha a solicitação para o Kubernetes Service. No pod, ao lado do servidor MCP, está em execução o MCP Gateway – ele aceita HTTP e o transmite para o stdin do processo.
Helm Chart Universal
Para não escrever manifestos para cada servidor MCP, criei um Helm chart universal: mcp-helm-chart no ArtifactHub.
O que ele pode fazer:
mode: proxy– executa o MCP Gateway como um sidecar container ao lado do servidor MCP, traduz HTTP ↔ stdio.mode: native– para servidores que já suportam HTTP (sem sidecar).- Integração com
Hashicorp VaulteExternalSecretspara segredos. - Suporte para Gateway API e Ingress clássico.
- HPA para escalonamento horizontal.
Instalando mcp-digitalocean com Ingress-nginx sem autenticação:
bashhelm repo add mcp https://javdet.github.io/mcp-helm-chart helm install my-mcp mcp/mcp -f values.yaml
No values.yaml, é importante especificar:
yaml--- mode: proxy proxy: image: repository: node tag: "20-bookworm" pullPolicy: IfNotPresent gateway: package: "@michlyn/mcpgateway" stdioCommand: "npx -y @digitalocean/mcp --services apps,droplets,doks,networking" outputTransport: streamable-http port: 8080 httpPath: /mcp # O token pode ser armazenado no Hashicorp Vault e obtido por meio do Vault Webhook vault: enabled: true role: "mcp" path: "kubernetes_dev-fra1-01" env: - name: DIGITALOCEAN_API_TOKEN value: vault:devops/data/ai/mcp/digitalocean#token ingress: enabled: true className: "internal" annotations: nginx.ingress.kubernetes.io/proxy-buffering: "off" nginx.ingress.kubernetes.io/proxy-http-version: "1.1" nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$2 hosts: - host: aitool.example.com paths: - path: /digitalocean(/|$)(.*) pathType: ImplementationSpecific tls: - secretName: ssl-certificate hosts: - aitool.example.com
A instalação terá a seguinte aparência:
Os servidores MCP no modo Streamable HTTP são stateless. Eles são escalonados horizontalmente pelo HPA padrão sem problemas. A questão mais premente aqui continua sendo a autenticação e, melhor ainda, a autorização. Os próprios servidores MCP nem sempre suportam a autenticação de entrada, o que significa que você precisa resolvê-la sozinho.
Autenticação: JWT via Envoy
A autenticação Basic é um pouco melhor do que nada, então JWT imediatamente. Usei o Envoy API Gateway – ele suporta nativamente a validação JWT e já estava em nossa stack.
Gerando chaves e token
bash# 1. Gerar chaves RSA openssl genrsa -out mcp-jwt-private.pem 4096 openssl rsa -in mcp-jwt-private.pem -pubout -out mcp-jwt-public.pem # 2. Gerar Key ID KID=$(openssl rand -hex 16) # 3. Formar o cabeçalho JWT (base64url) HEADER=$(echo -n "{\"alg\":\"RS256\",\"typ\":\"JWT\",\"kid\":\"${KID}\"}" \ | base64 -w0 | tr '+/' '-_' | tr -d '=') # 4. Formar o payload JWT (duração – 1 ano) PAYLOAD=$(echo -n "{\"sub\":\"claude-desktop\",\"aud\":\"mcp-servers\",\"iss\":\"https://your-domain.com\",\"iat\":$(date +%s),\"exp\":$(( $(date +%s) + 31536000 ))}" \ | base64 -w0 | tr '+/' '-_' | tr -d '=') # 5. Assinar SIGNATURE=$(echo -n "${HEADER}.${PAYLOAD}" \ | openssl dgst -sha256 -sign mcp-jwt-private.pem \ | base64 -w0 | tr '+/' '-_' | tr -d '=') # 6. Token final echo "${HEADER}.${PAYLOAD}.${SIGNATURE}"
A chave pública é empacotada em JWKS e colocada no ConfigMap. O Envoy valida cada solicitação de entrada, verificando o emissor, o público e a assinatura.
Configuração de autenticação nos valores do chart (opção com Gateway API):
yamlgatewayApi: enabled: true parentRefs: - name: internal # Um Gateway com o nome interno já deve ter sido criado aqui namespace: ai-infra sectionName: https hostnames: - mcptools.example.com timeouts: request: "3600s" backendRequest: "3600s" rules: - matches: - path: type: PathPrefix value: /digitalocean filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / auth: type: jwt jwt: providers: - name: mcp-jwt-auth issuer: mcp-issuser audiences: - mcptools.example.com localJWKS: type: ValueRef valueRef: group: "" kind: ConfigMap name: jwks-config # Se você estiver usando o External Secret Operator, os segredos podem ser obtidos por meio dele externalSecrets: enabled: true refreshInterval: 1h secretStoreRef: name: aws kind: ClusterSecretStore target: creationPolicy: Owner dataFrom: - extract: key: infra/mcp/digitalocean
Atualmente, o acesso aos sistemas de destino (DigitalOcean, Grafana, Kubernetes) é feito por meio de uma única conta de serviço. Isso é suficiente para tarefas somente leitura: monitoramento, diagnóstico, obtenção de informações. Para operações de gravação, a questão está em aberto.
Acesso Automatizado
Tarefas periódicas (workflows n8n, pipelines CI/CD) se conectam aos mesmos servidores MCP via Streamable HTTP com tokens JWT de serviço separados. O esquema é idêntico – apenas o assunto no payload do token difere e, se necessário, o escopo de acesso no nível do Gateway.
Conclusão
As ferramentas e a infraestrutura MCP ainda precisam dar alguns passos um em direção ao outro para que o uso se torne realmente simples, confiável e seguro.
O esquema atual funciona: seis servidores MCP no Kubernetes, um único Helm chart, autenticação JWT via Envoy, segredos no Vault. Os colegas se conectam a servidores MCP remotos sem dependências locais, a automação usa os mesmos endpoints.
O que ainda está faltando:
- Autorização por usuário.
O protocolo MCP não fornece a transmissão do contexto do usuário. Por enquanto, vivemos com contas de serviço.
- Audit log.
Quem chamou qual ferramenta e com quais parâmetros – ainda não está registrado no nível do MCP. Você pode coletar no nível do Envoy, mas sem o contexto da chamada.
- Padrão de autenticação.
Cada fornecedor faz do seu jeito. OAuth, API Key, Bearer – não há uma abordagem única. Mas alguns servidores já estão apresentando autenticação completa, o que é bom.
Como você resolve a autorização por usuário para MCP? Por enquanto, vivemos com uma única conta de serviço – ficarei feliz em ouvir quem progrediu mais.
Anteriormente, escrevi sobre diferentes usos interessantes dessas ferramentas:






