Skip to main content
Glama
Destiny-Enterprises

Dashboard Builder MCP server

MCP-сервер Dashboard Builder

Позволяет ИИ-клиенту обнаруживать ваши наборы данных и создавать дашборды в Dashboard Builder.

Он общается с приложением Next.js по HTTP как обычный API-клиент, поэтому все защитные механизмы разрешений, политики зависимостей и правила валидации в приложении по-прежнему действуют. В основном приложении ничего не меняется.

Запускать его можно двумя способами:

Кто запускает

Идентичность

Что нужно пользователям

Хостинг

один сервер, вся организация

личный аккаунт каждого, привязанный к его ключу один раз

URL и ключ

Локально

каждый человек, своя машина

личный аккаунт этого человека

Node и копия этой папки

Хостинг — это обычное развертывание, и именно его описывает этот документ. Локальный режим предназначен для разработки самого сервера или для индивидуальной идентичности пользователя и описан в DEVELOPMENT.md.


Для пользователей: подключение к размещенному серверу

Вам нужно две вещи от того, кто его развернул: URL и ваш ключ доступа. Ничего клонировать, никаких файлов указывать, никакого .env.

Добавьте это в claude_desktop_config.json (Claude Desktop) или .mcp.json (Claude Code):

{
  "mcpServers": {
    "dashboard-builder": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mcp.yourcompany.com/mcp",
        "--header", "Authorization: Bearer YOUR_KEY_HERE",
        "--header", "X-Dashboard-Username: you",
        "--header", "X-Dashboard-Password: your-dashboard-password"
      ]
    }
  }
}

mcpServers — это ключ верхнего уровня, сосед preferences, а не вложенный в него. Выйдите из Claude Desktop через системный трей и откройте заново; закрытие окна недостаточно.

При наличии двух заголовков X-Dashboard-* сервер автоматически входит в систему от вашего имени при первом использовании и снова при истечении сессии — больше ничего делать не нужно, и каждый вызов действует как вы: ваши разрешения, ваш журнал аудита. Обратная сторона: ваш пароль от дашборда хранится в этом конфигурационном файле и передается (по HTTPS) с каждым запросом. Если пароль содержит символы вне ASCII, используйте вместо этого привязку через curl — HTTP-заголовки не передают их надежно.

Альтернатива: привяжите один раз через curl, не храните пароль в конфиге

Опустите два заголовка X-Dashboard-* и вместо этого привяжите свой ключ один раз — пароль используется для этого единственного входа и нигде не сохраняется; сервер хранит только полученные токены сессии, точно так же, как браузер хранит куки:

curl -X POST https://mcp.yourcompany.com/auth/bind \
  -H "Authorization: Bearer YOUR_KEY_HERE" \
  -H "content-type: application/json" \
  -d '{"username":"you","password":"your-dashboard-password"}'

Отличие от маршрута с заголовками: когда цепочка сессий в конце концов истекает, вы повторно запускаете эту команду, тогда как заголовки перепривязываются автоматически. DELETE /auth/bind с тем же заголовком Authorization в любом случае отключает ключ.

Alice's Claude ──[gate key]──> MCP server ──[Alice's session cookies]──> Dashboard API
                     ^                                ^
              client config              bound via credential headers or
                                         POST /auth/bind; refreshed
                                         automatically after that

Учетные данные

Где хранятся

Отвечает на вопрос

Ключ доступа

конфиг каждого пользователя

может ли этот человек использовать MCP-сервер?

Токены сессии

на сервере, один файл на ключ

от чьего имени действует этот ключ?

Если ключ никогда не был привязан, вызовы инструментов завершаются ошибкой, объясняющей шаг привязки — или, если сервер настроен с устаревшей сервисной учетной записью, они возвращаются к этой общей идентичности.

mcp-remote — это небольшой мост, который запускается локально и пересылает запросы на сервер, поэтому на машине пользователя должен быть установлен Node. Чтобы избежать даже этого, в Claude Desktop Настройки → Коннекторы → Добавить пользовательский коннектор принимает URL напрямую без локальных компонентов — этот путь ожидает OAuth, а не статический ключ, и доступность зависит от версии Desktop.


Related MCP server: MCP SQL Server Data Warehouse Connector

Развертывание сервера

server.js — это стартовый файл. Он слушает PORT как server.js в Next.js и ставит шлюз API-ключей перед каждым MCP-запросом, чтобы неаутентифицированные вызывающие отклонялись до того, как что-либо достигнет системы дашбордов.

Конечные точки: POST /mcp (защищено), POST /auth/bind и DELETE /auth/bind (защищено — привязать или отвязать идентичность дашборда вызывающего ключа), и GET /health (открыто, для проверки работоспособности платформы). Всё остальное возвращает 404.

Переменные окружения

Обязательные — без них сервер не запустится

Переменная

Значение

DASHBOARD_API_URL

https://dashboard.yourcompany.com

MCP_API_KEYS

alice:<secret>,bob:<secret> — по одному на человека, минимум 24 символа

Сгенерируйте ключи с помощью openssl rand -hex 24. Метка перед двоеточием появляется в журналах и корзинах ограничения скорости; сам секрет никогда не логируется. Чтобы отозвать доступ у человека, удалите его запись и перезапустите сервер — а также удалите его файл сессии в ~/.dashboard-mcp/sessions/, чтобы сбросить и привязанную идентичность.

Затем каждый ключ привязывается к учетной записи дашборда его владельцем через POST /auth/bind — см. раздел для пользователей выше. Никакие учетные данные дашборда не хранятся в окружении сервера.

Необязательный устаревший запасной вариант — общая сервисная учетная запись

Переменная

Значение

DASHBOARD_MCP_USERNAME

сервисная учетная запись

DASHBOARD_MCP_PASSWORD

пароль этой учетной записи

Если задано, ключи, которые не были привязаны, действуют как эта общая учетная запись вместо ошибки — как и ключ, у которого истекла привязка, пока он не будет перепривязан. Полезно во время миграции; пропустите это для новых развертываний, чтобы у каждого вызывающего была своя идентичность.

Настоятельно рекомендуется

Переменная

Значение

Зачем

DASHBOARD_MCP_ALLOW_WRITES

false

начать в режиме только для чтения, пока не привязаны идентичности

MCP_ALLOWED_HOSTS

mcp.yourcompany.com

включает защиту от DNS-rebinding

MCP_ALLOWED_ORIGINS

origin вашего клиента

то же

Оставьте DASHBOARD_MCP_PERSIST_SESSION по умолчанию (true): привязки хранятся по одному файлу на ключ и переживают перезапуски. Установка false хранит привязки только в памяти, поэтому каждый перезапуск — и каждый воркер в многопроцессорном хосте — требует повторной привязки.

MCP_ALLOWED_HOSTS и MCP_ALLOWED_ORIGINS — необязательные — сервер работает без них, и шлюз API-ключей по-прежнему действует. Установка любого из них включает защиту транспорта от DNS-rebinding. Если оставить оба неустановленными, журнал запуска явно сообщит об этом.

Необязательные

Переменная

По умолчанию

PORT

3001

HOST

127.0.0.1 — держит порт вне публичного интерфейса; обратный прокси достигает его локально

MCP_RATE_LIMIT

120 запросов на ключ за окно

MCP_RATE_LIMIT_WINDOW_MS

60000

Дополнительные переменные настройки — путь к файлу сессии, таймаут запроса, ограничения ответа и переопределение идентификатора типа дашборда — задокументированы в .env.example, который организован по режимам и перечисляет все переменные, которые читает сервер.

Примечание о нескольких воркерах

Привязки хранятся по одному файлу на ключ, и воркер, чей токен в памяти был заменен другим воркером, восстанавливается, перечитывая этот файл, который уже обновил выигравший воркер. Окно сбоя — это два воркера, обновляющих один и тот же токен в один и тот же момент; проигравший восстанавливается при следующей попытке, а в худшем случае ключ нужно перепривязать. Сам транспорт MCP не имеет состояния, поэтому запросы могут попадать на любой воркер.

Настройка Plesk

Настройка

Значение

Корень приложения

каталог mcp-server

Стартовый файл приложения

server.js

Режим приложения

production

Переменные окружения

таблицы выше, в панели Node.js

Перед запуском

npm install, затем npm run build

Добавьте в Дополнительные директивы nginx домена:

proxy_buffering off;
proxy_read_timeout 300s;

MCP отвечает через Server-Sent Events, и nginx по умолчанию буферизует проксируемые ответы. Без proxy_buffering off запросы выглядят зависшими, а не завершающимися ошибкой, что является запутанным способом потерять полдня.

Держите порт Node вне публичного брандмауэра. nginx Plesk проксирует на него и устанавливает X-Forwarded-For, что делает записываемые IP-адреса клиентов достоверными.

Доступ и идентичность

Ключ доступа управляет доступом; идентичность исходит из привязки. Ключ пропускает вызывающего через шлюз, а сессия, привязанная к этому ключу, определяет, кого видит дашборд — их разрешения, их журнал аудита. Эти две вещи намеренно разделены: ротация секрета ключа сбрасывает его привязку (сессия хранится под дайджестом ключа), а отзыв ключа удаляет доступ, не затрагивая учетную запись.

Привязка работает так же, как вход в браузере. POST /auth/bind один раз запускает настоящий /api/auth/login приложения, пароль отбрасывается после обмена, и сохраняется только вращающаяся сессия refresh-токена — один файл на ключ, режим 0600. Поскольку приложение вращает refresh-токен при каждом использовании, утекший файл сессии быстро умирает; поскольку пароль никогда не хранится, нечего долго хранить. Компромисс: когда цепочка refresh-токенов истекает или ломается, этот ключ перепривязывается одной командой curl.

Стабильные учетные данные на запрос (ApiKey в основной системе или OAuth) устранили бы даже эту перепривязку, но потребовали бы изменений в основном приложении. Этот дизайн намеренно не требует никаких изменений.


Разработка или локальный запуск

Запуск сервера на вашей собственной машине — для разработки или для индивидуальной идентичности без хостинга — описан отдельно в DEVELOPMENT.md.

Инструменты

Цепочка такая: источник данных (HTTP API или загрузка Excel) → набор данных (структурированное представление с рабочим процессом преобразования) → виджеты дашборда. Инструменты охватывают все три этапа.

Инструмент

Режим

Назначение

list_datasources

чтение

Идентификаторы источников данных, метки, типы (http/excel) и цели

describe_datasource

чтение

Форма одного источника: параметры, путь к ответу, колонки — никогда учётные данные

preview_datasource

чтение

Живые строки из источника; предлагает кандидатов на путь ответа при сбое

list_datasets

чтение

Идентификаторы наборов данных, метки и области видимости

describe_dataset

чтение

Точные имена полей, выведенные типы, по одному примеру значения на каждое

sample_dataset

чтение

Ограниченная выборка реальных строк

get_dataset

чтение

Полное определение набора данных: источник, материализация, сводка workflow или исходный конверт

validate_dataset_workflow

чтение

Прогон черновика workflow против реальных данных без сохранения; диагностика по шагам

list_dashboards

чтение

Идентификаторы дашбордов, метки и области видимости

get_dashboard

чтение

Детали дашборда плюс по одной строке на виджет; одна конфигурация по запросу

list_widget_kinds

чтение

Доступные для создания виды виджетов

describe_widget_kind

чтение

Контракт конфигурации для одного вида, плюс реальный пример из вашего рабочего пространства

test_datasource

запись

Пробный прогон конфигурации HTTP-эндпоинта; ничего не сохраняется, колонки и пути выводятся

create_datasource

запись

Создание HTTP-источника данных; сервер проверяет URL и создаёт набор данных по умолчанию

update_datasource

запись

Изменение частей HTTP-источника; объединяется с сохранённой конфигурацией

create_dataset

запись

Создание набора данных; сервер строит workflow по умолчанию, если он не задан

update_dataset

запись

Частичное обновление: метка, источник, лимиты, материализация или замена workflow

refresh_dataset_snapshot

запись

Повторный запуск набора данных со снапшот-материализацией или отчёт о последнем обновлении

create_dashboard

запись

Создание дашборда и привязка его наборов данных

set_dashboard_datasets

запись

Замена списка наборов данных дашборда

add_widget

запись

Добавление одного виджета с автоматическим размещением на сетке

update_widget

запись

Изменение заголовка, набора данных или ключей конфигурации

delete_widget

запись

Удаление виджета

arrange_dashboard

запись

Переупаковка сетки или применение явных позиций

test_datasource находится в наборе операций записи, потому что приложение ограничивает его правом создания/редактирования источника данных, и он вызывает вышестоящий эндпоинт — но ничего не сохраняет.

Заметки по дизайну

Дисциплина контекста. Вся поверхность инструментов занимает около 7 КБ — 24 описания плюс инструкции сервера — поэтому её дёшево держать загруженной. Ответы — это компактный текст, а не сырой JSON, и каждый список ограничен с явным примечанием о том, что было опущено. get_dashboard намеренно опускает конфигурации виджетов; вы запрашиваете один виджет по идентификатору, когда вам нужна его конфигурация.

Прогрессивное раскрытие. Конфигурация графика содержит примерно 59 полей. Помещение её в описание инструмента доминировало бы в контексте клиента при каждом запросе, поэтому describe_widget_kind вместо этого выдаёт контракт по требованию: имена полей, типы, примечания, минимальный рабочий пример и — самая полезная часть — реальную конфигурацию, собранную из существующего виджета этого вида в вашем собственном рабочем пространстве. Копирование формы, которая уже отображается, лучше, чем изобретение её по именам полей.

Геометрией занимается сервер. Модели ненадёжны в 2D-упаковке. add_widget принимает подсказку size (small, medium, large, full) и сам находит первую свободную непересекающуюся ячейку на сетке из 12 колонок. arrange_dashboard в режиме auto переупаковывает весь дашборд.

Сбой до API, а не после. Конфигурации виджетов хранятся приложением как непрозрачный JSON, поэтому опечатка в ключе даёт пустой виджет, а не ошибку. add_widget сначала проверяет конфигурацию на соответствие контракту вида — обязательные ключи, допустимые имена агрегаций, наличие field, когда агрегация его требует — и возвращает конкретный список того, чего не хватает.

Виджеты соответствуют тому, что создал бы интерфейс. Палитра приложения заполняет каждый новый виджет значением defaultConfig вида из реестра (config === undefined ? def.defaultConfig : config). add_widget повторяет это: значения по умолчанию вида подкладываются под всё, что передаёт вызывающий, поэтому виджет, созданный через MCP, несёт ту же базовую линию paginationMode и maxPoints, что и созданный вручную, вместо разреженной конфигурации, на которую рендереру пришлось бы опираться. Проверяется именно объединённый объект.

Объединение вместо повторной отправки. PATCH /widgets/:id заменяет объект конфигурации целиком. update_widget по умолчанию объединяет ваши ключи с существующей конфигурацией, поэтому изменение одной настройки не означает повторную отправку всего.

Закрытие при сбое при запуске. HTTP-сервер отказывается запускаться без хотя бы одной записи MCP_API_KEYS и отклоняет ключи короче 24 символов. Неаутентифицированный MCP-эндпоинт не должен быть возможен случайно. Ключи сравниваются как SHA-256-дайджесты с помощью timingSafeEqual, и в журнал попадают только метки.

Секреты остаются на стороне сервера. describe_datasource читает эндпоинт /schema приложения, который никогда не включает учётные данные. update_datasource требует полную сохранённую конфигурацию для объединения — он получает её внутри выполнения инструмента и отправляет объединённый результат обратно, никогда не отображая authConfig, сохранённые заголовки или тело в контексте модели.

Проверка перед сохранением. Конверты workflow легко испортить незаметно, поэтому порядок такой: скопируйте рабочий конверт с помощью get_dataset includeWorkflow, отредактируйте его, запустите validate_dataset_workflow (который выполняет его на стороне сервера и сообщает количество строк по шагам, выходные поля и количество null без сохранения чего-либо), затем сохраните с помощью update_dataset.

Известные ограничения

  • Каталог видов виджетов — это копия. src/catalog/widget-kinds.ts повторяет src/features/dashboard/widgets/registry.ts — включая defaultConfig каждого вида — и интерфейсы конфигурации для каждого вида. Реестр приложения — это клиентский компонент и импортирует React, поэтому его нельзя импортировать здесь. Если у вида виджета появится новое поле или изменится значение defaultConfig, обновите и каталог, иначе виджеты, созданные через MCP, будут расходиться с созданными через интерфейс.

  • Покрытие каталога высокое, но не полное. Документированные и фактические поля конфигурации: table 18/21, stat 22/25, chart 39/59, select 9/12, text 16/17. Что опущено — в основном косметические варианты (стили pie/line/bar, переопределения правой оси) и устаревшие ключи взаимодействия, заменённые highlightBindings. Живой пример, возвращаемый describe_widget_kind, является эталоном для них. Поля сгруппированы в core / display / interaction, чтобы контракт данных читался в первую очередь.

  • Привязки истекают вместе с цепочкой обновления. Сессия ключа длится столько, сколько приложение поддерживает живым свой ротационный refresh-токен. Когда он истекает, вызовы завершаются ошибкой с указанием исправления, и держатель ключа повторно выполняет привязку одной командой curl. Для бессрочной идентичности требуется подключение ApiKey в src/lib/api-guard.ts в основной системе, чего не сделано.

  • Записи прямые. В приложении есть workflow черновиков изменений и утверждений (ChangeDraft, ApprovalRequest). Эти инструменты пишут напрямую с правами вошедшей учётной записи. Если дашборды, созданные ИИ, должны проходить рецензирование перед публикацией, направьте инструменты записи через /api/change-drafts и оставьте права учётной записи только на чтение.

  • Источники данных Excel здесь только для чтения. Создание или обновление такого источника требует multipart-загрузки файла, что не вписывается в текстовый поток MCP. Они по-прежнему появляются в list_datasources, describe_datasource и preview_datasource; создавайте и обновляйте их в интерфейсе.

  • Нет инструментов удаления. Удаление источника данных каскадно выполняет мягкое удаление каждого набора данных, построенного на нём, поэтому удаления остаются действием человека в интерфейсе. delete_widget — единственный доступный разрушительный инструмент.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables secure querying of analytics data stored in AWS Athena/S3 through natural language, with multiple security layers including query validation, resource limits, and automatic PII redaction to prevent data breaches and destructive operations.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with SQL Server Data Warehouses using natural language for automatic schema discovery and report generation. It ensures security by restricting operations to read-only SELECT queries through both code validation and database permissions.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language querying and management of Apache Superset dashboard metadata, including user activity, data lineage, and change tracking.
    392 PyPI
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI applications to interact with Tableau for querying data, exploring content, and retrieving views through natural language.
    9,509 npm
    Apache 2.0