内容
# Tableau 公共创作 MCP
一个 MCP 服务器,从声明式规范中**创作** Tableau 工作簿,通过在已安装的 Tableau Public 应用程序中打开来**验证**,并通过 Tableau 自己的可见桌面工作流**发布**。
> 这是与现有的**读取器** MCP (`tableau-public`) 对应的部分,后者检查已发布的內容。读取器无法创建或发布任何内容。此服务器无法浏览公共个人资料。请同时安装这两个。
## 它生成的内容
下面的每个屏幕截图都是由这个服务器从 JSON 规范生成的 工作簿,然后在 Tableau Public 2026.2.0 中打开并拍照。没有任何内容是手动创作的,在截图被拍摄之前,也没有任何内容在 Tableau 中被触及。数据是 `tests/fixtures/data/` 中的合成 12 行固定装置。
**一个仪表盘** — 两个生成的 工作表在一个容器中平铺,固定 1200×800 画布,标题渲染:

**一个符号地图** — 从列名中检测到 `纬度`/`经度` 并标记为 Tableau 的 `[地理]` 语义角色,这就是在标记后面放置真实背景地图的原因。每个站点一个标记,按维度着色,按度量值调整大小:

**一个条形图** — 按维度着色,绘制标记标签,应用画布适应:

地图背后的规范是整个输入:
```json
{
"name": "站点地图",
"template": "map",
"data_source": "sites",
"detail": ["站点名称"],
"color": "状态",
"size": { "field": "年度会话", "aggregation": "Sum" },
"title": "候选站点"
}
```
## 它做什么
| | 读取器 MCP (`tableau-public`) | 此服务器 (`tableau-public-authoring`) |
|---|---|---|
| 搜索/检查公共个人资料 | ✅ | ❌ |
| 下载和解包 `.twbx` | ✅ | 仅检查 |
| **创建** 工作簿 | ❌ | ✅ |
| **打开** Tableau Public | ❌ | ✅ |
| **发布** 到您的帐户 | ❌ | ✅ (可见 UI) |
## 验证的能力
以下所有内容都通过生成 工作簿并在 **macOS 上的 Tableau Public 2026.2.0** 中打开而得到确认,而不仅仅是生成 XML。
**支持**
- CSV 数据源,自动物化为 `.hyper` 提取
- 字段类型推断:字符串、整数、实数、布尔值、日期、日期时间
- 工作表模板:`bar`、`line`、`text_table`、`heatmap`、`scatter`、`circle`、`map`(所有七个屏幕截图均在 Tableau Public 2026.2.0 中验证,并在 `tests/live/test_render_templates.py` 的每次实时运行中重新检查)
- 地理角色:通过名称检测 纬度/经度 列,这就是在 `map` 模板后面放置真实背景地图的原因
- 仪表盘:标题、固定或自动画布、 工作表在一个容器中平铺
- 计算字段(Tableau 公式语法)
- 分类过滤器,渲染为交互式过滤器卡
- 编码:颜色、大小、标签、工具提示和 **详细信息** — `详细信息` 提高详细程度,因此散点图按站点绘制一个标记,而不是按颜色值绘制一个标记
- 画布适应:`standard`、`fit_width`、`fit_height`、`entire_view`
- 工作表标题和副标题
- `.twbx` 打包,带有字节确定性的 `.twb` 文件
**v0.1 中不受支持** — 参见 `docs/architecture/CAPABILITY_BOUNDARY.md`
- 故事、参数、LOD 表达式、连接/自定义 SQL、实时连接
- 集、组、层次结构、表计算、参考线
- 填充/等值线地图、自定义领土、地图层、空间文件
- 仪表盘过滤器卡、图例、操作、浮动区域、设备布局
## 两项声明需仔细阅读
- **`.twbx` 不是字节可复制的。** 里面的 `.twb` 文件是 — 相同的规范,相同的字节。存档不是,因为嵌入的 `.hyper` 文件由 Tableau 的 Hyper 引擎写入,并带有非确定性的内部状态。比较 `.twb` 文件,而不是软件包摘要。参见 `docs/LIMITATIONS.md` §1。
- **独立的 `.twb` 文件仅在与其数据目录旁边时才可使用。** `output.package_twbx: false` 写入 `<name>.twb` **和** 一个 `<name>.data/` 目录,持有每个源的 `.hyper` 和 CSV 文件,并且 `.twb` 文件将其数据解析为相对于自身 — 因此请将两者放在一起,或一起移动。打包的构建在 `Data/` 下生成相同的布局,与存档中的内容相匹配。路径总是由于必要性而相对,而不是由于偏好而相对:绝对路径将嵌入一个主目录,并且 `build_workbook` 拒绝发出机器识别的数据(参见 `docs/architecture/THREAT_MODEL.md`,T6)。
## 影响一切的两个约束
1. **Tableau Public 没有发布 API。** REST API 仅涵盖 Server/Cloud,因此发布由可见的 UI 驱动。Tableau 将该命令记录为 `Server > Tableau Public > Save to Tableau Public`,但这是 Desktop Professional 路径:在 **Public** 版本 (2026.2.0) 中,Server 菜单仅包含 `Run Optimizer...`,而该命令位于 **File** 菜单上。通过 `Command+Shift+S` 键盘事件调用,File 菜单作为备用 — 参见 `docs/PUBLISHING_WORKFLOW.md`。
2. **Tableau Public 拒绝非提取数据源** (`Error Code: 3C242D89`)。因此,每个 CSV 文件都在构建时转换为 Hyper 提取。
## 安装
```bash
uv tool install git+https://github.com/andyyaro/tableau-public-authoring-mcp
tableau-public-authoring doctor
```
无需克隆,无需虚拟环境,无需编辑路径。`doctor` 检查服务器需要的一切,并打印确切的修复内容 — 在注册之前运行,因为以下每个先决条件都 **在运行时默默失败** 而不抛出异常:
```
[PASS] 平台 macOS
[PASS] python 3.13.14 at ~/.local/share/uv/tools/…/bin/python
[PASS] mcp sdk 可导入
[PASS] tableauhyperapi 可导入
[PASS] quartz (pyobjc) 可导入
[PASS] tableau public 2026.2.0 at /Applications/Tableau Public.app
[PASS] 可访问性 已授予此进程
[PASS] 屏幕录制 捕获成功
```
| 缺失 | 您将实际看到的内容 |
|---|---|
| Quartz | Tableau 似乎没有打开任何窗口;发布时显示“没有匹配的文档窗口 …” |
| 屏幕录制 | 验证截图返回空白,无错误 |
| 可访问性 | 键盘按键和点击操作无反应 |
| tableauhyperapi | 无法构建任何 工作簿 |
macOS 权限按可执行文件授予,因此请授予解释器 `doctor` 打印的权限 — 不授予 Tableau,也不授予您的终端(如果您注册了不同的终端)。详见 `docs/MACOS_PERMISSIONS.md`。
要求:安装了 Tableau Public 的 macOS(针对 2026.2.0、Apple 芯片开发),Python ≥ 3.10,和 [`uv`](https://docs.astral.sh/uv/)。
### 使用 Claude Code 注册
```bash
claude mcp add --transport stdio --scope user tableau-public-authoring \
-- tableau-public-authoring
```
这就是整个命令 — `uv tool install` 将可执行文件放在一个稳定的位置,因此没有要替换的绝对路径,它在升级后仍然存活。注册不会影响任何其他 MCP 服务器;请使用 `claude mcp list` 验证。重启 Claude Code 后,工具才会出现。
<details>
<summary>从克隆安装(用于开发)</summary>
```bash
git clone https://github.com/andyyaro/tableau-public-authoring-mcp
cd tableau-public-authoring-mcp
uv venv && uv sync && uv pip install -e .
uv run tableau-public-authoring doctor
```
通过显式指向其解释器来注册该构建:
```bash
claude mcp add --transport stdio --scope user tableau-public-authoring \
-- /绝对路径/到/.venv/bin/python -m tableau_public_authoring.server
```
避免为已注册的服务器使用 `uvx --from …`:它从 **内容哈希缓存路径** 运行,该路径在依赖项更改时 **更改**,而 macOS 权限授予与该路径绑定 — 因此服务器将在下一次升级时悄悄丢失可访问性和屏幕录制功能。对于一次性使用(例如 `uvx --from … tableau-public-authoring doctor`)来说,这是可以的。
</details>
## 升级
```bash
uv tool upgrade tableau-public-authoring
tableau-public-authoring doctor
```
## 构建 工作簿
```json
{
"spec_version": "0.1",
"workbook": { "name": "电动汽车充电准备情况", "description": "生成" },
"data_sources": [{ "id": "sites", "type": "csv", "path": "/abs/path/sites.csv" }],
"calculated_fields": [{
"name": "准备情况等级", "data_source": "sites", "datatype": "string",
"formula": "IF [准备情况得分] >= 70 THEN \"高\" ELSE \"低\" END"
}],
"worksheets": [{
"name": "按站点划分的准备情况", "template": "bar", "data_source": "sites",
"rows": ["站点名称"],
"columns": [{ "field": "准备情况得分", "aggregation": "Sum" }],
"color": "准备情况等级",
"filters": ["状态"],
"title": "按站点划分的电动汽车充电准备情况"
}],
"output": { "directory": "/abs/path/output", "package_twbx": true }
}
```
路径可以相对于单个 `base_dir` 而不是绝对路径 — 而相对路径 **限定** 在该目录内,而绝对路径则不限于此。参见 `docs/AUTHORING_SPEC.md`。
然后:`validate_workbook_spec`(干运行)→ `build_workbook` → `validate_in_tableau_public` → `publish_to_tableau_public`。
完整模式:`schemas/workbook-spec-v0.1.json` 和 `docs/AUTHORING_SPEC.md`。
## 为什么事情是这样的
这段代码的大部分形状是对 Tableau 实际做的事情的回应。`docs/LIMITATIONS.md` 列出了限制;`docs/history/CHANGE_HISTORY.md` 保留了发行说明,它们记录了每个修复程序为了解决哪个故障而编写的,以及证明有效的修复程序。`docs/fixtures/` 保留了对真实发布的 工作簿的法医分析,该 工作簿是从编译器反向工程的。
## 发布
`publish_to_tableau_public` 标记为破坏性操作,需要 `confirm_publish: true` 和 `profile`(您的 Tableau Public 个人资料名称);`overwrite` 默认值为 `false`。需要 `profile`,因为如果没有它,服务器无法检查是否已存在同名 工作簿,而 Tableau Public 不可逆地替换同名 工作簿,没有版本历史。
它驱动可见的命令,**从不读取、键入或存储凭证** — 它使用您现有的已登录的桌面会话。如果 Tableau 需要登录,该工具会停止并告诉您手动登录。发布是不可逆的,对整个世界可见。
使用 `dry_run: true` 来查看实际会发生什么。
## 测试
```bash
uv run pytest # 单元测试 + 集成测试(无需 Tableau)
uv run pytest -m live # 需要安装 Tableau Public
uv run ruff check . && uv run ruff format --check .
```
`live` 和 `publish` 测试在正常运行中被排除,CI 中绝不能运行。
## 安全
不会在任何地方存储凭证。XML 通过 `ElementTree` 生成(从不使用字符串连接),存档受到 ZIP-slip 防护,路径受到遍历检查,生成的 工作簿在打包前会扫描是否存在机器识别数据。参见 `docs/SECURITY.md` 和 `docs/architecture/THREAT_MODEL.md`。
## 回滚
```bash
claude mcp remove --scope user tableau-public-authoring
```
这会保留所有其他 MCP 服务器不变。
## 卸载
```bash
claude mcp remove tableau-public-authoring -s user
claude mcp list # 您的其他服务器应该仍然被列出
rm -rf <此仓库>/output # 生成的 工作簿 是惰性本地文件
```
任何已 **发布** 的内容都必须由您从 Tableau Public 个人资料的浏览器中删除。该服务器无删除能力,设计如此:发布在其侧是不可逆的,因此它需要 `confirm_publish` 并在没有 `overwrite` 的情况下拒绝名称冲突。