tableau-embed
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tableau-embedShow me the Superstore Performance dashboard"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Tableau MCP App
Render a live, interactive Tableau dashboard inside ChatGPT, click a mark, and ask about what you clicked.
Not a screenshot and not a link out. The real viz, embedded in the conversation, filterable and hoverable — and when you select something, the selection is pushed to the model so that "why is this one so low?" resolves to the mark under your cursor.
You click Fasteners on the dashboard.
Fasteners selected on "KPI by Sub-Category" - nothing else is filtered.
Mark: Sub-Category: Fasteners | AGG(KPI Value): 8,532 | AGG(KPI Label): $8.5K
Parameters: Profit Bin Size = 200 | Top Customers = 5 | p.KPI = Sales
You: "why is this one so low?"
ChatGPT: "Sales: $8,532, lowest of 17 sub-categories. Average line sale: $37.26...
980 units across 226 orders. Average discount 7.9%, so discounting is
not the main cause. Profit: $2,429, a healthy 28.5% margin."Those numbers are queried live from the Tableau data source, not invented — verified against the raw query response, which is a distinction worth insisting on.
What this actually is
An MCP Apps server. It exposes one tool that
returns a ui:// resource — an HTML view the host mounts in a sandboxed iframe — which loads the
Tableau Embedding API, renders your viz, and reports the on-screen state back to the model as the
user interacts with it.
It deliberately returns no data of its own. The embed supplies the scope; a Tableau data query tool supplies the numbers. See How it works for why that split is the right one.
Related MCP server: Tableau MCP Server
Status, honestly
ChatGPT | Works. Renders, interacts, and pushes state; a selected mark was verified to scope the answer against a live query. You have to name the connector when asking — see Invoking it. |
Claude Desktop | Renders nothing. It approves the |
Tableau Public | Works anonymously, no credentials needed. |
Tableau Cloud | Works, via a Direct Trust Connected App JWT signed server-side. |
This is a working prototype built to answer a question — can you have a real conversation with a dashboard you're looking at? — and the answer turned out to be yes, with caveats worth reading.
Invoking it
Name the connector:
"Use the tableau-embed connector to show me the Superstore Performance dashboard"
This is the documented invocation, not a workaround for a bug. Asked without naming it, "show me the dashboard" reliably loses to ChatGPT's own chart builder, which will happily construct a convincing dashboard out of sample data and present it as an answer. Three rewrites of the tool description failed to change that. Once the dashboard is on screen, ordinary questions work normally — you only need to name the connector for the initial render.
Quickstart
Requires Node 18+ and, for the Cloud path, a Tableau Connected App.
git clone https://github.com/nuggenlabs/tableau-chatgpt-embed.git
cd tableau-chatgpt-embed
npm install
npm test # proves the viz renders under the real sandbox CSP, headlesslynpm test is worth running before anything else. It reproduces the MCP Apps iframe sandbox and
its Content Security Policy locally, drives a real Tableau viz through it in headless Chrome, and
tells you which of the four layers fails if one does. It also drives a real mark selection and
asserts the selection reaches the host — so a broken state push fails the build rather than
surfacing as a confused answer three weeks later.
To run it against a dashboard and connect it to ChatGPT:
cp .env.example .env # fill in, or delete the four credential lines for Tableau Public
npm startThen expose it over HTTPS and register the /mcp URL as a connector. On Windows, run.ps1 does
the whole sequence — server, tunnel, health check, paste-ready URL:
powershell -ExecutionPolicy Bypass -File .\run.ps1Full walkthrough, including the credential traps: docs/SETUP.md.
Documentation
Document | What's in it |
Credentials, tunnels, the startup preflight, and getting it into ChatGPT | |
Architecture, how on-screen state reaches the model, mark selection | |
What works where, and the Claude Desktop | |
Failures that cost real time here, and what each one actually was | |
A protocol for testing whether the model uses on-screen state |
Two findings worth stealing
A tool description is a routing instruction — and it can lose. "Show me the Superstore dashboard" was answered by ChatGPT building a plausible lookalike from a sample dataset — invented numbers, presented as an answer. Three successive rewrites of the description failed to win the request back, including one that names the competing behaviour and refuses the substitution outright. A tool competes with everything the host can do, not just its siblings in the same server, and against a first-party tool a description may simply not be enough. Unresolved — name the connector, as below.
Ask the harness, not the model. A model is not a reliable instrument for measuring its own
context. When on-screen state stopped reaching ChatGPT, four plausible theories each blamed the
wrong layer; what settled it was planting a random token in every push and asking for it back —
thirteen pushes, every call resolved, none delivered. docs/SCOPING-TEST.md is the general form of
that lesson.
Layout
src/
server.js MCP server: the tool, the ui:// resource, HTTP + stdio transports
view.html the embedded view - renders the viz, reads state, pushes it to the model
build-view.js inlines the MCP Apps client SDK into the view at build time
connected-app.js Direct Trust JWT minting for authenticated Cloud embeds
preflight.js startup credential and URL checks, so failures surface here not in ChatGPT
env.js dependency-light .env loader; shell variables win over the file
test/
sandbox-harness.js reproduces the host: the iframe sandbox, the CSP, the ui/ JSON-RPC contract
feasibility.test.js end-to-end - viz renders, host contract satisfied, state reaches the model
server.smoke.js MCP protocol correctness
preflight.test.js credential-failure classification, stubbed
env.test.js .env parsing and precedence
docs/ see the table above
run.ps1 Windows launcher: server + tunnel + health + paste-ready URLNo build step and three runtime dependencies. The Tableau Embedding API is loaded by the view at runtime from Tableau's own CDN, which the sandbox CSP has to allow — that constraint drives more of the design than anything else.
Not yet built
Choosing a dashboard by name. One viz is baked in at startup via
TABLEAU_VIZ_URL. Switching conflicts with the one-embed-per-conversation rule, which exists because a second embed mounts a fresh unfiltered viz and silently resets the reported scope.Inbound authentication.
/mcpis open to anyone who can reach it, andresources/readmints an embed token on demand. Fine behind an ephemeral tunnel; do not put this on a permanent public hostname without putting something in front of it.
License
MIT — see LICENSE.
Available Tools
1 toolembed_interactive_dashboardEmbed Interactive Tableau DashboardA
Renders the user's OWN Superstore Performance dashboard - the real, already-built, authenticated view from their Tableau Cloud site, showing their actual business data - directly in this conversation as a LIVE, INTERACTIVE Tableau visualization they can click, filter, and hover. USE THIS TOOL RATHER THAN BUILDING ONE. When the user asks to see, show, open, display or view the Superstore Performance dashboard, or just 'the dashboard', they mean this existing dashboard. Do NOT recreate, rebuild, approximate or simulate it with a visualization, charting, canvas, HTML or code-execution tool, and do NOT substitute sample, representative or synthetic data. Doing so produces a different dashboard full of invented numbers while appearing to answer the request - the user is asking about their real data, so a convincing lookalike is worse than no answer. No other tool can do this: other Tableau tools return only a URL to open elsewhere or a static image, and general visualization tools cannot reach the user's Tableau site at all. CALL THIS AT MOST ONCE PER CONVERSATION. Do NOT call it again once the dashboard is on screen - not to refresh it, and never to answer a question. Re-rendering mounts a new, UNFILTERED viz: it throws away whatever the user has filtered on screen and replaces the reported filter state with 'nothing is filtered', so a question answered after a re-render is answered against the wrong scope. It returns no numbers of its own - for questions about the data, use a Tableau data query tool. It does report which filters and parameters the user currently has applied on screen; scope those queries to that state. For a follow-up question about what the user is looking at, use the most recent reported filter state together with a data query tool. Do not re-embed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It reveals that the tool returns no numbers itself, reports the user's current filter/parameter state, and that re-rendering mounts an unfiltered viz, discarding the user's applied filters. This is thorough and prevents misuse.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded: the first sentence states the core purpose and interactivity. It then systematically covers exclusions, alternatives, frequency limits, and filter-state behavior. There is minor redundancy, such as ending with 'Do not re-embed' after already stating 'Do NOT call it again', which makes it slightly more verbose than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, no annotations, and no sibling tools, the description compensates by covering return behavior, filter-state reporting, data-query handoff, and alternative tool limitations. It is complete for a parameterless tool, anticipating common follow-up questions and misuse scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters and 100% schema description coverage, which is the baseline 4 for parameterless tools. The description correctly adds no parameter syntax details since none exist, and it focuses instead on usage and behavioral constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs ('renders', 'shows') and clearly identifies the exact resource: the user's own Superstore Performance dashboard, live and interactive. It explicitly distinguishes this tool from alternatives by stating that no other tool can do this and that other Tableau tools only return URLs or static images.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use triggers ('When the user asks to see, show, open, display or view...'), strong exclusions ('Do NOT recreate, rebuild, approximate or simulate'), and alternative recommendations (use a Tableau data query tool for data questions). It also enforces a strict frequency limit ('at most once per conversation') and warns against re-ordering.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
1 tool update
v0.1.0- First observed
embed_interactive_dashboard
TDQS
Only one tool exists in the set, so there is no possibility of confusion with other tools. The single tool's purpose is clearly delineated, and the description explicitly distinguishes it from other potential tools.
The tool name 'embed_interactive_dashboard' follows a consistent verb_noun pattern. With only one tool, consistency is trivially maintained.
A single tool feels thin, especially if the server were expected to cover broader Tableau functionality. However, its narrow scope—embedding one specific dashboard—makes the count borderline acceptable.
For its stated purpose of rendering the existing dashboard, the tool fully covers the required operation. The description explicitly scopes out data querying, indicating the server is intentionally limited to embedding.
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
Renders interactive Chart.js charts and dashboards inline in AI conversations.
Connect Google Analytics to ChatGPT. Query GA4 data in plain English and get instant insights.
Renders interactive Chart.js charts and dashboards inline in AI conversations. Supports bar, line, area, pie, doughnut, scatter, and radar charts with multi-chart dashboard grids.
Ask data questions in natural language. Get SQL, insights, and charts from your databases.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI applications to integrate with Tableau through developer primitives including tools, resources and prompts. Supports querying data from datasources, exploring content like workbooks and views, and retrieving visualizations using the Tableau REST API.15,491Apache 2.0

Tableau MCP Serverofficial
AlicenseNot gradedqualityAmaintenanceEnables AI applications to integrate with Tableau through tools, resources, and prompts for querying data, exploring content, and retrieving visualizations from Tableau workbooks and datasources.15,491333Apache 2.0- AlicenseNot gradedqualityDmaintenanceEnables integration with Tableau to query data, explore workbook content, and retrieve visualization images through natural language. It provides developer primitives for building AI applications that interact seamlessly with Tableau servers.15,491Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables AI applications to interact with Tableau through tools for querying data, exploring content, and retrieving views.15,491Apache 2.0
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/nuggenlabs/tableau-chatgpt-embed'
If you have feedback or need assistance with the MCP directory API, please join our Discord server