Skip to main content
Glama

List counterparties

well_list_counterparties
Read-only

List the workspace's counterparty companies and how each one is CATEGORIZED — the company-level industry labels a counterparty carries. Use it for "which suppliers have no category?", "what industries are my counterparties in?", and before categorizing a counterparty so you name real ids instead of guessing.

Name a scope, and say whether to keep only the ones missing a category:

  • periods: [{ calendar_year, calendar_month }, …] (1-12): the counterparties whose invoices those months are still missing, categorized ones included, each row tagged with its month and carrying tx_count, base_total_amount in base_currency, and suggested_retrieval. Every month must have ended.

  • periods PLUS uncategorized_only: true: the same months, keeping ONLY the counterparties that carry no category. Use this whenever the question is which of a period's suppliers still need one, and whenever a step asks the user to categorize them: the categorized ones are not the work, and listing them buries it.

  • uncategorized_only: true alone: a WORKSPACE-WIDE sweep for every counterparty that carries no category, no month involved. Returns 50 rows per page plus total_count; tx_count, base_total_amount and suggested_retrieval are null because the call names no period. When next_cursor is not null the sweep has more counterparties: call again with cursor set to it to read them. It is a POSITION, not a row offset, so categorizing the rows of one page never hides the rows of the next. Only this sweep pages: cursor is refused beside periods.

COST: the period form has no batch endpoint, so each named month is a separate read of that month's spend. Ask for the months the user actually named, not a whole year "to be safe".

Every row carries categories ([{ category_id, name }]) and is_categorized. categorized_count and uncategorized_count count the COUNTERPARTIES OF THE SCOPE, once each however many months they appear in, not the rows returned. Under uncategorized_only the result lists the uncategorized ones alone while categorized_count still counts the ones it withheld, so the two together are the period's coverage and uncategorized_count is the work left. Report both: naming the listed rows as the period's whole counterparty set overstates how much is uncategorized.

TO SET a counterparty's categories, call well_update_company({ company_id, category_ids: [...] }) — that field REPLACES the company's whole set. Read the available labels first with well_query_records({ root: "categories", whereClause: { category_type: { _eq: "company" } } }): that is the company-category catalog. It has no curated allowlist — the labels are minted during enrichment — so pass ids from it rather than inventing a taxonomy.

suggested_retrieval is derived from the PROVIDER match, not from the category. Categorizing a counterparty does not change it; do not tell the user otherwise.

This tool only reads. It categorizes nothing, mints no task, connects nothing and fetches no invoice.

Call this directly — no other tool call is needed first (workspace is resolved from the caller's authorized token, same as every other well_* tool).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cursorNoThe next page of the workspace-wide uncategorized sweep: pass back the `next_cursor` the previous call returned. Only that sweep pages, so this needs `uncategorized_only: true` and NO `periods`, because a period scope returns every month it covers in one call.
periodsNoThe calendar months whose counterparties to list, 1-12. Each month costs one separate read of that month's spend. Duplicates are refused.
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.
uncategorized_onlyNoKeep only the counterparties that carry no industry category. WITH `periods`: the uncategorized counterparties OF those months. Use it whenever the question is which of a period's suppliers still need a category. WITHOUT `periods`: a WORKSPACE-WIDE sweep for every uncategorized counterparty, 50 rows per page plus the total, with a `next_cursor` for the page after this one.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeNoWhich SCOPE the call asked for; the row fields that are populated follow from it. `periods` whenever the call named months, whether or not it also filtered to the uncategorized ones.
rowsYes
errorNo
hintsNo
successYes
row_countNo
next_cursorNoThe uncategorized sweep's next page: pass it back as `cursor`. Null when this page ends the sweep, absent on the periods scope, which pages nothing.
total_countNoCounterparties MATCHING the call, before the row cap, so a capped sweep says what it left out. On the periods scope: the DISTINCT counterparties `rows` names, and a multi-month call lists one counterparty on one row per month, so row_count can exceed it. Under `uncategorized_only` it counts the uncategorized ones alone; the scope's whole population is `categorized_count` plus `uncategorized_count`.
workspace_idNo
base_currencyNo
periods_coveredNoThe months the result covers, oldest first.
categorized_countNoCOUNTERPARTIES of the scope that carry at least one category, counted over the whole scope, not over `rows`, and counted once however many months a counterparty appears in. Under `uncategorized_only` these are exactly the counterparties the result withheld, so a non-zero figure beside rows that are all uncategorized is the coverage, not a contradiction.
resolved_workspaceNoThe workspace that answered, when the caller named none and the token authorizes several.
uncategorized_onlyNoWhether `rows` holds ONLY the counterparties that carry no category. True on the workspace-wide sweep and on a period scope the call filtered. When true, `categorized_count` counts counterparties the result did NOT list.
uncategorized_countNoCOUNTERPARTIES of the scope that carry none, counted the same way. This is the outstanding work; with `categorized_count` it is the scope's whole population.

TDQS

A5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint and destructiveHint, but the description goes well beyond them: it states the tool only reads and categorizes nothing, mints no task, and fetches no invoice. It discloses the per-month cost, the cursor-as-position paging semantics, the distinction between row counts and counterparty counts, and the fact that suggested_retrieval is provider-derived and unaffected by categorization. This adds substantial behavioral context beyond the structured annotations.

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

Conciseness5/5

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

The description is long but every paragraph earns its place: it front-loads the core purpose, structures the three modes clearly, and packs warnings and constraints into distinct labeled sections. The length is justified by the tool's combinatorial parameter behavior and the many traps an agent could otherwise fall into.

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?

Given the tool's complexity, the 100% schema coverage, and the presence of an output schema, the description is complete. It covers all parameter combinations, paging behavior, cost implications, count semantics, null-value behavior, and the relevant sibling calls for adjacent operations. Nothing an agent needs to invoke this tool correctly appears to be missing.

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?

Although schema coverage is 100%, the description adds significant semantic meaning by explaining how periods, uncategorized_only, and cursor combine into three valid usage modes. It clarifies that cursor is refused with periods, that periods accept 1-12 months with each month costing a separate read, and that uncategorized_only alone triggers a paged workspace-wide sweep. This goes far beyond the input schema's field-level descriptions.

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?

The description explicitly states the tool lists the workspace's counterparty companies and their company-level industry categories, with a specific verb and resource. It clearly differentiates the three modes (period, period+uncategorized_only, workspace-wide sweep) and distinguishes this tool from category-setting and catalog-reading siblings.

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?

The description gives explicit when-to-use guidance: use it for finding uncategorized suppliers, use uncategorized_only for work-remaining questions, use the sweep for workspace-wide checks, and do not use it to set categories or read the label catalog. It also names the exact sibling calls well_update_company and well_query_records for those adjacent needs, and states that no prerequisite call is required.

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.

TDQS

A4.5/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: CRUD for companies, people, and invoices; financial analytics (cash, cost, runway, holdings); connector management and invocation; schema discovery; querying; reconciliation; and contact channel management. No two tools could be confused for the same action.

Naming Consistency5/5

All tools follow the `well_verb_noun` pattern with consistent verb choices (create, get, list, update, delete, add, remove, run, resolve, query, invoke). The naming is predictable and makes the tool's purpose immediately clear.

Tool Count4/5

With 26 tools, the set is slightly above the ideal 3-15 range, but every tool earns its place given the breadth of the domain (CRM, invoicing, financial analytics, reconciliation, connector management). The count is well-scoped and not excessive.

Completeness4/5

The tool surface covers core CRUD, financial KPIs, reconciliation, and connector management. Minor gaps exist (e.g., no direct tool to update contact channels or manage accounts), but the query and schema tools allow agents to work around them, and the primary workflows are fully supported.

Resources