List Flows
Retrieves a list of Tableau Prep flows on a site.
APIs called
Required Tableau API scopes
When the MCP server authenticates with OAuth (connected-app JWT), this tool requests:
tableau:flows:readtableau:mcp_site_settings:read
Note that flows use the dedicated tableau:flows:read scope, not the tableau:content:read scope
used by workbooks, data sources, and views. See
OAuth configuration for how scopes are negotiated.
Optional arguments
filter
A
filter expression
in the format field:operator:value. Multiple expressions are combined with a comma using a logical
AND.
Supported fields and operators. This list mirrors the official
Filtering and Sorting
reference for the Flows endpoint. The Tableau Flows endpoint accepts a narrower filter-field set
than other content endpoints — ownerEmail, ownerDomain, and tags are not supported and
will be rejected by the server.
| Field | Operators | Notes |
|---|---|---|
createdAt | eq, gt, gte, lt, lte | ISO 8601 YYYY-MM-DDTHH:MM:SSZ or date-only YYYY-MM-DD (auto-promoted to midnight) |
name | eq, in | Flow name (case-sensitive — pass exact case; whitespace-sensitive) |
ownerName | eq | Matches user.fullName (display name), NOT login/email. See "ownerName" below. |
projectId | eq | Project UUID |
projectName | eq, in | Project name (case-sensitive — pass exact case; whitespace-sensitive) |
updatedAt | eq, gt, gte, lt, lte | ISO 8601 YYYY-MM-DDTHH:MM:SSZ or date-only YYYY-MM-DD (auto-promoted to midnight) |
Examples:
name:eq:DailySalesCleanupprojectId:eq:6f8a2966-e173-11e8-ae74-ffd84c19d7f3
Caller-role visibility (important for sizing the response)
The set of flows Tableau returns depends on the caller's role on the site:
- Non-admin callers — Tableau returns only flows the caller has Read (view) permission for. On shared sites this is still typically many more flows than the user owns, so an unfiltered call is rarely "just my flows".
- Server / site-admin callers — Tableau returns every flow on the site regardless of
permissions; the permission filter does not apply. On large enterprise sites this can be thousands
of flows, so
mcp.resultInfo.truncatedis much more likely to come backtrueon the first call.
In both cases, scope down with ownerName (matched against fullName only — not email/login/UUID),
projectId (UUID), projectName, or a date-range createdAt / updatedAt filter when the user's
intent is narrower than "every flow visible to me on this site".
Filter value semantics (important)
Several filter fields have non-obvious value contracts that the official spec under-specifies or contradicts. The findings below were verified live against Tableau REST 3.30. When this tool detects a likely shape-mismatch on an empty result, the response includes a structured empty-result hint so the LLM can self-correct rather than reporting a misleading zero.
ownerName — matches display name only
Matches against user.fullName (display name) only. It does not match login (user.name, often
an email on federated sites) or user id. The Flows endpoint does not currently expose ownerEmail,
ownerDomain, or ownerId filter fields, so ownerName is the only owner-based filter available.
ownerName:eq:Jane Doe # ✅ matches by display name
ownerName:eq:jane.doe@example.com # ❌ silently returns 0 flows
ownerName:eq:711e59cf-d1c0-446e-be48-3673ae067f7b # ❌ silently returns 0 flows
If the supplied value looks like a login (no whitespace), email (contains @), or user id
(canonical UUID shape) and the response is empty, the tool returns a recovery hint suggesting either
a Users REST API lookup or re-listing without the filter to inspect owner.fullName.
projectId — must be a UUID
Must be the project's UUID (canonical 8-4-4-4-12 hex form). Any other value (including a project name) silently returns 0 results.
projectId:eq:6f8a2966-e173-11e8-ae74-ffd84c19d7f3 # ✅ matches the named project
projectId:eq:Finance # ❌ silently returns 0 flows
projectId:eq:not-a-uuid # ❌ silently returns 0 flows
If the supplied value is not in canonical UUID shape and the response is empty, the tool returns a
recovery hint suggesting projectName:eq:<name> or a Projects REST API lookup.
name, projectName — case-sensitive and whitespace-sensitive
Per the official Tableau REST API spec, values are case-sensitive — pass the exact name as it
appears in Tableau (e.g. Superstore Flow, not superstore flow). Leading and trailing whitespace
are also significant: Sales Cleanup (with a leading space) silently returns 0 results. Always
pass the exact, trimmed name.
Some Tableau versions are observed to match leniently in practice, but don't rely on it — passing exact case and trimmed whitespace is portable across all versions.
createdAt, updatedAt — ISO 8601 with Z suffix, or date-only
Two accepted forms:
- Full ISO 8601 with the
ZUTC suffix, e.g.2025-01-01T00:00:00Z. - Date-only
YYYY-MM-DD, e.g.2025-01-01— auto-promoted to midnight UTC (2025-01-01T00:00:00Z) before being sent to Tableau. Use this when the user spoke about a calendar day with no time-of-day ("flows updated before Nov 20").
Other shapes — locale-style MM/DD/YYYY (ambiguous across locales), no-timezone
(2025-01-01T00:00:00), and offset-style (2025-01-01T00:00:00+00:00) — are rejected client-side.
The Tableau server itself also accepts +00:00-style offsets, but the tool pins Z to keep the
contract small and the validation message unambiguous.
createdAt:gt:2025-01-01T00:00:00Z # ✅ canonical
createdAt:gt:2025-01-01 # ✅ auto-promoted to 2025-01-01T00:00:00Z
createdAt:gt:2025-01-01T00:00:00 # ❌ tool rejects (no timezone)
createdAt:gt:2025-01-01T00:00:00+00:00 # ❌ tool rejects (offset, not Z)
createdAt:gt:01/01/2025 # ❌ tool rejects (locale-ambiguous)
name, projectName with in: — bracket-and-comma form
Multi-value lists use the form name:in:[Foo,Bar], where commas separate the items. Items are not
quoted, so a single item's value cannot itself contain a comma — every comma is read as an item
separator (a Tableau filter-language limitation, not a tool one).
sort
A sort expression in the format field:asc or field:desc. Combinable with filter.
Example: createdAt:desc
pageSize
The value of the page-size argument provided to the
Query Flows for Site
REST API. The tool automatically performs pagination and will repeatedly call the REST API until
either all flows are retrieved or the limit argument has been reached.
Example: 1000
limit
The maximum number of flows to return. The tool will return at most this many flows.
Example: 2000
See also: MAX_RESULT_LIMIT
Response-size guidance
This tool returns one record per flow including project, owner, tags, and parameters. On shared sites the visible flow count can easily reach hundreds, so the tool description steers the LLM toward the narrowest call that answers the user's question:
- Targeted lookups ("does flow X exist?", "who owns flow Y?") — always pass
filterand a smalllimit(e.g. 5). - Scoped exploration ("flows in the Finance project") — pass
filter(projectIdorprojectName) plus a moderatelimit(e.g. 25–50). - Broad analytics ("how many flows per project?") — pass a moderate
limit(e.g. 100) and paginate further only when explicitly asked. - Only call without
limitwhen the user explicitly requests a complete or exhaustive listing.
Site administrators can also impose a hard cap with
MAX_RESULT_LIMITS=list-flows:N,
which always wins over the LLM-supplied limit.
Response shape
The tool returns a JSON object:
{
"flows": [
/* one record per flow, see "Example result" below */
],
"mcp": {
"resultInfo": {
"returnedCount": 12,
"truncated": false,
"totalAvailable": 12
}
}
}
The top-level flows array and mcp.resultInfo are always present. resultInfo reports
whether the returned list is complete, so the answer never depends on the absence of a signal:
returnedCount— the number of flows inflows.truncated—falsemeansflowsis the complete set matching the request (every flow the caller can see, subject to anyfilter);truemeans more matching flows exist on the server than were returned.truncationReason— present only whentruncatedistrue:"requested-limit"— the caller's ownlimitargument cut the result short. Call again with a higherlimit(or omit it) to fetch more."admin-cap"— a site-administrator per-call cap (MAX_RESULT_LIMITorMAX_RESULT_LIMITS=list-flows:N) cut the result short, and the caller did not request an equal-or-smallerlimititself. Thelimitargument cannot raise the cap, so narrow thefilteruntil the matching set fits, or ask the administrator to raise the cap.
totalAvailable— the total number of flows matching the request on the server (across all pages, ignoringlimit). Present only when no server-side allow-list (INCLUDE_PROJECT_IDS/INCLUDE_TAGS) is configured — that count is taken before the tool's allow-list filtering, so under a bounded context it would overstate the accessible total and is therefore omitted rather than risk a misleading "N of M". When present andtruncatedistrue, use it to report "N of M" (e.g. "showing 100 of 430").
When truncated is true, do not report returnedCount as the total. If totalAvailable is
present, report "N of M" (e.g. "showing 100 of 430"); otherwise say "at least N". A truncated
example:
{
"flows": [
/* the first 100 matching flows */
],
"mcp": {
"resultInfo": {
"returnedCount": 100,
"truncated": true,
"truncationReason": "admin-cap",
"totalAvailable": 430
}
}
}
:::tip For client / LLM authors mcp.resultInfo is a signal for the model, not text to show the
user. Translate it into one plain sentence — "These are all 12 flows matching your request" or "Here
are the first 100 of 430; more match" — and never surface the field names (or the absence of a
warning) to the end user. :::
Example result
{
"flows": [
{
"id": "d00700fe-28a0-4ece-a7af-5543ddf38a82",
"name": "Sales Cleanup",
"description": "Cleans up the daily sales feed",
"webpageUrl": "https://10ax.online.tableau.com/#/site/mcp-test/flows/3",
"fileType": "tflx",
"createdAt": "2024-11-06T04:57:55Z",
"updatedAt": "2024-11-06T21:31:00Z",
"project": {
"id": "6f8a2966-e173-11e8-ae74-ffd84c19d7f3",
"name": "Default",
"description": "The default project that was automatically created by Tableau."
},
"owner": {
"id": "711e59cf-d1c0-446e-be48-3673ae067f7b",
"name": "jane.doe@example.com",
"fullName": "Jane Doe",
"email": "jane.doe@example.com",
"siteRole": "Creator"
},
"tags": { "tag": [{ "label": "sales" }] }
}
]
}
The project and owner objects above include all fields that Tableau Server / Cloud is observed
to return. The official spec only documents id (and name on project); the additional fields
are captured opportunistically as optional properties and may be absent on older versions or for
users without visibility into the owner's profile.