MCP server for the ThoughtSpot REST API v2.0. Built with the official MCP Python SDK (FastMCP).
Lets any MCP-compatible client (Cursor, Claude Desktop, Claude Code, MCP Inspector, etc.) interact with your ThoughtSpot instance through natural language.
- 18 tools covering health, metadata search/delete, TML export/import, data-warehouse connections, data retrieval, and report exports
- Read and write operations for core resources (create, update, delete)
- TML round-trip: export objects as ThoughtSpot Modeling Language and re-import them (sync + async with status polling)
- Data access: run TML search queries and pull Liveboard / Answer data
- Report exports in PDF, PNG, CSV, and XLSX
- Automatic bearer-token exchange with in-memory caching, aggressive refresh (300s validity), and transparent 401 retry
- Markdown and JSON response formats on summary tools
- Runs over stdio (local) — works with Cursor, Claude Desktop, Claude Code, and Docker
- Works with self-hosted ThoughtSpot and ThoughtSpot Cloud
| Tool | Description |
|---|---|
| Health | |
thoughtspot_health_check |
Check the instance is reachable and credentials are valid |
| Metadata | |
thoughtspot_search_metadata |
Search for metadata objects (Liveboards, Answers, Models, Connections, Tags, Users, ...) |
thoughtspot_delete_metadata |
Permanently delete one or more metadata objects |
| TML | |
thoughtspot_export_tml |
Export ThoughtSpot objects as TML (ThoughtSpot Modeling Language) |
thoughtspot_import_tml |
Import (create or update) ThoughtSpot objects from TML definitions |
thoughtspot_async_import_tml |
Start an asynchronous TML import and return a task ID to poll |
thoughtspot_get_tml_import_status |
Poll the status of asynchronous TML import task(s) |
| Connections | |
thoughtspot_search_connections |
List or filter data-warehouse connections configured in ThoughtSpot |
thoughtspot_get_connection |
Get full details (config + registered objects) of one connection by GUID or name |
thoughtspot_create_connection |
Create a new data-warehouse connection |
thoughtspot_update_connection |
Update a connection — rename, re-describe, or register tables/schemas |
thoughtspot_set_connection_status |
Activate or deactivate a connection |
thoughtspot_delete_connection |
Permanently delete a connection |
| Data | |
thoughtspot_search_data |
Run a TML search query against a Worksheet, View, Table, or SQL view |
thoughtspot_get_liveboard_data |
Get the data behind a Liveboard's visualizations |
thoughtspot_get_answer_data |
Get the data behind a saved Answer |
| Reports | |
thoughtspot_export_liveboard_report |
Export a Liveboard (and its visualizations) as a PDF, PNG, CSV, or XLSX file |
thoughtspot_export_answer_report |
Export an Answer as a CSV, PDF, XLSX, or PNG file |
- A running ThoughtSpot instance with REST API v2.0 access — either:
- Self-hosted ThoughtSpot, or
- ThoughtSpot Cloud
- A service-account user with the privileges needed for the tools you plan to call.
- One of the following to run the server:
- uvx (zero-install; runs the published package on demand — see Run with uvx), or
- uv + Python 3.13+ (local clone / development), or
- Docker (no Python / uv needed on the host)
git clone https://github.com/trustxai/thoughtspot-mcp.git
cd thoughtspot-mcp
uv synccp .env.example .envEdit .env with your THOUGHTSPOT_HOST, THOUGHTSPOT_USERNAME, and one of
THOUGHTSPOT_SECRET_KEY (trusted auth) or THOUGHTSPOT_PASSWORD. See
Authentication for details.
uv run thoughtspot-mcpuvx runs the published PyPI package on demand — no
clone, no virtualenv, no persistent install. The command matches the package
name, so no --from is needed:
uvx thoughtspot-mcpCredentials are passed via the client's env block (see below), or exported in
your shell for a manual run:
THOUGHTSPOT_HOST=https://my-instance.thoughtspot.cloud \
THOUGHTSPOT_USERNAME=<service-account> \
THOUGHTSPOT_SECRET_KEY=<your-secret-key> \
uvx thoughtspot-mcpPython version: the package targets Python 3.13+. uv auto-provisions a matching interpreter, so this normally just works. If your environment pins an older default, force it with
uvx --python=3.13 thoughtspot-mcp.
Every MCP client (Cursor, Claude Desktop, etc.) can run the server in one of three ways:
- uvx — zero-install; runs the published package on demand (see Run with uvx).
- uv — from a local clone; best for development.
- Docker — no Python / uv required on the host; everything runs in a container. Build the image once and every client config reuses it.
docker build -t thoughtspot-mcp:latest .Add to .cursor/mcp.json (project-level) or ~/.cursor/mcp.json (global):
Option A — uvx
{
"mcpServers": {
"thoughtspot": {
"command": "uvx",
"args": ["thoughtspot-mcp"],
"env": {
"THOUGHTSPOT_HOST": "https://my-instance.thoughtspot.cloud",
"THOUGHTSPOT_USERNAME": "<service-account>",
"THOUGHTSPOT_SECRET_KEY": "<your-secret-key>"
}
}
}
}Option B — uv
{
"mcpServers": {
"thoughtspot": {
"command": "uv",
"args": ["--directory", "/path/to/thoughtspot-mcp", "run", "thoughtspot-mcp"],
"env": {
"THOUGHTSPOT_HOST": "https://my-instance.thoughtspot.cloud",
"THOUGHTSPOT_USERNAME": "<service-account>",
"THOUGHTSPOT_SECRET_KEY": "<your-secret-key>"
}
}
}
}Option C — Docker
{
"mcpServers": {
"thoughtspot": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"--name", "thoughtspot-mcp",
"-e", "THOUGHTSPOT_HOST",
"-e", "THOUGHTSPOT_USERNAME",
"-e", "THOUGHTSPOT_SECRET_KEY",
"thoughtspot-mcp:latest"
],
"env": {
"THOUGHTSPOT_HOST": "https://my-instance.thoughtspot.cloud",
"THOUGHTSPOT_USERNAME": "<service-account>",
"THOUGHTSPOT_SECRET_KEY": "<your-secret-key>"
}
}
}
}Add to claude_desktop_config.json:
Option A — uv
{
"mcpServers": {
"thoughtspot": {
"command": "uv",
"args": ["--directory", "/path/to/thoughtspot-mcp", "run", "thoughtspot-mcp"],
"env": {
"THOUGHTSPOT_HOST": "https://my-instance.thoughtspot.cloud",
"THOUGHTSPOT_USERNAME": "<service-account>",
"THOUGHTSPOT_SECRET_KEY": "<your-secret-key>"
}
}
}
}Option B — Docker
{
"mcpServers": {
"thoughtspot": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"--name", "thoughtspot-mcp",
"-e", "THOUGHTSPOT_HOST",
"-e", "THOUGHTSPOT_USERNAME",
"-e", "THOUGHTSPOT_SECRET_KEY",
"thoughtspot-mcp:latest"
],
"env": {
"THOUGHTSPOT_HOST": "https://my-instance.thoughtspot.cloud",
"THOUGHTSPOT_USERNAME": "<service-account>",
"THOUGHTSPOT_SECRET_KEY": "<your-secret-key>"
}
}
}
}claude mcp add \
--env THOUGHTSPOT_HOST=https://my-instance.thoughtspot.cloud \
--env THOUGHTSPOT_USERNAME=<service-account> \
--env THOUGHTSPOT_SECRET_KEY=<your-secret-key> \
--transport stdio \
thoughtspot \
-- uvx thoughtspot-mcpThe
--separatesclaude mcp add's own flags from the server command. Put every--envflag before the--and the server name; anything after the--is passed verbatim to the launched process. Placing--envafter the--makes the CLI mis-parse it as an argument touvx.
The Inspector can launch the stdio server directly:
npx @modelcontextprotocol/inspector uvx thoughtspot-mcpSet THOUGHTSPOT_HOST, THOUGHTSPOT_USERNAME, and your credential env var in the
Inspector's environment panel (or export them in your shell first).
The server authenticates against ThoughtSpot REST API v2.0 by exchanging your
credentials for a bearer token via POST /api/rest/2.0/auth/token/full. The
token is cached in memory and attached as Authorization: Bearer <token> on every
request.
Credentials are resolved by precedence — the first available option wins:
THOUGHTSPOT_ACCESS_TOKEN— a pre-fetched bearer token. Skips the token exchange entirely; use it when you already have a valid token.THOUGHTSPOT_SECRET_KEY(+THOUGHTSPOT_USERNAME) — trusted authentication. Preferred: no password is stored, and it enables RLS impersonation. Enable it under Develop → Security Settings in ThoughtSpot.THOUGHTSPOT_PASSWORD(+THOUGHTSPOT_USERNAME) — username/password token exchange. Simplest when trusted auth is off.
Token validity + auto-refresh. ThoughtSpot access tokens default to a 300-second validity window. The client refreshes aggressively (with a safety margin before expiry) and transparently retries once on an HTTP 401, so long-running sessions keep working without manual re-authentication.
| Variable | Required | Default | Description |
|---|---|---|---|
THOUGHTSPOT_HOST |
Yes | — | Instance base URL, e.g. https://my-instance.thoughtspot.cloud (no /api/rest path) |
THOUGHTSPOT_USERNAME |
Yes* | — | Service-account username used for token exchange |
THOUGHTSPOT_SECRET_KEY |
Yes* | — | Trusted-auth secret key (preferred credential) |
THOUGHTSPOT_PASSWORD |
Yes* | — | Password (fallback credential) |
THOUGHTSPOT_ACCESS_TOKEN |
No | — | Pre-fetched bearer token (skips exchange) |
THOUGHTSPOT_ORG_ID |
No | — | Target a specific Org (multi-tenant instances) |
THOUGHTSPOT_TOKEN_VALIDITY_SECONDS |
No | 300 |
Token validity window requested at exchange |
THOUGHTSPOT_REQUEST_TIMEOUT_SECONDS |
No | 30 |
HTTP request timeout (seconds) |
* Provide one credential path: either THOUGHTSPOT_ACCESS_TOKEN, or
THOUGHTSPOT_USERNAME + THOUGHTSPOT_SECRET_KEY, or THOUGHTSPOT_USERNAME +
THOUGHTSPOT_PASSWORD.
If you just want to exercise the server from the CLI:
# uvx — no clone
uvx thoughtspot-mcp
# uv
uv run thoughtspot-mcp
# Docker
docker run --rm -i --env-file .env thoughtspot-mcp:latestThese are real ThoughtSpot REST API v2.0 gotchas worth knowing:
- Connection update uses the plural path. Update a connection via
connections/{id}/update(pluralconnections). The singularconnection/{id}/updatepath is deprecated — using it can silently no-op or return an error. - Connection config must be wrapped. When creating or updating a connection,
the data-warehouse configuration payload must be nested under a
data_warehouse_configkey. A bare, unwrapped config is rejected. - Global rate limit → HTTP 429. ThoughtSpot enforces a global rate limit of
100 requests/second per IP. Bursty tool loops can trip it and receive
HTTP 429 Too Many Requests; back off and retry. - Trailing slash required on relevant-questions. The
/ai/relevant-questions/endpoint requires a trailing slash. Omitting it results in a routing failure (e.g. 404 / redirect), not the expected response.
Contributions are welcome! Open an issue or pull request to get started.
Apache-2.0 — see LICENSE for details.