cwprep - Tableau Prep Flow SDK
A Python SDK for programmatically generating Tableau Prep data flow (.tfl) files. Built through reverse-engineering the TFL JSON structure, enabling flow creation and modification via code without opening the GUI.
Installation
pip install cwprep
Quick Start
from cwprep import TFLBuilder, TFLPackager
# Create builder
builder = TFLBuilder(flow_name="My Flow")
# Add database connection
conn_id = builder.add_connection(
host="localhost",
username="root",
dbname="mydb"
)
# Add input tables
orders = builder.add_input_table("orders", "orders", conn_id)
customers = builder.add_input_table("customers", "customers", conn_id)
# Join tables
joined = builder.add_join(
name="Orders + Customers",
left_id=orders,
right_id=customers,
left_col="customer_id",
right_col="customer_id",
join_type="left"
)
# Add output
builder.add_output_server("Output", joined, "My_Datasource")
# Build and save
flow, display, meta = builder.build()
TFLPackager.save_to_folder("./output", flow, display, meta)
TFLPackager.pack_zip("./output", "./my_flow.tfl")
Features
| Feature | Method | Description |
|---|---|---|
| Database Connection | add_connection() | Connect to MySQL/PostgreSQL/Oracle |
| SQL Input | add_input_sql() | Custom SQL query input |
| Table Input | add_input_table() | Direct table connection |
| Join | add_join() | left/right/inner/full joins |
| Union | add_union() | Merge multiple tables |
| Filter | add_filter() | Expression-based filter |
| Value Filter | add_value_filter() | Keep/exclude by values |
| Keep Only | add_keep_only() | Select columns |
| Remove Columns | add_remove_columns() | Drop columns |
| Rename | add_rename() | Rename columns |
| Calculation | add_calculation() | Tableau formula fields |
| Aggregate | add_aggregate() | GROUP BY with SUM/AVG/COUNT |
| Pivot | add_pivot() | Rows to columns |
| Unpivot | add_unpivot() | Columns to rows |
| Output | add_output_server() | Publish to Tableau Server |
Examples
See the examples/ directory for complete demos:
demo_basic.py- Input, Join, Outputdemo_cleaning.py- Filter, Calculate, Renamedemo_aggregation.py- Union, Aggregate, Pivotdemo_comprehensive.py- All features combined
MCP Server
cwprep includes a built-in Model Context Protocol server, enabling AI clients (Claude Desktop, Cursor, Gemini CLI, etc.) to generate TFL files directly.
Prerequisites
| Method | Requirement |
|---|---|
uvx (recommended) | Install uv — it auto-downloads cwprep[mcp] in an isolated env |
pip install | Python ≥ 3.8 + pip install cwprep[mcp] |
Quick Start
# Local (stdio)
cwprep-mcp
# Remote (Streamable HTTP)
cwprep-mcp --transport streamable-http --port 8000
Client Configuration
All clients below use the uvx method (recommended). Replace uvx with cwprep-mcp if you prefer a local pip install.
Claude Desktop
Edit config file:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"cwprep": {
"command": "uvx",
"args": ["--from", "cwprep[mcp]", "cwprep-mcp"]
}
}
}
Cursor
Settings → MCP → Add new MCP server, or edit ~/.cursor/mcp.json:
{
"mcpServers": {
"cwprep": {
"command": "uvx",
"args": ["--from", "cwprep[mcp]", "cwprep-mcp"]
}
}
}
VS Code (Copilot)
Create .vscode/mcp.json in project root:
{
"servers": {
"cwprep": {
"command": "uvx",
"args": ["--from", "cwprep[mcp]", "cwprep-mcp"]
}
}
}
Windsurf (Codeium)
Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"cwprep": {
"command": "uvx",
"args": ["--from", "cwprep[mcp]", "cwprep-mcp"]
}
}
}
Claude Code (CLI)
claude mcp add cwprep -- uvx --from "cwprep[mcp]" cwprep-mcp
Gemini CLI
Edit ~/.gemini/settings.json:
{
"mcpServers": {
"cwprep": {
"command": "uvx",
"args": ["--from", "cwprep[mcp]", "cwprep-mcp"]
}
}
}
Continue (VS Code / JetBrains)
Edit ~/.continue/config.yaml:
mcpServers:
- name: cwprep
command: uvx
args:
- --from
- cwprep[mcp]
- cwprep-mcp
Remote HTTP Mode (any client)
Start the server:
cwprep-mcp --transport streamable-http --port 8000
Then configure your client with the endpoint: http://your-server-ip:8000/mcp
Available MCP Capabilities
| Type | Name | Description |
|---|---|---|
| 🔧 Tool | generate_tfl | Generate .tfl file from flow definition |
| 🔧 Tool | list_supported_operations | List all supported node types |
| 🔧 Tool | validate_flow_definition | Validate flow definition before generating |
| 📖 Resource | cwprep://docs/api-reference | SDK API reference |
| 📖 Resource | cwprep://docs/calculation-syntax | Tableau Prep calculation syntax |
| 💬 Prompt | design_data_flow | Interactive flow design assistant |
| 💬 Prompt | explain_tfl_structure | TFL file structure explanation |
AI Skill Support
This project includes a specialized AI Skill for assistants like Claude or Gemini to help you build flows.
- Location:
.agents/skills/tfl-generator/ - Features: Procedural guidance for flow construction, API reference, and Tableau Prep calculation syntax rules.
Directory Structure
cwprep/
├── .agents/skills/ # AI Agent skills and technical references
├── src/cwprep/ # SDK source code
│ ├── builder.py # TFLBuilder class
│ ├── packager.py # TFLPackager class
│ ├── config.py # Configuration utilities
│ └── mcp_server.py # MCP Server (Tools, Resources, Prompts)
├── examples/ # Demo scripts
├── docs/ # Documentation
└── tests/ # Unit tests
Configuration
Create config.yaml for default settings:
database:
host: localhost
username: root
dbname: mydb
port: "3306"
db_class: mysql
tableau_server:
url: http://your-server
project_name: Default
Changelog
See changelog.md for version history.
License
MIT License