# MCP tool reference (Spotter 3)

> For the complete documentation index, see [llms.txt](https://developers.thoughtspot.com/docs/llms.txt)

Source: https://developers.thoughtspot.com/docs/mcp-tool-reference-spotter3

# MCP tool reference (Spotter 3)

The ThoughtSpot Spotter Model Context Protocol (MCP) Server integration exposes tools for running natural language analytics queries and searching existing ThoughtSpot content. The core analytics pattern is: **create a session** → **send a message** → **poll for updates**. The `search_objects` tool is independent of this workflow and can be called at any time.

-   [create\_analysis\_session](#create_analysis_session)  
    Start an analytical session.
    
-   [send\_session\_message](#send_session_message)  
    Send a natural language question or follow-up.
    
-   [get\_session\_updates](#get_session_updates)  
    Poll for streamed responses.
    
-   [create\_dashboard](#create_dashboard)  
    Create a dashboard from session answers.
    
-   [search\_objects](#search_objects)  
    Search for existing ThoughtSpot content by name or description.
    
-   [list\_orgs](#list_orgs)  
    List the Orgs your account can access. (OAuth connections on Org-enabled instances only)
    
-   [switch\_org](#switch_org)  
    Switch your active Org for the current session. (OAuth connections on Org-enabled instances only)
    
-   [check\_connectivity](#check_connectivity)  
    Verify that the MCP Server is reachable.
    

## create\_analysis\_session

Start an analytical session with ThoughtSpot’s analytics agent. This is the required first step before sending any questions.

Sessions are conversational. Once created, you can send multiple follow-up questions to the same session without calling `create_analysis_session` again.

### Input parameter

The `data_source_id` is optional. Provide this when the user has specified or confirmed a data source, or when context makes a particular source obvious. Omit to let ThoughtSpot automatically select the most relevant source based on the question.

### Example call

```javascript
const session = await callMCPTool("create_analysis_session", {
    data_source_id: "model-guid-123" // Optional. GUID of the ThoughtSpot model to query. Omit to let ThoughtSpot automatically select the most relevant data source.
});
```

```python
call_mcp_tool(
    "create_analysis_session",
    {
        "data_source_id": "model-guid-123"  # Optional. GUID of the ThoughtSpot model to query.
    },
)
```

### Response

```json
{
  "analytical_session_id": "session-guid-abc123"
}
```

-   `analytical_session_id`: Session ID. Pass this to `send_session_message` and `get_session_updates`.
    
-   Always capture the returned `analytical_session_id`. It is required for all subsequent calls.
    

## send\_session\_message

Send a natural language analytical question or follow-up to an existing session. The agent processes requests asynchronously, so this tool does not return the answer directly; use `get_session_updates` to retrieve the response.

### Input parameters

 
| Field | Description |
| --- | --- |
| 
`analytical_session_id`

 | 

The session to send the message to. Obtained from the `create_analysis_session` call.

 |
| 

`message`

 | 

A natural language analytical question or follow-up to send to the ThoughtSpot agent.

 |
| 

`additional_context`  
_Optional_

 | 

Can be used to provide external information relating to the question. For example, "The user’s fiscal year starts in April," or "The user is a manager of the West region."

 |

### Example call

```javascript
const sendMessage = await callMCPTool("send_session_message", {
    analytical_session_id: "sess_abc123", // Session ID from create_analysis_session.
    message: "What were total sales by region last quarter?", // User's natural language question.
    additional_context: "The user's fiscal year starts in April. " +
        "Focus on underperforming regions only." // Optional. External information to influence the analysis.
});
```

```python
call_mcp_tool(
    "send_session_message",
    {
        "analytical_session_id": "sess_abc123",  # Session ID from create_analysis_session.
        "message": "What were total sales by region last quarter?", # User's natural language question.
        "additional_context": (  # Optional. External information
            "The user's fiscal year starts in April."
            "Focus on underperforming regions only." # to influence the analysis.
        ),
    },
)
```

### Response

```json
{
  "success": true
}
```

-   `success`: Confirms whether the message was successfully received by the agent.
    

> **NOTE:** After a successful send, immediately begin polling with get\_session\_updates. Do not send a second message until get\_session\_updates returns is\_done: true. The agent processes one message at a time per session. To ask a follow-up question, reuse the same analytical\_session\_id. There is no need to create a new session.

## get\_session\_updates

Poll for the latest response from a ThoughtSpot analytics session. Call this repeatedly after `send_session_message` until `is_done` is `true`.

**Important**: A single call to `get_session_updates` will rarely contain the full response. Spotter streams its work incrementally, including intermediate thinking steps, across multiple polling calls. You must accumulate updates from every poll and combine them to get the complete picture.

### Input parameters

Send the `analytical_session_id` to specify the session to retrieve updates for.

### Example call

```typescript
const updates = await callMCPTool("get_session_updates", {
    analytical_session_id: "session-guid-abc123" // Session ID from the `create_analysis_session` call.
});
```

```python
call_mcp_tool(
    "get_session_updates",
    {"analytical_session_id": "sess_abc123"},  # Session ID from create_analysis_session.
)
```

### Response

Each poll returns a wrapper object with an `is_done` flag and a `session_updates` array. Session updates stream across multiple polling calls. Accumulate them all before rendering the final answer.

`session_updates` objects use three `type` values:

  
| Type | `is_thinking` | Description |
| --- | --- | --- |
| 
`step_notification`

 | 

`true`

 | 

A short heading announcing the step Spotter is about to start, such as `Searching data models` or `Running query`. Step headings arrive as soon as Spotter begins each step, before the narration text for that step. Render these immediately so the user sees progress in real time.

 |
| 

`text_chunk`

 | 

`true` (thinking) or `false` (final)

 | 

A fragment of Spotter’s narration. Concatenate chunks to form the complete narration string. When `is_thinking` is `false`, the chunk is part of the final answer narration, not an intermediate thinking step.

 |
| 

`answer`

 | 

`false`

 | 

The analytical result. Contains a title, the ThoughtSpot search query used, an embeddable `iframe_url`, and an `answer_id` for creating dashboards. Exactly one `answer` update is present per question.

 |

Poll returning intermediate updates:

```json
{
  "is_done": false,
  "session_updates": [
    {
      "is_thinking": true,
      "type": "step_notification",
      "text": "Searching data models"
    },
    {
      "is_thinking": true,
      "type": "text_chunk",
      "text": " to find the most relevant dataset for your question..."
    }
  ]
}
```

Poll returning the final answer:

```json
{
  "is_done": true,
  "session_updates": [
    {
      "is_thinking": true,
      "type": "step_notification",
      "text": "Running query"
    },
    {
      "is_thinking": true,
      "type": "text_chunk",
      "text": "Running the query against the sales data model..."
    },
    {
      "is_thinking": false,
      "type": "text_chunk",
      "text": "I'm interpreting 'last quarter' as Q4 2025 (October–December), based on a fiscal year starting in April."
    },
    {
      "is_thinking": false,
      "type": "answer",
      "answer_id": "{\"session_id\":\"1a3d...\",\"gen_no\":2}",
      "answer_title": "Total sales by region",
      "answer_data_source_id": "cd252e5c-...",
      "answer_query": "[sales] [region]",
      "iframe_url": "https://your-instance.thoughtspot.cloud/?tsmcp=true#/embed/conv-assist-answer?..."
    }
  ]
}
```

> **NOTE:** The step\_notification type was introduced alongside the default response format. Step headings always arrive before the narration text for that step.

### Handling streamed responses

Spotter queries are processed asynchronously and streamed in real time. This means the full response is never contained in a single `get_session_updates` call.

Each call to `get_session_updates` returns only the updates generated since the previous call. The `session_updates` array may indicate that Spotter is still processing with an `is_thinking` state, may include intermediate updates, or may contain several updates at once. Updates typically arrive as `step_notification` or `text_chunk` types, reflecting Spotter’s ongoing reasoning, before the final answer update is provided. This intermediate content shows Spotter’s step-by-step thought process and should be preserved and presented to the user for transparency into how the answer is derived.

A typical response sequence might look like:

1.  Step headings: `step_notification` updates announcing each step Spotter is about to start.
    
2.  Thinking narration: `text_chunk` updates with `is_thinking: true` describing what Spotter is doing.
    
3.  Clarifications or caveats: `text_chunk` updates with `is_thinking: false` explaining assumptions, filters applied, or potential ambiguities in the question.
    
4.  The final answer: one or more `answer` updates containing the visualization title, the underlying query, and the embeddable iframe URL.
    

This means a complete response might span 5–20+ `get_session_updates` calls and contain many `session_update` objects before `is_done` becomes `true`. All of this content, the thinking, the narration, and the final answer, should be accumulated and presented together to give the user the full picture.

### Default response format

Includes three types, `step_notification`, `text_chunk`, `answer`. Flat, fixed keys, `is_thinking` as the top-level flag that distinguishes intermediate reasoning from the final answer.

```json
{"is_thinking":true,"type":"step_notification","text":"Searching for Datasets"}
{"is_thinking":true,"type":"text_chunk","text":" to find the most relevant dataset..."}
{"is_thinking":false,"type":"answer",
 "answer_id":"{\"session_id\":\"1a3d...\",\"gen_no\":2}",
 "answer_title":"Total sales by region",
 "answer_data_source_id":"cd252e5c-...",
 "answer_query":"[sales] [region]",
 "iframe_url":"https://your-instance.thoughtspot.cloud/?tsmcp=true#/embed/conv-assist-answer?..."}
```

#### Type definition: session\_update

Each item in the `session_updates` list is a `session_update` object. The `type` field determines which other fields are present.

  
| Field | Type | Description |
| --- | --- | --- |
| 
`type`

 | 

`"step_notification"`

 | 

A short heading announcing the step Spotter is about to start, such as `Searching data models` or `Running query`.

 |
| 

`"text_chunk"`

 | 

A streaming fragment of Spotter’s narration. Concatenate all chunks to reconstruct the full text.

 |
| 

`"answer"`

 | 

Populates `answer_title`, `answer_query`, `answer_data_source_id`, `iframe_url` fields. A data visualization result with a title, the underlying query, and an embeddable URL.

 |
| 

`text`

 | 

_String_

 | 

The text content of the message. Present only when `type` is `"step_notification"` or `"text_chunk"`. For `"text_chunk"` updates, concatenate all chunks to form the complete message.

 |
| 

`answer_title`

 | 

_String_

 | 

A human-readable title describing what the answer shows. Present only when `type` is `"answer"`.

 |
| 

`answer_data_source_id`

 | 

_String_

 | 

GUID of the data source used to generate the answer. Present only when `type` is `"answer"`.

 |
| 

`answer_query`

 | 

_String_

 | 

The search query ThoughtSpot used to generate the answer. Present only when `type` is `"answer"`. Useful for explaining to users what data was queried or for diagnosing unexpected results.

 |
| 

`iframe_url`

 | 

_String_

 | 

An embeddable URL for rendering the answer as an interactive visualization. Present only when `type` is `"answer"`. Use this to display a live chart or table if your environment supports iframes.

 |

### Full response (raw event stream)

By default, `get_session_updates` returns a simplified response optimized for host agent understanding. For integrations that need granular metadata about Spotter’s internal tool calls, you can enable the full raw event stream.

For guidance on when to use the full response and how to enable it, see [Accessing full tool responses]({{navprefix}}/{{mcp-connect-custom-chatbot}}#accessing-full-tool-responses).

#### Full response format (raw upstream events)

When `enable-raw-session-updates=true` is appended to your MCP endpoint URL, `get_session_updates` returns the raw Spotter event stream. The full response does not include a preconstructed `iframe_url`. You must build it yourself. For guidance, see [Accessing full tool responses]({{navprefix}}/{{mcp-connect-custom-chatbot}}#accessing-full-tool-responses).

```json
{"type":"ack","node_id":"pvzWZ8wdaL0w"}
{"type":"conv_title","title":"Total revenue by region","conv_id":"iZ87F742SMkA"}
{"type":"notification","group_id":"5aOOckJ31v8d","code":"TOOL_CALL_NOTIFICATION",
 "metadata":{"type":"thinking","tool_name":"search_datasets",
             "tool_args":{"keywords":["revenue","region","sales"]},
             "tool_code":"SEARCHING_DATASETS","tool_title":"Searching for Datasets"}}
{"id":"m2xDLBXcPF5D","type":"text-chunk","group_id":"br31Y9vnKmDp",
 "metadata":{"format":"markdown","type":"thinking"},"content":" to find a"}
{"id":"SpzpcgHBt_Pm","type":"answer","group_id":"TlhE-TPW05tu",
 "title":"total sales by region",
 "answer_id":"{\"session_id\":\"fc3bd346-...\",\"gen_no\":2}",
 "metadata":{"sage_query":"[sales] [region]","session_id":"fc3bd346-...","gen_no":2,
             "transaction_id":"8e5654f3-...","generation_number":1,
             "warning_details":[{"warningType":"CHART_INTENT_APPLIED"},
                                {"warningType":"CHART_INTENT_DETECTED"}],
             "ambiguous_phrases":null,"query_intent":null,
             "tml_phrases":["[sales] [region]"],"cached":false,
             "sub_queries":null,"worksheet_id":"cd252e5c-...","type":"thinking"}}
```

For the complete event schema, see the [Spotter Agent API]({{navprefix}}/{{spotter-agent-apis}}#_api_response_2).

## create\_dashboard

Create a ThoughtSpot dashboard from answers generated in an analysis session.

-   Call this only after `get_session_updates` returns `is_done: true`, because you need the `answer_id` values from completed answer updates.
    
-   Collect all updates where type is answer across every poll of `get_session_updates`. Each one produces an `answer_id` you can include in the dashboard.
    
-   The `note_tile` should summarize the full analysis. It is the first thing a viewer sees on the dashboard.
    
-   Multiple answers from the same session or across multiple sessions can be combined into a single dashboard.
    

### Input parameters

 
| Field | Description |
| --- | --- |
| 
`title`

 | 

Required. Title of the dashboard to be created.

 |
| 

`answers`

 | 

Required. List of answer objects to add to the dashboard. Each answer requires an `answer_id` (from `get_session_updates` where `type` is `answer`) and a `title`.

 |
| 

`note_tile`

 | 

Required. An HTML summary of the analysis and answers, rendered as a styled tile on the dashboard. Must be a single line with no line breaks. Use `<br>` for spacing within the HTML. Include emojis, colors, and a `"Generated on <date> <time>"` header.

 |

### Example call

```typescript
const dashboard = await callMCPTool("create_dashboard", {
    title: "Q4 2025 Regional Sales Analysis",
    answers: [{
            answer_id: "ans_xyz789", // answer_id from each answer-type update returned by get_session_updates.
            title: "Total Sales by Region — Q4 2025"
        },
        {
            answer_id: "ans_xyz790",
            title: "Underperforming Regions — Q4 2025 vs Q4 2024"
        }
    ],
    note_tile: "<h2 style='text-align:center;'> Q4 2025 Regional Sales Analysis</h2>" +
        "<p>Analysis of total sales by region for Q4 2025, highlighting " +
        "top-performing and underperforming regions.<br>" +
        "Generated on 2026-04-16 10:00 AM</p>" // Required. Single-line HTML string rendered as a styled summary tile at the top of the dashboard.
});
```

```python
dashboard = call_mcp_tool(
    "create_dashboard",
    {
        "title": "Q4 2025 Regional Sales Analysis",
        "answers": [
            {
                "answer_id": "ans_xyz789", # answer_id from each answer-type update returned by get_session_updates.
                "title": "Total Sales by Region — Q4 2025",
            },
            {
                "answer_id": "ans_xyz790",
                "title": "Underperforming Regions — Q4 2025 vs Q4 2024",
            },
        ],
        "note_tile": (
            "<h2 style='text-align:center;'> Q4 2025 Regional Sales Analysis</h2>"
            "<p>Analysis of total sales by region for Q4 2025, highlighting "
            "top-performing and underperforming regions.<br>"
            "Generated on 2026-04-16 10:00 AM</p>"  # Required. single-line HTML string rendered as a styled summary tile at the top of the dashboard.
        ),
    },
)
```

### Response

 
| Field | Description |
| --- | --- |
| 
`dashboard_id`

 | 

The unique identifier of the created dashboard.

 |
| 

`dashboard_url`

 | 

A link to the newly created dashboard in ThoughtSpot.

 |

## search\_objects

Search for existing ThoughtSpot content by name or description, and return the matching objects with their metadata and deep links.

Use this tool when a user refers to content that already exists. For example, "open the regional sales Liveboard" or "what dashboards has Priya built". The `search_objects` tool is independent of the analysis session workflow. It does not require a session and does not need to be called before `create_analysis_session`.

`search_objects` returns identifiers and metadata only. It never returns the object’s data or contents, and it does not run queries.

To answer a data question, use the session workflow instead.

### Input parameters

 
| Field | Description |
| --- | --- |
| 
`query`  
_Required_

 | 

The search term, matched against object names and descriptions. Must be non-empty.

 |
| 

`types`  
_Optional_

 | 

Restrict results to these object types. Accepts an array of `LIVEBOARD`, `LIVEBOARD_VIZ`, `ANSWER`, `WORKSHEET`. Omit to search all types.

 |
| 

`author_name`  
_Optional_

 | 

Restrict results to objects authored by this user, matched against the author’s display name. Case-insensitive substring match.

 |
| 

`tag`  
_Optional_

 | 

Restrict results to objects carrying this tag or sticker, matched by tag name. Case-insensitive substring match.

 |
| 

`modified_since`  
_Optional_

 | 

Return only objects last modified on or after this epoch-millisecond timestamp.

 |
| 

`verified_only`  
_Optional_

 | 

If `true`, return only objects marked as verified.

 |
| 

`limit`  
_Optional_

 | 

Maximum number of results to return. Positive integer. Defaults to `10`.

 |
| 

`cursor`  
_Optional_

 | 

Opaque pagination cursor returned as `next_cursor` by a previous call. Omit on the first page.

 |

### Object types

The `types` input parameter and the `type` field on each result use the same tokens. Any value returned in a result can be passed back as a `types` filter.

 
| Value | Meaning |
| --- | --- |
| 
`LIVEBOARD`

 | 

A Liveboard.

 |
| 

`LIVEBOARD_VIZ`

 | 

A single visualization pinned on a Liveboard. Distinct from a standalone Answer. Render this as "Liveboard viz".

 |
| 

`ANSWER`

 | 

A saved Answer.

 |
| 

`WORKSHEET`

 | 

A data model object.

 |

### Example call

```javascript
const results = await callMCPTool("search_objects", {
    query: "regional sales",  // Required. Search term matched against object names and descriptions.
    types: ["LIVEBOARD", "LIVEBOARD_VIZ"], // Optional. Restrict to these object types.
    author_name: "Priya", // Optional. Case-insensitive substring match on author display name.
    tag: "Certified", // Optional. Case-insensitive substring match on tag name.
    verified_only: true, // Optional. Return only verified objects.
    limit: 5 // Optional. Maximum results to return. Defaults to 10.
});
```

```python
call_mcp_tool(
    "search_objects",
    {
        "query": "regional sales", # Required. Search term matched against object names and descriptions.
        "types": ["LIVEBOARD", "LIVEBOARD_VIZ"], # Optional. Restrict to these object types.
        "author_name": "Priya", # Optional. Case-insensitive substring match on author display name.
        "tag": "Certified", # Optional. Case-insensitive substring match on tag name.
        "verified_only": True, # Optional. Return only verified objects.
        "limit": 5, # Optional. Maximum results to return. Defaults to 10.
    },
)
```

### Response

A call returns one of three outcomes.

#### Successful match

`status` is omitted when the search returned results.

```json
{
  "results": [
    {
      "object_id": "b2c4e6a8-1234-4f5a-9abc-def012345678",
      "title": "Regional Sales Performance",
      "type": "LIVEBOARD",
      "author_name": "Priya Raman",
      "description": "Weekly sales tracking by region and rep.",
      "tags": ["Sales", "Certified"],
      "last_modified": "2026-05-15T14:30:00.000Z",
      "verified": true,
      "external_link": "https://your-instance.thoughtspot.cloud/#/insights/pinboard/b2c4e6a8-1234-4f5a-9abc-def012345678",
      "query": null,
      "confidence": 0.94
    },
    {
      "object_id": "b2c4e6a8-1234-4f5a-9abc-def012345678",
      "visualization_id": "77f1a0d3-5678-4b21-8e90-aa1122334455",
      "title": "Sales by Region",
      "type": "LIVEBOARD_VIZ",
      "author_name": "Priya Raman",
      "tags": ["Sales"],
      "last_modified": "2026-05-15T14:30:00.000Z",
      "verified": false,
      "external_link": "https://your-instance.thoughtspot.cloud/#/insights/pinboard/b2c4e6a8-1234-4f5a-9abc-def012345678/77f1a0d3-5678-4b21-8e90-aa1122334455",
      "query": "sales by region monthly",
      "confidence": 0.81
    }
  ],
  "next_cursor": "10"
}
```

#### No results

The search ran successfully but nothing matched.

```json
{
  "status": "no_results",
  "results": [],
  "next_cursor": null
}
```

Tell the user that nothing matched and suggest broadening the search term or removing a filter. Do not synthesize results.

#### Error

The search could not be completed.

```json
{
  "status": "error",
  "results": [],
  "error": {
    "code": "RATE_LIMITED",
    "message": "ThoughtSpot rate limit reached. Try again shortly.",
    "retryable": true
  }
}
```

If `retryable` is `true`, wait briefly and retry the same call. If `retryable` is `false`, surface the `message` to the user and do not retry automatically.

### Response fields

  
| Field | Type | Description |
| --- | --- | --- |
| 
`status`

 | 

String

 | 

Omitted on a successful hit list. `no_results` means the search ran but matched nothing. `error` means the search failed and `error` is populated.

 |
| 

`results`

 | 

Array

 | 

Ranked list of matching objects, most relevant first. Empty for `no_results` and `error`.

 |
| 

`next_cursor`

 | 

String

 | 

Cursor to pass back as `cursor` to retrieve the next page. `null` when there are no more results. Omitted on `error`.

 |
| 

`error`

 | 

Object

 | 

Present only when `status` is `error`. Contains `code`, `message`, and `retryable`.

 |

### Fields on each result

  
| Field | Type | Description |
| --- | --- | --- |
| 
`object_id`

 | 

String

 | 

GUID of the object. For a `LIVEBOARD_VIZ` result, this is the GUID of the parent Liveboard, not the visualization.

 |
| 

`visualization_id`

 | 

String

 | 

Present only on `LIVEBOARD_VIZ` results. GUID of the specific visualization pinned on the Liveboard identified by `object_id`.

 |
| 

`title`

 | 

String

 | 

Display name of the object.

 |
| 

`type`

 | 

String

 | 

Object type: `LIVEBOARD`, `LIVEBOARD_VIZ`, `ANSWER`, or `WORKSHEET`. Can be passed back as a `types` filter.

 |
| 

`author_name`

 | 

String

 | 

Display name of the user who authored the object.

 |
| 

`description`

 | 

String

 | 

Description of the object. Omitted when the object has none.

 |
| 

`tags`

 | 

Array of strings

 | 

Names of the tags or stickers applied to the object.

 |
| 

`last_modified`

 | 

String

 | 

ISO 8601 timestamp of the last modification. For example, `2026-05-15T14:30:00.000Z`. Omitted when unavailable. Render as a plain date.

 |
| 

`verified`

 | 

Boolean

 | 

Whether the object is marked as verified.

 |
| 

`external_link`

 | 

String

 | 

Deep link to open the object in the ThoughtSpot UI. This link opens in a browser tab. It is not an embeddable iframe URL.

 |
| 

`query`

 | 

String

 | 

For an Answer or Liveboard viz, the search tokens that define it. For example, `sales by region monthly`. `null` for a Liveboard.

 |
| 

`confidence`

 | 

Number

 | 

Relevance score for the search term. Use for ranking only. Do not display this value to the user.

 |

### Pagination

`search_objects` returns up to `limit` results per call (default `10`). When more results are available, the response includes a `next_cursor` value. Pass this value back as `cursor` in the next call to retrieve the following page. When `next_cursor` is `null`, there are no further results.

```javascript
// Fetch the first page
let response = await callMCPTool("search_objects", { query: "sales" });

// Fetch the next page if a cursor was returned
if (response.next_cursor) {
    response = await callMCPTool("search_objects", {
        query: "sales",
        cursor: response.next_cursor
    });
}
```

## Visualizations embedded in iframe

When displaying the embedded visualization using the `iframe_url` property, the following user interaction features are included by default:

  
| Area | Option | Visibility |
| --- | --- | --- |
| 
Primary actions and actions in the More (`…​`) options menu

 | 

**Pin**

 | 

Visible

 |
| 

**Save**

 | 

Visible

 |
| 

**Download**

 | 

Visible

 |
| 

**Edit**

 | 

Not visible

 |
| 

**Add to Coaching**

 | 

Not visible

 |
| 

Context menu actions

 | 

**Aggregate**

 | 

Visible

 |
| 

**Filter**

 | 

Visible

 |
| 

**Sort**

 | 

Visible

 |
| 

**Position**

 | 

Visible

 |
| 

**Conditional formatting**

 | 

Not visible

 |
| 

**Rename**

 | 

Not visible

 |
| 

**Edit**

 | 

Not visible

 |
| 

**Remove**

 | 

Not visible

 |
| 

Axis menu

 | 

**Exclude**

 | 

Visible

 |
| 

**Only include**

 | 

Visible

 |
| 

**Drill down**

 | 

Visible

 |
| 

**Show underlying data**

 | 

Visible

 |

The following features are not supported directly in visualizations embedded in an iframe. However, you can use the **Make a Copy** option to access these capabilities:

-   Changing filters
    
-   Changing chart type or chart configuration
    
-   View query SQL or query visualizer
    
-   SpotIQ analysis
    

## Org switching tools

Some ThoughtSpot deployments use Orgs, the isolated tenant workspaces within a single instance, each with its own users, data models, and resources. A user may have membership in one or several Orgs and want to analyze data from a different Org without ending the session, closing the connection, or re-authenticating. When connecting to the MCP Server over OAuth on an Org-enabled instance, users can discover and switch between Orgs during a session using `list_orgs` and `switch_org`.

Org switching is a two-step pattern:

1.  The agent calls `list_orgs` to retrieve the Orgs the user can currently access. The response identifies which Org is active and returns the `id` of the Orgs to switch.
    
2.  The agent calls `switch_org` with the target `org_id`. ThoughtSpot switches the active Org for the session and confirms the new active Org ID.
    

> **IMPORTANT:** The list\_orgs and switch\_org tools are available on OAuth MCP server endpoints only. Bearer-token MCP Server endpoints do not expose these tools. The switch\_org is a state-changing operation. Host applications that gate state-changing tools behind user confirmation will prompt the user before this tool runs. list\_orgs reflects the user’s current org membership at call time, not a snapshot taken at connection. Orgs granted or revoked mid-session appear immediately. Data models and resources in a target Org are not visible until after switching. Use list\_orgs to discover Org names, then switch\_org to enter an Org and explore its contents.

### list\_orgs

Returns the `orgId` of the Orgs that the authenticated user has access to and flags the Org that the user is currently logged in to.

Use the `list_orgs` tool to discover which Orgs you can reach before switching. The list always reflects your live access at call time, not a snapshot taken when you connected, so orgs granted or revoked since your session started are reflected immediately.

#### Example call

```javascript
const orgs = await callMCPTool("list_orgs", {});
```

```python
call_mcp_tool("list_orgs", {})
```

#### Response

```json
{
  "orgs": [
    {
      "id": 1001,
      "name": "Finance",
      "description": "Finance org — Q3 revenue models and budget data.",
      "is_active": true
    },
    {
      "id": 1002,
      "name": "Staging",
      "description": "Staging environment for testing new data models."
    }
  ]
}
```

 
| Field | Description |
| --- | --- |
| 
`id`

 | 

Unique identifier for the Org. Pass this value to `switch_org` to switch to this Org.

 |
| 

`name`

 | 

Display name of the Org.

 |
| 

`description`

 | 

Description of the Org.

 |
| 

`is_active`

 | 

Set to `true` if the user’s current session is in this Org (the active Org). If the user’s current session is not in this Org, this field is omitted from the response.

 |

### switch\_org

Switches the active Org for the current session.

After a successful switch, all subsequent tool calls including `create_analysis_session` and data source lookups run against the Org to which the user is switched. This switch persists across all active sessions without requiring re-authentication or logging out.

> **IMPORTANT:** switch\_org is a state-changing tool (readOnlyHint: false). Host applications that gate state-changing tools behind user confirmation will prompt the user before this tool runs. The data models that exist in a target Org cannot be viewed or accessed until after you have switched into it. Use list\_orgs to discover available Orgs and then use switch\_org to switch. After switching Orgs, the list of data model resources will stay static unless the LLM client provides dynamic resource lists. The active Org selection persists across sessions and applies across all your active sessions. It resets only on re-authentication or after prolonged inactivity.

#### Input parameters

 
| Field | Description |
| --- | --- |
| 
`org_id`  
_Required_

 | 

The ID of the org to switch to. Obtain this value from `list_orgs`.

 |

### Example call

```javascript
const result = await callMCPTool("switch_org", {
    org_id: 1002 // ID of the org to switch to, obtained from list_orgs.
});
```

```python
call_mcp_tool(
    "switch_org",
    {"org_id": 1002},  # ID of the org to switch to, obtained from list_orgs.
)
```

### Response

```json
{
  "success": true,
  "active_org_id": 1002
}
```

-   `success`: `true` if the org switch completed successfully. If the user lacks access to the requested Org, it is set as `false` and the active Org remains unchanged.
    
-   `active_org_id`: The ID of the active Org.
    

### Known limitations

-   Signing in currently relies on a browser cookie from your ThoughtSpot cluster. If your browser blocks third-party cookies, the connection may fail to complete.
    
-   Re-authentication is required in the following scenarios:
    
    -   If connection remains idle for 14 days, the session expires and requires reauthentication.
        
    -   If your ThoughtSpot instance is temporarily unreachable when your session token renews, you may be signed out and prompted to reconnect.
        
    

## check\_connectivity

Runs a basic health check to verify that the ThoughtSpot Spotter MCP Server is reachable and responding. Use this tool to confirm your connection before starting an analytical session.

> **NOTE:** check\_connectivity is the Spotter 3 equivalent of the ping tool in the legacy MCP version.

### Example call

```javascript
const result = await callMCPTool("check_connectivity", {});
```

```python
call_mcp_tool("check_connectivity", {})
```

### Response

```json
{
  "success": true
}
```

-   `success`: Returns `true` if the Spotter MCP Server is reachable and operational.
    

## Additional resources

-   For a chat client example, see [Python Agent with Simple React UI](https://github.com/thoughtspot/developer-examples/tree/main/mcp/python-react-agent-simple-ui).
    
-   For information about rendering iframe visualizations, see the [startAutoMCPFrameRenderer]({{navprefix}}/{{startAutoMCPFrameRenderer}}) function reference.