Skip to main content
Glama

List connectors

well_list_connectors
Read-only

List the connectors a workspace can install AND everything it has already connected, each with a one-click install deep link. The result DRAWS THE CONNECT CARD the user clicks in.

ONE tool answers both halves of the connect question — "what can I connect to Well?" and "what is connected, still syncing, or broken?" — because every existing connection is overlaid onto its catalog row. Do NOT read workspace_connectors records to work out connection coverage; this tool is that answer.

⚠️ FOR A SILENT COVERAGE CHECK, CALL well_get_connector_coverage INSTEAD. Same scope arguments, same rows, no card. A data skill confirming a bank is connected before it measures anything must use that one: this tool renders on every call, so a check run here drops a connect picker into a conversation about something else and then waits for a click nobody meant to make.

⚠️ WAIT ON THE CARD IN THE TURN THAT DREW IT. Write your one line for the user FIRST — the wait holds the turn open for up to a minute, and a user looking at a card with no sentence beside it has been given no reason to click — then call well_wait_for_selection on the kind this result names in next_step.

Each entry has:

  • service_id: the connector's stable catalog id (e.g. "stripe"), used in the install link.

  • name, category_id, direction: what the connector is.

  • data_domains: the financial domains it serves — any of "bank", "accounting", "invoicing" — or null for a non-financial connector. One connector can serve several domains (Qonto serves all three). "bank" here means the connector delivers cash movements, which a payroll or billing platform also does; do NOT read it as "this is a bank". To list banks, pass kind: "bank", which the server scopes on its own bank classification.

  • invoice_source: this connector can bring supplier invoices into Well, either because it issues or holds them (an accounting or an invoicing tool) or because invoices arrive through it as files (a mailbox, a messaging app, a file drive). Read it to decide which tools to offer for a missing-invoice hunt. It is a property of the connector, not of this workspace's connection.

  • reason: why this row is on the card. "catalog" is the list that was asked for. "picked_vendor" is a connector behind a counterparty the user picked. Say which is which; never present a catalog row as one the user chose.

  • status: "available" connectors are connectable now; "coming_soon"/"unavailable"/"maintenance" are not.

  • is_matched / is_selected: whether this workspace's detected tools matched this connector / already picked it.

  • match_score: 0..1 confidence of that match; null when unmatched. A high score is a tool Well is confident the workspace already uses.

  • is_connected: this workspace has a connection you should REPAIR or MANAGE, not install fresh. True for "enabled", "processing", "error" and "need_reconnect"; false for "to_configure" and "disabled", where a fresh install IS the right next step.

  • connection_status: the existing connection's state, or null when this workspace has no connection row for the connector at all. One of:

    • "enabled" — connected and syncing.

    • "processing" — the grant is in and the FIRST sync is still running; data may be partial. Connected: do NOT ask the user to connect it again.

    • "error" — authenticated but its last real sync failed. Offer install_url as a reconnect.

    • "need_reconnect" — the grant is dead and only the user can restore it. Offer install_url as a reconnect, NOT a first install.

    • "to_configure" — a connect attempt that never completed its handshake. Nothing is connected: offer install_url as a first install, and never claim the tool is connected.

    • "disabled" — the connection was torn down. Offer install_url as a first install. A "degraded" connector never appears: it is resolved server-side against its own sync history into "enabled" or "error", so you never surface a state that clears itself. A connection whose state this build cannot read also reports null, and there is_connected stays true — read the two fields together, and treat "null status, is_connected true" as an existing connection whose health is unknown.

  • workspace_connector_id: the connection instance's id, or null when there is no connection row. This is the id well_invoke_connector_tool and well_list_connector_tools need — resolve it HERE, never via well_query_records on workspace_connectors.

  • last_successful_sync_at: ISO timestamp of the last SUCCESSFUL sync, or null when none has landed yet. An "enabled" connector with null here has a valid grant but has never delivered data.

  • sync_in_progress: a data sync is running right now. Tell the user to wait rather than to act.

  • is_preselected: Well recommends connecting this one now (a high-confidence match with is_connected false). The interactive picker pre-checks exactly these. A "to_configure" or "disabled" row can still be pre-checked — installing it IS the fix. On kind: "accounting" at most ONE row carries it — the single highest-confidence accounting tool — because connecting the accounting software is a pick-one step; every other scope pre-checks each high-confidence match.

  • install_url: a one-click link that STARTS or REPAIRS the connection in Well. It works from any state — it signs the user in if needed, creates their workspace if they have none, then runs the connector's own auth flow — and it covers banks too (a bank opens its bank-login flow pre-selected). Null only when the connector is not "available". Hand this to the user to get started in one click.

  • countries: the ISO 3166-1 alpha-2 countries this connector serves, or null when none is known. It is what the country scope sorts on; use it to explain why a bank fits the company, never to hide a bank the country field is null on.

unsent_document_counts is a TOP-LEVEL field, present only when include_unsent_counts was passed. It names every tool this workspace forwards documents to, with the documents each one has not received yet, biggest backlog first. IT IS THE ONLY PLACE THE BACKLOG IS REPORTED: that array carries the workspace's whole set of outbound connections whatever catalog page came back, the connector rows carry no count at all, and the catalog runs to hundreds of rows, so a tool with a real backlog is missing from any page that did not happen to carry it. An entry reading 0 is a tool that is up to date: say nothing about it. unsent_document_count_is_upper_bound true means a document filter applies to that connection, so the count is a maximum and reads as "up to ". Every count is read off Well's own forward record, so it measures what Well wrote down rather than what the tool confirmed. Name each tool by the entry's name.

install_all_url is a TOP-LEVEL field, not a per-connector one. It is ONE link that installs every installable connector in this result that is not already connected, in the order they are listed. Its reach is wider than the per-row links: a connector the catalog holds by service id alone carries a null install_url and is still installed by this link, so never read a null install_url as "cannot be installed". When the answer offers several connectors to install, hand the user install_all_url and do NOT list the per-connector install_url links beside it — the one link IS the whole offer, and a table of links beside it puts the reader back through several sign-ins. One link carries at most 10 connectors, and install_all_omitted names the service ids it left out, so offer those rows their own install_url. install_all_url is null when the result offers nothing to install. It is null too wherever the result names no set the user has chosen: the unfiltered catalog and the whole bank domain never carry the link, and a name search or an accounting or invoicing domain carries it only while the WHOLE result fits in one link and this page holds all of it — past that the link would stand for whichever rows the page happened to carry. from_selection always carries the link, however many vendors were picked, because the user named each one. Where install_all_url is null, the rows' own install_url links ARE the offer: list them, and never announce a batch link the result does not carry.

Paging: page with offset and page_count, never with the length of connectors. On the first page of an unsearched browse the workspace's ALREADY CONNECTED connectors are prepended so the catalog's ordering cannot bury them past any page you would ask for — so connectors can be longer than the page it came from, and page_count is the catalog window's own length. Advance by offset + page_count; total counts every matching connector across all pages. Those prepended rows carry is_connected true (or a to_configure/disabled state), so a workspace's live tools are visible without paging for them.

Scoping: pass kind ("bank" | "accounting" | "invoicing") to get only the connectors serving that domain — the whole set, server-ordered, including the long tail of bank institutions. Pass kind: "upload_surface" for the places invoices ARRIVE — mailboxes, messaging apps, file drives. Pass kind: "storage" for the drives Well FILES INTO — Google Drive, Dropbox, OneDrive — the step that asks where Well should write the documents it collects. Neither of those two is a financial domain: the server resolves each from the connectors' own display categories, so read the rows it returns and never re-derive the set from category_id yourself. They are opposite DIRECTIONS on the same drives, so a "storage" row carries direction "output" and no data_domains, and its is_connected reports the workspace's own file-drop connection, never the drive's separate invoice-source connection. Pass q to name-search the full catalog. Omit all of them for the curated, matched-first view. Use well_list_connector_tools for a live connection's actions.

Country: pass country (ISO 3166-1 alpha-2, e.g. "FR") on a connect-a-bank step so the banks that serve the company's country sort first, then the ones that serve its region, then the rest. It reorders the page only — no row is dropped, and a country the catalog carries no coverage for is left in place — so a bank the user names is still found with q. Take the country from the workspace identity; omit it when the country is unknown, and the order is unchanged.

Pass from_selection: true for the connect step that FOLLOWS a vendor pick. It returns the connectors behind the counterparties the user picked on the missing-invoices card in this conversation, and NOTHING else: only the picked vendors' connectors, and of those only the ones that can bring an invoice in (reason "picked_vendor"). It offers no accounting or invoicing tool the user did not pick: that offer belongs to its own step, scoped with kind. When the pick leaves no row, the list is empty and the card is not worth drawing. ⚠️ This tool draws its card on EVERY call, the empty one included, so never call it with from_selection to find out whether the pick has a connector behind it. Ask well_get_worklist_status({ worklist: "invoice_sources_for_pick" }) first: it draws nothing, and it reports how many of the picked vendors carry a connector that can bring an invoice in. Make the from_selection call only when that count is above zero. An ABSENT count is not a zero: the probe answers success: false when it could not read the pick at all, so retry it rather than reading its silence as a vendor with no connector. row_count reports the same number back on this result. picked_vendors_filtered counts the picked vendors' connectors that were dropped for bringing no invoices in: when it is above zero, say a filter ran rather than letting a short card read as a pick nobody made. It takes no q and no kind: those browse a catalog, and this names a set already decided. An empty list means this conversation holds no pick for this workspace, or no picked counterparty matched a connector.

Every result carries scope — "catalog", one of the three domains, "upload_surface", "storage", or "picked_vendors" — naming what the list IS. The card words its title from that field, so a caller must not describe the result as a domain the scope does not name.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qNoName search across the full catalog (e.g. a specific bank). Omit for the curated, matched-first view.
kindNoScope the card server-side. Three financial domains: "bank" (every bank and neobank, including the long tail of open-banking institutions, plus the platforms that hold an account like Qonto and Pennylane — never a payroll or billing tool that merely reports transactions), "accounting", and "invoicing". Plus two scopes the server resolves from display categories rather than from a financial domain: "upload_surface", the places invoices ARRIVE (mailboxes, messaging apps, file drives), and "storage", the drives Well FILES INTO (Google Drive, Dropbox, OneDrive). The last two are opposite directions on the same drives, so a workspace can hold both connections and each is offered on its own card. Use this for a connect-a-bank, a connect-where-invoices-arrive or a connect-where-Well-files step instead of filtering the default view yourself. Omit for every connectable connector.
limitNoMax connectors to return (1-100, default 50).
titleNoHeading for the connect card shown to the user, OVERRIDING the wording the card otherwise derives from the scope/kind. Use it to frame the step in its flow (e.g. "Connect your accounting tool for the close"). At most 120 characters. Omit to keep the default wording for the requested kind.
offsetNoNumber of connectors to skip, for paging (default 0).
countryNoThe company's country as an ISO 3166-1 alpha-2 code (e.g. "FR"). When set, the connectors that serve that country sort first, then the ones that serve its region, then the rest — the order only, no row is dropped. Use it on a connect-a-bank step so the banks that fit the company appear first; take it from the workspace identity's country. Omit when the country is unknown, and the order is left unchanged.
subtitleNoSupporting line under the connect card's heading, OVERRIDING the scope-derived subtitle. At most 240 characters. Omit to keep the default wording for the requested kind.
workspace_idNoTarget workspace. This read reports one workspace's own data. Omit it and the token's primary workspace answers, which may not be the one you mean; the result names the workspace that did.
from_selectionNoScope the card to the connectors behind the counterparties the user picked on the missing-invoices card in this conversation, each installable one pre-checked. Use it for the connect step that FOLLOWS a vendor pick. It returns those vendors' connectors and NOTHING else: a picked connector that brings no invoices in is dropped, and no accounting or invoicing tool the user did not pick is offered here: that offer is its own step, scoped with `kind`. Cannot be combined with `q` or `kind`: those name a catalog to browse, and this names a set already decided. Returns an empty list when this conversation holds no pick for this workspace, or when no picked counterparty matched a connector.
conversation_idNoThe 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.
include_unsent_countsNoAdd the top-level `unsent_document_counts`: every tool Well forwards this workspace's documents to, each with how many documents it has not received yet. That array is the whole answer — it holds every one of the workspace's outbound connections, whatever catalog page was requested, and the rows carry no count at all. Off by default, because it costs an extra read. The figure is the workspace's whole backlog, not a period's.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNo
limitNoThe page size that was REQUESTED. The catalog may return fewer.
scopeNoWhat this result is a list OF: the requested kind, the picked vendors' connectors, or the curated catalog when neither was asked for. The card words itself from this, so it never describes the rows as a domain that was not requested.
totalNoEvery connector matching the query, across all pages — NOT the length of `connectors`.
offsetNoHow many catalog rows this page skipped.
successYes
next_stepNoWhat to do with the card this result renders. Added by the dispatcher when the card asks for a click.
row_countNoHow many rows this result puts ON THE CARD, prepended rows included. `0` on a `picked_vendors` scope means the pick has no connector behind it that can bring an invoice in: the card carries nothing to tick, so say so in half a sentence and move on. Not a paging cursor — `page_count` is.
connectorsNo
page_countNoThe catalog page's own length, and the ONLY safe paging cursor: advance by `offset + page_count`. `connectors` can be LONGER — on the first page of an unsearched browse the workspace's already-connected rows are prepended so they cannot be lost to the catalog's ordering — so paging by the array's length silently skips exactly that many catalog rows on every later request.
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
install_all_urlYesOne link that installs every installable connector in this result. Null when the result offers nothing to install, or when its scope names a set the reader has not chosen. When it is non-null it is the ONLY install link the answer offers — do not list the rows' own install_url beside it. When it is null, the rows' own install_url is the offer instead.
resolved_workspaceNoThe workspace that answered, when the caller named none and the token authorizes several.
install_all_omittedYesThe service ids install_all_url could not carry, because one link names a bounded number of connectors. Offer these rows their own install_url instead of promising the batch link covers them.
conversation_id_noteNoPresent only when the server opened a fresh lane, stating that no choice recorded earlier was read.
conversation_id_sourceNoWhere the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.
unsent_document_countsNoEvery tool this workspace forwards documents to, each with the documents it has not received yet, biggest backlog first. Present only when `include_unsent_counts` was set. THIS IS THE ONLY PLACE THE BACKLOG IS REPORTED: it is not a page, it carries the workspace's whole set of outbound connections whether or not the requested catalog page holds their rows, and the catalog rows carry no count. An empty array means the workspace forwards to nothing; an absent field means nothing was measured. `unsent_document_count_is_upper_bound: true` means a document filter applies to that connection, so the count is a maximum and reads as `up to <n>`. Every count is read off Well's own forward record, so it measures what Well wrote down rather than what the tool confirmed. Name a tool by its `name`. An entry reading `0` is a tool that is up to date: say nothing about it.
picked_vendors_filteredNoHow many of the picked vendors' connectors were dropped for bringing no invoices in. Present on the `picked_vendors` scope only. Above zero means the card is SHORTER than the pick: say that those vendors' tools cannot deliver an invoice, rather than letting the gap read as a pick the user never made.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • addedInput schema / properties / conversation_id
      Added value: +{
      +  "description": "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.",
      +  "type": "string"
      +}
    • changedInput schema / properties / from_selection / description
      Previous value: -"Scope the card to the connectors behind the counterparties the user picked on the missing-invoices card this session, each installable one pre-checked. Use it for the connect step that FOLLOWS a vendor pick. It returns those vendors' connectors and NOTHING else: a picked connector that brings no invoices in is dropped, and no accounting or invoicing tool the user did not pick is offered here — that offer is its own step, scoped with `kind`. Cannot be combined with `q` or `kind` — those name a catalog to browse, and this names a set already decided. Returns an empty list when the session holds no pick for this workspace, or when no picked counterparty matched a connector."New value: +"Scope the card to the connectors behind the counterparties the user picked on the missing-invoices card in this conversation, each installable one pre-checked. Use it for the connect step that FOLLOWS a vendor pick. It returns those vendors' connectors and NOTHING else: a picked connector that brings no invoices in is dropped, and no accounting or invoicing tool the user did not pick is offered here: that offer is its own step, scoped with `kind`. Cannot be combined with `q` or `kind`: those name a catalog to browse, and this names a set already decided. Returns an empty list when this conversation holds no pick for this workspace, or when no picked counterparty matched a connector."
    • addedInput schema / properties / include_unsent_counts
      Added value: +{
      +  "const": true,
      +  "description": "Add the top-level `unsent_document_counts`: every tool Well forwards this workspace's documents to, each with how many documents it has not received yet. That array is the whole answer — it holds every one of the workspace's outbound connections, whatever catalog page was requested, and the rows carry no count at all. Off by default, because it costs an extra read. The figure is the workspace's whole backlog, not a period's.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_note
      Added value: +{
      +  "description": "Present only when the server opened a fresh lane, stating that no choice recorded earlier was read.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_source
      Added value: +{
      +  "description": "Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.",
      +  "enum": [
      +    "host_meta",
      +    "argument",
      +    "minted"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / unsent_document_counts
      Added value: +{
      +  "description": "Every tool this workspace forwards documents to, each with the documents it has not received yet, biggest backlog first. Present only when `include_unsent_counts` was set. THIS IS THE ONLY PLACE THE BACKLOG IS REPORTED: it is not a page, it carries the workspace's whole set of outbound connections whether or not the requested catalog page holds their rows, and the catalog rows carry no count. An empty array means the workspace forwards to nothing; an absent field means nothing was measured. `unsent_document_count_is_upper_bound: true` means a document filter applies to that connection, so the count is a maximum and reads as `up to <n>`. Every count is read off Well's own forward record, so it measures what Well wrote down rather than what the tool confirmed. Name a tool by its `name`. An entry reading `0` is a tool that is up to date: say nothing about it.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "name": {
      +        "type": "string"
      +      },
      +      "service_id": {
      +        "type": "string"
      +      },
      +      "unsent_document_count": {
      +        "maximum": 9007199254740991,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "unsent_document_count_is_upper_bound": {
      +        "type": "boolean"
      +      },
      +      "workspace_connector_id": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "service_id",
      +      "name",
      +      "workspace_connector_id",
      +      "unsent_document_count",
      +      "unsent_document_count_is_upper_bound"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  2. Changed5 schema fields changed
    • changedInput schema / properties / kind / description
      Previous value: -"Scope the card server-side. Three financial domains: \"bank\" (every bank and neobank, including the long tail of open-banking institutions, plus the platforms that hold an account like Qonto and Pennylane — never a payroll or billing tool that merely reports transactions), \"accounting\", and \"invoicing\". Plus \"upload_surface\": the places invoices ARRIVE — mailboxes, messaging apps, file drives — which is a set of display categories rather than a financial domain, resolved by the server. Use this for a connect-a-bank or a connect-where-invoices-arrive step instead of filtering the default view yourself. Omit for every connectable connector."New value: +"Scope the card server-side. Three financial domains: \"bank\" (every bank and neobank, including the long tail of open-banking institutions, plus the platforms that hold an account like Qonto and Pennylane — never a payroll or billing tool that merely reports transactions), \"accounting\", and \"invoicing\". Plus two scopes the server resolves from display categories rather than from a financial domain: \"upload_surface\", the places invoices ARRIVE (mailboxes, messaging apps, file drives), and \"storage\", the drives Well FILES INTO (Google Drive, Dropbox, OneDrive). The last two are opposite directions on the same drives, so a workspace can hold both connections and each is offered on its own card. Use this for a connect-a-bank, a connect-where-invoices-arrive or a connect-where-Well-files step instead of filtering the default view yourself. Omit for every connectable connector."
    • changedInput schema / properties / kind / enum
      Previous value: -[
      -  "bank",
      -  "accounting",
      -  "invoicing",
      -  "upload_surface"
      -]New value: +[
      +  "bank",
      +  "accounting",
      +  "invoicing",
      +  "upload_surface",
      +  "storage"
      +]
    • changedOutput schema / properties / connectors / items / properties / connection_status / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "enabled",
      -      "processing",
      -      "error",
      -      "need_reconnect",
      -      "to_configure",
      -      "suspended",
      -      "disabled"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "enabled",
      +      "processing",
      +      "error",
      +      "need_reconnect",
      +      "to_configure",
      +      "disabled"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedOutput schema / properties / row_count
      Added value: +{
      +  "description": "How many rows this result puts ON THE CARD, prepended rows included. `0` on a `picked_vendors` scope means the pick has no connector behind it that can bring an invoice in: the card carries nothing to tick, so say so in half a sentence and move on. Not a paging cursor — `page_count` is.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / scope / enum
      Previous value: -[
      -  "catalog",
      -  "bank",
      -  "accounting",
      -  "invoicing",
      -  "upload_surface",
      -  "picked_vendors"
      -]New value: +[
      +  "catalog",
      +  "bank",
      +  "accounting",
      +  "invoicing",
      +  "upload_surface",
      +  "storage",
      +  "picked_vendors"
      +]
  3. Changed8 schema fields changed
    • changedInput schema / properties / from_selection / description
      Previous value: -"Scope the card to the connectors behind the counterparties the user picked on the missing-invoices card this session, each installable one pre-checked. Use it for the connect step that FOLLOWS a vendor pick, where the user has already chosen and the card must offer only what they chose. Cannot be combined with `q` or `kind` — those name a catalog to browse, and this names a set already decided. Returns an empty list when the session holds no pick for this workspace, or when no picked counterparty matched a connector."New value: +"Scope the card to the connectors behind the counterparties the user picked on the missing-invoices card this session, each installable one pre-checked. Use it for the connect step that FOLLOWS a vendor pick. It returns those vendors' connectors and NOTHING else: a picked connector that brings no invoices in is dropped, and no accounting or invoicing tool the user did not pick is offered here — that offer is its own step, scoped with `kind`. Cannot be combined with `q` or `kind` — those name a catalog to browse, and this names a set already decided. Returns an empty list when the session holds no pick for this workspace, or when no picked counterparty matched a connector."
    • changedInput schema / properties / kind / description
      Previous value: -"Scope the catalog to one financial domain: \"bank\" (every bank and neobank, including the long tail of open-banking institutions, plus the platforms that hold an account like Qonto and Pennylane — never a payroll or billing tool that merely reports transactions), \"accounting\", or \"invoicing\". Use this for a connect-a-bank or connect-an-accounting-tool step instead of filtering the default view yourself. Omit for every connectable connector."New value: +"Scope the card server-side. Three financial domains: \"bank\" (every bank and neobank, including the long tail of open-banking institutions, plus the platforms that hold an account like Qonto and Pennylane — never a payroll or billing tool that merely reports transactions), \"accounting\", and \"invoicing\". Plus \"upload_surface\": the places invoices ARRIVE — mailboxes, messaging apps, file drives — which is a set of display categories rather than a financial domain, resolved by the server. Use this for a connect-a-bank or a connect-where-invoices-arrive step instead of filtering the default view yourself. Omit for every connectable connector."
    • changedInput schema / properties / kind / enum
      Previous value: -[
      -  "bank",
      -  "accounting",
      -  "invoicing"
      -]New value: +[
      +  "bank",
      +  "accounting",
      +  "invoicing",
      +  "upload_surface"
      +]
    • addedOutput schema / properties / connectors / items / properties / invoice_source
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / connectors / items / properties / reason
      Added value: +{
      +  "enum": [
      +    "catalog",
      +    "picked_vendor"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / properties / connectors / items / required
      Previous value: -[
      -  "service_id",
      -  "name",
      -  "category_id",
      -  "status",
      -  "direction",
      -  "data_domains",
      -  "logo_url",
      -  "popularity_score",
      -  "is_matched",
      -  "is_selected",
      -  "match_score",
      -  "is_connected",
      -  "connection_status",
      -  "workspace_connector_id",
      -  "last_successful_sync_at",
      -  "sync_in_progress",
      -  "is_preselected",
      -  "install_url",
      -  "countries"
      -]New value: +[
      +  "service_id",
      +  "name",
      +  "category_id",
      +  "status",
      +  "direction",
      +  "data_domains",
      +  "invoice_source",
      +  "reason",
      +  "logo_url",
      +  "popularity_score",
      +  "is_matched",
      +  "is_selected",
      +  "match_score",
      +  "is_connected",
      +  "connection_status",
      +  "workspace_connector_id",
      +  "last_successful_sync_at",
      +  "sync_in_progress",
      +  "is_preselected",
      +  "install_url",
      +  "countries"
      +]
    • addedOutput schema / properties / picked_vendors_filtered
      Added value: +{
      +  "description": "How many of the picked vendors' connectors were dropped for bringing no invoices in. Present on the `picked_vendors` scope only. Above zero means the card is SHORTER than the pick: say that those vendors' tools cannot deliver an invoice, rather than letting the gap read as a pick the user never made.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / scope / enum
      Previous value: -[
      -  "catalog",
      -  "bank",
      -  "accounting",
      -  "invoicing",
      -  "picked_vendors"
      -]New value: +[
      +  "catalog",
      +  "bank",
      +  "accounting",
      +  "invoicing",
      +  "upload_surface",
      +  "picked_vendors"
      +]
  4. Changed3 schema fields changed
    • addedInput schema / properties / country
      Added value: +{
      +  "description": "The company's country as an ISO 3166-1 alpha-2 code (e.g. \"FR\"). When set, the connectors that serve that country sort first, then the ones that serve its region, then the rest — the order only, no row is dropped. Use it on a connect-a-bank step so the banks that fit the company appear first; take it from the workspace identity's country. Omit when the country is unknown, and the order is left unchanged.",
      +  "enum": [
      +    "AD",
      +    "AE",
      +    "AF",
      +    "AG",
      +    "AI",
      +    "AL",
      +    "AM",
      +    "AO",
      +    "AQ",
      +    "AR",
      +    "AS",
      +    "AT",
      +    "AU",
      +    "AW",
      +    "AX",
      +    "AZ",
      +    "BA",
      +    "BB",
      +    "BD",
      +    "BE",
      +    "BF",
      +    "BG",
      +    "BH",
      +    "BI",
      +    "BJ",
      +    "BL",
      +    "BM",
      +    "BN",
      +    "BO",
      +    "BQ",
      +    "BR",
      +    "BS",
      +    "BT",
      +    "BV",
      +    "BW",
      +    "BY",
      +    "BZ",
      +    "CA",
      +    "CC",
      +    "CD",
      +    "CF",
      +    "CG",
      +    "CH",
      +    "CI",
      +    "CK",
      +    "CL",
      +    "CM",
      +    "CN",
      +    "CO",
      +    "CR",
      +    "CU",
      +    "CV",
      +    "CW",
      +    "CX",
      +    "CY",
      +    "CZ",
      +    "DE",
      +    "DJ",
      +    "DK",
      +    "DM",
      +    "DO",
      +    "DZ",
      +    "EC",
      +    "EE",
      +    "EG",
      +    "EH",
      +    "ER",
      +    "ES",
      +    "ET",
      +    "FI",
      +    "FJ",
      +    "FK",
      +    "FM",
      +    "FO",
      +    "FR",
      +    "GA",
      +    "GB",
      +    "GD",
      +    "GE",
      +    "GF",
      +    "GG",
      +    "GH",
      +    "GI",
      +    "GL",
      +    "GM",
      +    "GN",
      +    "GP",
      +    "GQ",
      +    "GR",
      +    "GS",
      +    "GT",
      +    "GU",
      +    "GW",
      +    "GY",
      +    "HK",
      +    "HM",
      +    "HN",
      +    "HR",
      +    "HT",
      +    "HU",
      +    "ID",
      +    "IE",
      +    "IL",
      +    "IM",
      +    "IN",
      +    "IO",
      +    "IQ",
      +    "IR",
      +    "IS",
      +    "IT",
      +    "JE",
      +    "JM",
      +    "JO",
      +    "JP",
      +    "KE",
      +    "KG",
      +    "KH",
      +    "KI",
      +    "KM",
      +    "KN",
      +    "KP",
      +    "KR",
      +    "KW",
      +    "KY",
      +    "KZ",
      +    "LA",
      +    "LB",
      +    "LC",
      +    "LI",
      +    "LK",
      +    "LR",
      +    "LS",
      +    "LT",
      +    "LU",
      +    "LV",
      +    "LY",
      +    "MA",
      +    "MC",
      +    "MD",
      +    "ME",
      +    "MF",
      +    "MG",
      +    "MH",
      +    "MK",
      +    "ML",
      +    "MM",
      +    "MN",
      +    "MO",
      +    "MP",
      +    "MQ",
      +    "MR",
      +    "MS",
      +    "MT",
      +    "MU",
      +    "MV",
      +    "MW",
      +    "MX",
      +    "MY",
      +    "MZ",
      +    "NA",
      +    "NC",
      +    "NE",
      +    "NF",
      +    "NG",
      +    "NI",
      +    "NL",
      +    "NO",
      +    "NP",
      +    "NR",
      +    "NU",
      +    "NZ",
      +    "OM",
      +    "PA",
      +    "PE",
      +    "PF",
      +    "PG",
      +    "PH",
      +    "PK",
      +    "PL",
      +    "PM",
      +    "PN",
      +    "PR",
      +    "PS",
      +    "PT",
      +    "PW",
      +    "PY",
      +    "QA",
      +    "RE",
      +    "RO",
      +    "RS",
      +    "RU",
      +    "RW",
      +    "SA",
      +    "SB",
      +    "SC",
      +    "SD",
      +    "SE",
      +    "SG",
      +    "SH",
      +    "SI",
      +    "SJ",
      +    "SK",
      +    "SL",
      +    "SM",
      +    "SN",
      +    "SO",
      +    "SR",
      +    "SS",
      +    "ST",
      +    "SV",
      +    "SX",
      +    "SY",
      +    "SZ",
      +    "TC",
      +    "TD",
      +    "TF",
      +    "TG",
      +    "TH",
      +    "TJ",
      +    "TK",
      +    "TL",
      +    "TM",
      +    "TN",
      +    "TO",
      +    "TR",
      +    "TT",
      +    "TV",
      +    "TW",
      +    "TZ",
      +    "UA",
      +    "UG",
      +    "UM",
      +    "US",
      +    "UY",
      +    "UZ",
      +    "VA",
      +    "VC",
      +    "VE",
      +    "VG",
      +    "VI",
      +    "VN",
      +    "VU",
      +    "WF",
      +    "WS",
      +    "YE",
      +    "YT",
      +    "ZA",
      +    "ZM",
      +    "ZW"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / connectors / items / properties / countries
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / connectors / items / required
      Previous value: -[
      -  "service_id",
      -  "name",
      -  "category_id",
      -  "status",
      -  "direction",
      -  "data_domains",
      -  "logo_url",
      -  "popularity_score",
      -  "is_matched",
      -  "is_selected",
      -  "match_score",
      -  "is_connected",
      -  "connection_status",
      -  "workspace_connector_id",
      -  "last_successful_sync_at",
      -  "sync_in_progress",
      -  "is_preselected",
      -  "install_url"
      -]New value: +[
      +  "service_id",
      +  "name",
      +  "category_id",
      +  "status",
      +  "direction",
      +  "data_domains",
      +  "logo_url",
      +  "popularity_score",
      +  "is_matched",
      +  "is_selected",
      +  "match_score",
      +  "is_connected",
      +  "connection_status",
      +  "workspace_connector_id",
      +  "last_successful_sync_at",
      +  "sync_in_progress",
      +  "is_preselected",
      +  "install_url",
      +  "countries"
      +]
  5. Changed1 schema field changed
    • addedOutput schema / properties / next_step
      Added value: +{
      +  "description": "What to do with the card this result renders. Added by the dispatcher when the card asks for a click.",
      +  "type": "string"
      +}
  6. Changed4 schema fields changed
    • addedOutput schema / properties / limit / description
      Added value: +"The page size that was REQUESTED. The catalog may return fewer."
    • addedOutput schema / properties / offset / description
      Added value: +"How many catalog rows this page skipped."
    • addedOutput schema / properties / page_count
      Added value: +{
      +  "description": "The catalog page's own length, and the ONLY safe paging cursor: advance by `offset + page_count`. `connectors` can be LONGER — on the first page of an unsearched browse the workspace's already-connected rows are prepended so they cannot be lost to the catalog's ordering — so paging by the array's length silently skips exactly that many catalog rows on every later request.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / total / description
      Added value: +"Every connector matching the query, across all pages — NOT the length of `connectors`."
  7. Changed7 schema fields changed
    • addedInput schema / properties / subtitle
      Added value: +{
      +  "description": "Supporting line under the connect card's heading, OVERRIDING the scope-derived subtitle. At most 240 characters. Omit to keep the default wording for the requested kind.",
      +  "maxLength": 240,
      +  "type": "string"
      +}
    • addedInput schema / properties / title
      Added value: +{
      +  "description": "Heading for the connect card shown to the user, OVERRIDING the wording the card otherwise derives from the scope/kind. Use it to frame the step in its flow (e.g. \"Connect your accounting tool for the close\"). At most 120 characters. Omit to keep the default wording for the requested kind.",
      +  "maxLength": 120,
      +  "type": "string"
      +}
    • changedInput schema / properties / workspace_id / description
      Previous value: -"Target workspace. Omit to use the only authorized workspace, or (for read tools) to query all authorized workspaces grouped by workspace. Required for write tools when the token authorizes more than one workspace."New value: +"Target workspace. This read reports one workspace's own data. Omit it and the token's primary workspace answers, which may not be the one you mean; the result names the workspace that did."
    • addedOutput schema / properties / install_all_omitted
      Added value: +{
      +  "description": "The service ids install_all_url could not carry, because one link names a bounded number of connectors. Offer these rows their own install_url instead of promising the batch link covers them.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / install_all_url
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "One link that installs every installable connector in this result. Null when the result offers nothing to install, or when its scope names a set the reader has not chosen. When it is non-null it is the ONLY install link the answer offers — do not list the rows' own install_url beside it. When it is null, the rows' own install_url is the offer instead."
      +}
    • addedOutput schema / properties / resolved_workspace
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The workspace that answered, when the caller named none and the token authorizes several.",
      +  "properties": {
      +    "name": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "workspace_id": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "workspace_id",
      +    "name"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "success"
      -]New value: +[
      +  "install_all_url",
      +  "install_all_omitted",
      +  "success"
      +]
  8. Changed2 schema fields changed
    • addedInput schema / properties / from_selection
      Added value: +{
      +  "const": true,
      +  "description": "Scope the card to the connectors behind the counterparties the user picked on the missing-invoices card this session, each installable one pre-checked. Use it for the connect step that FOLLOWS a vendor pick, where the user has already chosen and the card must offer only what they chose. Cannot be combined with `q` or `kind` — those name a catalog to browse, and this names a set already decided. Returns an empty list when the session holds no pick for this workspace, or when no picked counterparty matched a connector.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / scope
      Added value: +{
      +  "description": "What this result is a list OF: the requested kind, the picked vendors' connectors, or the curated catalog when neither was asked for. The card words itself from this, so it never describes the rows as a domain that was not requested.",
      +  "enum": [
      +    "catalog",
      +    "bank",
      +    "accounting",
      +    "invoicing",
      +    "picked_vendors"
      +  ],
      +  "type": "string"
      +}
  9. Changed6 schema fields changed
    • addedInput schema / properties / kind
      Added value: +{
      +  "description": "Scope the catalog to one financial domain: \"bank\" (every bank and neobank, including the long tail of open-banking institutions, plus the platforms that hold an account like Qonto and Pennylane — never a payroll or billing tool that merely reports transactions), \"accounting\", or \"invoicing\". Use this for a connect-a-bank or connect-an-accounting-tool step instead of filtering the default view yourself. Omit for every connectable connector.",
      +  "enum": [
      +    "bank",
      +    "accounting",
      +    "invoicing"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / properties / connectors / items / properties / connection_status / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "enabled",
      -      "processing",
      -      "error"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "enabled",
      +      "processing",
      +      "error",
      +      "need_reconnect",
      +      "to_configure",
      +      "suspended",
      +      "disabled"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedOutput schema / properties / connectors / items / properties / data_domains
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "enum": [
      +          "bank",
      +          "accounting",
      +          "invoicing"
      +        ],
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / connectors / items / properties / last_successful_sync_at
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / connectors / items / properties / sync_in_progress
      Added value: +{
      +  "type": "boolean"
      +}
    • changedOutput schema / properties / connectors / items / required
      Previous value: -[
      -  "service_id",
      -  "name",
      -  "category_id",
      -  "status",
      -  "direction",
      -  "logo_url",
      -  "popularity_score",
      -  "is_matched",
      -  "is_selected",
      -  "match_score",
      -  "is_connected",
      -  "connection_status",
      -  "workspace_connector_id",
      -  "is_preselected",
      -  "install_url"
      -]New value: +[
      +  "service_id",
      +  "name",
      +  "category_id",
      +  "status",
      +  "direction",
      +  "data_domains",
      +  "logo_url",
      +  "popularity_score",
      +  "is_matched",
      +  "is_selected",
      +  "match_score",
      +  "is_connected",
      +  "connection_status",
      +  "workspace_connector_id",
      +  "last_successful_sync_at",
      +  "sync_in_progress",
      +  "is_preselected",
      +  "install_url"
      +]
  10. Changed2 schema fields changed
    • addedOutput schema / properties / connectors / items / properties / workspace_connector_id
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / connectors / items / required
      Previous value: -[
      -  "service_id",
      -  "name",
      -  "category_id",
      -  "status",
      -  "direction",
      -  "logo_url",
      -  "popularity_score",
      -  "is_matched",
      -  "is_selected",
      -  "match_score",
      -  "is_connected",
      -  "connection_status",
      -  "is_preselected",
      -  "install_url"
      -]New value: +[
      +  "service_id",
      +  "name",
      +  "category_id",
      +  "status",
      +  "direction",
      +  "logo_url",
      +  "popularity_score",
      +  "is_matched",
      +  "is_selected",
      +  "match_score",
      +  "is_connected",
      +  "connection_status",
      +  "workspace_connector_id",
      +  "is_preselected",
      +  "install_url"
      +]
  11. Changed2 schema fields changed
    • addedOutput schema / properties / connectors / items / properties / connection_status
      Added value: +{
      +  "anyOf": [
      +    {
      +      "enum": [
      +        "enabled",
      +        "processing",
      +        "error"
      +      ],
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / connectors / items / required
      Previous value: -[
      -  "service_id",
      -  "name",
      -  "category_id",
      -  "status",
      -  "direction",
      -  "logo_url",
      -  "popularity_score",
      -  "is_matched",
      -  "is_selected",
      -  "match_score",
      -  "is_connected",
      -  "is_preselected",
      -  "install_url"
      -]New value: +[
      +  "service_id",
      +  "name",
      +  "category_id",
      +  "status",
      +  "direction",
      +  "logo_url",
      +  "popularity_score",
      +  "is_matched",
      +  "is_selected",
      +  "match_score",
      +  "is_connected",
      +  "connection_status",
      +  "is_preselected",
      +  "install_url"
      +]
  12. Changed4 schema fields changed
    • addedOutput schema / properties / connectors / items / properties / is_connected
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / connectors / items / properties / is_preselected
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / connectors / items / properties / match_score
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / connectors / items / required
      Previous value: -[
      -  "service_id",
      -  "name",
      -  "category_id",
      -  "status",
      -  "direction",
      -  "logo_url",
      -  "popularity_score",
      -  "is_matched",
      -  "is_selected",
      -  "install_url"
      -]New value: +[
      +  "service_id",
      +  "name",
      +  "category_id",
      +  "status",
      +  "direction",
      +  "logo_url",
      +  "popularity_score",
      +  "is_matched",
      +  "is_selected",
      +  "match_score",
      +  "is_connected",
      +  "is_preselected",
      +  "install_url"
      +]
  13. First observed

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool readOnly and non-destructive, so the bar is lower; the description adds critical behavior beyond those hints: 'This tool draws its card on EVERY call, the empty one included', it waits on the turn that drew it, and it explains status semantics like to_configure/disabled and the server-side resolution of 'degraded'. This materially changes how an agent should sequence calls.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but it is front-loaded with the highest-stakes warnings (card rendering, silent alternative, wait protocol) and organized into scoping, paging, per-field, and top-level-field sections. Some admonitions repeat, so it is not a model of brevity, but nearly every sentence carries operational weight given the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 11 optional parameters, complex connection-status semantics, top-level fields, paging behavior, and sibling interactions, the description is exhaustive: every status, null case, scope, and edge condition is covered. An agent has enough to call it correctly and interpret the result without external knowledge.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds flow-level meaning beyond the schema: from_selection is the step that FOLLOWS a vendor pick, country reorders but never drops rows, kind: storage is the output direction versus upload_surface, and include_unsent_counts exposes the whole backlog independent of the page. These are not inferable from the parameter names alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with a specific verb and resource: 'List the connectors a workspace can install AND everything it has already connected, each with a one-click install deep link.' It names the card-drawing side effect and distinguishes itself from well_get_connector_coverage and well_list_connector_tools, so an agent can tell it apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool versus alternatives: 'Do NOT read workspace_connectors records to work out connection coverage; this tool is that answer', routes silent checks to well_get_connector_coverage, vendor-pick probes to well_get_worklist_status, and live-connection actions to well_list_connector_tools. It also instructs the agent to call well_wait_for_selection in the turn that drew the card.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources