Skip to main content
Glama
rfawwaz13

tableau-mcp-dev

by rfawwaz13

Tableau Data Assistant — Gemini + MCP + Web Chat

Paket lengkap end-to-end:

  1. tableau_client.py — wrapper REST API + VizQL Data Service Tableau (auth PAT, list workbook/datasource/view, query datasource).

  2. tableau_mcp_server.py — membungkus wrapper di atas jadi MCP tools (@mcp.tool()), dijalankan lewat stdio.

  3. agent_service.pyfactory: memilih backend LLM (Gemini atau OpenAI) berdasarkan LLM_PROVIDER di .env. Interface publiknya (connect(), ask_stream()) sama persis untuk kedua provider, jadi web_app.py dan gemini_client.py tidak perlu tahu/berubah soal LLM apa yang dipakai.

    • backends/gemini_backend.py — implementasi pakai Gemini (google-genai).

    • backends/openai_backend.py — implementasi pakai OpenAI (Chat Completions API).

  4. gemini_client.py — CLI chat (terminal) untuk testing cepat.

  5. web_app.py — server FastAPI + WebSocket yang menyajikan UI chat dan menjembatani browser ⇄ agent_service.

  6. static/ — UI chat (HTML/CSS/JS statis, tanpa framework) yang bisa di-embed ke dashboard Tableau.

Browser (embed di Tableau dashboard)
        │  WebSocket (/ws)
        ▼
   web_app.py (FastAPI)
        │  ask_stream()
        ▼
  agent_service.py ── Gemini function calling
        │  MCP (stdio, subprocess)
        ▼
 tableau_mcp_server.py
        │  REST API + VizQL Data Service
        ▼
   Tableau Server / Cloud

1. Instalasi

python -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Related MCP server: Hickey_MCP

2. Konfigurasi

cp env.example.txt .env

Isi .env:

TABLEAU_SERVER=https://my-tableau-server.com
TABLEAU_SITE=my_site_content_url        # kosongkan "" jika Default site
TABLEAU_PAT_NAME=...
TABLEAU_PAT_SECRET=...
TABLEAU_API_VERSION=3.22

GEMINI_API_KEY=...
GEMINI_MODEL=gemini-2.5-pro              # opsional, default gemini-2.5-pro

PAT dibuat di: Tableau → Account Settings → Personal Access Tokens.

2b. Ganti LLM provider (Gemini ⇄ OpenAI)

Cukup ubah satu baris di .env:

LLM_PROVIDER=gemini     # atau: openai

Lalu isi kunci API yang sesuai (GEMINI_API_KEY/GEMINI_MODEL atau OPENAI_API_KEY/OPENAI_MODEL — lihat env.example.txt). Tidak ada file lain yang perlu diedit; agent_service.py otomatis meng-import backend yang tepat, dan status bar di UI chat juga otomatis menampilkan provider yang sedang aktif (mis. "siap · gemini · 6 tools").

Kalau nanti ingin menambah provider lain (mis. Claude via Anthropic API, atau model lokal), cukup buat backends/<nama>_backend.py baru dengan class TableauAgentSession yang method-nya identik (connect(), ask_stream(), close()), lalu tambahkan satu cabang elif di agent_service.py.

3. Menjalankan

a) CLI (cepat untuk testing):

python gemini_client.py

b) Web app (untuk di-embed ke dashboard):

uvicorn web_app:app --host 0.0.0.0 --port 8000 --reload

Buka http://localhost:8000 — chat box siap dipakai. Setiap tab browser = satu sesi percakapan independen (satu TableauAgentSession per koneksi WebSocket).

4. Meng-embed ke dashboard Tableau

Opsi A — Objek "Web Page" (paling sederhana)

  1. Deploy web_app.py ke server yang bisa diakses via HTTPS (browser modern mewajibkan HTTPS untuk konten campuran di dalam iframe dashboard Tableau Cloud/Server).

  2. Di Tableau Desktop/Web Edit, buka dashboard Anda → seret objek Web Page ke canvas.

  3. Isi URL dengan alamat app Anda, mis. https://assistant.perusahaan-anda.com/.

  4. Atur ukuran objek sesuai kebutuhan (chat box didesain responsif, nyaman mulai lebar ~360px).

  5. Publish dashboard. Chat box akan tampil sebagai panel di sisi dashboard.

Opsi B — Tableau Extensions API (sudah tersedia lengkap di paket ini)

File yang terlibat:

  • static/tableau-extension.js — inisialisasi tableau.extensions, membaca semua worksheet + filter aktif di dashboard, menyimpannya di window.__dashboardContext, dan mendengarkan event FilterChanged supaya konteks selalu ter-update.

  • static/index.html — memuat SDK tableau.extensions.1.latest.js yang di-self-host di static/vendor/ (bukan dari CDN eksternal — banyak jaringan Tableau Server korporat memblokir domain seperti extensions.tableau.com, menyebabkan net::ERR_NAME_NOT_RESOLVED dan extension gagal total), lalu tableau-extension.js, lalu app.js. Ada juga badge kecil (#context-badge) yang menampilkan filter aktif secara visual di atas chat.

  • static/vendor/tableau.extensions.1.latest.js — salinan resmi SDK dari repo tableau/extensions-api di GitHub. Untuk update ke versi lebih baru:

    curl -sL -o static/vendor/tableau.extensions.1.latest.js \
      https://raw.githubusercontent.com/tableau/extensions-api/master/lib/tableau.extensions.1.latest.js
  • static/app.js — setiap kali user mengirim pesan, window.__dashboardContext ikut dikirim ke backend sebagai field context (selain message).

  • web_app.py & agent_service.py — menerima context dari WebSocket dan menyisipkannya ke prompt Gemini, jadi assistant otomatis tahu filter yang sedang aktif tanpa Anda ketik manual.

  • tableau-data-assistant.trex — manifest extension.

Catatan penting: kalau halaman ini dibuka sebagai objek Web Page biasa (Opsi A), tableau.extensions tidak akan pernah tersedia — semua kode di atas otomatis no-op dan chat tetap berfungsi normal tanpa konteks dashboard. Jadi satu paket ini mendukung kedua opsi sekaligus, tidak perlu versi terpisah.

Langkah setup:

  1. Sunting tableau-data-assistant.trex:

    • Ganti <url>https://assistant.perusahaan-anda.com/</url> dengan alamat HTTPS tempat web_app.py Anda benar-benar di-deploy.

    • Untuk testing lokal, Tableau Desktop mengizinkan http://localhost:8000 selama opsi "Allow the extension to run local content" (kadang disebut "Extensions - localhost only") diaktifkan di Tableau Desktop → Help → Settings and Performance, atau saat menambahkan extension pertama kali Desktop akan menampilkan dialog konfirmasi ini.

    • Sesuaikan id, name, author, email, organization, website sesuai perusahaan Anda.

  2. Di Tableau Desktop, buka dashboard Anda → seret objek Extension (bukan Web Page) ke canvas.

  3. Pada dialog yang muncul, pilih "My Extensions""Access Local Extensions" → arahkan ke file tableau-data-assistant.trex di komputer Anda (atau file share/URL tempat manifest itu di-host, tergantung workflow tim Anda).

  4. Tableau akan menampilkan dialog izin ("This extension can access all data in the workbook") — ini karena manifest meminta <full-data/> supaya assistant bisa membaca filter secara lengkap. Klik Allow.

  5. Extension akan memuat index.html Anda di dalam iframe khusus extension. Coba ubah filter di worksheet lain pada dashboard — badge konteks di atas chat akan otomatis update, dan pertanyaan berikutnya ke assistant akan otomatis menyertakan info filter tersebut.

  6. Untuk publish ke Tableau Server/Cloud: upload .trex sebagai bagian dari dashboard saat di-publish (Tableau akan menyimpannya bersama workbook), dan pastikan admin site Anda mengizinkan "Run on Tableau Server/Cloud" untuk extension dengan source URL Anda (di Server: Settings → Extensions → Allowed list; kadang perlu ditambahkan admin jika site Anda mode "safe list only").

5. Catatan produksi (penting)

  • Jangan expose GEMINI_API_KEY atau PAT Tableau ke browser — pada arsitektur ini keduanya sudah aman karena hanya dipakai di backend (agent_service.py, tableau_mcp_server.py); browser hanya bicara ke web_app.py lewat WebSocket teks biasa.

  • Set allow_origins di web_app.py (CORS) ke domain Tableau Server/Cloud Anda, jangan biarkan "*" di production.

  • Satu TableauAgentSession = satu subprocess MCP + histori chat in-memory. Untuk trafik tinggi, pertimbangkan: batas jumlah sesi aktif, timeout idle-session, atau kembangkan agent_service.py agar satu subprocess MCP dipakai bersama (pool) alih-alih satu per user.

  • Jalankan di belakang reverse proxy (nginx/Caddy) dengan TLS untuk HTTPS + WSS.

  • Tambahkan autentikasi (mis. cek session/cookie SSO perusahaan) di web_app.py sebelum membuka WebSocket, supaya tidak semua orang bisa memanggil Tableau & Gemini API Anda.

6. Struktur file lengkap

tableau-mcp-gemini/
├── tableau_client.py       # REST API + VizQL Data Service wrapper
├── tableau_mcp_server.py   # MCP tools (list_workbooks, query_datasource, dst.)
├── agent_service.py        # Factory: pilih backend LLM sesuai LLM_PROVIDER
├── backends/
│   ├── gemini_backend.py   # Implementasi LLM: Gemini
│   └── openai_backend.py   # Implementasi LLM: OpenAI
├── gemini_client.py        # CLI chat (khusus Gemini, testing cepat)
├── web_app.py              # FastAPI + WebSocket server
├── static/
│   ├── index.html          # shell UI chat
│   ├── style.css           # styling (console-style trace, bukan bubble generik)
│   └── app.js              # koneksi WebSocket + render pesan/trace
├── requirements.txt
├── env.example.txt         # salin jadi .env
└── README.md

8. Troubleshooting: assistant tidak "menyadari" perubahan filter

Kalau assistant tetap menjawab seolah tidak ada filter aktif setelah Anda ubah filter di dashboard:

  1. Cek dulu console browser untuk error net::ERR_NAME_NOT_RESOLVED pada tableau.extensions.1.latest.js. Ini penyebab paling umum: jaringan tempat Tableau Server Anda berjalan biasanya jaringan internal/korporat yang tidak boleh akses domain luar, sehingga CDN SDK gagal dimuat sama sekali dan window.tableau tidak pernah ada — akibatnya tableau-extension.js langsung berhenti di baris pengecekan paling awal. Paket ini sudah memakai SDK yang di-self-host di static/vendor/tableau.extensions.1.latest.js (bukan CDN) justru untuk menghindari masalah ini — pastikan Anda pakai versi index.html terbaru yang me-reference /static/vendor/..., bukan versi lama yang masih menunjuk ke https://extensions.tableau.com/....

  2. Buka console browser (klik-kanan panel extension → Inspect di Tableau Desktop, atau F12 di web edit) dan cari log [tableau-extension] konteks diperbarui: .... Kalau log ini tidak muncul sama sekali saat Anda ganti filter → berarti FilterChanged event tidak sampai ke script (biasanya karena extension belum ter-load penuh, atau Anda sedang menguji lewat mode Web Page biasa, bukan mode Extension).

  3. Kalau log muncul tapi isinya "tidak ada filter aktif saat ini" walau Anda yakin sudah mengubah filter → cek tipe filter yang dipakai. Versi terbaru tableau-extension.js sudah menangani filter categorical, range, relative-date, dan hierarchical; kalau dashboard Anda memakai tipe filter lain yang tidak dikenali, filter tetap dicatat tapi tanpa detail nilainya — cek juga apakah filter itu diterapkan di worksheet yang datanya sedang dibaca (extension hanya membaca filter per-worksheet lewat getFiltersAsync(), bukan filter yang cuma ada di level dashboard tanpa terhubung ke worksheet mana pun).

  4. Kalau badge di atas chat sudah menampilkan filter yang benar, tapi jawaban assistant tetap mengabaikannya → itu bukan soal pembacaan filter lagi, melainkan soal bagaimana Gemini memakainya. Pastikan Anda pakai agent_service.py versi terbaru (ada SYSTEM_INSTRUCTION yang secara eksplisit mewajibkan model menerapkan filter dari konteks ke query query_datasource, dan menandai konteks sebagai "TERKINI" supaya tidak bingung dengan konteks lama di riwayat chat).

  5. Untuk mengetes cepat tanpa bolak-balik ke dashboard: buka / langsung di browser (mode Web Page biasa), lalu di console jalankan window.__dashboardContext = 'Dashboard "Test" — filter aktif:\nWorksheet "Sales": Region = [West]' sebelum mengirim pesan — ini mensimulasikan konteks tanpa perlu Extensions API sungguhan.

9. Menambah tool baru

  1. Tambah method di tableau_client.py.

  2. Bungkus jadi @mcp.tool() di tableau_mcp_server.py.

  3. Restart web_app.py / gemini_client.py — tool baru otomatis terdeteksi lewat session.list_tools(), tidak perlu ubah agent_service.py, web_app.py, atau UI.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    -
    quality
    -
    maintenance
    Personal MCP server for Snowflake and Tableau integration, enabling SQL queries and database/table listing as well as Tableau workbook, view, datasource management.
  • F
    license
    A
    quality
    B
    maintenance
    MCP server that automates the publishing and validation of Tableau workbooks and data sources on Tableau Server or Tableau Cloud, enabling an AI agent to discover, build, validate, and publish content without human intervention.
    10

View all related MCP servers

Related MCP Connectors

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

  • Official Microsoft MCP Server to query Microsoft Entra data using natural language

  • MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.

View all MCP Connectors

Latest Blog Posts

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/rfawwaz13/tableau-mcp-dev'

If you have feedback or need assistance with the MCP directory API, please join our Discord server