`discover` is the first control tool. Search in plain language for the job, not the provider. The response gives an agent enough information to choose a catalog tool without loading every provider integration.

## Signature

```text
discover({ query, limit? })
```

Input fields:

| Field | Type | Required | Meaning |
| --- | --- | --- | --- |
| `query` | string | yes | The outcome or job in plain language. |
| `limit` | integer, 1–50 | no | Maximum matches; the server defaults to 10. |

Example request:

```json
{
  "name": "discover",
  "arguments": {
    "query": "scrape the text of a web page",
    "limit": 5
  }
}
```

## Return shape

The result includes the normalized query, a count, provider-neutral `capabilities`, bounded `tools` nested under each capability, `providers`, and a legacy flat `results` projection. Public price fields remain USD decimal strings; display fields are derived by the server.

```json
{
  "query": "scrape the text of a web page",
  "count": 1,
  "capabilities": [
    {
      "id": "<capability id>",
      "name": "<provider-neutral job>",
      "tools": [{ "tool_id": "<catalog tool id>" }]
    }
  ],
  "next_step": "Call inspect with the tool_id you want."
}
```

Only published, live and unarchived records appear. If there are no matches, rephrase the outcome; do not switch to guessing provider names or ids.

## Common errors

- Missing or blank `query`: send a non-empty string.
- Invalid `limit`: send an integer from 1 through 50.
- Zero matches: change the job description and search again.

`discover` is read-only. Choose a returned `tool_id` and continue to [inspect](https://scrollport.com/docs/control-tools/inspect).