fes-mcp
Sisense Meta-Management MCP Server
⚠️ Уведомление об экспериментальном проекте
Инструмент, созданный сообществом, от инженерного отдела Sisense Field Engineering
Этот проект — экспериментальный инструмент, разработанный инженерным отделом Sisense Field Engineering для облегчения изучения и исследования возможностей Sisense клиентами. Он не является частью основного жизненного цикла выпуска продукта Sisense и не проходит те же процессы валидации, поддержки или сертификации, что и общедоступные (GA) функции Sisense. Он предоставляется «как есть» — см. Поддержка и вклад.
Сервер MCP, соответствующий стандартам, который предоставляет операции с окружением Sisense как инструменты, готовые для ИИ, на основе SDK PySisense: управление, управление активами и пользователями/группами, задачи жизненного цикла и проверки работоспособности — не создание дашбордов или аналитические Q&A.
Он работает для любого пользователя Sisense: каждый вызов инструмента выполняется с собственными учетными данными вызывающего пользователя в Sisense, поэтому результаты и разрешения точно соответствуют тому, что этот пользователь может видеть и делать в самом Sisense, что обеспечивается нативно API Sisense.
Только инструменты, без агента. Claude Desktop, Claude Code, claude.ai, Cursor — любой MCP-клиент приносит своего собственного агента; этот проект предоставляет и выполняет ~100 подобранных инструментов (дашборды, модели данных, пользователи/группы, папки, плагины, проверки работоспособности, …).
Архитектура
Современная форма спецификации MCP — два взаимодействующих сервиса,
поставляемых как два Docker-образа (fes-auth, fes-mcp — собранные из
одного многоступенчатого Dockerfile с общими слоями):
fes-auth — сервер авторизации (AS). Владеет всем, что касается кто вызывает: OAuth 2.1 для MCP-клиентов (PKCE, динамическая регистрация клиентов, обнаружение), страница входа в браузере и хранилище учетных данных, сопоставляющее каждый выданный MCP-токен с токеном Sisense пользователя. Он проксирует каждый вызов инструмента на сервер ресурсов с внедренными учетными данными Sisense.
fes-mcp — сервер ресурсов (RS). Не имеет состояния, не знает об OAuth. Читает внедренные учетные данные из каждого запроса, проверяет их против Sisense (с кэшированием) и выполняет инструмент от имени этого пользователя против этого экземпляра 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)]Стык между двумя сервисами — это просто эти два заголовка плюс контракт 401, поэтому каждая половина может развиваться — или быть заменена — без ведома другой. Между ними намеренно нет общего секрета — доверие обеспечивается внутренней сетью (порт RS никогда не публикуется).
Процесс входа (что испытывает пользователь)
Каждый пользователь добавляет коннектор один раз в своем MCP-клиенте, указывая свой собственный экземпляр Sisense в 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 automaticКлиент никогда не видит учетные данные Sisense; сервер никогда не хранит пароли (используются один раз для выпуска токена пользователя, затем отбрасываются). Пользователи на экземплярах с SSO/MFA входят, вставляя вместо этого свой личный API-токен Sisense.
Вызов инструмента (установившийся режим)
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)Жизненный цикл учетных данных и самовосстановление
Сервер ресурсов повторно проверяет каждую пару (экземпляр, токен) против Sisense через
FES_MCP_VERIFY_TTLсекунд (по умолчанию 300). Токен, отозванный в Sisense, превращается в HTTP 401 в течение максимум этого окна.fes-auth рассматривает 401 от RS как мертвые учетные данные: он удаляет запись из хранилища и повторно запрашивает MCP-клиента, чей следующий шаг — повторный запуск процесса входа. Таким образом, отзыв на стороне сервера распространяется без ручных действий.
Сеансы по замыслу хранятся в памяти (без базы данных): перезапуск fes-auth выводит всех пользователей — следующий вызов каждого пользователя снова открывает вход в браузере (с
?target=, это просто имя пользователя/ пароль). Перезапуск fes-mcp незаметен: он не хранит состояние.
Развертывание (docker compose)
docker compose up --buildЭто собирает два образа (docker build --target fes-auth|fes-mcp) и
публикует только fes-auth на :8200; fes-mcp остается внутренним. Завершите
TLS на фронте (ALB / nginx / Caddy) — MCP-клиенты требуют HTTPS для OAuth —
и установите FES_MCP_PUBLIC_URL на этот публичный URL:
FES_MCP_PUBLIC_URL=https://your-host.example.com docker compose up -d --buildЗатем пользователи добавляют https://your-host.example.com/mcp?target=https://their-instance.sisense.com
как пользовательский коннектор. Часть ?target= необязательна — без нее на
странице входа запрашивается URL Sisense как третье поле.
Конечные точки на fes-auth: /mcp (проксируемый MCP), /login,
/.well-known/* + /authorize + /token + /register (OAuth 2.1), /
(статус), /healthz. Включено усиление защиты: ограничение скорости входа по
IP, защищенная от CSRF форма входа, журналы доступа с идентификаторами запросов.
Быстрый старт (локальная разработка)
Требуется Python 3.11+ и uv. Локальная разработка
полностью пропускает AS: транспорт stdio по умолчанию использует аутентификацию
env — одни учетные данные из .env, все выполняется от вашего имени.
uv sync
cp .env.example .env # set SISENSE_DOMAIN / SISENSE_TOKEN
uv run fes-mcp # stdio transportКонфигурация MCP-клиента (например, claude_desktop_config.json):
{
"mcpServers": {
"sisense": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/fes_mcp", "fes-mcp"]
}
}
}Чтобы запустить полное разделение локально без 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.comСтруктура
src/fes_mcp/—settings(конфигурация env) ·registry(загрузка/ фильтрация) ·dispatcher(диспетчеризация SDK по учетным данным) ·upstream(проверка учетных данных RS) ·auth(OAuth-провайдер + страница входа) ·authserver(сервис fes-auth + прокси) ·middleware(журналы доступа) ·server(сборка FastMCP)config/tools.registry.with_examples.json— автоматически сгенерированный реестр инструментов. Никогда не пишется вручную; перегенерируйте с помощью./refresh_registry.shпри обновлении PySisense.config/allowlist.txt— подобранная поверхность инструментов, по одному инструменту на строку. Удалите/закомментируйте строку, чтобы удалить инструмент. Инструменты, не перечисленные в списке, никогда не предоставляются, поэтому обновления реестра не могут незаметно расширить поверхность. (Инструменты миграции намеренно не перечислены — им нужно двухэкземплярное соединение, которое этот сервер не моделирует.)Изменяющие инструменты ограничены
FES_MCP_ALLOW_MUTATIONS=true— см. Безопасность для полных мер защиты от изменений.
Технические и соображения безопасности
Обработка учетных данных
MCP-клиент никогда не видит учетные данные Sisense, и сервер никогда не хранит
пароли — пароль используется один раз против API входа Sisense для выпуска
собственного токена пользователя, затем отбрасывается. Токены Sisense хранятся
в хранилище в памяти fes-auth, привязанном к MCP-токену доступа, и переживают
ротацию обновления. В режиме разработки единственные учетные данные из env
(SISENSE_DOMAIN/SISENSE_TOKEN) остаются на вашей машине. Ничего не
сохраняется на диск: перезапуск fes-auth стирает хранилище (все входят заново)
— это осознанный компромисс ради отсутствия базы данных и поверхности
шифрования в состоянии покоя.
Усиление защиты на размещенной поверхности: ограничение скорости входа по IP, защищенная от CSRF форма входа, журналы доступа с идентификаторами запросов и поинструментальные журналы (инструмент / домен пользователя / результат / длительность).
Авторизация
Ничего кастомного: авторизация — это работа Sisense. Каждый вызов инструмента выполняется с собственным токеном Sisense вызывающего пользователя, поэтому Sisense применяет их реальные разрешения к каждому вызову API, и ошибки разрешений передаются клиенту дословно. Это также причина, почему сервер не только для администраторов — любой пользователь Sisense получает ровно свою собственную область.
Доверие между двумя сервисами
Доверие fes-auth ↔ fes-mcp — на уровне сети: без общего секрета. Порт RS
никогда не должен быть доступен извне внутренней сети (compose публикует
только fes-auth). Глубина защиты: FES_MCP_ALLOWED_SISENSE_ORIGINS закрепляет,
какие источники Sisense RS будет принимать в X-Sisense-Url.
Изменения
Изменяющие инструменты предоставляются только при
FES_MCP_ALLOW_MUTATIONS=true, всегда несут destructiveHint, блокируются на
стороне сервера как второй уровень при отключении и записываются в журнал
аудита изменений.
Кроме того, изменяющие инструменты запрашивают у человека одобрение перед
выполнением — через элиситацию MCP, на клиентах, объявляющих эту возможность
(Claude Code, Cursor, VS Code). Диалог «продолжить/прервать» открывается
посреди вызова, раскрывая точные аргументы; прерывание или отклонение ничего
не меняет. На клиентах без элиситации (Claude Desktop, claude.ai) вызов
выполняется обычным образом, и собственный процесс одобрения инструментов
клиента плюс аннотация destructiveHint являются защитой, как для любого
MCP-сервера.
Продолжение без диалога — осознанное решение (fail-open), а не упущение: элиситация — это необязательная возможность клиента, и ее может автоматически ответить неисправный клиент, поэтому она рассматривается строго как UX — граница авторизации всегда является собственными разрешениями пользователя в Sisense.
Поток данных к LLM-провайдеру
Этот сервер не имеет уровня суммаризации или редактирования данных: каждый
результат инструмента — полные строки, а не метаданные {ok, count} —
возвращается MCP-клиенту и попадает в контекст модели. Это сделано намеренно
и именно это обеспечивает работу многошаговых цепочек инструментов: модель
может рассуждать, фильтровать и передавать вывод одного инструмента в
следующий вызов, только если она действительно видит данные.
Следствие: тот, кто подключает этот сервер к MCP-клиенту, принимает, что данные Sisense (содержимое дашбордов, результаты запросов, списки пользователей, …) передаются LLM-провайдеру этого клиента — например, Anthropic для Claude — на их собственных условиях с этим провайдером. Сервер не может обеспечить или ограничить это; это осознанное принятие для каждого развертывания.
Рекомендуемые правила использования
Начните с режима только для чтения: держите
FES_MCP_ALLOW_MUTATIONS=false(по умолчанию), пока не обретете уверенность в непроизводственной среде.Сократите
config/allowlist.txtдо инструментов, которые действительно нужны вашему развертыванию — меньше инструментов означает меньше раскрытия данных и более понятную историю одобрений.Предпочитайте непроизводственные экземпляры Sisense при исследовании; инструменты настолько безопасны, насколько безопасны разрешения вошедшего пользователя.
Тестируйте разрушительные операции с MCP-клиентом, поддерживающим элиситацию (Claude Code, Cursor), чтобы видеть диалоги подтверждения.
Конфигурация
Переменная | По умолчанию | Используется | Назначение |
| — | fes-mcp | учетные данные режима разработки ( |
|
| оба | проверять TLS при вызове Sisense |
| по транспорту: http ⇒ | fes-mcp | источник учетных данных |
|
| fes-mcp |
|
|
| оба | привязка HTTP |
| — | fes-auth | публичный базовый URL (обнаружение/редиректы OAuth) |
| — | fes-auth | сервер ресурсов для проксирования вызовов инструментов |
|
| fes-mcp | секунды, в течение которых проверенная пара (экземпляр, токен) доверяется |
| — (принимать любые) | fes-mcp | точное совпадение allowlist для |
|
| fes-mcp | переопределение через запятую tool_ids / модулей |
|
| fes-mcp | предоставлять изменяющие инструменты |
| встроенный реестр | fes-mcp | альтернативный JSON реестра |
|
| оба | подробность журнала (только stderr) |
Тесты
uv run python -m pytest(python -m важен: он помещает корень репозитория в sys.path, на что
полагаются импорты from tests.conftest import … в тестовых модулях.)
49 тестов, без сети и без учетных данных (Sisense и SDK замоканы): выбор реестра, проверка/ошибки диспетчера, MCP-циклы, подтверждение мутаций (approve/abort/decline/no-capability), проверка вышестоящих учетных данных (внедренные заголовки, контракт 401, список разрешенных источников, отзыв TTL), и полное разделение AS+RS — OAuth-танец с ?target= и без, метаданные обнаружения, проксированные вызовы инструментов, ротация обновлений, самовосстановление при отзыве на стороне Sisense, плюс пути злоупотреблений (поддельный CSRF, ограничение скорости перебора, истекшие сессии).
Регенерация реестра
./refresh_registry.sh # rebuild config/ from the installed PySisense SDKНовые методы SDK попадают в реестр, но остаются скрытыми, пока не будут явно добавлены в config/allowlist.txt.
Поддержка и вклад
Это экспериментальный проект, созданный сообществом и поддерживаемый Sisense Field Engineering, предоставляемый «как есть».
Не открывайте тикет GSS — это не функция GA Sisense.
По вопросам использования или помощи в начале работы обращайтесь к вашему менеджеру по успеху клиентов (CSM), который направит отзывы команде Field Engineering.
Проблемы и вклад приветствуются через репозиторий.
Лицензия
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