Lenses
Gerencie, explore, transforme e junte dados em vários clusters usando diferentes versões do Apache Kafka via Lenses.io (incluindo a Edição Comunitária gratuita).
Documentação
🌊🔍 Servidor MCP Lenses para Apache Kafka 🔎🌊
Este é o servidor MCP (Model Context Protocol) Lenses para Apache Kafka. O Lenses oferece uma solução de experiência de desenvolvedor para engenheiros que criam aplicações em tempo real conectadas ao Kafka. É construído para a empresa e apoiado por um poderoso modelo de IAM e governança.
Com o Lenses, você pode encontrar, explorar, transformar, integrar e replicar dados em um ambiente multi-Kafka e multi-fornecedor. Agora, todo esse poder está acessível através de suas ferramentas de IA e Agentes de IA via MCP, trazendo contexto em tempo real para seus fluxos de trabalho de engenharia com agentes.
A maneira mais rápida de experimentar o servidor MCP é com a Lenses Community Edition gratuita, que executa o Lenses MCP Server como um servidor MCP remoto e vem com um cluster Kafka de broker único pré-configurado com dados de demonstração, ideal para desenvolvimento local ou avaliação (passos aqui).
Sumário
- 1. Instalar uv e Python
- 2. Configurar Variáveis de Ambiente
- 3. Autenticação OAuth 2.1 (Recomendada)
- 4. Chave de API Lenses (Alternativa)
- 5. Executando o Servidor Localmente
- 6. Executando com Docker
- 7. Rastreamento OpenTelemetry
- 8. Servidor MCP Context7 Opcional
- Apêndice: Detalhes do Fluxo OAuth
1. Instalar uv e Python
Usamos uv para gerenciamento de dependências e configuração do projeto. Se você não tiver o uv instalado, siga o guia de instalação oficial.
Este projeto requer Python 3.13 (qualquer versão 3.13.x). Para verificar sua versão do Python, execute:
uv run python --version
2. Configurar Variáveis de Ambiente
Copie o arquivo de ambiente de exemplo e configure-o com base no seu método de autenticação:
cp .env.example .env
Variáveis obrigatórias dependem da sua escolha de autenticação:
- Para OAuth (recomendado):
LENSES_URLeMCP_ADVERTISED_URL - Para Chave de API (alternativa):
LENSES_URLeLENSES_API_KEY
3. Autenticação OAuth 2.1 (Recomendada)
OAuth 2.1 é o método de autenticação recomendado para todas as implantações do Lenses MCP. Ele fornece autorização segura baseada em escopos, sem compartilhar chaves de API estáticas.
Como funciona
OAuth 2.1 usa tokens de portador validados via RFC 7662 Token Introspection. O fluxo envolve três participantes:
- Cliente MCP — Sua ferramenta de IA (Claude, Cursor, etc.)
- Servidor de Autorização — Lenses HQ em
LENSES_ADVERTISED_URL - Servidor MCP — Este servidor (o servidor de recursos)
Quando você se conecta, o cliente automaticamente:
- Descobre metadados OAuth deste servidor (
/.well-known/oauth-protected-resource/mcp) - Registra-se com o servidor de autorização
- Inicia a autorização OAuth (com PKCE) e obtém um token de acesso
- Usa o token para autenticar solicitações a este servidor MCP
Este servidor então valida o token com o Lenses HQ antes de permitir acesso aos recursos do Kafka.
Configuração simples
Para usar OAuth, você deve definir OAUTH_ENABLED como true, então você só precisa definir duas variáveis de ambiente:
OAUTH_ENABLED=true
LENSES_URL=https://lenses.example.com
MCP_ADVERTISED_URL=http://localhost:8000
LENSES_URL— Sua instância Lenses (usada internamente e como servidor de autorização OAuth)MCP_ADVERTISED_URL— A URL pública onde este servidor MCP é acessível pelos clientes
TRANSPORT assume automaticamente o valor de http quando MCP_ADVERTISED_URL está definido.
Avançado: implantações com planos separados
Se o servidor MCP acessa o Lenses em um endereço interno, mas os clientes o acessam em uma URL pública:
OAUTH_ENABLED=true
LENSES_URL=http://lenses-hq.internal:9991
LENSES_ADVERTISED_URL=https://lenses.example.com
MCP_ADVERTISED_URL=https://mcp.example.com
Escopos de autorização
O servidor anuncia três escopos:
| Escopo | Descrição |
|---|---|
read | Acesso somente leitura aos recursos do Lenses (tópicos, ambientes, conectores, etc.) |
write | Criar e atualizar recursos |
delete | Excluir recursos |
Quando você autentica, será solicitado a conceder esses escopos. Seu token só concederá os escopos que você selecionar.
Configuração do Lenses HQ
O Lenses HQ deve suportar OAuth 2.0 e introspecção de token. Certifique-se de que a configuração do seu Lenses HQ inclua:
oauth2:
authorizationServer:
unauthenticatedIntrospection: true
Isso permite que o servidor MCP valide tokens sem credenciais de cliente.
4. Chave de API Lenses (Alternativa)
Para compatibilidade retroativa e testes, você pode usar uma chave de API estática em vez de OAuth. Isso não é recomendado para produção, mas pode ser útil para desenvolvimento local ou sistemas legados.
Crie uma chave de API Lenses provisionando uma Conta de Serviço IAM no Lenses. Adicione a chave de API a .env:
LENSES_URL=https://lenses.example.com
LENSES_API_KEY=<YOUR_LENSES_API_KEY>
Ao usar autenticação por chave de API, TRANSPORT assume o valor padrão de stdio (somente local), a menos que você defina explicitamente MCP_ADVERTISED_URL.
5. Executando o Servidor Localmente
Primeiro, instale as dependências:
uv sync
Com OAuth (Recomendado)
Execute com transporte stdio (para ferramentas de IA locais):
OAUTH_ENABLED=true \
LENSES_URL=https://lenses.example.com \
MCP_ADVERTISED_URL=http://localhost:8000 \
uv run src/lenses_mcp/server.py
Ou execute com transporte HTTP (para clientes remotos):
OAUTH_ENABLED=true \
LENSES_URL=https://lenses.example.com \
MCP_ADVERTISED_URL=http://localhost:8000 \
uv run fastmcp run src/lenses_mcp/server.py --transport=http --port=8000
Para configurar no Claude Desktop, Cursor ou ferramentas similares:
{
"mcpServers": {
"Lenses": {
"command": "uv",
"args": [
"run",
"--project", "<ABSOLUTE_PATH_TO_THIS_REPO>",
"--with", "fastmcp",
"fastmcp",
"run",
"<ABSOLUTE_PATH_TO_THIS_REPO>/src/lenses_mcp/server.py"
],
"env": {
"OAUTH_ENABLED": "true",
"LENSES_URL": "https://lenses.example.com",
"MCP_ADVERTISED_URL": "http://localhost:8000"
},
"transport": "stdio"
}
}
}
Com Chave de API (Legado)
Usando uma chave de API estática:
LENSES_URL=https://lenses.example.com \
LENSES_API_KEY=<YOUR_LENSES_API_KEY> \
uv run src/lenses_mcp/server.py
Ou com transporte HTTP:
LENSES_URL=https://lenses.example.com \
LENSES_API_KEY=<YOUR_LENSES_API_KEY> \
uv run fastmcp run src/lenses_mcp/server.py --transport=http --port=8000
Para configurar no Claude Desktop, Cursor ou ferramentas similares:
{
"mcpServers": {
"Lenses.io": {
"command": "uv",
"args": [
"run",
"--project", "<ABSOLUTE_PATH_TO_THIS_REPO>",
"--with", "fastmcp",
"fastmcp",
"run",
"<ABSOLUTE_PATH_TO_THIS_REPO>/src/lenses_mcp/server.py"
],
"env": {
"LENSES_URL": "https://lenses.example.com",
"LENSES_API_KEY": "<YOUR_LENSES_API_KEY>"
},
"transport": "stdio"
}
}
}
Nota: Alguns clientes podem exigir o caminho absoluto para uv no comando.
6. Executando com Docker
O servidor Lenses MCP está disponível como uma imagem Docker em lensesio/mcp. Você pode executá-lo com OAuth (recomendado) ou autenticação por chave de API.
Com OAuth (Recomendado)
Transporte stdio (para ferramentas de IA locais):
docker run --rm -it \
-e OAUTH_ENABLED=true \
-e LENSES_URL=https://lenses.example.com \
-e MCP_ADVERTISED_URL=http://localhost:8000 \
lensesio/mcp
Transporte HTTP (para clientes remotos, escuta em http://0.0.0.0:8000/mcp):
docker run --rm -it -p 8000:8000 \
-e OAUTH_ENABLED=true \
-e LENSES_URL=https://lenses.example.com \
-e MCP_ADVERTISED_URL=http://localhost:8000 \
-e TRANSPORT=http \
lensesio/mcp
Para implantações com planos separados, onde o servidor MCP acessa o Lenses internamente, mas os clientes usam uma URL pública:
docker run --rm -it -p 8000:8000 \
-e OAUTH_ENABLED=true \
-e LENSES_URL=http://lenses-hq.internal:9991 \
-e LENSES_ADVERTISED_URL=https://lenses.example.com \
-e MCP_ADVERTISED_URL=https://mcp.example.com \
-e TRANSPORT=http \
lensesio/mcp
Com Chave de API (Legado)
Transporte stdio (para ferramentas de IA locais):
docker run --rm -it \
-e LENSES_API_KEY=<YOUR_API_KEY> \
-e LENSES_URL=https://lenses.example.com \
lensesio/mcp
Transporte HTTP (para clientes remotos, escuta em http://0.0.0.0:8000/mcp):
docker run --rm -it -p 8000:8000 \
-e LENSES_API_KEY=<YOUR_API_KEY> \
-e LENSES_URL=https://lenses.example.com \
-e TRANSPORT=http \
lensesio/mcp
Referência de Variáveis de Ambiente
| Variável | Obrigatória | Padrão | Descrição |
|---|---|---|---|
OAUTH_ENABLED | Não | false | Ativa/desativa OAuth |
LENSES_URL | Sim | http://localhost:9991 | URL da instância Lenses no formato [scheme]://[host]:[port]. Use https:// para conexões seguras (usa automaticamente wss:// para WebSockets) |
MCP_ADVERTISED_URL | Para OAuth | - | URL base pública deste servidor MCP, conforme acessível pelos clientes. Definir isso ativa OAuth e define o padrão de TRANSPORT como http |
LENSES_API_KEY | Para autenticação por chave de API | - | Sua chave de API Lenses (crie via Conta de Serviço IAM). Necessária apenas se não estiver usando OAuth |
TRANSPORT | Não | http se MCP_ADVERTISED_URL estiver definido, caso contrário stdio | Modo de transporte: stdio, http |
PORT | Não | 8000 | Porta para escutar (usada apenas com transporte http) |
LENSES_ADVERTISED_URL | Não | LENSES_URL | URL pública do Lenses HQ anunciada aos clientes MCP para OAuth. Substitua apenas em implantações com planos separados |
MCP_SCOPES | Não | read,write,delete | Escopos OAuth separados por vírgula anunciados nos metadados de recursos protegidos |
INTROSPECTION_URL | Não | Descoberto a partir dos metadados de LENSES_ADVERTISED_URL | Substituição para a URL do endpoint de introspecção de token RFC 7662 |
INTROSPECTION_CACHE_TTL | Não | 0 (desativado) | TTL de cache para resultados de introspecção em segundos |
OTEL_ENABLED | Não | false | Exportar rastreamentos OpenTelemetry (veja seção 7) |
OTEL_EXPORTER | Não | otlp | otlp para enviar a um coletor, ou console para imprimir spans para depuração |
OTEL_SERVICE_NAME | Não | lenses-mcp | Nome do serviço relatado ao backend de rastreamento |
OTEL_EXPORTER_OTLP_ENDPOINT | Não | http://localhost:4318 | URL base do coletor. Lida pelo SDK OpenTelemetry, então todas as variáveis OTEL_* padrão se aplicam |
OTEL_EXPORTER_OTLP_PROTOCOL | Não | http/protobuf | http/protobuf (porta 4318) ou grpc (porta 4317, requer o extra otlp-grpc) |
Variáveis de ambiente legadas (para compatibilidade retroativa):
LENSES_API_HTTP_URL,LENSES_API_HTTP_PORTLENSES_API_WEBSOCKET_URL,LENSES_API_WEBSOCKET_PORT
Elas são derivadas automaticamente de LENSES_URL, mas podem ser definidas explicitamente para substituição.
Endpoints de Transporte
- stdio: Entrada/saída padrão (sem endpoint de rede)
- http: Endpoint HTTP em
/mcp - sse: Endpoint Server-Sent Events em
/sse
Construindo a Imagem Docker Localmente
Para construir a imagem Docker localmente:
docker build -t lensesio/mcp .
7. Rastreamento OpenTelemetry
O servidor é construído sobre FastMCP 4, que emite um span OpenTelemetry para cada
solicitação MCP — tools/call <tool_name>, tools/list, prompts/get <prompt_name>
e assim por diante. Os spans carregam o nome da ferramenta ou prompt, o ID da sessão MCP, a
versão do protocolo negociada e o status de erro quando uma chamada falha.
O rastreamento está desativado por padrão e não custa nada até você ativá-lo.
Ativando
OTEL_ENABLED=true \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
uv run python src/lenses_mcp/server.py
Com Docker:
docker run -p 8000:8000 \
-e LENSES_URL=<your-lenses-url> \
-e LENSES_API_KEY=<your-api-key> \
-e TRANSPORT=http \
-e OTEL_ENABLED=true \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318 \
lensesio/mcp
OTEL_EXPORTER_OTLP_ENDPOINT é uma URL base — o SDK acrescenta /v1/traces
para HTTP. Aponte-o para a raiz do coletor, não para o caminho de traces. Use
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT se precisar especificar a URL completa.
Exportadores
O exportador OTLP HTTP (porta 4318) está incluído por padrão. O exportador gRPC
(porta 4317) adiciona grpcio e acrescenta aproximadamente 27MB à imagem, então
é um extra opcional:
uv sync --extra otlp-grpc
# then
OTEL_EXPORTER_OTLP_PROTOCOL=grpc OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317 ...
Solicitar grpc sem o extra instalado registra um aviso e deixa o rastreamento
desativado; isso nunca impede o servidor de iniciar. O mesmo vale para qualquer outra
configuração incorreta de telemetria — um coletor inacessível ou um nome de exportador inválido é
registrado e o servidor continua atendendo solicitações.
Verificando localmente
A verificação mais rápida não precisa de coletor — imprima spans no stderr:
OTEL_ENABLED=true OTEL_EXPORTER=console uv run python src/lenses_mcp/server.py
O exportador de console escreve em stderr, não em stdout: com o transporte stdio
padrão, o stdout carrega o wire JSON-RPC e qualquer outra coisa impressa lá
o corromperia. Redirecione stderr para um arquivo se os spans congestionarem seu terminal:
OTEL_ENABLED=true OTEL_EXPORTER=console \
uv run python src/lenses_mcp/server.py 2>spans.log
Para uma interface de traces, o Jaeger aceita OTLP/HTTP na porta 4318 e serve sua interface na porta 16686:
docker run -p 16686:16686 -p 4318:4318 \
-e COLLECTOR_OTLP_ENABLED=true jaegertracing/all-in-one:1.62.0
Em seguida, navegue até http://localhost:16686 e selecione o serviço lenses-mcp.
Propagação de contexto de trace
Os spans são emitidos por solicitação MCP; não há span pai em nível de sessão. Um
trace aninhado só se forma quando o cliente propaga o contexto de trace
(traceparent no _meta da solicitação), que o FastMCP extrai e usa como pai.
Clientes que não são instrumentados com OpenTelemetry produzem um trace raiz
por chamada, o que é esperado. Para obter traces agrupados, instrumente o agente que
chama este servidor.
8. Servidor MCP Context7 Opcional
A documentação do Lenses está disponível no Context7. É opcional, mas altamente recomendado usar o Servidor MCP Context7 e ajustar seus prompts com use context7 para garantir que a documentação disponível para o LLM esteja atualizada.
Apêndice: Detalhes do Fluxo OAuth
Sequência de validação de token
O servidor MCP valida tokens de portador usando a seguinte sequência:
-
Metadados de Recursos Protegidos (RFC 9728) —
RemoteAuthProviderserve/.well-known/oauth-protected-resource/mcppara que os clientes possam descobrir qual servidor de autorização usar e quais escopos estão disponíveis. -
Descoberta Automática — Na primeira solicitação recebida, o
DiscoveryTokenVerifierbusca preguiçosamente{LENSES_ADVERTISED_URL}/.well-known/oauth-authorization-serverpara descobrir ointrospection_endpoint. A URL do endpoint também pode ser definida explicitamente viaINTROSPECTION_URL. -
Introspecção de Token (RFC 7662) — Para cada token de portador recebido, o verificador faz um POST para o endpoint de introspecção (
/oauth2/introspect) sem autenticação do cliente. O servidor de autorização responde com:active— se o token é válidoscope— escopos concedidos (ex.:read write)client_id— o proprietário do tokenexp— timestamp de expiração
Tokens inativos ou expirados são rejeitados antes de chegarem à API do Lenses.
-
Encaminhamento de Token — Tokens válidos são encaminhados para a API do Lenses via
Authorization: Bearer <token>para que o Lenses possa realizar suas próprias verificações de autorização.
Escopos de autorização
O servidor anuncia três escopos em seus metadados de recurso protegido:
| Escopo | Descrição |
|---|---|
read | Acesso somente leitura aos recursos do Lenses (tópicos, ambientes, conectores, etc.) |
write | Criar e atualizar recursos |
delete | Excluir recursos |
Os escopos não são aplicados globalmente no nível de introspecção — um token com qualquer subconjunto desses escopos é aceito. A aplicação de escopos por ferramenta pode ser adicionada usando o decorador require_scopes do FastMCP.
Configuração e Requisitos
Em uma implantação simples, apenas duas variáveis de ambiente são necessárias:
LENSES_URL=https://lenses.example.com
MCP_ADVERTISED_URL=http://localhost:8000
Para implantações de plano dividido onde o servidor MCP alcança o Lenses em um endereço interno, mas os clientes usam uma URL pública, defina:
LENSES_URL=http://lenses-hq.internal:9991
LENSES_ADVERTISED_URL=https://lenses.example.com
MCP_ADVERTISED_URL=https://mcp.example.com
O Lenses HQ deve suportar:
- Metadados do Servidor de Autorização OAuth 2.0 (RFC 8414) em
/.well-known/oauth-authorization-server - Introspecção de Token (RFC 7662) no
introspection_endpoint, com autenticação do cliente desabilitada - PKCE com S256 (RFC 7636) para fluxos de autorização do cliente
O servidor MCP não envia credenciais do cliente ao fazer introspecção. O Lenses HQ deve ser configurado com:
oauth2:
authorizationServer:
unauthenticatedIntrospection: true
Sem essa configuração, todo token de portador será rejeitado como inválido.