Metadata-Version: 2.5
Name: tableau-cli
Version: 0.1.5
Summary: CLI for Tableau Server/Cloud, designed for AI agent integration
Project-URL: Repository, https://github.com/i-richardwang/tableau-cli
Author: Richard Wang
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Requires-Dist: click>=8.0
Requires-Dist: httpx>=0.27
Provides-Extra: convert
Requires-Dist: tableauhyperapi>=0.0.26479; extra == 'convert'
Provides-Extra: dev
Requires-Dist: pyarrow>=15.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.11; extra == 'dev'
Requires-Dist: tzdata; extra == 'dev'
Description-Content-Type: text/markdown

# tableau-cli

A command-line interface for Tableau Server / Tableau Cloud, designed for AI agent integration. All output is structured JSON to stdout, with agent-friendly error messages that include actionable hints.

## Why CLI over MCP?

MCP (Model Context Protocol) servers continuously occupy agent context — every tool description is loaded into the system prompt, even when only one command is needed. A CLI follows a simpler call-execute-exit pattern: the agent invokes a command, reads the JSON output, and moves on.

The companion agent skill under `skills/` extends the same idea to command knowledge — the full reference is loaded only when the agent is about to execute a command, not kept in context upfront. See [Use with Coding Agents](#use-with-coding-agents) below.

This project provides the same capabilities as the [tableau-mcp](https://github.com/tableau/tableau-mcp) server, with behavioral alignment in data transformations, error handling, and output structures.

## Quick Start

### Prerequisites

- Python >= 3.11
- A Tableau Server or Tableau Cloud instance
- A [Personal Access Token (PAT)](https://help.tableau.com/current/server/en-us/security_personal_access_tokens.htm)

### Install

```bash
git clone https://github.com/i-richardwang/tableau-cli.git
cd tableau-cli
pip install -e .

# Optional: install conversion dependencies (TDSX/HYPER → Parquet/CSV)
pip install -e ".[convert]"
```

### Configure

```bash
# Option 1: CLI config (saved to ~/.tableau-cli.json)
tableau-cli config set \
  --server https://your-tableau-server.com \
  --site-name YourSite \
  --pat-name your-token-name \
  --pat-value your-token-value

# Option 2: Environment variables
export SERVER=https://your-tableau-server.com
export SITE_NAME=YourSite
export PAT_NAME=your-token-name
export PAT_VALUE=your-token-value
```

Environment variables take precedence over the config file. `siteName` defaults to `""` (the default site) if not set.

```bash
# Verify configuration
tableau-cli config show
```

## Use with Coding Agents

This repository ships an agent skill (`skills/tableau-cli/`) that routes a user's request to the right command and loads the full CLI reference only at execution time. The repository doubles as its own plugin marketplace for both Claude Code and Codex.

**Claude Code**

```
/plugin marketplace add i-richardwang/tableau-cli
/plugin install tableau-cli@tableau-cli
```

To receive updates, enable auto-update for the `tableau-cli` marketplace in `/plugin`, or run `/plugin marketplace update tableau-cli` manually.

**Codex**

```
codex plugin marketplace add i-richardwang/tableau-cli
codex plugin add tableau-cli@tableau-cli
```

To receive updates, run `codex plugin marketplace upgrade`.

The skill is only needed when an agent drives the tool — the CLI works standalone from any shell.

## Commands

### Search

Search across all content types (workbooks, views, datasources, etc.).

```bash
tableau-cli search "Superstore"
tableau-cli search "Sales" --type workbook,view
tableau-cli search "Revenue" --limit 10 --order-by hitsTotal:desc
```

### Datasources

```bash
# List all datasources
tableau-cli datasources list
tableau-cli ds list --filter "name:has:Sales" --limit 50

# Download datasource file (.tdsx)
tableau-cli datasources download <datasourceId> -o ./data/

# Download and convert to Parquet or CSV in one step (requires tableau-cli[convert] or uv)
tableau-cli ds download <datasourceId> -o ./data/ --to parquet
tableau-cli ds download <datasourceId> -o ./data/ --to csv

# Get field metadata (VizQL Data Service + Metadata API enrichment).
# On Tableau >= 2025.3 the result also includes the datasource model:
# logical tables and their relationships.
tableau-cli datasources metadata <luid>

# Query datasource data (VizQL Data Service)
tableau-cli datasources query <luid> --query '{"fields": [{"fieldCaption": "Category"}, {"fieldCaption": "Sales"}]}'
tableau-cli ds query <luid> --query '{"fields": [...]}' --limit 100
```

### Views

```bash
# List views (includes upstream datasources via Metadata API enrichment)
tableau-cli views list
tableau-cli views list --filter "name:has:Dashboard" --format table

# Get view details: upstream datasources, workbook/project/owner info, and web URL
tableau-cli views get <viewId>

# Get view data as CSV
tableau-cli views data <viewId>

# Get view data with view filters applied
tableau-cli views data <viewId> --vf "Region=West" --vf "Category=Technology"

# Download view image
tableau-cli views image <viewId> -o dashboard.png
tableau-cli views image <viewId> --width 1200 --height 800 --img-format SVG -o dashboard.svg
tableau-cli views image <viewId> --vf "Region=West" -o west.png
```

### Convert

Convert local TDSX/HYPER files to Parquet or CSV.

Conversion runs locally through the official `tableauhyperapi` package. Its native Hyper engine exports directly to Parquet or CSV, without loading the entire extract into a DataFrame. You have two options:

- Install the export dependency into the CLI: `pip install tableau-cli[convert]`.
- Don't install anything: if [uv](https://docs.astral.sh/uv/) is on your `PATH`, conversion transparently falls back to running the step in an ephemeral `uv run --with ...` environment, so the conversion dependency never lands in your host Python. The first run provisions the environment (a few seconds); later runs use uv's cache. This is the recommended path when the CLI itself was installed via `uv tool install tableau-cli`.

The conversion runtime requires native 64-bit Python 3.11 or newer. Supported targets are Apple Silicon Macs (macOS 13+), Intel Macs, Windows x86_64, and the Linux x86_64 distributions supported by [Hyper API](https://tableau.github.io/hyper-db/docs/installation/). Package installation selects the engine for the interpreter's platform; Apple Silicon uses the native ARM package.

Each extract must contain exactly one table. Exports preserve column order and use Hyper's native [Parquet and CSV mappings](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/copy-to.html). CSV includes a header and uses ISO dates. The destination is replaced only after a complete export. Download-and-convert commands check that the local engine can start before downloading the datasource.

For most use cases, `ds download --to parquet` (or `--to csv`) is simpler — it downloads and converts in one step. The `convert` command is useful when you already have a `.tdsx` or `.hyper` file on disk.

```bash
# Convert TDSX to Parquet (default)
tableau-cli convert data.tdsx
tableau-cli convert data.tdsx -o ./output/

# Convert to CSV
tableau-cli convert data.tdsx --to csv
tableau-cli convert data.tdsx --to csv -o ./output/

# Convert standalone HYPER file
tableau-cli convert extract.hyper --to csv -o ./output/result.csv
```

### Workbooks

```bash
# List workbooks (includes upstream datasources via Metadata API enrichment)
tableau-cli workbooks list
tableau-cli wb list --filter "name:eq:Finance" --format table

# Get workbook details (includes views with usage statistics,
# upstream datasources, and the default view's web URL)
tableau-cli workbooks get <workbookId>
```

### Projects

```bash
# List projects
tableau-cli projects list
tableau-cli projects list --filter "topLevelProject:eq:true" --format table
```

### Config

```bash
tableau-cli config set --server https://tableau.example.com
tableau-cli config show
```

## Output

All commands output structured JSON to stdout by default. Use `--format table` for human-readable table output.

```bash
# JSON (default, for agent consumption)
tableau-cli ds list

# Table (for human reading)
tableau-cli ds list --format table
```

### File Output

Commands that save files (`ds download`, `views image -o`, `convert`) output a JSON object with the file path to stdout, enabling agents to chain operations:

```bash
# Download and convert in one step
tableau-cli ds download <id> -o ./data/ --to parquet  # → {"filePath": ".../data.parquet"}

# Or as separate steps (useful for keeping the original .tdsx)
tableau-cli ds download <id> -o ./data/               # → {"filePath": ".../data.tdsx"}
tableau-cli convert ./data/data.tdsx -o ./data/        # → {"filePath": ".../data.parquet"}
```

### Error Output

Errors are also structured JSON, designed to guide agents toward resolution:

```json
{
  "isError": true,
  "errorType": "feature-disabled",
  "message": "The VizQL Data Service is disabled on this Tableau Server.",
  "hint": "To enable it, use TSM using the instructions at https://help.tableau.com/..."
}
```

Error types include: `authentication-error`, `feature-disabled`, `tableau-api-error`, `config-error`, `validation-error`, and translated [VDS error codes](https://help.tableau.com/current/api/vizql-data-service/en-us/docs/vds_error_codes.html) with actionable hints.

## API Coverage

| Area | APIs Used |
|------|-----------|
| Authentication | REST API v3.24 — PAT sign-in / sign-out |
| Datasources | REST API (list, download) + VizQL Data Service (metadata, model, query) + Metadata API (GraphQL enrichment) |
| Views | REST API (list, get, data, image with view filters) + Metadata API (lineage enrichment) |
| Workbooks | REST API (list, get with view enrichment) + Metadata API (lineage enrichment) |
| Projects | REST API (list) |
| Search | Content Exploration API + Metadata API (lineage enrichment) |
| Convert | Local file conversion: TDSX/HYPER → Parquet/CSV (optional dependencies) |

## Development

```bash
# Run directly
python -m tableau_cli.cli views list

# Install development and conversion dependencies
pip install -e ".[convert,dev]"

# Validate local exports and isolated uv execution
ruff check .
pytest
```

## Acknowledgements

This project is derived from [@tableau/mcp-server](https://github.com/tableau/tableau-mcp), adapting its Tableau REST API, VizQL Data Service, and Metadata API integrations into a CLI format.

## License

[Apache License 2.0](./LICENSE)
