Lenses
Gestiona, explora, transforma y une datos a través de múltiples clústeres utilizando diferentes variantes de Apache Kafka mediante Lenses.io (incluyendo la edición comunitaria gratuita).
Documentación
🌊🔍 Servidor MCP Lenses para Apache Kafka 🔎🌊
Este es el servidor MCP (Model Context Protocol) de Lenses para Apache Kafka. Lenses ofrece una solución de experiencia de desarrollo para ingenieros que construyen aplicaciones en tiempo real conectadas a Kafka. Está diseñado para la empresa y respaldado por un potente modelo de IAM y gobernanza.
Con Lenses, puedes encontrar, explorar, transformar, integrar y replicar datos en un entorno multi-Kafka y de múltiples proveedores. Ahora, todo este poder es accesible a través de tus herramientas de IA y Agentes de IA mediante MCP, aportando contexto en tiempo real a tus flujos de trabajo de ingeniería agénticos.
La forma más rápida de probar el servidor MCP es con la Lenses Community Edition gratuita, que ejecuta Lenses MCP Server como un servidor MCP remoto e incluye un clúster de Kafka de un solo broker preconfigurado con datos de demostración, ideal para desarrollo local o evaluación (pasos aquí).
Tabla de Contenidos
- 1. Instalar uv y Python
- 2. Configurar Variables de Entorno
- 3. Autenticación OAuth 2.1 (Recomendada)
- 4. Clave API de Lenses (Alternativa)
- 5. Ejecutar el Servidor Localmente
- 6. Ejecutar con Docker
- 7. Trazabilidad OpenTelemetry
- 8. Servidor MCP Context7 Opcional
- Apéndice: Detalles del Flujo OAuth
1. Instalar uv y Python
Usamos uv para la gestión de dependencias y la configuración del proyecto. Si no tienes uv instalado, sigue la guía de instalación oficial.
Este proyecto requiere Python 3.13 (cualquier versión 3.13.x). Para verificar tu versión de Python, ejecuta:
uv run python --version
2. Configurar Variables de Entorno
Copia el archivo de entorno de ejemplo y configúralo según tu método de autenticación:
cp .env.example .env
Las variables requeridas dependen de tu elección de autenticación:
- Para OAuth (recomendado):
LENSES_URLyMCP_ADVERTISED_URL - Para Clave API (alternativa):
LENSES_URLyLENSES_API_KEY
3. Autenticación OAuth 2.1 (Recomendada)
OAuth 2.1 es el método de autenticación recomendado para todas las implementaciones de Lenses MCP. Proporciona autorización segura basada en ámbitos sin compartir claves API estáticas.
Cómo funciona
OAuth 2.1 utiliza tokens de portador que se validan mediante RFC 7662 Token Introspection. El flujo involucra tres participantes:
- Cliente MCP — Tu herramienta de IA (Claude, Cursor, etc.)
- Servidor de Autorización — Lenses HQ en
LENSES_ADVERTISED_URL - Servidor MCP — Este servidor (el servidor de recursos)
Cuando te conectas, el cliente automáticamente:
- Descubre los metadatos OAuth de este servidor (
/.well-known/oauth-protected-resource/mcp) - Se registra con el servidor de autorización
- Inicia la autorización OAuth (con PKCE) y obtiene un token de acceso
- Usa el token para autenticar solicitudes a este servidor MCP
Este servidor luego valida el token con Lenses HQ antes de permitir el acceso a los recursos de Kafka.
Configuración simple
Para usar OAuth, debes establecer OAUTH_ENABLED en true, y solo necesitas configurar dos variables de entorno:
OAUTH_ENABLED=true
LENSES_URL=https://lenses.example.com
MCP_ADVERTISED_URL=http://localhost:8000
LENSES_URL— Tu instancia de Lenses (usada internamente y como servidor de autorización OAuth)MCP_ADVERTISED_URL— La URL pública donde este servidor MCP es accesible para los clientes
TRANSPORT toma automáticamente el valor predeterminado de http cuando MCP_ADVERTISED_URL está configurado.
Avanzado: implementaciones de plano dividido
Si el servidor MCP accede a Lenses mediante una dirección interna pero los clientes lo alcanzan mediante una 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
Ámbitos de autorización
El servidor anuncia tres ámbitos:
| Ámbito | Descripción |
|---|---|
read | Acceso de solo lectura a los recursos de Lenses (temas, entornos, conectores, etc.) |
write | Crear y actualizar recursos |
delete | Eliminar recursos |
Cuando te autentiques, se te pedirá que otorgues estos ámbitos. Tu token solo otorgará los ámbitos que selecciones.
Configuración de Lenses HQ
Lenses HQ debe admitir OAuth 2.0 e introspección de tokens. Asegúrate de que la configuración de Lenses HQ incluya:
oauth2:
authorizationServer:
unauthenticatedIntrospection: true
Esto permite que el servidor MCP valide tokens sin credenciales de cliente.
4. Clave API de Lenses (Alternativa)
Para compatibilidad con versiones anteriores y pruebas, puedes usar una clave API estática en lugar de OAuth. No se recomienda para producción, pero puede ser útil para desarrollo local o sistemas heredados.
Crea una clave API de Lenses aprovisionando una Cuenta de Servicio IAM en Lenses. Agrega la clave API a .env:
LENSES_URL=https://lenses.example.com
LENSES_API_KEY=<YOUR_LENSES_API_KEY>
Al usar autenticación con clave API, TRANSPORT toma el valor predeterminado de stdio (solo local) a menos que establezcas explícitamente MCP_ADVERTISED_URL.
5. Ejecutar el Servidor Localmente
Primero, instala las dependencias:
uv sync
Con OAuth (Recomendado)
Ejecuta con transporte stdio (para herramientas de IA locales):
OAUTH_ENABLED=true \
LENSES_URL=https://lenses.example.com \
MCP_ADVERTISED_URL=http://localhost:8000 \
uv run src/lenses_mcp/server.py
O ejecuta con 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 en Claude Desktop, Cursor o herramientas 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"
}
}
}
Con Clave API (Legado)
Usando una clave API estática:
LENSES_URL=https://lenses.example.com \
LENSES_API_KEY=<YOUR_LENSES_API_KEY> \
uv run src/lenses_mcp/server.py
O con 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 en Claude Desktop, Cursor o herramientas 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: Algunos clientes pueden requerir la ruta absoluta a uv en el comando.
6. Ejecutar con Docker
El servidor MCP de Lenses está disponible como imagen Docker en lensesio/mcp. Puedes ejecutarlo con OAuth (recomendado) o autenticación con clave API.
Con OAuth (Recomendado)
Transporte stdio (para herramientas de IA locales):
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, escucha en 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 implementaciones de plano dividido donde el servidor MCP accede a Lenses internamente pero los clientes usan una 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
Con Clave API (Legado)
Transporte stdio (para herramientas de IA locales):
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, escucha en 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
Referencia de Variables de Entorno
| Variable | Requerida | Predeterminado | Descripción |
|---|---|---|---|
OAUTH_ENABLED | No | false | Habilita/deshabilita OAuth |
LENSES_URL | Sí | http://localhost:9991 | URL de la instancia de Lenses en formato [scheme]://[host]:[port]. Usa https:// para conexiones seguras (usa automáticamente wss:// para WebSockets) |
MCP_ADVERTISED_URL | Para OAuth | - | URL base pública de este servidor MCP tal como la alcanzan los clientes. Configurar esto habilita OAuth y establece TRANSPORT a http por defecto |
LENSES_API_KEY | Para autenticación con clave API | - | Tu clave API de Lenses (crea una mediante Cuenta de Servicio IAM). Solo se necesita si no usas OAuth |
TRANSPORT | No | http si MCP_ADVERTISED_URL está configurado, si no stdio | Modo de transporte: stdio, http |
PORT | No | 8000 | Puerto de escucha (solo se usa con transporte http) |
LENSES_ADVERTISED_URL | No | LENSES_URL | URL pública de Lenses HQ anunciada a los clientes MCP para OAuth. Anula solo en implementaciones de plano dividido |
MCP_SCOPES | No | read,write,delete | Ámbitos OAuth separados por comas anunciados en los metadatos de recursos protegidos |
INTROSPECTION_URL | No | Descubierto desde los metadatos de LENSES_ADVERTISED_URL | Anulación para la URL del endpoint de introspección de tokens RFC 7662 |
INTROSPECTION_CACHE_TTL | No | 0 (deshabilitado) | TTL de caché para resultados de introspección en segundos |
OTEL_ENABLED | No | false | Exportar trazas OpenTelemetry (ver sección 7) |
OTEL_EXPORTER | No | otlp | otlp para enviar a un colector, o console para imprimir tramos para depuración |
OTEL_SERVICE_NAME | No | lenses-mcp | Nombre del servicio reportado al backend de trazabilidad |
OTEL_EXPORTER_OTLP_ENDPOINT | No | http://localhost:4318 | URL base del colector. La lee el SDK de OpenTelemetry, por lo que se aplican todas las variables estándar de OTEL_* |
OTEL_EXPORTER_OTLP_PROTOCOL | No | http/protobuf | http/protobuf (puerto 4318) o grpc (puerto 4317, requiere el extra otlp-grpc) |
Variables de entorno heredadas (para compatibilidad con versiones anteriores):
LENSES_API_HTTP_URL,LENSES_API_HTTP_PORTLENSES_API_WEBSOCKET_URL,LENSES_API_WEBSOCKET_PORT
Se derivan automáticamente de LENSES_URL pero se pueden establecer explícitamente para anular.
Endpoints de Transporte
- stdio: Entrada/salida estándar (sin endpoint de red)
- http: Endpoint HTTP en
/mcp - sse: Endpoint de Server-Sent Events en
/sse
Construir la Imagen Docker Localmente
Para construir la imagen Docker localmente:
docker build -t lensesio/mcp .
7. Trazabilidad OpenTelemetry
El servidor está construido sobre FastMCP 4, que emite un tramo OpenTelemetry para cada
solicitud MCP — tools/call <tool_name>, tools/list, prompts/get <prompt_name>
y así sucesivamente. Los tramos llevan el nombre de la herramienta o prompt, el ID de sesión MCP, la
versión del protocolo negociada y el estado de error cuando una llamada falla.
La trazabilidad está desactivada por defecto y no cuesta nada hasta que la actives.
Habilitación
OTEL_ENABLED=true \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
uv run python src/lenses_mcp/server.py
Con 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 es una URL base — el SDK agrega /v1/traces
para HTTP. Apúntalo a la raíz del colector, no a la ruta de trazas. Usa
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT si necesitas especificar la URL completa.
Exportadores
El exportador OTLP HTTP (puerto 4318) está incluido por defecto. El exportador gRPC
(puerto 4317) incorpora grpcio y agrega aproximadamente 27MB a la imagen, por lo que
es un extra opcional:
uv sync --extra otlp-grpc
# then
OTEL_EXPORTER_OTLP_PROTOCOL=grpc OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317 ...
Solicitar grpc sin el extra instalado registra una advertencia y deja la trazabilidad
desactivada; nunca impide que el servidor se inicie. Lo mismo ocurre con cualquier otra
configuración incorrecta de telemetría — un colector inalcanzable o un nombre de exportador incorrecto se
registra y el servidor continúa atendiendo solicitudes.
Verificación local
La verificación más rápida no necesita colector — imprime los tramos en stderr:
OTEL_ENABLED=true OTEL_EXPORTER=console uv run python src/lenses_mcp/server.py
El exportador de consola escribe en stderr, no en stdout: con el transporte stdio
predeterminado, stdout lleva el cable JSON-RPC y cualquier otra cosa impresa allí
lo corrompería. Redirige stderr a un archivo si los tramos saturan tu terminal:
OTEL_ENABLED=true OTEL_EXPORTER=console \
uv run python src/lenses_mcp/server.py 2>spans.log
Para una interfaz de trazas, Jaeger acepta OTLP/HTTP en 4318 y sirve su interfaz en 16686:
docker run -p 16686:16686 -p 4318:4318 \
-e COLLECTOR_OTLP_ENABLED=true jaegertracing/all-in-one:1.62.0
Luego navega a http://localhost:16686 y selecciona el servicio lenses-mcp.
Propagación del contexto de trazas
Los tramos se emiten por solicitud MCP; no hay un tramo padre a nivel de sesión. Una
traza anidada solo se forma cuando el cliente propaga el contexto de trazas
(traceparent en la solicitud _meta), que FastMCP extrae y usa como padre.
Los clientes que no están instrumentados con OpenTelemetry producen una traza raíz
por llamada, lo cual es esperado. Para obtener trazas agrupadas, instrumenta el agente que
llama a este servidor.
8. Servidor MCP Context7 Opcional
La documentación de Lenses está disponible en Context7. Es opcional pero muy recomendable usar el Servidor MCP Context7 y ajustar tus prompts con use context7 para asegurar que la documentación disponible para el LLM esté actualizada.
Apéndice: Detalles del Flujo OAuth
Secuencia de validación de tokens
El servidor MCP valida los tokens de portador usando la siguiente secuencia:
-
Metadatos de Recursos Protegidos (RFC 9728) —
RemoteAuthProvidersirve/.well-known/oauth-protected-resource/mcppara que los clientes puedan descubrir qué servidor de autorización usar y qué ámbitos están disponibles. -
Auto-descubrimiento — En la primera solicitud entrante, el
DiscoveryTokenVerifierobtiene de forma diferida{LENSES_ADVERTISED_URL}/.well-known/oauth-authorization-serverpara descubrir elintrospection_endpoint. La URL del endpoint también se puede establecer explícitamente medianteINTROSPECTION_URL. -
Introspección de tokens (RFC 7662) — Para cada token de portador entrante, el verificador envía un POST al endpoint de introspección (
/oauth2/introspect) sin autenticación de cliente. El servidor de autorización responde con:active— si el token es válidoscope— los alcances otorgados (p. ej.,read write)client_id— el propietario del tokenexp— la marca de tiempo de expiración
Los tokens inactivos o expirados se rechazan antes de llegar a la API de Lenses.
-
Reenvío de tokens — Los tokens válidos se reenvían a la API de Lenses mediante
Authorization: Bearer <token>para que Lenses pueda realizar sus propias comprobaciones de autorización.
Alcances de autorización
El servidor anuncia tres alcances en sus metadatos de recursos protegidos:
| Alcance | Descripción |
|---|---|
read | Acceso de solo lectura a los recursos de Lenses (temas, entornos, conectores, etc.) |
write | Crear y actualizar recursos |
delete | Eliminar recursos |
Los alcances no se aplican globalmente a nivel de introspección: se acepta un token con cualquier subconjunto de estos alcances. La aplicación de alcances por herramienta se puede agregar usando el decorador require_scopes de FastMCP.
Configuración y requisitos
En una implementación simple, solo se requieren dos variables de entorno:
LENSES_URL=https://lenses.example.com
MCP_ADVERTISED_URL=http://localhost:8000
Para implementaciones de plano dividido donde el servidor MCP llega a Lenses mediante una dirección interna pero los clientes usan una URL pública, configure:
LENSES_URL=http://lenses-hq.internal:9991
LENSES_ADVERTISED_URL=https://lenses.example.com
MCP_ADVERTISED_URL=https://mcp.example.com
Lenses HQ debe admitir:
- Metadatos del servidor de autorización OAuth 2.0 (RFC 8414) en
/.well-known/oauth-authorization-server - Introspección de tokens (RFC 7662) en el
introspection_endpoint, con autenticación de cliente deshabilitada - PKCE con S256 (RFC 7636) para flujos de autorización de cliente
El servidor MCP no envía credenciales de cliente al realizar la introspección. Lenses HQ debe configurarse con:
oauth2:
authorizationServer:
unauthenticatedIntrospection: true
Sin esta configuración, cada token de portador será rechazado como inválido.