List workspaces
well_list_workspacesList the workspaces this connection is authorized to access. This draws nothing on the user's screen.
Use this FIRST when a single token may cover more than one workspace, and use it for every case a caller can settle on its OWN: exactly one workspace, a hint that matches one, a pin this conversation already wrote, or none at all. Read the rows and say which workspace you took.
⚠️ TO ASK THE USER WHICH WORKSPACE, CALL well_show_workspace_picker INSTEAD. It draws one tile per workspace and waits for a click. Reach for it only when the token authorizes several AND no hint resolves — a chooser over a set of one asks nothing, and a chooser the caller could have answered itself asks a question it already knows the answer to.
Use this FIRST when a single token may cover more than one workspace. Each entry has:
workspace_id: pass this as the workspace_id argument on other tools to target one workspace.
workspace_name: human-readable name (null if it can't be resolved).
is_primary: true for the token's default workspace (used when you omit workspace_id on a write).
kind: "demo" for the sample-data workspace a sign-up opens with, "real" for every other workspace, null if it can't be resolved. A demo workspace holds sample data only: never report its figures as the company's own.
workspace_situation: what the workspace IS for the account, already decided — never re-derive it from the other fields. "personal": the person's own space, the first real workspace they created, which files household categories (groceries, rent, health). "demo": the sample-data workspace. "company_child": a company workspace created under another workspace, which lineage_parent_workspace_id names. "legacy_child": a company workspace created under another workspace by the old parent pointer, whose company no person has confirmed yet (own_company_id is null until a person confirms it); it has no lineage_parent_workspace_id. "company": a company's own workspace, which files business categories — the close flow runs in one — even when own_company_id is null. "unmarked_root": a real workspace carrying no mark: not the person's own space, anchored to nothing, created under nothing. null when the class could not be read: say the class is unknown rather than guess.
own_company_id: the public id of the company this workspace is anchored to, or null when there is no live anchor — including a company workspace whose anchor company was deleted. A row without it is NOT thereby a membership workspace: read workspace_situation for what the workspace is.
role: "membership" on the person's own space, the first real workspace they created, which files household categories (groceries, rent, health). null on a company workspace, a demo, a space older than the marker, and a row that cannot be resolved. It is the stored marker behind the "personal" class: read role and workspace_situation for what a workspace is and which list of categories it files; never infer it from a missing own_company_id or lineage_parent_workspace_id.
lineage_parent_workspace_id: the workspace_id of the membership this workspace was created under, or null when the workspace has no active lineage. A workspace whose id appears here on other rows is the parent of those company workspaces.
identity: the company behind the workspace (registered name, trade name, registry number, country, website, currency, fiscal year start, where the fiscal year start came from, and the jurisdiction's default fiscal year start), so two similarly-named workspaces can be told apart. Every field is null when the workspace has no accounting settings yet. Tax identifiers are deliberately not included.
holds_records: on a row whose workspace_situation is personal or unmarked_root, whether the workspace holds anything a new company workspace would leave behind: a data source connected or still connecting, or any transaction, invoice, document or journal entry.
truemeans it holds records,falsemeans it holds none, andnullmeans the signal could not be read or the row is another class. Onlyfalseshows the workspace is empty.read_only: true on a company workspace the in-app chat's turn does not act in: one created under the turn's membership (listed beside it) or a family child the turn's grant carries (listed as a normal row would be). Either way it is named as the turn's workspace's child through
lineage_parent_workspace_id, so a membership can be told apart from its companies and a switch card can move there. At most 20 beside-the-grant rows are listed: a membership with more has its first 20 listed and itsholds_recordsnull. No tool of this turn acts in a read_only row, so pass its id to no tool except the switch that moves the chat there. Absent on the in-app turn's own workspace, and on every row over MCP. Absent too on WhatsApp on a company workspace of the person's own that a call reaches: there, pass that row's workspace_id as the call's workspace_id to read or write in it, and never call it read-only.has_bank_transactions: whether a connector the workspace BANKS with has delivered any transaction to it, meaning a bank, a neobank, or a treasury or spend platform whose product is an account. An accounting platform and a payment processor deliver transactions too and do NOT count here. Neither does a transaction whose source connector is unknown, whose install has since been disconnected, or whose catalog entry has been retired. Only
trueshows that a bank has fed this workspace:falsemeans no such transaction was found andnullmeans the signal could not be read, so an absent value is never a zero and neither value licenses skipping a bank-connection step. Read this before any month read when the flow needs to know whether the workspace banks with anything at all.
The result also carries default_workspace_id: on a brand-new account, the tile the picker card preselects. That is the demo workspace, when the grant holds exactly one demo and every other workspace in it is still empty (no company of its own, no registered name, currency or fiscal year, no connected source, no business data) and the conversation has not pinned another workspace. It is null otherwise, and always null on a picker scoped with workspace_ids. It chooses nothing: nothing acts on it without the person's click, so never switch to it or run in it on your own. It is not is_primary, which is only the fallback for an omitted argument.
The result also carries session, what the user's card clicks have already recorded in this conversation: pinned_workspace_id (null when not switched), workspace_queue (the workspaces to work through next, empty when none), selected_periods (the months picked on the period card, empty when none), and selected_counterparties (the counterparties picked on the missing-invoices card, with the workspace their company ids belong to; null when none was picked). Call this any time you need to resync with clicks you may have missed.
When the token authorizes a single workspace you can omit workspace_id everywhere; when it authorizes several, read tools fan out across all of them unless you pass a workspace_id, and write tools require one.
⚠️ A row without own_company_id has no live anchor — workspace_situation says what the workspace is, and a company workspace can carry none. TO ASK THE USER WHICH COMPANY a workspace of theirs IS — to show its detected company candidates and let them pick — CALL well_show_company_candidates, never this read: this list never shows the candidates.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| workspace_id | No | Target workspace. Optional: this tool describes the token itself rather than one workspace's data, so omitting it returns the same answer. | |
| conversation_id | No | The conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation. | |
| workspace_scope | No | Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| error | No | ||
| session | No | What this conversation's card clicks recorded so far; null/empty fields when nothing was clicked yet. | |
| success | Yes | ||
| workspaces | Yes | ||
| conversation_id | No | The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation. | |
| newly_connected | No | Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later. | |
| conversation_id_note | No | Present only when the server opened a fresh lane, stating that no choice recorded earlier was read. | |
| default_workspace_id | Yes | The tile the picker card preselects on a brand-new account: the demo workspace, when the grant holds exactly one demo and every other workspace is still empty (no company of its own, no registered name, currency or fiscal year, no connected source, no business data) and this conversation has not pinned another workspace. Null otherwise, and on a scoped picker. It chooses nothing: nothing acts on it without the person's click. Not the same as is_primary. | |
| conversation_id_source | No | Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened. |