fes-mcp
Sisense Meta-Management MCP Server
⚠️ Aviso de proyecto experimental
Herramienta contribuida por la comunidad desde Sisense Field Engineering
Este proyecto es una herramienta experimental desarrollada por Sisense Field Engineering para facilitar el aprendizaje y la exploración de las capacidades de Sisense por parte de los clientes. No forma parte del ciclo de vida de lanzamiento del producto principal de Sisense y no pasa por los mismos procesos de validación, soporte o certificación que las funciones de Sisense generalmente disponibles (GA). Se proporciona "tal cual" — consulte Soporte y contribuciones.
Un servidor MCP conforme a los estándares que expone operaciones del entorno de Sisense como herramientas listas para IA, respaldado por el SDK PySisense: gobernanza, gestión de activos y usuarios/grupos, tareas de ciclo de vida y comprobaciones de estado — no creación de gráficos ni preguntas y respuestas analíticas.
Funciona para cualquier usuario de Sisense: cada llamada a una herramienta se ejecuta con las credenciales de Sisense del propio usuario que llama, por lo que los resultados y permisos son exactamente lo que ese usuario puede ver y hacer en Sisense, aplicado de forma nativa por las API de Sisense.
Solo herramientas, sin agente. Claude Desktop, Claude Code, claude.ai, Cursor — cualquier cliente MCP trae su propio agente; este proyecto anuncia y ejecuta ~100 herramientas seleccionadas (paneles, modelos de datos, usuarios/grupos, carpetas, plugins, comprobaciones de salud, …).
Arquitectura
La forma moderna de la especificación MCP, como dos servicios cooperantes distribuidos como dos imágenes de Docker (fes-auth, fes-mcp — construidas a partir de un único Dockerfile de múltiples etapas con capas compartidas):
fes-auth — el servidor de autorización (AS). Gestiona todo lo relacionado con quién llama: OAuth 2.1 para clientes MCP (PKCE, registro dinámico de clientes, descubrimiento), la página de inicio de sesión del navegador y el almacén de credenciales que asigna cada token MCP emitido al token de Sisense del usuario. Proxy de cada llamada de herramienta al servidor de recursos con la credencial de Sisense inyectada.
fes-mcp — el servidor de recursos (RS). Sin estado, no conoce OAuth. Lee la credencial inyectada de cada solicitud, la verifica contra Sisense (en caché) y ejecuta la herramienta como ese usuario contra esa instancia de Sisense.
flowchart LR
subgraph clients [MCP clients]
C1[Claude Desktop]
C2[Claude Code]
C3[claude.ai / Cursor]
end
subgraph box [one host - docker compose]
subgraph AS [fes-auth : authorization server]
O[OAuth 2.1\nPKCE + DCR + discovery]
L[/login page/]
V[(vault\nMCP token → Sisense credential)]
P[/mcp proxy\ninjects credential headers/]
end
subgraph RS [fes-mcp : resource server]
T[Tool layer\nregistry-driven, ~100 tools]
D[Dispatcher\nper-credential PySisense client]
end
end
R[(tool registry JSON\nauto-generated from SDK)] -.defines.-> T
C1 & C2 & C3 -- "MCP over HTTPS\nBearer <MCP token>" --> P
C1 & C2 & C3 -. "browser: sign in once" .-> L
P -- "Authorization: Bearer <Sisense token>\nX-Sisense-Url: <instance>\n(internal network only)" --> T
T --> D
D -- "REST, as the signed-in user" --> F[(Sisense Fusion Deployment)]La unión entre los dos servicios son solo esos dos encabezados más el contrato 401, por lo que cada mitad puede evolucionar — o ser reemplazada — sin que la otra lo note. Deliberadamente no hay secreto compartido entre los dos — la confianza es la red interna (el puerto del RS nunca se publica).
Flujo de inicio de sesión (lo que experimenta un usuario)
Cada usuario agrega el conector una vez en su cliente MCP, indicando su propia instancia de Sisense en la URL:
https://your-host/mcp?target=https://acme.sisense.comsequenceDiagram
participant U as User (browser)
participant C as MCP client
participant A as fes-auth
participant S as Sisense
C->>A: POST /mcp?target=<sisense url> (no token)
A-->>C: 401 + resource metadata URL (carries target)
C->>A: discovery + client registration (RFC 7591)
C->>U: open browser at A's /login
Note over U,A: target present → instance fixed,<br/>only username/password asked<br/>(no target → domain field shown)
U->>A: username/password (or API token for SSO)
A->>S: POST /api/v1/authentication/login
S-->>A: user's Sisense token (kept server-side, in the vault)
A-->>C: authorization code → MCP access token (PKCE)
Note over C,A: from here, silent — token refresh is automaticEl cliente nunca ve las credenciales de Sisense; el servidor nunca almacena contraseñas (se usan una vez para generar el token del usuario y luego se descartan). Los usuarios en instancias con SSO/MFA inician sesión pegando su token personal de API de Sisense en su lugar.
Llamada a herramienta (estado estable)
sequenceDiagram
participant C as MCP client
participant A as fes-auth (proxy)
participant R as fes-mcp (tools)
participant S as Sisense (target)
C->>A: POST /mcp (Bearer <MCP token>)
A->>A: validate token → vault → Sisense credential
A->>R: same request + Authorization: Bearer <Sisense token><br/>+ X-Sisense-Url: <instance>
R->>S: verify credential (TTL-cached) · SDK call as that user
S-->>R: result (user's permissions, user in audit log)
R-->>A: MCP response (streamed)
A-->>C: MCP response (streamed)Ciclo de vida de credenciales y autocuración
El servidor de recursos vuelve a verificar cada par (instancia, token) contra Sisense después de
FES_MCP_VERIFY_TTLsegundos (por defecto 300). Un token revocado en Sisense se convierte en un 401 HTTP en un máximo de ese intervalo.fes-auth trata un 401 del RS como credencial muerta: elimina la entrada del almacén y vuelve a desafiar al cliente MCP, cuyo siguiente paso es volver a ejecutar el flujo de inicio de sesión. Por lo tanto, la revocación del lado del servidor se propaga sin pasos manuales.
Las sesiones están en memoria por diseño (sin base de datos): reiniciar fes-auth cierra la sesión de todos — la siguiente llamada de cada usuario vuelve a mostrar el inicio de sesión del navegador (con
?target=configurado, eso es solo nombre de usuario/contraseña). Reiniciar fes-mcp es invisible: no mantiene estado.
Despliegue (docker compose)
docker compose up --buildEsto construye las dos imágenes (docker build --target fes-auth|fes-mcp) y publica solo fes-auth en :8200; fes-mcp permanece interno. Termine TLS en el frente (ALB / nginx / Caddy) — los clientes MCP requieren HTTPS para OAuth — y establezca FES_MCP_PUBLIC_URL a esa URL pública:
FES_MCP_PUBLIC_URL=https://your-host.example.com docker compose up -d --buildLos usuarios agregan entonces https://your-host.example.com/mcp?target=https://their-instance.sisense.com como conector personalizado. La parte ?target= es opcional — sin ella, la página de inicio de sesión solicita la URL de Sisense como tercer campo.
Endpoints en fes-auth: /mcp (MCP proxy), /login, /.well-known/* + /authorize + /token + /register (OAuth 2.1), / (estado), /healthz. Endurecimiento incluido: limitación de velocidad de inicio de sesión por IP, formulario de inicio de sesión protegido contra CSRF, registros de acceso con identificadores de solicitud.
Inicio rápido (desarrollo local)
Requiere Python 3.11+ y uv. El desarrollo local omite el AS por completo: el transporte stdio usa por defecto autenticación env — una credencial de .env, todo se ejecuta como tú.
uv sync
cp .env.example .env # set SISENSE_DOMAIN / SISENSE_TOKEN
uv run fes-mcp # stdio transportConfiguración del cliente MCP (por ejemplo, claude_desktop_config.json):
{
"mcpServers": {
"sisense": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/fes_mcp", "fes-mcp"]
}
}
}Para ejecutar la división completa localmente sin Docker:
FES_MCP_TRANSPORT=http uv run fes-mcp & # RS on :8200 (upstream auth)
FES_MCP_PORT=8300 FES_MCP_RS_URL=http://127.0.0.1:8200 uv run fes-auth
# connector: http://127.0.0.1:8300/mcp?target=https://your.sisense.comEstructura
src/fes_mcp/—settings(configuración de entorno) ·registry(carga/filtro) ·dispatcher(despacho SDK por credencial) ·upstream(verificación de credenciales RS) ·auth(proveedor OAuth + página de inicio de sesión) ·authserver(servicio fes-auth + proxy) ·middleware(registros de acceso) ·server(ensamblaje FastMCP)config/tools.registry.with_examples.json— registro de herramientas generado automáticamente. Nunca escrito a mano; regenere con./refresh_registry.shcuando PySisense se actualice.config/allowlist.txt— la superficie de herramientas seleccionada, una herramienta por línea. Elimine/comente una línea para quitar una herramienta. Las herramientas no listadas nunca se exponen, por lo que las actualizaciones del registro no pueden ampliar silenciosamente la superficie. (Las herramientas de migración deliberadamente no están listadas — necesitan una conexión de doble instancia que este servidor no modela.)Las herramientas de mutación están protegidas detrás de
FES_MCP_ALLOW_MUTATIONS=true— consulte Seguridad para las salvaguardas completas de mutación.
Consideraciones técnicas y de seguridad
Manejo de credenciales
El cliente MCP nunca ve las credenciales de Sisense, y el servidor nunca almacena contraseñas — una contraseña se usa una vez contra la API de inicio de sesión de Sisense para generar el token del propio usuario, y luego se descarta. Los tokens de Sisense viven en el almacén en memoria de fes-auth, vinculados al token de acceso MCP, y sobreviven a la rotación de refresco. En modo de desarrollo, la única credencial de entorno (SISENSE_DOMAIN/SISENSE_TOKEN) permanece en tu máquina. Nada se persiste en disco: un reinicio de fes-auth borra el almacén (todos vuelven a iniciar sesión) — el intercambio deliberado por no tener base de datos ni superficie de cifrado en reposo.
Endurecimiento en la superficie alojada: limitación de velocidad de inicio de sesión por IP, formulario de inicio de sesión protegido contra CSRF, registros de acceso con identificadores de solicitud y registros de herramientas por llamada (herramienta / dominio de usuario / resultado / duración).
Autorización
Nada personalizado: la autorización es trabajo de Sisense. Cada llamada de herramienta se ejecuta con el token de Sisense del propio usuario que llama, por lo que Sisense aplica sus permisos reales en cada llamada a la API y los errores de permiso se muestran al cliente tal cual. Esta es también la razón por la que el servidor no es solo para administradores — cualquier usuario de Sisense obtiene exactamente su propio alcance.
Confianza entre los dos servicios
La confianza entre fes-auth ↔ fes-mcp es a nivel de red: sin secreto compartido. El puerto del RS nunca debe ser accesible desde fuera de la red interna (compose publica solo fes-auth). Defensa en profundidad: FES_MCP_ALLOWED_SISENSE_ORIGINS fija qué orígenes de Sisense aceptará el RS en X-Sisense-Url.
Mutaciones
Las herramientas de mutación se exponen solo cuando FES_MCP_ALLOW_MUTATIONS=true, siempre llevan destructiveHint, se bloquean en el lado del servidor como segunda capa cuando están deshabilitadas y se escriben en un registro de auditoría de mutaciones.
Además, las herramientas de mutación piden aprobación al humano antes de ejecutarse — mediante elicitación MCP, en clientes que declaran la capacidad (Claude Code, Cursor, VS Code). Se abre un diálogo de proceder/abortar a mitad de la llamada que revela los argumentos exactos; abortar o rechazar no cambia nada. En clientes sin elicitación (Claude Desktop, claude.ai) la llamada procede normalmente y el flujo de aprobación de herramientas del propio cliente más la anotación destructiveHint son la salvaguarda, como para cualquier servidor MCP.
Proceder sin el diálogo es una decisión deliberada (fail-open), no un descuido: la elicitación es una capacidad opcional del cliente y puede ser respondida automáticamente por un cliente que se comporte mal, por lo que se trata estrictamente como UX — el límite de autorización es siempre los permisos de Sisense del propio usuario.
Flujo de datos al proveedor de LLM
Este servidor no tiene capa de resumen ni de redacción de datos: cada resultado de herramienta — filas completas, no metadatos {ok, count} — se devuelve al cliente MCP y llega al contexto del modelo. Esto es por diseño y es lo que hace posible el encadenamiento de herramientas en múltiples pasos: el modelo solo puede razonar, filtrar y alimentar la salida de una herramienta en la siguiente llamada si realmente ve los datos.
La consecuencia: quien conecte este servidor a un cliente MCP acepta que los datos de Sisense (contenidos de paneles, resultados de consultas, listas de usuarios, …) fluyan al proveedor de LLM de ese cliente — por ejemplo, Anthropic, para Claude — bajo sus propios términos con ese proveedor. El servidor no puede imponer ni limitar esto; es una aceptación por despliegue que debe hacerse conscientemente.
Pautas de uso recomendadas
Comience en modo solo lectura: mantenga
FES_MCP_ALLOW_MUTATIONS=false(el valor por defecto) hasta que haya ganado confianza en un entorno que no sea de producción.Seleccione
config/allowlist.txthasta las herramientas que su despliegue realmente necesita — menos herramientas significa menos exposición de datos y una historia de aprobación más clara.Prefiera instancias de Sisense que no sean de producción mientras explora; las herramientas son tan seguras como los permisos del usuario que ha iniciado sesión.
Pruebe operaciones destructivas con un cliente MCP que soporte elicitación (Claude Code, Cursor) para que vea los diálogos de confirmación.
Configuración
Variable | Por defecto | Usado por | Propósito |
| — | fes-mcp | credencial de modo desarrollo ( |
|
| ambos | verificar TLS al llamar a Sisense |
| según el transporte: http ⇒ | fes-mcp | fuente de credenciales |
|
| fes-mcp |
|
|
| ambos | enlace HTTP |
| — | fes-auth | URL base pública (descubrimiento/redirecciones OAuth) |
| — | fes-auth | el servidor de recursos al que proxy las llamadas de herramientas |
|
| fes-mcp | segundos que se confía en un par (instancia, token) verificado |
| — (aceptar cualquiera) | fes-mcp | lista blanca de coincidencia exacta para |
|
| fes-mcp | anulación de tool_ids / módulos separados por comas |
|
| fes-mcp | exponer herramientas de mutación |
| registro incluido | fes-mcp | JSON de registro alternativo |
|
| ambos | verbosidad del registro (solo stderr) |
Pruebas
uv run python -m pytest49 pruebas, sin red y sin credenciales necesarias (Sisense y el SDK están
simulados): selección de registro, validación/errores del despachador, viajes de ida y vuelta de MCP,
confirmación de mutación (aprobar/abortar/rechazar/sin capacidad), verificación de credenciales
ascendentes (cabeceras inyectadas, contrato 401, lista de permitidos de origen,
revocación de TTL), y la división completa AS+RS — baile OAuth con y sin
?target=, metadatos de descubrimiento, llamadas a herramientas proxy, rotación de refresco,
autocuración ante revocación del lado de Sisense, además de las rutas de abuso (CSRF falsificado,
límite de tasa por fuerza bruta, sesiones caducadas).
Regeneración del registro
./refresh_registry.sh # rebuild config/ from the installed PySisense SDKLos nuevos métodos del SDK llegan al registro pero permanecen ocultos hasta que se
añadan explícitamente a config/allowlist.txt.
Soporte y contribuciones
Este es un proyecto experimental, contribuido por la comunidad y mantenido por Sisense Field Engineering, proporcionado "tal cual".
No abra un ticket de GSS — esta no es una función GA de Sisense.
Para preguntas de uso o ayuda para comenzar, contacte a su Gerente de Éxito del Cliente (CSM), quien canalizará los comentarios al equipo de Field Engineering.
Los problemas y contribuciones son bienvenidos a través del repositorio.
Licencia
This server cannot be installed
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 Connectors
Runtime permission, approval, and audit layer for AI agent tool execution.
Manage SRG+ hubs, channels, content, assets, users, and workspaces from any MCP-aware AI agent.
Manage AI assistants, history, calls, campaigns, contacts, knowledge, messaging, and automations.
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/hnegi01/fes-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server