Tableau MCP Server
README.md
# Tableau MCP Server
A Model Context Protocol (MCP) server for Tableau Cloud that provides dashboard access, data querying, and export capabilities through Cursor IDE.
## Features
- **š Discovery & Search** - Find workbooks, views, and data sources
- **š Data Access** - Query view data with filters as CSV or JSON
- **š¤ Export** - Export dashboards as PDF, PNG, or PowerPoint
- **š Data Refresh** - Trigger extract refreshes for data sources
## Prerequisites
- Node.js 18.x or later
- Google Cloud Platform account with:
- Cloud Run enabled
- Secret Manager enabled
- Cloud Storage bucket for exports
- Tableau Cloud/Server with:
- Personal Access Token (PAT) credentials
- API access enabled
## Quick Start
### 1. Clone and Install
```bash
cd tableau-mcp
npm install
```
### 2. Configure Environment Variables
Create a `.env` file (or set environment variables):
```env
# Tableau Configuration
TABLEAU_SERVER_URL=https://prod-apnortheast-a.online.tableau.com
TABLEAU_SITE_ID=your-site-content-url
TABLEAU_PAT_NAME=your-pat-name
TABLEAU_PAT_SECRET=your-pat-secret
# MCP Server
MCP_API_KEY=your-secure-api-key
# Google Cloud
GCS_EXPORT_BUCKET=tableau-mcp-exports
GCP_PROJECT_ID=your-project-id
```
### 3. Run Locally
```bash
npm start
```
The server starts on `http://localhost:8080`:
- Health check: `GET /health`
- SSE endpoint: `GET /sse` and `POST /sse`
### 4. Configure Cursor
Add to your `.cursor/mcp.json`:
```json
{
"mcpServers": {
"tableau": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://tableau-mcp-400124661305.australia-southeast1.run.app/sse",
"--header",
"X-API-Key: <your-api-key>"
]
}
}
}
```
> **Note**: Replace `<your-api-key>` with your actual API key from Secret Manager (`tableau-mcp-api-key`).
## Available Tools
### Utility Tools
| Tool | Description |
|------|-------------|
| `tableau_get_instructions` | Get guidance on using Tableau MCP tools |
| `tableau_search` | Search content across Tableau |
### Dashboard Tools
| Tool | Description |
|------|-------------|
| `tableau_list_workbooks` | List all accessible workbooks |
| `tableau_get_workbook` | Get workbook details |
| `tableau_list_views` | List views in a workbook |
| `tableau_get_filters` | Get available filters for a view |
| `tableau_apply_filter` | Store filters for query/export |
### Data Tools
| Tool | Description |
|------|-------------|
| `tableau_query_view` | Export view data as CSV/JSON |
| `tableau_list_datasources` | List published data sources |
| `tableau_refresh_datasource` | Trigger extract refresh |
### Export Tools
| Tool | Description |
|------|-------------|
| `tableau_export_pdf` | Export view as PDF |
| `tableau_export_image` | Export view as PNG |
| `tableau_export_pptx` | Export view as PowerPoint |
## Usage Examples
### Find and Export a Dashboard
```
1. Search for dashboards:
tableau_search({ query: "sales" })
2. List views in a workbook:
tableau_list_views({ workbookId: "abc123" })
3. Export as PDF:
tableau_export_pdf({ viewId: "xyz789" })
```
### Query Filtered Data
```
1. Get available filters:
tableau_get_filters({ viewId: "xyz789" })
2. Query with filters:
tableau_query_view({
viewId: "xyz789",
format: "json",
filters: { "Region": "West" }
})
```
## Deployment
### Cloud Run Deployment
1. **Create GCS Bucket**
```bash
gsutil mb -l australia-southeast1 gs://tableau-mcp-exports
```
2. **Create Secrets in Secret Manager**
```bash
echo -n "your-pat-name" | gcloud secrets create tableau-pat-name --data-file=-
echo -n "your-pat-secret" | gcloud secrets create tableau-pat-secret --data-file=-
echo -n "your-api-key" | gcloud secrets create tableau-mcp-api-key --data-file=-
```
3. **Grant Service Account Permissions**
```bash
# Secret Manager access
gcloud secrets add-iam-policy-binding tableau-pat-secret \
--member="serviceAccount:YOUR_SA@PROJECT.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
# GCS access
gsutil iam ch serviceAccount:YOUR_SA@PROJECT.iam.gserviceaccount.com:objectCreator,objectViewer \
gs://tableau-mcp-exports
```
4. **Configure Cloud Build Trigger**
- Source: Your GitHub repository
- Event: Push to `main` branch
- Configuration: `cloudbuild.yaml`
- Substitution variables:
- `_TABLEAU_SERVER_URL`: Your Tableau Cloud URL
- `_TABLEAU_SITE_ID`: Your site content URL
- `_GCS_EXPORT_BUCKET`: Your export bucket name
5. **Deploy**
Push to `main` branch to trigger automatic deployment.
### Manual Deployment
```bash
gcloud run deploy tableau-mcp \
--source . \
--region australia-southeast1 \
--memory 1Gi \
--timeout 300s \
--min-instances 1 \
--allow-unauthenticated
```
## Configuration Reference
### Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `TABLEAU_SERVER_URL` | ā
| Tableau Cloud/Server URL |
| `TABLEAU_SITE_ID` | ā
| Site content URL |
| `TABLEAU_PAT_NAME` | ā
| Personal Access Token name |
| `TABLEAU_PAT_SECRET` | ā
| Personal Access Token secret |
| `MCP_API_KEY` | ā
| API key for MCP authentication |
| `GCS_EXPORT_BUCKET` | ā
| GCS bucket for exports |
| `GCP_PROJECT_ID` | ā
| Google Cloud project ID |
| `PORT` | ā | Server port (default: 8080) |
| `TABLEAU_API_VERSION` | ā | API version (default: 3.21) |
### Cloud Run Settings
| Setting | Value |
|---------|-------|
| Region | australia-southeast1 |
| Memory | 1Gi |
| CPU | 1 |
| Timeout | 300s |
| Min instances | 1 |
| Max instances | 10 |
| Concurrency | 80 |
## Limitations
- **Filters**: Cannot apply filters to live dashboard views - only at query/export time
- **PPTX Export**: Generated from PNG images, not native Tableau export
- **Data Query**: Maximum 100,000 rows per request
- **Export URLs**: Valid for 1 hour only
- **Rate Limits**: Throttled to 10 requests/second to Tableau API
## Project Structure
```
tableau-mcp/
āāā mcp-http-server.js # Main Express HTTP server
āāā mcp-handler.js # MCP protocol handler
āāā mcp_tools.json # Tool definitions
āāā config.js # Configuration management
āāā package.json # Dependencies
āāā Dockerfile # Container configuration
āāā cloudbuild.yaml # CI/CD configuration
āāā lib/
ā āāā tableau-client.js # Tableau REST API client
ā āāā gcs-client.js # GCS upload/signing
ā āāā logger.js # Structured logging
āāā 00-utility-tools/tools/
ā āāā get-instructions.js
ā āāā search.js
āāā 01-dashboard-tools/tools/
ā āāā list-workbooks.js
ā āāā get-workbook.js
ā āāā list-views.js
ā āāā get-filters.js
ā āāā apply-filter.js
āāā 02-data-tools/tools/
ā āāā query-view-data.js
ā āāā list-datasources.js
ā āāā refresh-datasource.js
āāā 03-export-tools/tools/
āāā export-pdf.js
āāā export-image.js
āāā export-pptx.js
```
## Troubleshooting
### Authentication Errors
- Verify PAT credentials are correct
- Check that PAT has not expired
- Ensure site ID matches the site content URL (not the site name)
### Export Failures
- Check GCS bucket exists and is accessible
- Verify service account has `objectCreator` and `objectViewer` roles
- Large exports may timeout - try smaller views or increase Cloud Run timeout
### Rate Limiting
- The server throttles to 10 requests/second
- Batch operations may be slower due to throttling
- Consider increasing throttle limit for Tableau Server (not Cloud)
## License
MIT
## Author
Agile Market Intelligence