Skip to main content
Glama

waterfall_tech_act

Destructive

Run the tech stack waterfall over a TABLE's rows, on the server — op update_rows. Nothing personal goes through this call, and nothing found comes back: name the rows and the columns once, oto reads each row, runs the same cascade as waterfall_tech and writes the find into the row.

Cheaper than one call per row: only rows whose status_column is empty are taken, and each gets found (its provider in the status comment), no_match or failed — so a row is never paid twice; call again with the same arguments until remaining is 0 (clear a status to retry that row). no_match is written only when a provider answered without finding and none failed: a row whose steps failed or never ran stays empty, its code in errors. Rows with the same inputs share ONE lookup. Up to 8 rows run in parallel; a call that runs out of time says stopped: "time_budget" and leaves the rest pending. ⚠️ The asynchronous steps (none) are left out here — they would answer after the row is written; the one-contact tool collects them. The answer is counts plus errors: [{row_id, code}]; dry_run reads the rows, counts the lookups and returns the first one's plan, calling nothing. From a hosted agent, a step whose tool the agent may not call is skipped and its rows stay pending (tool_not_in_job, not a quota): the answer then names them (missing_tools) with the owner's one-click fix.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "op": "<op>",
      "datastore": "<datastore>",
      "inputs": "<inputs>",
      "output": "<output>",
      "status_column": "<status_column>"
    },
    "name": "waterfall_tech_act"
  }
}

Input Schema

NameRequiredDescriptionDefault
opYes`update_rows`.
_orgNoOrg (id) de CET APPEL. `oto_list_orgs()`.
rolesNo
_groupNoÉquipe (id) de CET APPEL, sous son org parente.
filterNodata_rows filter grammar; `{}` = every row not yet treated.
inputsYes{input: column} — inputs are `domain`, `company_name`. Map every column you have: more inputs open more (and cheaper) steps.
outputYes{field of the find: column} — `technologies`, `count`, `source` (website | vendor_database | job_postings), `by_category`, `matched` (with `technologies`), or `provider`.
_run_idNoOBLIGATOIRE à chaque appel dès `run_start` ou `data_claim_next` : sans lui, l'écriture sur une ligne réservée est refusée. Hérité seulement si le serveur tient un run actif — n'y compte pas.
dry_runNoread and plan only — nothing called, nothing written.
qualifyNo
row_idsNothe rows to run (at most 50). Exclusive with `filter`.
_projectNoProjet (id) de CET APPEL — jeton PRIMAIRE. `oto_project(op='list')`.
_instanceNoInstance de connecteur PRÉCISE (un credential exact). `oto_instance(op='list')`.
datastoreYesthe table, by name or number.
providersNothe steps to try, in order, for these rows (see `waterfall_tech`).
batch_sizeNorows per call with `filter` (1-50, default 25).
qualify_minNo
technologiesNoas on `waterfall_tech`, the same for every row — a row is `found` only when one of them is detected, `no_match` when none is.
apify_max_usdNo
status_columnYeswhere found | no_match | failed is written.
max_paid_stepsNo
people_per_rowNo

Schema Changelog

Changes observed during successful MCP inspections.

No schema history has been recorded yet.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and openWorldHint=true, and the description adds substantial beyond-schema behavior: what gets written where (`found`/`no_match`/`failed` in `status_column`), the exact rule preventing double payment, the dedup rule (same inputs share ONE lookup), 8-row parallelism, time-budget truncation (`stopped: "time_budget"`), and that `no_match` is only written when a provider answered and none failed. Nothing contradicts the annotations — the write behavior is consistent with destructiveHint=true.

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

Conciseness3/5

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

The main idea and the retry loop are front-loaded, but the body is a single dense block with nested parentheticals and long clauses (e.g. the `no_match` rule spans two sentences with an internal colon-and-appositive construction). Every sentence carries information, yet the formatting makes it harder to scan than it needs to be for a 22-parameter tool.

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

Completeness4/5

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

For a complex batch mutation with no output schema, the description covers the return shape (counts plus `errors: [{row_id, code}]`), `remaining`, the `stopped` sentinel, and the hosted-agent `missing_tools` path, which is what an agent needs to drive the call-until-done loop. The remaining gap is the handful of unexplained tuning parameters (`apify_max_usd`, `max_paid_steps`, `people_per_row`).

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

Parameters3/5

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

Schema coverage is 73%, so the baseline is 3. The description does add real meaning for `status_column`, `inputs`/`output`, `filter` vs `row_ids` exclusivity, and `dry_run`, but several parameters — `people_per_row`, `apify_max_usd`, `max_paid_steps`, `qualify`, `qualify_min` — are neither explained here nor documented in the schema, so it does not fully compensate for the gap.

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 first line states a specific verb and resource — run the tech stack waterfall over a TABLE's rows on the server via `op: update_rows` — and immediately differentiates from the single-row sibling by naming `waterfall_tech` and calling this 'Cheaper than one call per row.' An agent can tell exactly which of the waterfall_* family to pick without opening a schema.

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?

It gives explicit operating instructions: call again with the same arguments until `remaining` is 0, clear a status to retry a row, use `dry_run` to plan without calling anything, and only rows with empty `status_column` are consumed. It also names the alternative for the async-step case ('the one-contact tool collects them') and the hosted-agent fallback (`tool_not_in_job`, `missing_tools`, `fix`).

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