---
title: list_connections
description: List the data connections you can author against, warehouses and the uploaded-file source. The eleven fields, why it takes no arguments, errors and scope.
updated: 2026-09-20
tools: [list_connections]
---

Lists the data connections you can build a refreshable dashboard against, so
you can find the connection id to pass to
[`introspect_schema`](/reference/mcp-tools/introspect-schema),
[`explore_data`](/reference/mcp-tools/explore-data),
[`validate_cube_sql`](/reference/mcp-tools/validate-cube-sql), or `source.connection`
in the spec you publish.

Two kinds of row appear here: the workspace's **warehouse** connections, and its
one **uploaded-file** source once it has one. Warehouse connections are created
and managed in the Dashies web app, never through MCP; the uploaded-file source
is the other way round, created by
[`create_file_upload`](/reference/mcp-tools/create-file-upload) the first time a
file is uploaded to the workspace.

Behaviour hints for clients: read-only, not open-world.

## Parameters

This tool **takes no parameters**. Its input schema declares no properties at
all, and that is deliberate: which connections you see is decided by how the MCP
connection was authorized, not by an argument. See
[Scope](#scope) below.

## Returns

**Eleven fields per connection**, every one of them always present. Seven describe
how the connection was configured, three describe what actually happened to it,
and one says whose it is:

| Field | Meaning |
|---|---|
| `id` | The connection id you pass as `connection`. |
| `kind` | Always `warehouse`, **including on the uploaded-file source**. It says where the row is stored, not that the row is a warehouse. Read `engine` to tell them apart. |
| `label` | The name you gave it in the web app, or `Uploaded files` on the uploaded-file source. |
| `engine` | What the connection runs on, such as `postgres` or `snowflake`. **No list is given here, because an engine list goes stale on the merge that adds the next engine.** The one value worth knowing by name is `file`: that row is the workspace's uploaded-file source, not a warehouse. |
| `status` | `pending`, `active`, `error` or `disabled`. Only `active` can author. |
| `last_verified_at` | When a Test last succeeded. |
| `last_error` | A classified token such as `connection_auth`, never raw driver text. |
| `health_state` | What real refreshes observed. `null` until something has observed it. |
| `health_error` | The classified reason behind `health_state`. |
| `health_source` | What made that observation. |
| `shared_sample` | `true` on the shared "Dashies sample data" connection, `false` on every connection of your own. |

No password, secret, Vault reference or internal object name is ever included:
the projection is an allowlist, not a filter.

### The uploaded files row, and its `uploads`

Once a workspace has uploaded a file, its uploads share one connection, labelled
`Uploaded files`. That row, and no other, carries one more field, `uploads`: the
workspace's newest uploads, each with its `upload_id`, `filename`, `status`,
`bytes`, `sha256`, `failure`, `created_at`, `ready_at` and `table_count`. The text
lists them indented under the row. `uploads` is `null` when they could not be
read just now, which is different from an empty list.
[`get_file_upload`](/reference/mcp-tools/get-file-upload) reads one in full.

### The shared "Dashies sample data" connection

One connection is listed in **every** space, last, with `shared_sample: true`: a
read-only Snowflake warehouse Dashies provides, holding synthetic data, usable on
every plan. On a trial or paid plan a dashboard built on it refreshes on a
schedule like any warehouse; on a **free** plan its numbers are built into the
page and move only when it is republished, because a cadence and an on-demand
refresh both need a paid plan. Its line in the text carries
`SAMPLE DATA: shared by Dashies, synthetic, read-only`. Build on it
exactly as on any warehouse, say that the numbers are sample data, and never try
to edit, test or delete it - it belongs to nobody, and every such call is refused
with the same not-found an unknown id gets.

:::warning{title="status and health_state are independent, not two views of one thing"}
`status` is what a **Test** concluded. `health_state` is what a **real refresh**
observed. `status: active` beside `health_state: failing` is a normal and
meaningful reading, not a contradiction: the connection is configured and
enabled, and the last refresh failed at the connection level. Never collapse
them.
:::

```text
Data connections in the "acme-co" workspace (2):
- Analytics Postgres [7a1e...-...] | engine: postgres | status: active | last verified: 2026-07-29T04:12:09Z
- Snowflake Prod [0c22...-...] | engine: snowflake | status: error | last verified: 2026-07-20T11:03:44Z | last error: connection_auth | last observed: failing (connection_auth)

Pass a connection's id as the `connection` argument to introspect_schema / explore_data / validate_cube_sql, and as `source.connection` in the spec you publish with publish_dashboard, to author a dashboard that refreshes from it. Only 'active' connections can be used.

BEGIN_JSON
{"count":2,"connections":[{"id":"...","kind":"warehouse","label":"Analytics Postgres","engine":"postgres","status":"active","last_verified_at":"...","last_error":null,"health_state":null,"health_error":null,"health_source":null,"shared_sample":false}]}
END_JSON
```

The `| last observed: <state>` segment appears **only** when something has
actually observed the connection, so one that has never refreshed prints nothing
there. With a classified reason it renders `last observed: failing (connection_auth)`.

### The header names the space

Every listing heads `Data connections in the "<slug>" workspace (N):`, or
`Data connections in this workspace (N):` when the authorization carries an id
but no slug.

:::note{title="It said Warehouse connections until 2026-09-20"}
The uploaded-file source is in this listing by design, and it is not a warehouse,
so the header was describing one of its own rows wrongly. Its `kind` column does
say `warehouse`; that is where the row is stored. Issue `#3404`.
:::

:::note{title="There used to be a second header, and why it went"}
A grant naming no workspace headed its listing `Your personal warehouse
connections (N):`, and this page argued the word `personal` there was
load-bearing: the bare form reads as "all of yours", and an author on an older
authorization who read it that way built against a connection and was refused at
the binding call by a deliberately ambiguous message they could not diagnose. That
was issue `#818`.

The header is gone with the listing. The warning it carried is not needed, and not
merely stale: by the time it was removed, the only row that branch could still
return was the shared sample, which is listed in **every** space and is not
scoped to a person at all, so the sentence was false about the one row it could
describe. A grant naming no workspace is now refused before any listing happens.
:::

### Empty state

Both lines:

```text
There are no data connections in the "acme-co" workspace.
Connect a warehouse from the Dashies web app (Data sources) with the "acme-co" workspace as the active space, or upload a CSV or Excel file with create_file_upload, to author dashboards that refresh from it. The built-in 'self' connection (Dashies' own no-PII metrics) is always available without a connection id.
```

An authorization locked to a workspace whose slug is unavailable says
`this workspace` wherever those lines say `the "acme-co" workspace`. There was a
second empty state, for a grant naming no workspace; that grant is refused now.

:::note{title="self is never listed"}
The built-in `self` connection is always available and never appears here. Use it
by passing `connection: "self"` or by omitting the argument entirely. An empty
list therefore means "no connections of your own", not "nothing to author
against".
:::

## Errors

| Condition | Text |
|---|---|
| The authorization names no workspace | `Data sources belong to a workspace, and this MCP connection is not authorized for any workspace, so there is no space whose data sources it can list. Re-authorize it and choose the workspace it should use.` |
| The read failed | `Could not list your connections: <err>` |

## Scope

The read space comes **from the grant alone**. A workspace authorization lists
that workspace's connections, whoever on the team created them. An authorization
that names no workspace is **refused**, with the sentence under
[Errors](#errors) above: a data source belongs to a workspace, so there is no
space whose connections such a grant could list.

A connection belongs permanently to the space it was created in and cannot be
moved, so a connection you can see in one space is simply absent from the other.
Inside a workspace, a member holding a **creator seat** can use a connection to
author. A view-only role cannot: reading a connection's schema or running a
statement against it needs a creator seat, so `introspect_schema`, `explore_data`
and `validate_cube_sql` refuse and say so. Only the member who added it and
workspace admins can rename, re-test, rotate or delete it.

## Check it worked

If the list is empty but you expect entries, check which space you authorized
for: re-authorizing and choosing the workspace is what switches the read space,
and there is no argument that overrides it. The header tells you which space you
got, so read it rather than inferring from the contents.

If an entry shows `status: error`, test the connection in the web app before
authoring against it, since an inactive connection is refused at the point of use
rather than here. If it shows `status: active` with `last observed: failing`,
the configuration is fine and the last real refresh was not: read
[`get_refresh_status`](/reference/mcp-tools/get-refresh-status) on a dashboard
bound to it for the run that failed.
