---
title: codespar_discover
description: Find the right tool for a free-form use case. Returns the recommended catalog tool with its connection status, pitfalls, plan and related tools, plus any native meta-tool that covers the same job.
---

import { Callout } from "fumadocs-ui/components/callout";
import { Tabs, Tab } from "fumadocs-ui/components/tabs";

<MetaToolHeader tool="codespar_discover" />

Use it when you do not already know the canonical tool name to call. When a native meta-tool comes back in `meta_tools`, prefer it.

## Actions

<MetaToolActions tool="codespar_discover" />

## Example

<Split min={380}>
<SplitPane label="Call · tools/call">

```json title="arguments"
{
  "name": "codespar_discover",
  "arguments": {
    "use_case": "send a Pix to a supplier",
    "country": "BR",
    "limit": 5
  }
}
```

</SplitPane>
<SplitPane label="Result · fields the tool document names">

```json title="result"
{
  "meta_tools": ["codespar_pay"]
}
```

Alongside `meta_tools`, the tool document says the result carries the recommended catalog tool, its connection status, known pitfalls, a recommended plan and related tools; it does not name those fields. Full shape: see runtime, via [`/v1/meta-tools.json`](https://api.codespar.dev/v1/meta-tools.json).

</SplitPane>
</Split>

## When to use

- **An open intent** ("buy a TV", "save my address", "send a Pix") before you know which tool does it. `buy a TV` surfaces `codespar_shop`, `send a Pix` surfaces `codespar_pay`, `save my address` surfaces `codespar_manage_connections`.
- **Once per intent**, then cache the answer for the conversation: the call queries the live catalog and the embedding index and counts as a [tool call](/docs/concepts/billing).
- **Paired with [`codespar_manage_connections`](/docs/concepts/meta-tools/manage-connections)** when the best match is not connected: discover finds the tool, manage_connections tells you whether this user can reach it and hands back the connect flow if not.
- **Not for setup questions.** "How do I start / what can you do" is [`codespar_get_started`](/docs/concepts/meta-tools/get-started), which returns the ordered happy path for the workspace without a discovery detour.

## Arguments

| Field | Type | Required | Description |
|---|---|---|---|
| `use_case` | `string` | Yes | Free-form description of what you want to accomplish ("send an email", "create a Pix payment"). Describe the intent, not the tool name |
| `category` | `string` | No | Optional category filter |
| `country` | `string` | No | ISO 3166-1 alpha-2, or `*` for any |
| `limit` | `number` | No | Max related tools returned, 1..20, default 5 |

## Errors and what to do

| Error | Cause | What to do |
|---|---|---|
| `invalid_args` | `use_case` missing. | Pass a sentence describing the intent. |
| A best match that is not connected | The ranked results are biased toward providers the session has already connected, but the top match can still be unconnected. | Check it with `codespar_manage_connections` `status`, and surface the connect flow from `initiate`. |

## Money and mandate

Nothing moves. The call reads the catalog index in the CodeSpar backend; no provider is called and no mandate is involved. The tools it recommends have their own gates.

## Related

- [`codespar_get_started`](/docs/concepts/meta-tools/get-started): the happy path when the question is about setup
- [`codespar_manage_connections`](/docs/concepts/meta-tools/manage-connections): check and unblock the recommended tool
- [SDK reference, discover](/docs/api/sdk/session#discoverquery-promisediscoverresult): the typed wrapper
- [Tool router](/docs/concepts/tool-router): how the catalog is scored at execute time

## Notes

**Two-stage retrieval, as previously documented.** Semantic first (the query is embedded with OpenAI `text-embedding-3-small`, 1536 dimensions, and cosine-ranked against `mcp_tools.embedding`), then a `pg_trgm` lexical fallback over `tool_name + description` when the semantic pass returns thin results. Ranking is biased toward connected providers: a connected match outranks a higher-scoring unconnected match at the margin, on purpose. Operators populate the embedding column with the `embed-mcp-tools.ts` seed script, which is idempotent (it re-embeds only rows whose `description_hash` changed); the managed-tier runbook covers re-embedding when the catalog changes. No tenant stamps an OpenAI key for this; the embeddings call is on CodeSpar's side.

**Result shape (SDK), as previously documented.** `session.discover(query)` returned `{ matches: Array<{ tool_name, server_id, score, description, connected }> }`. That wrapper takes a query string; the MCP tool takes `use_case`. This revision did not re-verify the list against the runtime, and the MCP result is not documented to have the same shape (the tool document names `meta_tools`).

**From the SDK.** `session.discover("emit a Pix QR code for a buyer in Brazil")` in TypeScript, `session.discover(...)` in Python; or `session.execute("codespar_discover", arguments)` with the same arguments as the MCP call.
