Skip to main content
Glama
Destiny-Enterprises

Dashboard Builder MCP server

Dashboard Builder MCP 서버

AI 클라이언트가 Dashboard Builder에서 데이터셋을 발견하고 대시보드를 작성할 수 있게 해줍니다.

일반 API 클라이언트처럼 HTTP를 통해 Next.js 앱과 통신하므로, 앱의 모든 권한 가드, 의존성 정책 및 검증 규칙이 그대로 적용됩니다. 메인 애플리케이션에는 아무것도 변경되지 않습니다.

두 가지 방식으로 실행할 수 있습니다:

실행 주체

신원

사용자에게 필요한 것

호스팅

서버 하나, 조직 전체

각 개인의 계정, 키에 한 번 바인딩됨

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"}'

헤더 방식과의 차이점: 세션 체인이 결국 만료되면 이 명령을 다시 실행해야 하지만, 헤더 방식은 자동으로 다시 바인드됩니다. 동일한 Authorization 헤더를 사용한 DELETE /auth/bind는 두 경우 모두 키를 로그아웃시킵니다.

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의 Settings → Connectors → Add custom connector에서 로컬에 아무것도 없이 URL을 직접 받습니다 — 이 경로는 정적 키 대신 OAuth를 기대하며, 가용성은 Desktop 버전에 따라 다릅니다.


Related MCP server: MCP SQL Server Data Warehouse Connector

서버 배포하기

server.js가 시작 파일입니다. Next.js server.js처럼 PORT에서 수신 대기하며, 모든 MCP 요청 앞에 API 키 게이트를 두어 인증되지 않은 호출자가 대시보드 시스템에 도달하기 전에 거부되도록 합니다.

엔드포인트: 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 리바인딩 보호 활성화

MCP_ALLOWED_ORIGINS

클라이언트 오리진

동일

DASHBOARD_MCP_PERSIST_SESSION은 기본값(true)으로 두세요: 바인드는 키당 파일 하나로 저장되어 재시작 후에도 유지됩니다. false로 설정하면 바인드가 메모리에만 유지되므로 재시작마다 — 그리고 다중 워커 호스트의 모든 워커마다 — 다시 바인드해야 합니다.

MCP_ALLOWED_HOSTS와 MCP_ALLOWED_ORIGINS는 선택 사항입니다 — 서버는 이것들 없이도 실행되며 API 키 게이트는 여전히 적용됩니다. 둘 중 하나를 설정하면 전송 계층의 DNS 리바인딩 보호가 켜집니다. 둘 다 설정하지 않으면 시작 로그에 명시적으로 표시됩니다.

선택 사항

변수

기본값

PORT

3001

HOST

127.0.0.1 — 포트를 공용 인터페이스에서 격리; 리버스 프록시가 로컬로 접근

MCP_RATE_LIMIT

창당 키당 120개 요청

MCP_RATE_LIMIT_WINDOW_MS

60000

추가 튜닝 변수 — 세션 파일 경로, 요청 시간 초과, 응답 상한 및 대시보드 종류 ID 재정의 — 는 .env.example에 인라인으로 문서화되어 있으며, 모드별로 구성되어 서버가 읽는 모든 변수를 나열합니다.

다중 워커 참고 사항

바인드는 키당 파일 하나이며, 다른 워커에 의해 메모리 내 토큰이 교체된 워커는 승리한 워커가 이미 업데이트한 해당 파일을 다시 읽어 복구합니다. 실패 창은 두 워커가 동시에 같은 토큰을 갱신하는 경우이며, 패배한 쪽은 다음 시도에서 복구하고 최악의 경우 키를 다시 바인드해야 합니다. MCP 전송 자체는 상태 비저장이므로 요청은 어떤 워커에든 도달할 수 있습니다.

Plesk 설정

설정

값

애플리케이션 루트

mcp-server 디렉터리

애플리케이션 시작 파일

server.js

애플리케이션 모드

production

환경 변수

위 표들, Node.js 패널에서

시작 전

npm install, 그 다음 npm run build

도메인의 Additional nginx directives에 추가:

proxy_buffering off;
proxy_read_timeout 300s;

MCP는 Server-Sent Events로 응답하며 nginx는 기본적으로 프록시된 응답을 버퍼링합니다. proxy_buffering off가 없으면 요청이 실패하는 대신 멈춘 것처럼 보이며, 이는 한나절을 허비하게 만드는 혼란스러운 방식입니다.

Node 포트는 공용 방화벽에서 차단된 상태로 유지하세요. Plesk의 nginx가 프록시하고 X-Forwarded-For를 설정하며, 이것이 로그된 클라이언트 IP를 신뢰할 수 있게 만드는 이유입니다.

접근과 신원

게이트 키는 접근을 제어합니다. 신원은 바인드에서 옵니다. 키는 호출자를 게이트를 통과시키고, 해당 키에 바인드된 세션이 대시보드가 보는 대상을 결정합니다 — 그들의 권한, 그들의 감사 추적. 이 둘은 의도적으로 분리되어 있습니다: 키의 비밀번호를 교체하면 바인드가 해제되고(세션은 키의 다이제스트 아래에 정리됨), 키를 해지하면 계정에는 영향을 주지 않고 접근만 제거됩니다.

바인드는 브라우저 로그인과 같은 방식으로 작동합니다. POST /auth/bind는 앱의 실제 /api/auth/login을 한 번 실행하고, 비밀번호는 교환 후 폐기되며, 회전하는 리프레시 토큰 세션만 유지됩니다 — 키당 파일 하나, 모드 0600. 앱이 사용할 때마다 리프레시 토큰을 회전시키므로 유출된 세션 파일은 빠르게 무용지물이 됩니다. 비밀번호가 저장되지 않으므로 장기적으로 유출될 것이 없습니다. 단점: 리프레시 체인이 만료되거나 끊어지면 해당 키는 curl 한 번으로 다시 바인드됩니다.

안정적인 요청별 자격 증명(메인 시스템의 ApiKey 또는 OAuth)은 그 재바인드조차 제거하겠지만, 메인 애플리케이션의 변경이 필요합니다. 이 설계는 의도적으로 어떤 변경도 필요로 하지 않습니다.


로컬에서 개발 또는 실행하기

자신의 머신에서 서버를 실행하는 것 — 개발용, 또는 호스팅 없이 사용자별 신원을 위한 — 은 DEVELOPMENT.md에 별도로 문서화되어 있습니다.

도구

체인은 다음과 같습니다: 데이터 소스(HTTP API 또는 Excel 업로드) → 데이터셋(변환 워크플로우가 있는 형태화된 뷰) → 대시보드 위젯. 도구는 세 단계를 모두 다룹니다.

도구

모드

용도

list_datasources

read

데이터 소스 ID, 라벨, 종류(http/excel) 및 대상

describe_datasource

read

한 소스의 구조: 파라미터, 응답 경로, 컬럼 — 자격 증명은 절대 포함하지 않음

preview_datasource

read

소스의 실시간 행; 실패 시 후보 응답 경로 목록 제공

list_datasets

read

데이터셋 ID, 라벨 및 범위

describe_dataset

read

정확한 필드 이름, 추론된 유형, 각각의 샘플 값 하나

sample_dataset

read

실제 행의 상한이 있는 샘플

get_dataset

read

전체 데이터셋 정의: 소스, 구체화, 워크플로 요약 또는 원본 봉투

validate_dataset_workflow

read

저장 없이 실제 데이터에 대해 워크플로 초안 실행; 단계별 진단

list_dashboards

read

대시보드 ID, 라벨 및 범위

get_dashboard

read

대시보드 상세 정보와 위젯별 한 줄; 요청 시 구성 하나

list_widget_kinds

read

작성 가능한 위젯 종류

describe_widget_kind

read

한 종류의 구성 계약과 작업 공간의 실제 예시

test_datasource

write

HTTP 엔드포인트 구성 드라이런; 저장되지 않으며 컬럼과 경로가 추론됨

create_datasource

write

HTTP 데이터 소스 생성; 서버가 URL을 검사하고 기본 데이터셋을 시드함

update_datasource

write

HTTP 소스의 일부 변경; 저장된 구성과 병합됨

create_dataset

write

데이터셋 생성; 워크플로가 주어지지 않으면 서버가 기본 워크플로를 구축함

update_dataset

write

부분 업데이트: 라벨, 소스, 제한, 구체화 또는 워크플로 교체

refresh_dataset_snapshot

write

스냅샷 구체화 데이터셋 재실행 또는 마지막 새로고침 보고

create_dashboard

write

대시보드 생성 및 데이터셋 연결

set_dashboard_datasets

write

대시보드의 데이터셋 목록 교체

add_widget

write

위젯 하나 추가, 그리드에 자동 배치

update_widget

write

제목, 데이터셋 또는 구성 키 변경

delete_widget

write

위젯 제거

arrange_dashboard

write

그리드 재배치 또는 명시적 위치 적용

test_datasource는 앱이 데이터 소스 생성/편집 권한 뒤에 게이트를 두고 업스트림 엔드포인트를 호출하기 때문에 쓰기 집합에 속하지만, 아무것도 영구 저장하지 않습니다.

설계 노트

컨텍스트 규율. 전체 도구 표면은 약 7KB — 설명 24개와 서버 지침 — 이므로 로드된 상태를 유지하는 비용이 저렴합니다. 응답은 원시 JSON이 아닌 간결한 텍스트이며, 모든 목록은 생략된 내용에 대한 명시적 메모와 함께 상한이 적용됩니다. get_dashboard는 의도적으로 위젯 구성을 생략합니다. 구성이 필요할 때 ID로 위젯 하나를 요청합니다.

점진적 공개. 차트 구성에는 약 59개의 필드가 있습니다. 이를 도구 설명에 넣으면 매 요청마다 클라이언트의 컨텍스트를 지배하게 되므로, describe_widget_kind가 대신 요청 시 계약을 제공합니다: 필드 이름, 유형, 메모, 최소 작동 예시, 그리고 유용한 부분인 — 작업 공간에서 해당 종류의 기존 위젯에서 수집한 실제 구성. 이미 렌더링되는 형태를 복사하는 것이 필드 이름에서 새로 만드는 것보다 낫습니다.

서버가 기하학을 처리합니다. 모델은 2D 패킹에 신뢰할 수 없습니다. add_widget는 size 힌트(small, medium, large, full)를 받아 12열 그리드에서 첫 번째로 비어 있는 겹치지 않는 셀을 직접 찾습니다. arrange_dashboard의 auto 모드는 전체 대시보드를 재배치합니다.

API 전에 실패하고, 후에 실패하지 않습니다. 위젯 구성은 앱에 의해 불투명한 JSON으로 저장되므로, 철자가 틀린 키는 오류 대신 빈 위젯을 생성합니다. add_widget는 먼저 해당 종류의 계약에 대해 구성을 검증합니다 — 필수 키, 유효한 집계 이름, 집계가 필요로 할 때 field 존재 — 그리고 누락된 항목의 구체적인 목록을 반환합니다.

위젯은 UI가 생성하는 것과 일치합니다. 앱의 팔레트는 레지스트리의 defaultConfig로 모든 새 위젯을 시드합니다(config === undefined ? def.defaultConfig : config). add_widget는 이를 반영합니다: 종류 기본값은 호출자가 제공하는 모든 것 아래에 레이어링되므로, MCP로 작성된 차트는 렌더러가 대체해야 하는 희소 구성 대신 수동으로 만든 것과 동일한 paginationMode 및 maxPoints 기준선을 갖습니다. 병합된 객체가 검증 대상입니다.

재전송 대신 병합. PATCH /widgets/:id는 구성 객체를 통째로 교체합니다. update_widget는 기본적으로 키를 기존 구성에 병합하므로, 하나의 설정을 변경한다고 전부를 재전송할 필요는 없습니다.

시작 시 안전 실패. HTTP 서버는 MCP_API_KEYS 항목이 하나 이상 없으면 시작을 거부하고, 24자 미만의 키는 거부합니다. 인증되지 않은 MCP 엔드포인트는 우연히 존재할 수 없어야 합니다. 키는 timingSafeEqual로 SHA-256 다이제스트로 비교되며, 라벨만 로깅됩니다.

비밀은 서버 측에 유지됩니다. describe_datasource는 자격 증명을 절대 포함하지 않는 앱의 /schema 엔드포인트를 읽습니다. update_datasource는 병합할 전체 저장 구성을 필요로 합니다 — 도구 실행 내부에서 이를 가져와 병합된 결과를 보내며, authConfig, 저장된 헤더 또는 본문을 모델의 컨텍스트에 렌더링하지 않습니다.

저장 전 검증. 워크플로 봉투는 미묘하게 잘못되기 쉽습니다. 따라서 흐름은: get_dataset includeWorkflow로 작동하는 봉투를 복사하고, 편집한 다음, validate_dataset_workflow를 실행하고(서버 측에서 실행하여 아무것도 영구 저장하지 않고 단계별 행 수, 출력 필드 및 null 수를 보고), 그런 다음 update_dataset로 저장합니다.

알려진 제한 사항

  • 위젯 종류 카탈로그는 복사본입니다. src/catalog/widget-kinds.ts는 src/features/dashboard/widgets/registry.ts — 각 종류의 defaultConfig 포함 — 및 종류별 구성 인터페이스를 반영합니다. 앱의 레지스트리는 클라이언트 컴포넌트이고 React를 가져오므로 여기서 가져올 수 없습니다. 위젯 종류에 필드가 추가되거나 defaultConfig 값이 변경되면 카탈로그도 업데이트해야 합니다. 그렇지 않으면 MCP로 생성된 위젯이 UI로 생성된 위젯과 달라집니다.

  • 카탈로그 범위는 높지만 완전하지는 않습니다. 문서화된 필드 vs. 실제 구성 필드: table 18/21, stat 22/25, chart 39/59, select 9/12, text 16/17. 제외된 것은 대부분 미관상 변형(파이/라인/바 스타일 옵션, 오른쪽 축 재정의)과 highlightBindings로 대체된 레거시 상호작용 키입니다. describe_widget_kind가 반환하는 실제 예시가 이에 대한 참조입니다. 필드는 핵심/표시/상호작용으로 그룹화되어 데이터 계약이 먼저 읽힙니다.

  • 바인딩은 새로고침 체인과 함께 만료됩니다. 키의 세션은 앱이 순환 새로고침 토큰을 유지하는 한 지속됩니다. 만료되면 호출이 수정 방법을 명명하는 오류와 함께 실패하고, 키 보유자는 curl 한 번으로 다시 바인딩합니다. 만료되지 않는 ID는 메인 시스템의 src/lib/api-guard.ts에 ApiKey를 연결해야 하는데, 이는 완료되지 않았습니다.

  • 쓰기는 직접적입니다. 앱에는 변경 초안 및 승인 워크플로(ChangeDraft, ApprovalRequest)가 있습니다. 이 도구들은 로그인한 계정의 권한으로 직접 기록합니다. AI가 작성한 대시보드가 게시 전에 검토되어야 한다면, 쓰기 도구를 /api/change-drafts로 라우팅하고 계정의 권한을 읽기 전용으로 유지하세요.

  • Excel 데이터 소스는 여기서 읽기 전용입니다. 생성 또는 새로고침에는 MCP 텍스트 흐름에 맞지 않는 multipart 파일 업로드가 필요합니다. 여전히 list_datasources, describe_datasource 및 preview_datasource에 나타나며, 생성과 새로고침은 UI에서 수행하세요.

  • 삭제 도구가 없습니다. 데이터 소스 삭제는 그 위에 구축된 모든 데이터셋에 소프트 삭제를 연쇄 적용하므로, 삭제는 UI에서 사람의 작업으로 남습니다. 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.
    504 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.
    26,488 npm
    Apache 2.0