Biztory Tableau Knowledge Mcp

io.github.biztoryPublished by GitHub account biztoryv0.4.0Updated Nov 5, 2026

Search, explore and enrich the Tableau Knowledge graph, and port it to Apache Ossie (OSI).

Overview

AI-generated overview

Connects an assistant to a Tableau Cloud site's Tableau Knowledge graph to search it by meaning, trace lineage and impact, and enrich it with business context.

What you can do
  • Search and read graph nodes by meaning or id, with edges, lineage and impact analysis
  • List the published data sources and workbooks a graph is built from, plus ingest status
  • Read, create, update and delete semantic contexts, including turning a local document into context
  • Report graph health and coverage, and ask Tableau's own agent questions about a graph
  • Add or remove sources and create or update graphs
  • Export and import Apache Ossie semantic models, validate Ossie documents, and check Business Preferences files
When to use it
Useful when you work with a Tableau Cloud site that has Tableau Knowledge enabled and want an assistant to answer questions about fields, lineage, downstream impact and business definitions, or to maintain the graph's semantic context and port it to Apache Ossie.
Requirements
Runs locally over stdio via uvx from PyPI (needs uv). Requires a Tableau Cloud site with Tableau Knowledge (Tableau+ license; not on Tableau Server) and a Personal Access Token: TABLEAU_SERVER, TABLEAU_SITE_CONTENT_URL, TABLEAU_PAT_NAME and TABLEAU_PAT_SECRET, or alternatively TABLEAU_AUTH_TOKEN. Writing semantic contexts needs the Creator role. Network access to the Tableau host over HTTPS.
Before you install
The PAT secret (TABLEAU_PAT_SECRET) is a credential; set it in the client's env block, not on the command line. Write tools change semantic contexts, a graph's sources, and a graph's name, description or primary flag, and deleting a context or removing sources can lose attached context; confirm before writing. Several write tools use Tableau's undocumented web-app API, which can change without notice. Uploading a document sends its content to your Tableau site. Graph text written by others…

Installation

In SourceWeft

  1. Open Biztory Tableau Knowledge Mcp in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

[Tableau Knowledge MCP by Biztory]

biztory-tableau-knowledge-mcp

Put your Tableau knowledge graph to work in any AI assistant.
Search it by meaning, trace lineage and impact, and enrich it with business context.

[CI] [CodeQL] [Fuzz] [OpenSSF Best Practices] [OpenSSF Scorecard] [Ruff] [PyPI] [Python versions] [MCP compatible] [MIT License] [Tableau Cloud + Knowledge] [Minimal dependencies]

[Biztory Tableau Knowledge MCP server on mcprush]

[Add to Cursor] [Add to VS Code]

[Book a meeting with us]


biztory-tableau-knowledge-mcp turns your site's Tableau Knowledge Graph API into twenty-three MCP tools, so an AI assistant (Claude, Cursor, VS Code, Cline, and others) can work with the graph in plain language:

  • "Which fields mean revenue, and where do they come from?"
  • "If the Superstore data source changes, which workbooks and dashboards are affected?"
  • "What business context is attached to Profit? Add: 'Profit is after returns, in EUR.'"
  • "How healthy is our graph, and what are the five highest-impact fixes?"
  • "Export Superstore to Apache Ossie so we can port it to Snowflake."
  • "Write the Business Preferences for the P&L dashboard."
  • "Add every Superstore data source on the site to the Sales graph."
  • "Ask Tableau's agent how many data sources the graph has, and check its answer."

It ships nine read tools (semantic search, node lookup, edges, lineage, impact, sources, semantic contexts, graph health, and a connection probe) and four write tools for semantic contexts, the business statements that make the graph useful to people and to AI (one turns a document into context). Five tools manage the graph itself: add and remove data sources and workbooks, create and update graphs, and ask Tableau's own agent a question to test its answers. Those go through the API behind the Tableau Knowledge web app, which Tableau doesn't document. Four more tools port semantic layers through Apache Ossie (formerly Open Semantic Interchange, OSI), the open standard that Snowflake, dbt, Power BI, Databricks, Tableau Next and others convert to and from. And one checks Business Preferences files line by line against the fields the agent will actually see.

See it in action

[Claude finds the 13 Superstore data sources on the site with list_sources(site_search), adds the 12 that are missing with add_sources, and confirms the ingestion completed]

[Claude asks Tableau's agent how many data sources the graph has, then checks the answer with list_sources: the agent said 11 but the graph has 13]

[Claude uploads a KPI glossary file with create_semantic_context_from_document; Tableau turns each line into a graph-wide statement]

Replays of real tool results from a test site, with site-specific names removed. Regenerate with docs/images/render_demo_gifs.py.

Why it's different

  • Ask by meaning, not by id. Every read tool takes a node id or a description ("the net sales field"). Descriptions resolve through the graph's own semantic search, and the answer says which node it picked, with the match score and runners-up, so a wrong guess is visible instead of silent.
  • Answers, not payloads. impact_analysis groups and counts everything downstream by type; lineage adds node and edge counts; graph_health caps hundreds of suggestions to the top ones while keeping every total.
  • Errors tell the model what to do next. Tableau's error codes become concrete steps (site_not_entitled → an admin must enable Knowledge; no_active_graph → pass a graph_id; no embedder → use exact ids), with the trace_id kept for support. Rate limits are retried with Retry-After.
  • Writes you can trust. Only semantic contexts and a graph's sources can be written (the latter through Tableau Knowledge's undocumented web-app API, which can change without notice). Write tools take exact ids (a fuzzy match never decides where a write lands), validate before sending, carry honest MCP annotations so clients ask first, and delete_semantic_context returns what it deleted.
  • Port your semantic layer. export_to_ossie turns a published data source into a validated Ossie model, with Tableau calcs translated to portable SQL wherever that is exact and a loss report for everything else. import_from_ossie brings descriptions, synonyms and definitions from any Ossie model back into Tableau Knowledge, with a reviewable plan first.
  • Tiny and hardened. Stdio only (no inbound port), secrets from env only, HTTPS enforced, redirects refused, ids encoded so they can never reach another endpoint, fuzzed parsers, and two runtime dependencies: the MCP SDK and PyYAML (stdlib urllib for HTTP).

Requirements

Tableau Knowledge is a Tableau Cloud feature (September 2026 and later, Tableau+ license); it is not available on Tableau Server. Any user can read the graph, filtered by their content permissions. Writing semantic contexts needs the Creator role.

Quickstart

You need uv (curl -LsSf https://astral.sh/uv/install.sh | sh) and a Tableau Personal Access Token.

Claude Code, one line:

bash
claude mcp add tableau-knowledge \  -e TABLEAU_SERVER=https://10ax.online.tableau.com \  -e TABLEAU_SITE_CONTENT_URL=YourSite \  -e TABLEAU_PAT_NAME=my-token \  -e TABLEAU_PAT_SECRET=the-full-secret \  -- uvx biztory-tableau-knowledge-mcp

That's all. uvx fetches the package from PyPI and runs it in an isolated environment; nothing to clone or install. Then ask: "Use server_info: what graphs does my site have?"

Configuration

All configuration is via environment variables (set them in your client's env block, never on the command line).

Env varRequiredDefaultDescription
TABLEAU_SERVERyesn/ahttps://<pod>.online.tableau.com. Any URL from your browser works; the path is stripped.
TABLEAU_SITE_CONTENT_URLyes""Site slug (the part after /#/site/).
TABLEAU_PAT_NAMEyes¹n/aPersonal Access Token name.
TABLEAU_PAT_SECRETyes¹n/aPAT secret: the whole string, do not split on :.
TABLEAU_KNOWLEDGE_GRAPH_IDnoprimary graphDefault graph for every tool. server_info lists the site's graphs; each tool also takes a graph_id.
TABLEAU_TIMEOUTno60Per-request timeout (seconds).
TABLEAU_API_VERSIONnoautoREST version used for sign-in; else read from serverinfo. (The Knowledge API itself is always v1.)
TABLEAU_ALLOW_HTTPnooffSet to 1 to allow a plain http:// server on a trusted network. Otherwise only HTTPS (or loopback).
TABLEAU_LOG_LEVELnoINFODEBUG logs each HTTP call (method + URL; never headers, bodies or secrets) to stderr.
TABLEAU_AUTH_TOKENnon/aAdvanced: a pre-obtained X-Tableau-Auth session token instead of a PAT.

¹ Provide a PAT (TABLEAU_PAT_NAME + TABLEAU_PAT_SECRET) or TABLEAU_AUTH_TOKEN.

Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):

json
{  "mcpServers": {    "tableau-knowledge": {      "command": "uvx",      "args": ["biztory-tableau-knowledge-mcp"],      "env": {        "TABLEAU_SERVER": "https://10ax.online.tableau.com",        "TABLEAU_SITE_CONTENT_URL": "YourSite",        "TABLEAU_PAT_NAME": "my-token",        "TABLEAU_PAT_SECRET": "the-full-secret"      }    }  }}

Fully quit and reopen Claude Desktop, then check the tools menu.

Cursor · VS Code · Cline · Windsurf

Use the Add to Cursor / Add to VS Code buttons above and fill in the env values, or add the same block as for Claude Desktop to:

  • Cursor: ~/.cursor/mcp.json (global) or .cursor/mcp.json (project).
  • VS Code: .vscode/mcp.json (the top-level key there is servers instead of mcpServers).
  • Cline: the MCP Servers panel, then Configure, into cline_mcp_settings.json.
  • Windsurf: ~/.codeium/windsurf/mcp_config.json.

On Windows, if uvx isn't found by the GUI app, use its absolute path (e.g. %USERPROFILE%\.local\bin\uvx.exe).

Tools

node arguments accept a node id or a plain-language description. Every graph-scoped tool also takes an optional graph_id.

ToolWhat it doesKey args
server_infoSite, versions, auth, whether Knowledge is enabled, the site's feature switches, and every graph (id, name, status, primary, stats incl. context coverage). Good first call.none
search_nodesSemantic search over the graph ("revenue" finds "Net Sales"), ranked with scores.query, node_type, scope_id, limit, threshold
get_nodeOne node: properties, attached semantic statements, child nodes.node, include_children
list_edgesThe edges around one node, with direction and the node on the other end.node, edge_type, direction
lineageUpstream and downstream neighborhood (10 steps) along lineage/dependency edges, with counts.node
impact_analysisEverything that depends on a node, transitively, grouped and counted by type.node
list_sourcesThe published data sources and workbooks the graph is built from, plus the latest ingest status. With site_search, finds sources anywhere on the site (LUID + whether they're in the graph).node_type, site_search
search_semantic_contextsBusiness statements on the graph: all, graph-wide only, or attached to one node.node, is_global
graph_healthHealth score, coverage metrics, and prioritized improvement suggestions.pds_id, severity, suggestion_type, limit
create_semantic_context(write) Attach statements to one node (exact id) or to the whole graph.statements, target_node_id / is_global, name
update_semantic_context(write) Replace statements, rename, re-attach, or make graph-wide.ctx_id, statements, name, attach_to / make_global
delete_semantic_context(write) Delete a user-managed context; returns what was deleted.ctx_id
create_semantic_context_from_document(write) Upload a .txt/.md/.csv/.pdf/.docx/.xlsx (max 2 MB); Tableau makes each line a statement. Undocumented web-app API.file_path, target_node_id / is_global
add_sources(write) Add data sources / workbooks to a graph by exact LUID; Tableau ingests them in the background. Undocumented web-app API.pds_luids, workbook_luids, graph_id
remove_sources(write) Remove data sources / workbooks (and their nodes) from a graph; returns what was removed. Undocumented web-app API.pds_luids, workbook_luids, graph_id
create_graph(write) Create an empty knowledge graph; fill it with add_sources. Undocumented web-app API.name, description
update_graph(write) Rename a graph, replace its description, or make it the primary graph. Undocumented web-app API.graph_id, name, make_primary
ask_tableau_agentAsk Tableau's own agent about a graph, e.g. to test context against an answer key; follow-ups via conversation_id. Undocumented web-app API.question, conversation_id
export_to_ossieA published data source as an Apache Ossie model (YAML), plus validation and a loss report.datasource, include_hidden, default_aggregation_metrics
validate_ossieCheck any Ossie model (YAML/JSON) against the official schema and the spec's rules. Local only.document, model_name
import_from_ossie(write) Plan, then apply, the semantic contexts an Ossie model adds to a data source.document, target_datasource_id, apply
ossie_guideReference for Ossie: object model, expressions, Tableau mapping, converters, porting playbook. Local only.topic
check_business_preferencesCheck a Business Preferences file (format, limits, wording) and every field it names against the dashboard's captions. No text: the rulebook.text, target, product

Write tools are annotated readOnlyHint: false (update, delete and import also destructiveHint: true) so your client can ask before each one. Tableau-managed (SEMANTIC_CONTEXT_EXTERNAL) contexts are read-only.

Port your semantic layer with Apache Ossie

Apache Ossie (incubating, formerly Open Semantic Interchange) is a vendor-neutral YAML standard for semantic models. There was no converter for classic Tableau; this server is one, built on the Knowledge graph, so the business context travels too.

Tableau → Ossie (export_to_ossie):

Tableau KnowledgeOssie
Published data sourceModel (name, description, ai_context)
Logical tableDataset
Column fieldField (sql = source column; dimension, datatype)
Row-level calcField, Tableau formula in the TABLEAU dialect plus portable sql when exact
Aggregate calcMetric (dataset-scoped, or model-scoped with qualified names when it spans tables)
{FIXED [d]: SUM([x])}SUM(x) OVER (PARTITION BY d)
Default aggregation of a measureMetric (total_sales = SUM(sales))
Descriptions and semantic contextsdescription and ai_context
Ids, captions, roles, original formulascustom_extensions vendor TABLEAU (for exact round trips)

The export validates its own output and returns a losses list. Knowledge has no physical table paths or join keys, so source and relationships need filling in. INCLUDE/EXCLUDE LODs, table calcs, parameters and some functions stay Tableau-only, each named in the report.

Ossie → Tableau Knowledge (import_from_ossie): the Knowledge API can write semantic contexts, so that is what an Ossie model becomes. Descriptions, ai_context instructions, synonyms ("Also known as…"), example questions and metric definitions land on the matching nodes, one ossie:<model> context per node. Matching uses the ids from a previous export first, then names. On sites that accept only graph-wide context through the API, the same statements become one global ossie:<model> context, each prefixed with what it describes (Superstore / Sales: Also known as: revenue.); scope forces node or global. The first call returns the plan (create / update / unchanged, plus anything unmatched), and nothing is written until apply=true. Statements Tableau already holds are skipped, so re-importing an unedited export writes nothing.

Slash commands. The server ships MCP prompts that walk through each workflow: Export a data source to Ossie, Import an Ossie model into Tableau Knowledge, and Write Business Preferences. In Claude Code they appear as /mcp__tableau-knowledge__export_datasource_to_ossie and /mcp__tableau-knowledge__import_ossie_into_tableau_knowledge (with the server name you chose).

Onward to other platforms. Converters exist for Snowflake, dbt, Power BI, Databricks, Tableau Next, Cube, ThoughtSpot, Omni, Sigma and more. None are on PyPI yet, so ossie_guide (topic converters) gives the exact commands, pinned to a reviewed commit. The server will wrap them as tools once they are published.

Write Business Preferences that work

A Business Preferences file is the list of # rule lines Tableau's agent reads before it answers: one file per dashboard on Tableau Cloud (50 rules, 8,000 characters), one per semantic model on Tableau Next (30,000 characters). It shapes how the agent plans an answer, so every line has to be one it can follow. check_business_preferences encodes the field-tested lessons from Business Preferences in Tableau Cloud: What We Learned (Celia Fryar, XeoMatrix, September 2026):

  • Format slips that Tableau silently ignores: a space before #, no space after it.
  • Limits with headroom; no headers, blank lines or duplicates; no contradictions.
  • Wording that misleads the agent: thresholds without "use only this value", formatting rules that leak into the query, conversational lines, absences that can be over-read, ambiguous ordering and averages. It also suggests the two baseline rules (keep queries numeric, fail honestly) when they are missing.
  • Field names, checked live: give it the dashboard, and every [Field] must be a visible caption the agent will see, with "did you mean" suggestions. It also flags workbook problems: duplicate (Account ID (Account)), generic (Amount) and helper fields.

The write_business_preferences prompt runs the whole loop. It gathers the real captions, asks you for terms, thresholds and policies, then drafts and checks until clean, and returns v1 with the upload-then-publish and testing advice. Call check_business_preferences with no text for the full rulebook.

How a description becomes a node

text
# illustrative"the net sales field"   │  1. exact lookup: GET /nodes/{id}           → found? use it, no guessing   │  2. not an id: semantic search (top 4)      → best match + runners-up   ▼{ "id": "field:…:Net Sales", …,  "resolution": { "match": {"name": "Net Sales", "type": "FIELD", "score": 0.82},                  "alternatives": [ … ],                  "note": "Not an exact id: resolved by semantic search …" } }

The model sees the score and the alternatives, so it can confirm with you or retry with an alternative's id. Write tools skip this step entirely and require exact ids.

Example prompts

  • "Use server_info: which graphs does this site have, and which is primary?"
  • "Find the fields that mean revenue, then show the lineage of the best match."
  • "Run impact_analysis on the Superstore data source: which workbooks and dashboards depend on it?"
  • "What semantic context is attached to the Profit field?"
  • "Show the graph's health score and the five high-severity suggestions, with the nodes they target."
  • "Add a statement to the Profit field: 'Profit is calculated after returns and reported in EUR.'"

Architecture

[Architecture]

The server speaks MCP over stdio to the client and HTTPS to Tableau: it signs in with your PAT to get an X-Tableau-Auth session (refreshed on expiry), then calls /api/v1/knowledge. Nothing is stored; every answer is live.

Things the API does that you should know

  • Search is by meaning. Scores are relative; a top score around 0.4-0.5 can still be the right node, so check the alternatives.
  • Lineage follows dependencies, not containment. A single field's lineage is often just itself; list_edges shows which table HAS it.
  • Context search doesn't filter by text yet. search_semantic_contexts filters by node or is_global; find statements by meaning with search_nodes.
  • Unknown ids behave differently per endpoint. The API's lineage returns an empty graph for an unknown id; this server resolves the node first, so you always get a clear error instead.
  • Deletes are idempotent. Deleting an unknown id succeeds without effect.
  • Some sites accept only graph-wide context. Creating a node-attached context can fail with node_semantic_context_disabled ("node-scoped context is managed by Tableau and arrives through ingestion"); BiztoryPulse does this. Use is_global=true and name the field in the statement. import_from_ossie falls back to that automatically.
  • The API is rate-limited. Crawling a large graph node by node hits HTTP 429; the server retries with back-off, but prefer lineage and impact_analysis over many get_node calls.

Security

  • Writes are limited to semantic contexts, take exact ids, are validated before sending, and are annotated so your client can ask first. A Viewer or Explorer PAT makes the server read-only in practice.
  • Local and stdio-only. No inbound network port is opened.
  • Secrets from env only. Never tool arguments, never logged, never returned.
  • Credentials go only to your Tableau host. HTTPS required, certificates verified, redirects refused.
  • No injection through ids. Node and context ids are encoded as one path segment; graph_id is checked against Tableau's pattern before it is sent. Both parsers of untrusted input are fuzzed in CI.
  • YAML is parsed safely. Ossie documents go through yaml.safe_load (no tags, no code), with a 5 MB cap; validate_ossie and ossie_guide never contact Tableau.
  • Verifiable releases. Every GitHub release carries Sigstore signatures and a CycloneDX SBOM, and PyPI uploads use Trusted Publishing.
  • Pin a version in production: uvx biztory-tableau-knowledge-mcp==0.4.0.

See SECURITY.md for the threat model, data handling, disclosure policy and how to verify a release.

Troubleshooting

SymptomFix
Server doesn't appearFully quit and relaunch the client; check the config path and JSON validity.
spawn uvx ENOENTInstall uv, or use the absolute path to uvx.
Sign-in fails (401, 401001)The PAT is invalid or expired (15 days unused). Create a new one and check TABLEAU_SITE_CONTENT_URL.
site_not_entitledThe site doesn't have Tableau Knowledge; a Tableau Cloud Manager admin must enable it.
no_active_graphThe site has no primary graph: pass a graph_id from server_info.
"Semantic search is unavailable"The graph has no embedder. Use exact ids (list_sources → get_node).
tableau_forbidden on a writeWriting semantic contexts needs the Creator role.
HTTP 429 after retriesYou hit Tableau's rate limit; wait a minute and use fewer, broader calls.

Inspect the server directly with the MCP Inspector:

bash
npx @modelcontextprotocol/inspector uvx biztory-tableau-knowledge-mcp

Development

bash
git clone https://github.com/biztory/biztory-tableau-knowledge-mcp && cd biztory-tableau-knowledge-mcpuv sync --all-extrasuv run biztory-tableau-knowledge-mcp                   # run from source (needs the env vars above)uv run pytest --cov=biztory_tableau_knowledge_mcp      # tests + coverage (offline; no Tableau needed)uv run ruff check . && uv run ruff format --check . && uv run mypy

Tool tests run through the real client against an in-process fake of the Knowledge API (tests/conftest.py), so URL building, id encoding and error mapping are all exercised. Live tests are opt-in: TABLEAU_LIVE=1 runs the read-only ones; TABLEAU_LIVE_WRITE=1 adds a round trip that creates, updates and deletes one temporary context it made itself.

The same gates run in CI (Linux/macOS/Windows, Python 3.10 to 3.13): ruff check, ruff format --check, mypy --strict, and pytest with a coverage floor. CodeQL scans every push, the OpenSSF Scorecard runs weekly, and a fuzzing job (fuzz/) attacks the untrusted-input parsers. The package ships a PEP 561 py.typed marker.

Contributions welcome: see CONTRIBUTING.md and the Code of Conduct.

Roadmap

  • Export to and import from Apache Ossie (formerly OSI)
  • Wrap the Ossie converters (Snowflake, dbt, Power BI, Databricks) as tools once they are published on PyPI
  • Ossie relationships from Tableau join keys, when the Knowledge API exposes them
  • A demo recording in this README
  • Optional per-session caching of server_info and resolved nodes

Ideas and votes welcome in Discussions.

License

MIT © Biztory. Sister project: tableau-graphql-mcp for lineage over the Tableau Metadata API.

Source: README.md at commit bdf54a3

Tools

23

server_info

Connection and graphs

Report the connected Tableau site and its knowledge graphs: server URL, site, product version, auth method, whether Tableau Knowledge is available, and every graph (id, name, status, is_primary). Good first call: it confirms the connection and gives the graph ids the other tools accept as `graph_id` (omit `graph_id` to use the primary graph).

Takes no parameters.

search_nodes

Search graph nodes

Find graph nodes by MEANING (semantic search), not exact name: "revenue" can match a field named "Net Sales". Returns ranked matches with a 0-1 `score`; when a semantic statement matched, it is shown under the node's `semantic_statements`. - `node_type` narrows to one type: PDS (published data source), WORKBOOK, SHEET, DASHBOARD, EMBEDDED_DATASOURCE, TABLE, FIELD, WAREHOUSE_TABLE, WAREHOUSE_COLUMN, CONNECTION, SCHEMA, SITE, SEMANTIC_CONTEXT, SEMANTIC_CONTEXT_EXTERNAL. - `scope_id` limits the search to one data source's subtree (a PDS node id plus its tables and fields). - `limit` 1-100 (default 10); `threshold` drops matches scoring below it (0-1). Use the returned `id`s with get_node, list_edges, lineage and impact_analysis.

Parameterslimitqueryrequiredgraph_idscope_idnode_typethreshold

get_node

Get node

Get one node with its properties, its semantic statements (the business context attached to it), and the child nodes it points to (`connected_nodes`, each with the edge type). `node` is a node id, or a plain-language description that is resolved by semantic search (the response then includes `resolution` with the match score and alternatives). Set `include_children` false to skip `connected_nodes` on large containers.

Parametersnoderequiredgraph_idinclude_children

list_edges

List edges

List the edges around one node, each with its `direction` (outgoing/incoming) and the node on the other end. One hop only; use lineage for the wider neighborhood. `node` is a node id or a plain-language description. `edge_type` narrows to one of: CONTAINS, HAS, JOINS, DEPENDS_ON, LINEAGE, SEMANTIC_EQUIV, DESCRIBES. `direction` is "outgoing" or "incoming"; omit for both.

Parametersnoderequiredgraph_iddirectionedge_type

lineage

Lineage

The lineage neighborhood of a node: every node reachable within 10 steps, upstream AND downstream, along lineage/dependency edges (LINEAGE, DEPENDS_ON), e.g. a data source and the workbooks built on it. Answers "where does this come from?" and "what uses it?". Containment (a table HAS a field, a workbook CONTAINS a sheet) is not followed, so a single field often returns only itself; use list_edges or get_node to see what contains it. `node` is a node id or a plain-language description. Returns the anchor node, `nodes`, `edges` (source_id -> target_id, with type), and counts by node and edge type. For "what breaks if this changes?", impact_analysis is more direct.

Parametersnoderequiredgraph_id

impact_analysis

Impact analysis

What breaks if this changes: every asset that depends on the node, directly OR transitively (up to 10 steps, following DEPENDS_ON), e.g. the calcs, sheets, dashboards and workbooks downstream of a column. The node itself is not included. `node` is a node id or a plain-language description. Returns `total`, `counts_by_type`, and `affected_assets` sorted by type then name.

Parametersnoderequiredgraph_id

list_sources

List sources

List the published data sources and workbooks connected to the knowledge graph, i.e. what the graph has been built from. `node_type` "PDS" or "WORKBOOK" narrows it; omit for both. `ingest` shows the graph's latest ingestion (status running/completed, per-asset results). With `site_search` (part of a name, case-insensitive), it instead searches the whole SITE for data sources and workbooks to add with add_sources: each hit has its `luid` and `in_graph`.

Parametersgraph_idnode_typesite_search

search_semantic_contexts

Find semantic contexts

List semantic contexts: the business statements (definitions, rules, caveats) attached to the graph. Includes user-managed (SEMANTIC_CONTEXT, editable) and Tableau-managed (SEMANTIC_CONTEXT_EXTERNAL, read-only) contexts. - With `node` (an id or a description): only the contexts attached to that node. - Without `node`: every context on the graph; `is_global` true = only graph-wide contexts, false = only node-attached ones, omitted = both. The API doesn't filter by text yet; to find statements by meaning, use search_nodes.

Parametersnodegraph_idis_global

graph_health

Graph health

Graph-health report: a 0-100 `health_score`, coverage metrics (e.g. how many nodes carry semantic context), graph stats, and concrete improvement suggestions (each with severity, recommended_action and the target node ids), grouped by category and topic. `pds_id` scopes the report to one published data source's subtree. `severity` ("high", "medium", "low"), `suggestion_type` and `limit` (default 20; a busy graph has hundreds) filter only the suggestion lists; the score, metrics and `summary` totals always cover the full (or PDS-scoped) graph.

Parameterslimitpds_idgraph_idseveritysuggestion_type

create_semantic_context

Add semantic context

WRITE: attach business context (one or more statements, 5-1000 characters each) to the knowledge graph, e.g. "Net Sales excludes returns and is reported in EUR." Set exactly ONE of: `target_node_id` (an exact node id from search_nodes/get_node; the context then DESCRIBES that node) or `is_global=true` (applies to the whole graph). CONNECTION, SITE, SCHEMA and semantic-context nodes can't be targets. Some sites accept only graph-wide context through the API (error node_semantic_context_disabled): then use is_global=true and name the field or data source in each statement. `name` is optional (derived when omitted). Needs the Creator role. Returns the new context, with its id.

Parametersnamegraph_idis_globalstatementsrequiredtarget_node_id

update_semantic_context

Update semantic context

WRITE: change a user-managed semantic context (`ctx_id`, e.g. "semctx:<uuid>"). Only what you pass changes. - `statements` REPLACES the whole stored set (include every statement you want to keep). - `name` renames it. - `attach_to` (an exact node id) re-attaches it to that node; `make_global=true` detaches it and makes it graph-wide. Not both. Tableau-managed (SEMANTIC_CONTEXT_EXTERNAL) contexts can't be changed. Needs the Creator role.

Parametersnamectx_idrequiredgraph_idattach_tostatementsmake_global

delete_semantic_context

Delete semantic context

WRITE: delete a user-managed semantic context and its statements. Only semantic contexts created through Tableau Knowledge can be deleted; ids of other nodes are ignored, and Tableau-managed (SEMANTIC_CONTEXT_EXTERNAL) contexts are refused. Returns what was deleted (name and statements, so it can be recreated if needed). Deleting an id that doesn't exist succeeds without effect. Needs the Creator role.

Parametersctx_idrequiredgraph_id

create_semantic_context_from_document

Add semantic context from a document

WRITE: upload a local document (.txt, .md, .csv, .pdf, .docx, .xlsx; max 2 MB) and let Tableau turn it into semantic context, e.g. a KPI glossary or a business-rules note. `file_path` is a path on the machine running this server; the file's content is sent to your Tableau site, so confirm the file with the user first. Set exactly ONE of `target_node_id` (an exact node id) or `is_global=true`, as for create_semantic_context (some sites accept only graph-wide context). Tableau makes each line a statement (headings too), so write one rule per line. Returns the new context with its statements and any `statements_skipped`. Uses Tableau Knowledge's undocumented web-app API, which can change without notice.

Parametersnamegraph_idfile_pathrequiredis_globaltarget_node_id

add_sources

Add sources to graph

WRITE: add published data sources (`pds_luids`) and/or workbooks (`workbook_luids`) to a knowledge graph. Tableau ingests them in the background (seconds to minutes); check with list_sources (`ingest.status`). Adds only: sources already in the graph stay, and re-adding one re-ingests it. Exact LUIDs only, never names: find them with list_sources(site_search="part of a name"). `graph_id` is required (or TABLEAU_KNOWLEDGE_GRAPH_ID): this never falls back to the primary graph. Confirm the list with the user first. Uses Tableau Knowledge's undocumented web-app API, which can change without notice.

Parametersgraph_idpds_luidsworkbook_luids

remove_sources

Remove sources from graph

WRITE: remove published data sources and/or workbooks, and the nodes built from them, from a knowledge graph. The Tableau content itself is untouched. Context attached to removed nodes may be lost; graph-wide context stays. Exact LUIDs only (a source's properties.luid from list_sources); pass them in either list, the type comes from the graph. LUIDs that aren't in the graph are reported and skipped. `graph_id` is required (or TABLEAU_KNOWLEDGE_GRAPH_ID). Confirm with the user first. Returns what was removed; add_sources with the same LUIDs puts it back. Uses Tableau Knowledge's undocumented web-app API, which can change without notice.

Parametersgraph_idpds_luidsworkbook_luids

create_graph

Create graph

WRITE: create a new, empty knowledge graph on the site (sites allow a few: see server_info `features.max_graphs_per_site`). Then fill it with add_sources. Returns the graph with its id. Confirm the name with the user first. Uses Tableau Knowledge's undocumented web-app API, which can change without notice.

Parametersnamerequireddescription

update_graph

Update graph

WRITE: rename a knowledge graph, replace its description, and/or make it the site's primary graph (the default for everyone who doesn't pick a graph; only one graph is primary). Only what you pass changes. `graph_id` is an exact id from server_info. Confirm with the user first. Uses Tableau Knowledge's undocumented web-app API, which can change without notice.

Parametersnamegraph_idrequireddescriptionmake_primary

ask_tableau_agent

Ask Tableau Agent

Ask Tableau's own agent (the chat in Tableau Knowledge) a question about a graph and get its answer, e.g. to test semantic context and Business Preferences against an answer key: ask one question at a time and compare the numbers yourself. Pass the returned `conversation_id` to ask a follow-up in the same conversation (this server keeps the history in memory, so it lasts until the server restarts). Omit it for a fresh conversation, which is the fair way to test. `tools_used` lists the agent's own tool calls. The agent can also write semantic statements when asked to, so phrase questions as questions. Can take a minute. Uses Tableau Knowledge's undocumented web-app API, which can change without notice.

Parametersgraph_idquestionrequiredconversation_id

export_to_ossie

Export to Ossie

Export a published data source's semantic model to Apache Ossie (formerly OSI) YAML, the vendor-neutral format that Snowflake, dbt, Power BI, Databricks, Tableau Next and other tools convert from. Returns `ossie` (the YAML text, to save as `file_name`), `summary`, `validation` and `losses` (what could not be carried and what to fix by hand). `datasource` is a PDS id (from list_sources) or a description of it. Logical tables become datasets, fields become fields, row-level calcs become fields and aggregate calcs become metrics; every calc keeps its Tableau formula and gains portable SQL when the translation is exact. Semantic-context statements become ai_context. `default_aggregation_metrics` also turns each measure's Tableau default aggregation into a metric (total_sales = SUM(sales)). Always read `losses`: Tableau Knowledge has no physical table paths or join keys, so `source` and `relationships` need filling in before the model is used elsewhere. See ossie_guide.

Parametersgraph_iddatasourcerequiredinclude_hiddendefault_aggregation_metrics

validate_ossie

Validate Ossie model

Validate an Apache Ossie (formerly OSI) model, given as YAML or JSON text, against the official JSON Schema (0.2.0.dev0, bundled) and the spec's semantic rules: duplicate names, keys and relationship columns that are not declared fields, unknown datasets, qualified names in dataset-scoped metrics. 0.1.1 documents (`semantic_model:` list) are converted first; pass `model_name` when one holds several models. Runs locally: nothing is sent to Tableau.

Parametersdocumentrequiredmodel_name

import_from_ossie

Import from Ossie

Bring the business meaning of an Apache Ossie (formerly OSI) model into Tableau Knowledge as semantic contexts. WRITES only when `apply` is true; by default it returns the PLAN. `document` is the model as YAML or JSON text. Elements are matched to nodes of one published data source: models exported by export_to_ossie map back by their stored ids; other models need `target_datasource_id` (an exact PDS id from list_sources) and match by name. Each matched node gets one context named `ossie:<model>` holding its description, ai_context instructions, synonyms ("Also known as: ..."), example questions, metric definition (`include_definitions`) and relationships. Re-importing updates those contexts instead of duplicating them. `scope`: "auto" (default) attaches contexts to nodes and, on sites that accept only graph-wide context through the API (error node_semantic_context_disabled), writes the plan's `global_fallback` instead: one global `ossie:<model>` context whose statements are prefixed with what they describe. "node" never falls back; "global" plans the global context directly. Workflow: call without `apply`, show the user the operations (create/update/unchanged) and `unmatched` list, then call again with `apply=true` once they agree. Needs the Creator role.

Parametersapplyscopedocumentrequiredgraph_idmodel_nameinclude_definitionstarget_datasource_id

ossie_guide

Ossie guide

Reference for Apache Ossie (formerly Open Semantic Interchange, OSI), the open standard for semantic models: what it is and its versions, the object model and rules, expressions and dialects, how Tableau maps onto it, relationships, ai_context, extensions, validation, the converters for other platforms (with exact commands), and a porting playbook with pitfalls. Read it before hand-editing a model or advising on a port. `topic` is one of: overview, model, expressions, tableau, relationships, ai_context, extensions, validation, converters, porting; omit it for everything.

Parameterstopic

check_business_preferences

Check Business Preferences

Check a Tableau Business Preferences file (the "# rule" lines Tableau's agent reads before it answers) so every line is one the agent will actually follow. Call it with no `text` first to get the rulebook: format, limits, wording rules, workbook preparation and how to test. Checks: the "# " line format (a slip makes Tableau silently ignore the line), the limits (Tableau Cloud: 50 rules and 8,000 characters per dashboard; Tableau Next: 30,000 per semantic model), headers, duplicates, contradictions, thresholds without "use only this value", formatting rules that would leak into queries, conversational lines, absences that can be over-read, ambiguous ordering and averages, and missing baseline rules (query formatting, failure handling). `target` (a dashboard, sheet, workbook or data source: id or description) also checks every [Field] and "Field" the file names against the captions the agent will see in Tableau Knowledge, with "did you mean" suggestions, and flags workbook problems (duplicate, generic or helper field names). `product` is "cloud" or "next". Returns `ok` (no errors), `issues` by line, and stats.

Parameterstexttargetproductgraph_id

Version history

3
  1. v0.4.0LatestNov 5, 2026
  2. v0.3.0Oct 30, 2026
  3. v0.1.1Oct 30, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts