Server data from the Official MCP Registry
Generate Tableau .twb/.twbx workbooks: 47 tools for charts, dashboards, rules, CSV pipelines.
Generate Tableau .twb/.twbx workbooks: 47 tools for charts, dashboards, rules, CSV pipelines.
Remote endpoints: streamable-http: https://web-production-dcbcb.up.railway.app/mcp
Twilize is a legitimate MCP server for Tableau workbook generation with proper authentication structure and no malicious patterns detected. The codebase demonstrates reasonable security practices with appropriate use of file I/O and XML processing. Minor code quality findings around input validation and broad exception handling prevent a higher score, but permissions align well with the server's stated purpose of workbook engineering. Supply chain analysis found 6 known vulnerabilities in dependencies (0 critical, 5 high severity). Package verification found 1 issue.
4 files analyzed · 11 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Set these up before or after installing:
Environment variable: PYTHONUNBUFFERED
Environment variable: PYTHONIOENCODING
Environment variable: MCP_LOG_LEVEL
Environment variable: OPENAI_API_KEY
Available as Local & Remote
This plugin can run on your machine or connect to a hosted endpoint. during install.
From the project's GitHub README.
Tableau Workbook (.twb/.twbx) generation toolkit for reproducible dashboards and workbook engineering Programmatically create Tableau workbooks with stable analytical primitives, dashboard composition, and built-in structural validation.
If you just want to use twilize from an MCP client and skip the Python setup entirely, install it through the Smithery MCP registry:
Smithery writes the uvx twilize launch command directly into your MCP
client's config. You need uv
installed locally (Smithery will prompt you if it's missing) — nothing else.
If you'd rather wire the server up by hand, or you want the full Python library API, keep reading.
twilize is a Model Context Protocol (MCP) server and Python toolkit for generating Tableau Desktop workbook files (.twb / .twbx) from code or AI-driven tool calls.
It is designed as a workbook engineering layer, not as a conversational data exploration agent. The goal is to make workbook generation reproducible, inspectable, and safe to automate in local workflows, scripts, and CI.
The default workflow is:
.twb or .twbx) or the built-in zero-config template.twb or .twbx that opens in Tableau Desktop Interfaces
┌───────────────────────────────────────────────────────────────┐
│ ┌──────────────────────────┐ ┌───────────────────────────┐ │
│ │ MCP Server │ │ Python Library │ │
│ │ tools_workbook │ │ from twilize.twb_editor │ │
│ │ tools_layout │ │ import TWBEditor │ │
│ │ tools_migration │ │ │ │
│ │ tools_support │ │ editor.add_...() │ │
│ │ │ │ editor.configure_...() │ │
│ │ (Claude / Cursor / │ │ editor.save(...) │ │
│ │ VSCode / Claude Code) │ │ │ │
│ └─────────────┬────────────┘ └──────────────┬────────────┘ │
│ └──────────────┬────────────────┘ │
└───────────────────────────── ┼ ─────────────────────────────┘
▼
┌───────────────────────────────────────────────────────────────┐
│ TWBEditor │
│ ParametersMixin · ConnectionsMixin │
│ ChartsMixin · DashboardsMixin │
└──────────┬──────────────────┬──────────────────┬─────────────┘
▼ ▼ ▼
┌──────────────────┐ ┌──────────────┐ ┌──────────────────────┐
│ Chart Builders │ │ Dashboard │ │ Analysis & │
│ │ │ System │ │ Migration │
│ Basic DualAxis │ │ │ │ │
│ Pie Text │ │ layouts │ │ migration.py │
│ Map Recipes │ │ actions │ │ twb_analyzer.py │
│ │ │ dependencies│ │ capability_registry │
└────────┬─────────┘ └──────┬───────┘ └──────────┬───────────┘
└───────────────────┼──────────────────────┘
▼
┌───────────────────────────────────────────────────────────────┐
│ XML Engine (lxml) │
│ template.twb/.twbx → patch → validate → save │
└───────────────────────────────┬───────────────────────────────┘
▼
output.twb / output.twbx
pip install twilize
To run the bundled Hyper-backed example that inspects .hyper files and
resolves the physical Orders_* table automatically, install the optional
example dependency as well:
pip install "twilize[examples]"
To allow an MCP client to build Tableau workbooks automatically, add twilize
to that client's MCP configuration.
The launch command is the same across clients:
uvx twilize
Each client stores this command in a different configuration format. Use the matching example below.
Open ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows and add:
{
"mcpServers": {
"twilize": {
"command": "uvx",
"args": ["twilize"]
}
}
}
commandtwilizeuvx twilizeclaude mcp add twilize -- uvx twilize
Open the workspace .vscode/mcp.json file or your user-profile mcp.json
file and add:
{
"servers": {
"twilize": {
"command": "uvx",
"args": ["twilize"]
}
}
}
In VSCode, you can open these files from the Command Palette with
MCP: Open Workspace Folder Configuration or
MCP: Open User Configuration. You can also use MCP: Add Server and
enter the same uvx twilize command through the guided flow.
Open ~/.codeium/windsurf/mcp_config.json and add:
{
"mcpServers": {
"twilize": {
"command": "uvx",
"args": ["twilize"]
}
}
}
If you do not want to install Python or uv locally, point your MCP
client at the hosted twilize server. This loses local file access (the
server cannot read CSVs or write .twbx files into your ~/Downloads),
so it is best for read-only workflows like template recommendation,
capability inspection, and remote workbook validation.
{
"mcpServers": {
"twilize": {
"type": "streamable-http",
"url": "https://web-production-dcbcb.up.railway.app/mcp"
}
}
}
Use TWBEditor(...) to start from a template and rebuild workbook content.
Use TWBEditor.open_existing(...) when you want to keep existing worksheets
and dashboards and reconfigure a sheet in place.
from twilize.twb_editor import TWBEditor
editor = TWBEditor("") # "" uses the built-in Superstore template
editor.clear_worksheets()
editor.add_calculated_field("Profit Ratio", "SUM([Profit])/SUM([Sales])")
editor.add_worksheet("Sales by Category")
editor.configure_chart(
worksheet_name="Sales by Category",
mark_type="Bar",
rows=["Category"],
columns=["SUM(Sales)"],
)
editor.add_worksheet("Segment Pie")
editor.configure_chart(
worksheet_name="Segment Pie",
mark_type="Pie",
color="Segment",
wedge_size="SUM(Sales)",
)
editor.add_dashboard(
dashboard_name="Overview",
worksheet_names=["Sales by Category", "Segment Pie"],
layout="horizontal",
)
editor.save("output/my_workbook.twb")
.twbx files are ZIP archives that bundle the workbook XML together with data extracts (.hyper) and image assets. twilize reads and writes them transparently:
from twilize.twb_editor import TWBEditor
# Open a packaged workbook — extracts and images are preserved automatically
editor = TWBEditor.open_existing("templates/dashboard/MyDashboard.twbx")
# Make changes as usual
editor.add_calculated_field("Profit Ratio", "SUM([Profit])/SUM([Sales])")
# Save as .twbx — re-bundles the updated .twb with the original extracts/images
editor.save("output/MyDashboard_v2.twbx")
# Or extract just the XML when the packaged format isn't needed
editor.save("output/MyDashboard_v2.twb")
A plain .twb can also be packaged:
editor = TWBEditor("templates/twb/superstore.twb")
# ...
editor.save("output/superstore.twbx") # produces a single-entry ZIP with the .twb inside
| Tool | Description |
|---|---|
create_workbook | Load a .twb or .twbx template and initialize a rebuild-from-template workspace |
open_workbook | Open an existing .twb or .twbx and keep its worksheets and dashboards for editing |
list_fields | List all available dimensions and measures |
list_worksheets | List worksheet names in the active workbook |
list_dashboards | List dashboards and the worksheet zones they reference |
add_parameter | Add an interactive parameter for what-if analysis |
add_calculated_field | Add a calculated field with Tableau formula |
remove_calculated_field | Remove a previously added calculated field |
add_worksheet | Add a new blank worksheet |
configure_chart | Configure chart type and field mappings |
configure_worksheet_style | Apply worksheet-level styling: background color, axis/grid/border visibility |
configure_dual_axis | Configure a dual-axis chart composition |
configure_chart_recipe | Configure a showcase recipe chart such as lollipop, donut, butterfly, or calendar |
add_dashboard | Create a dashboard combining worksheets |
add_dashboard_action | Add filter or highlight actions to a dashboard |
generate_layout_json | Build an interactive structured dashboard flexbox layout |
list_capabilities | Show twilize's declared support boundary |
describe_capability | Explain whether a chart or feature is core, advanced, recipe, or unsupported |
analyze_twb | Analyze a .twb file against the capability catalog; output includes both the full capability breakdown and the capability gap triage summary |
diff_template_gap | Summarize the non-core gap of a template |
validate_workbook | Validate a workbook against the official Tableau TWB XSD schema (2026.1) |
migrate_twb_guided | Run the built-in TWB migration workflow and pause for warning confirmation when needed |
set_mysql_connection | Configure the datasource to use a local MySQL connection |
set_tableauserver_connection | Configure connection to an online Tableau Server |
set_hyper_connection | Configure the datasource to use a local Hyper extract connection |
save_workbook | Save the workbook as .twb (plain XML) or .twbx (ZIP with bundled extracts and images) |
These are the stable building blocks the project should continue to promise:
These are supported, but they are higher-level compositions or interaction features rather than the default surface area:
mark_color_1/2, color_map_1, reverse_axis_1, hide_zeroline, synchronizedRANK_DENSE, RUNNING_SUM, WINDOW_SUM via add_calculated_field(table_calc="Rows")MIN(1) dummy axis + axis_fixed_range + color_map + customized_labelconfigure_dual_axis(extra_axes=[...]); supports color_map for :Measure Names paletteconfigure_chart(label_runs=[...]) for multi-style KPI cards and dynamic titles with inline field valuesconfigure_worksheet_style supports pane-level cell/datalabel/mark styles, per-field label/cell/header formats, axis tick control, tooltip disabling, and all Tableau visual noise suppressionsconfigure_worksheet_style(hide_row_label="FieldName")show_title: false in layout dictsThese can be generated today, but they should be treated as recipes or examples rather than first-class promises:
Recipe charts are intentionally exposed through a single configure_chart_recipe
tool so the public MCP surface does not grow one tool at a time for every
showcase pattern.
This distinction matters because twilize is not trying to become a chart zoo or compete with Tableau's own conversational analysis tooling. The project is strongest when it provides a reliable, automatable workbook generation layer.
When you are not sure whether something belongs in the stable SDK surface:
list_capabilities to inspect the declared boundarydescribe_capability to check a specific chart, encoding, or featureanalyze_twb or diff_template_gap before chasing a showcase templateThis keeps new feature work aligned with the project's real product boundary instead of with whatever happens to appear in a sample workbook.
save() automatically validates the TWB XML structure before writing:
<workbook> or <datasources> raise TWBValidationError<view> or <panes> are logged but do not block savingeditor.save("output.twb", validate=False) or editor.save("output.twbx", validate=False)TWBEditor.validate_schema() checks the workbook against the official Tableau TWB XSD schema (2026.1), vendored at vendor/tableau-document-schemas/:
result = editor.validate_schema()
print(result.to_text())
# PASS Workbook is valid against Tableau TWB XSD schema (2026.1)
# — or —
# FAIL Schema validation failed (2 error(s)):
# * Element 'workbook': Missing child element(s)...
result.valid # bool
result.errors # list[str] — lxml error messages
result.schema_available # False if the vendor submodule is not checked out
The same check is available as an MCP tool:
validate_workbook() # validate current open workbook in memory
validate_workbook(file_path="out.twb") # validate a file on disk (.twb or .twbx)
XSD errors are informational — Tableau itself generates workbooks that occasionally deviate from the schema — but recurring errors signal structural problems worth fixing.
| Layout | Description |
|---|---|
vertical | Stack worksheets top to bottom |
horizontal | Place worksheets side by side |
grid-2x2 | 2x2 grid layout for up to four worksheets |
dict or .json path | Declarative custom layouts for more complex dashboards |
Custom layouts can be built programmatically using a nested layout dictionary or via generate_layout_json for MCP workflows.
The examples/hyper_and_new_charts.py example uses the Sample - EU Superstore.hyper
extract bundled directly in the package (src/twilize/references/) and resolves the
physical Orders_* table via Tableau Hyper API before switching the workbook connection.
No repository clone is needed — install with pip install "twilize[examples]" and run directly.
twilize includes a migration subsystem for switching an existing .twb to a new
datasource — for example, repointing a workbook built on one Excel file to a
different Excel with a different schema, or migrating between language variants
of the same dataset.
Migration is a multi-step workflow. Each step is available as both an MCP tool and a Python function:
1. inspect_target_schema → Scan the target Excel and list its columns
2. profile_twb_for_migration → Inventory which fields the workbook uses
3. propose_field_mapping → Match source fields to target columns (fuzzy)
4. preview_twb_migration → Dry-run: show what would change, blockers/warnings
5. apply_twb_migration → Write the migrated .twb + JSON reports
migrate_twb_guided is a convenience wrapper that runs steps 2–5 in sequence
and pauses automatically when only low-confidence field matches remain, returning
a warning_review_bundle for human review before proceeding.
from twilize.migration import migrate_twb_guided_json
import json
# One-call guided migration
result = migrate_twb_guided_json(
file_path="templates/SalesDashboard.twb",
target_source="data/new_data_source.xlsx",
output_path="output/SalesDashboard_migrated.twb",
)
bundle = json.loads(result)
if bundle["status"] == "warning_review_required":
# Inspect low-confidence matches and confirm or override them
print(bundle["warning_review_bundle"])
# Re-run with confirmed mappings
result = migrate_twb_guided_json(
file_path="templates/SalesDashboard.twb",
target_source="data/new_data_source.xlsx",
output_path="output/SalesDashboard_migrated.twb",
mapping_overrides={"Old Field Name": "New Column Name"},
)
When using twilize as an MCP server, an AI agent can run the full workflow:
inspect_target_schema(target_source="data/new_data_source.xlsx")
→ returns column list and data types
migrate_twb_guided(
file_path="templates/SalesDashboard.twb",
target_source="data/new_data_source.xlsx",
output_path="output/SalesDashboard_migrated.twb"
)
→ returns status: "applied" or "warning_review_required"
A completed migration writes three files:
| File | Contents |
|---|---|
<output>.twb | Migrated workbook with rewritten field references |
migration_report.json | Per-field status: mapped / warning / blocked |
field_mapping.json | Final source→target field mapping for audit |
scope="workbook" migrates all worksheets. Pass a worksheet name to limit
migration to a single sheet.
examples/migrate_workflow/ contains a template .twb, the original
Superstore Excel, a target Chinese-locale Superstore Excel, and a runnable
script:
python examples/migrate_workflow/test_migration_workflow.py
twilize/
|-- src/twilize/
| |-- __init__.py
| |-- capability_registry.py
| |-- config.py
| |-- charts/
| |-- connections.py
| |-- dashboard_actions.py
| |-- dashboard_dependencies.py
| |-- dashboard_layouts.py
| |-- dashboards.py
| |-- field_registry.py
| |-- layout.py
| |-- layout_model.py
| |-- layout_rendering.py
| |-- mcp/
| |-- parameters.py
| |-- twb_analyzer.py
| |-- twb_editor.py
| |-- validator.py
| `-- server.py
|-- tests/
|-- examples/
|-- docs/
|-- pyproject.toml
`-- README.md
# Install in editable mode
pip install -e .
# Run test suite
pytest --basetemp=output/pytest_tmp
# Run the mixed showcase example
python examples/scripts/demo_all_supported_charts.py
# Run the advanced Hyper-backed example
python examples/scripts/demo_hyper_and_new_charts.py
# Run the guided migration example
python examples/migrate_workflow/test_migration_workflow.py
# Start MCP server
twilize
twilize ships with a full MCP server manifest (mcp-server.json) — the MCP equivalent of a Tableau Extension .trex file. It declares:
| .trex Equivalent | MCP Field | Description |
|---|---|---|
| Extension ID | id | com.twilize.mcp-server |
| Version | version | Current package version |
| Name / Description | name, description | Server identity |
| Author | author | Name, email, org, URL |
| Permissions | permissions | file-read, file-write |
| Source URL | command | uvx twilize |
| Min API version | minPythonVersion | 3.10 |
Additionally, the manifest declares all 40 tools with categories, 6 resources, and pre-built client configurations for Claude Desktop, Cursor, VS Code, and Claude Code.
For the complete tool reference with parameter schemas, see docs/MCP_SERVER.md.
pip install build twine
python -m build
twine upload dist/*
The smithery.yaml file is ready for submission to Smithery.
The server.json file follows the
official MCP Registry schema
and is ready to publish via the mcp-publisher CLI.
# 1. Install the publisher CLI (macOS / Linux)
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" \
| tar xz mcp-publisher && sudo mv mcp-publisher /usr/local/bin/
# 2. Authenticate with the GitHub account that owns the namespace
mcp-publisher login github
# 3. Publish the contents of server.json (run from repo root)
mcp-publisher publish
# 4. Confirm
curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.subhatta123/twilize"
The legacy mcp-server.json (older schema used by the
modelcontextprotocol/servers README) is also kept for backwards
compatibility with clients that scrape that list.
The repository ships two Railway configs:
railway.json — builds the browser dashboard extension (FastAPI + Vite frontend at /).railway.mcp.json — builds the HTTP MCP server from Dockerfile.mcp and exposes it on /mcp for clients that connect over streamable-http.To deploy the MCP server as a second Railway service:
subhatta123/twilize.railway.mcp.json.curl https://<your-domain>/mcp — a JSON-RPC text/event-stream error confirms the server is responding.Twilize builds upon and was inspired by cwtwb, a Python-based open-source tool for programmatically generating and automating the migration of Tableau Workbooks (.twb files), originally authored by @imgwho.
cwtwb is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). In accordance with that license, Twilize is also distributed under AGPL-3.0.
AGPL-3.0-or-later
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.
by Microsoft · Content & Media
Convert files (PDF, Word, Excel, images, audio) to Markdown for LLM consumption
by mcp-marketplace · Developer Tools
Scaffold, build, and publish TypeScript MCP servers to npm — conversationally
by Taylorwilsdon · Productivity
Control Gmail, Calendar, Docs, Sheets, Drive, and more from your AI