# Interactive tools

Interactive tools render a real, interactive map directly inline in the chat. Your agent doesn't return a description of a map, it returns the map itself. There are two of them: [`view_map`](#view_map) for ad-hoc visualizations the agent composes from your data, and [`load_builder_map`](#load_builder_map) for opening one of your saved CARTO Builder maps.

{% hint style="info" %}
Interactive tools render inline only in MCP clients that support [MCP Apps](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/apps): Claude.ai, ChatGPT, Claude Desktop, and others. In clients that don't, the tool returns a text confirmation describing what would have been rendered.
{% endhint %}

***

### `view_map`

**Description**

Renders an ad-hoc interactive map inline in the chat from a `@deck.gl/json` declarative specification the agent generates. Use this when the user asks to map, visualize, or show the geographic distribution of points, polygons, hexagons, quadbins, clusters, density heatmaps, or raster, and the map doesn't already exist as a saved CARTO Builder map. For an existing saved map, use [`load_builder_map`](#load_builder_map) instead.

The agent generates the visualization spec from your natural-language request over any table or SQL query in your connected data warehouses. CARTO handles authentication, basemaps, and tooltips behind the scenes. You don't need to know the spec to use this tool.

The widget includes pan/zoom controls and hover/click tooltips (when the layer is `pickable` and a `getTooltip` expression is provided). The legend is not part of the map widget itself. When the MCP client supports inline UI artifacts, the agent renders the legend as a separate artifact directly underneath the map.

For example, the screenshot below was produced by the following prompt:

> *"Map Hurricane Milton's best track points, area track and track line alongside aggregated enriched H3 POIs with avg precipitation and underlying raster layer."*

<figure><img src="/files/662XQtG5uTqGA5t9LGVM" alt="view_map rendering an interactive map inline in the chat"><figcaption></figcaption></figure>

**Input properties**

| Parameter     | Type   | Required | Description                                                                                                                              |
| ------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `deckglProps` | object | Yes      | The visualization specification, automatically generated by the agent from your natural-language request. You don't write this yourself. |

**Output**

In MCP hosts that support [MCP Apps](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/apps), an interactive map widget renders directly inline in the chat. In hosts that don't, the tool returns a text confirmation.

**Example prompts**

Natural-language requests the agent will turn into a `view_map` call:

* *"Show me populated places on a world map"*
* *"Make a heatmap of UK solar panels"*
* *"Map the H3 cells with highest order volume in Madrid"*

<details>

<summary>For developers: deck.gl spec reference</summary>

This section documents the shape of the `deckglProps` value the agent emits, for developers building custom MCP clients or debugging what their agent produces. End users do not need this.

**External references**

* [deck.gl JSON converter](https://deck.gl/docs/api-reference/json/overview). The underlying declarative spec format (`@@type`, `@@function`, `@@=` accessor expressions).
* [@deck.gl/carto layers](https://deck.gl/docs/api-reference/carto/overview). `VectorTileLayer`, `H3TileLayer`, `QuadbinTileLayer`, `ClusterTileLayer`, `HeatmapTileLayer`, `RasterTileLayer`, `PointLabelLayer`.
* [CARTO basemap styles](https://docs.carto.com/carto-for-developers/key-concepts/carto-for-deck.gl/basemaps/carto-basemap). `positron`, `dark-matter`, `voyager`.

**CARTO data sources reference** (for the `data: { "@@function": "...Source", ... }` inline value):

* [vectorTableSource](/carto-for-developers/reference/data-sources/vectortablesource.md), [vectorQuerySource](/carto-for-developers/reference/data-sources/vectorquerysource.md), [vectorTilesetSource](/carto-for-developers/reference/data-sources/vectortilesetsource.md)
* [h3TableSource](/carto-for-developers/reference/data-sources/h3tablesource.md), [h3QuerySource](/carto-for-developers/reference/data-sources/h3querysource.md), [h3TilesetSource](/carto-for-developers/reference/data-sources/h3tilesetsource.md)
* [quadbinTableSource](/carto-for-developers/reference/data-sources/quadbintablesource.md), [quadbinQuerySource](/carto-for-developers/reference/data-sources/quadbinquerysource.md), [quadbinTilesetSource](/carto-for-developers/reference/data-sources/quadbintilesetsource.md)
* [rasterSource](/carto-for-developers/reference/data-sources/rastersource.md)
* [boundaryTableSource](/carto-for-developers/reference/data-sources/boundarytablesource.md), [boundaryQuerySource](/carto-for-developers/reference/data-sources/boundaryquerysource.md)

**Spec essentials**

* **Sources go inline as the layer's `data` value**, never as top-level keys: `"data": { "@@function": "vectorTableSource", "connectionName": "...", "tableName": "..." }`.
* **Each tile layer is hardcoded to its source's tiling scheme.** Mixing schemes silently renders empty:
  * `VectorTileLayer` accepts `vector*Source` or `boundary*Source`
  * `H3TileLayer` accepts `h3*Source`
  * `QuadbinTileLayer` accepts `quadbin*Source`
  * `RasterTileLayer` accepts `rasterSource`
  * `ClusterTileLayer` and `HeatmapTileLayer` accept `h3*Source` OR `quadbin*Source` (not vector)
* **H3 and quadbin table/query sources require `aggregationExp`** (e.g., `"SUM(population) AS population, AVG(elevation) AS elevation"`). Without it the layer renders empty at any zoom below the source's native resolution.
* **Basemap** is set via top-level `mapStyle` with a CARTO style URL: `https://basemaps.cartocdn.com/gl/{positron|dark-matter|voyager}-gl-style/style.json`.
* **Credentials are injected by the renderer.** Never include `accessToken`, `apiBaseUrl`, or `clientId` in the spec.

**Example spec — vector points**

```
view_map({
  deckglProps: {
    initialViewState: { latitude: 20, longitude: 0, zoom: 2 },
    mapStyle: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
    layers: [{
      "@@type": "VectorTileLayer",
      id: "places",
      pickable: true,
      data: {
        "@@function": "vectorTableSource",
        connectionName: "carto_dw",
        tableName: "carto-demo-data.demo_tables.populated_places"
      },
      getFillColor: [255, 100, 50],
      pointRadiusMinPixels: 3
    }],
    getTooltip: "@@=object && '<b>' + object.properties.name + '</b>'"
  }
})
```

**Example spec — H3 heatmap from raw points**

For point-source heatmaps and clusters, raw points must be wrapped in `h3QuerySource` (or `quadbinQuerySource`) with SQL that pre-bins the geometry. `HeatmapTileLayer` and `ClusterTileLayer` reject vector sources.

```
view_map({
  deckglProps: {
    initialViewState: { latitude: 54, longitude: -2.5, zoom: 5.5 },
    mapStyle: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
    layers: [{
      "@@type": "HeatmapTileLayer",
      id: "uk-solar",
      data: {
        "@@function": "h3QuerySource",
        connectionName: "carto_dw",
        sqlQuery: "SELECT `carto-un`.carto.H3_FROMGEOGPOINT(geom, 9) AS h3, COUNT(*) AS n FROM `dataset.uk_solar_panels` WHERE geom IS NOT NULL GROUP BY 1",
        aggregationExp: "SUM(n) AS n"
      },
      getWeight: "@@=properties.n",
      radiusPixels: 25,
      colorRange: [[255,255,178,0], [254,217,118,160], [254,178,76,200], [253,141,60,220], [240,59,32,240], [189,0,38,255]]
    }]
  }
})
```

**Tool response structure**

```
{
  "content": [
    {
      "type": "text",
      "text": "Displaying ad-hoc deck.gl visualization on an interactive map."
    }
  ]
}
```

</details>

***

### `load_builder_map`

**Description**

Renders an existing saved CARTO Builder map inline in the chat. Use it in two flows:

* **Preview a map you just created via the CLI.** After `carto maps create` returns a `builderUrl`, ask the agent to "show me that map" and `load_builder_map` renders the result inline without leaving the conversation.
* **View any saved Builder map mid-conversation.** Reference it by URL, by ID, or by name (the agent locates it via [`list_maps`](/carto-for-agents/mcp-server/tools-reference/platform-tools.md#list_maps) first).

To render an ad-hoc visualization from a deck.gl spec instead, use [`view_map`](#view_map).

For example, the screenshot below was produced by the following prompt:

> *"Render inline existing US Population Map and help me validate it before sending the link to exec by email."*

<figure><img src="/files/ekEFxW314AKyv3nX58pE" alt="load_builder_map rendering a saved Builder map inline in the chat"><figcaption></figcaption></figure>

{% hint style="warning" %}
**`load_builder_map` is a very limited, read-only preview — not the full Builder experience.** The tool renders the saved map's layers, viewport, popups, and legend. Many Builder elements (widgets, SQL parameters, AI Agents, and other interactive panels) are not rendered. When the saved map uses a non-CARTO basemap (Google Photorealistic 3D Tiles, custom Mapbox style, etc.), the renderer falls back to a CARTO basemap. The user must be authenticated and can click "Open in Builder" from the preview for the full experience.
{% endhint %}

**Input properties**

| Parameter | Type   | Required | Description                                                                                                                                                                     |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mapId`   | string | Yes      | UUID of a saved CARTO Builder map (the `mapId` segment of `https://<workspace>.app.carto.com/viewer/<mapId>`). The user must have read access: owned, shared, or marked public. |

**Output**

In MCP hosts that support [MCP Apps](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/apps), the saved map renders inline. In hosts that don't, the tool returns a text confirmation.

**Example**

*"Show me the retail stores map"*

The agent first calls `list_maps` with a name search, then loads the matching map:

```
list_maps({ search: "retail stores" })
// → returns a map with id "a1b2c3d4-e5f6-..."

load_builder_map({ mapId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" })
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.carto.com/carto-for-agents/mcp-server/tools-reference/interactive-tools.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
