Cadence
Reference

Search

How a search matches tasks and docs, and what each way in returns.

Cadence searches a space's tasks and docs by their title and body. The same matching rules apply on every way in, so this page states them once. The ways in differ in what they return, and in one matching detail: the browser trims the query before searching (see How you mark the last word as finished).

Every search needs read on the space.

Ways in

  • MCP tasks_search searches tasks. Pass space_key, the query as q, and optionally limit (1 to 100, default 25). See Tasks § Search tasks.
  • MCP docs_search searches docs. Pass space_key, the query as query, and optionally limit (1 to 100, default 25). See Docs.

The two tools name their query argument differently: q for tasks and query for docs. There is no MCP tool that searches tasks and docs together.

In the browser:

Over the HTTP API:

  • GET /api/v1/spaces/:space_key/search searches tasks and docs together. See The combined search endpoint below.
  • GET /api/v1/spaces/:space_key/docs/search searches docs only. See Docs.

Archived tasks and archived docs are never returned. A doc is found only through its published version: a doc that has never been published, or whose published version has been taken down, is not returned.

How a query matches

Tasks and docs are matched the same way.

You can type phrases in quotes ("release notes") or plain words. Cadence matches whole words by their stem, so deploying also finds deploy and deployed.

OR between words works only once the last word is finished, as described at the end of this section. Otherwise the last word is matched on its own as a prefix and must also be present: deploy OR rollback finds only tasks and docs that contain both deploy and a word starting with rollback. Over MCP and the HTTP API, end the query with a space to make OR apply, for example deploy OR rollback with a trailing space. In the browser, end it with a punctuation mark instead, such as deploy OR rollback.

The last word matches as a prefix. Cadence treats the last word of a query as unfinished, so it matches any word that starts with it. deplo finds a task that says deploy, and rollback deplo finds one that says both rollback and deploy. The results appear before you have finished typing the word.

The prefix is matched against stems. Cadence stores words by their stem, and the prefix has to be the start of that stem. A task that says deploying is stored under deploy. deplo and deploy find it, but deployi does not, because no stored word starts with deployi. If a search stops finding something as you type, the word has gone past its stem. Finish the word, or delete back to its stem.

A hyphenated last word matches whole. When the last word is joined to the one before it by a hyphen, such as blue-green or rel-7, Cadence matches the whole hyphenated word and does not treat it as a prefix.

A query shorter than 2 characters returns nothing. Cadence trims spaces from both ends of the query, then counts what is left. A 1-character query returns no results.

How you mark the last word as finished depends on the way in.

  • Over MCP and the HTTP API, Cadence keeps the query exactly as you send it. End the query with a space, a closing " or a punctuation mark, and the last word matches whole words only: roll (with a trailing space) does not find rollback, while roll does.
  • The browser's search window and docs search page trim the query before searching. A trailing space therefore does not finish the last word there. Only a closing " or a punctuation mark does.

Finding a task by its key

This applies to task search only: MCP tasks_search, the browser's search window, and the combined HTTP endpoint.

If the whole query is a task's KEY-N id, such as OPS-42, Cadence returns that task first, ahead of every other match. Case does not matter: ops-42 finds the same task. The task appears only once, so if its title or body also matches the query, it is not repeated further down.

A key finds a task only when:

  • the task is in the space you are searching. A key from another space finds nothing by key.
  • the task is not archived.

Over MCP, a lease (the grant a worker holds while it works a task) still sees only the tasks its scope covers, so a keyed task outside that scope is not returned. See Leases § What a lease can reach.

The task found by key has no snippet ("snippet": null). Its rank is higher than every other task in the results. It takes one of the limit places, so a search with limit 10 returns the keyed task and at most 9 more.

Doc search has no key lookup. docs_search and the docs search endpoint treat a key like any other text.

Snippets

Each match carries a snippet: one excerpt of about 5 to 20 words from the task's or doc's body, with the matched words wrapped in <mark> and </mark>. A hit that matched only on its title has no <mark> in its snippet. The excerpt is plain text. Markdown syntax such as headings, links and emphasis is removed before the excerpt is taken.

A task's snippet reflects its body as last saved. A doc's snippet comes from its published version, so text that exists only in a draft is not searched and does not appear.

Highlighted titles

The browser's search window and docs search page also highlight the matched words in each result's title. MCP and the HTTP API do not return a highlighted title. They return the task or doc itself, with its plain title.

The combined search endpoint

GET /api/v1/spaces/:space_key/search searches a space's tasks and docs in one request. Needs read. Pass the query as q, and optionally a limit:

curl "https://cadence.example.com/api/v1/spaces/OPS/search?q=OPS-42" \
  -H "Authorization: Bearer smc_your_token_here"

The response is a flat list. Each row carries a type of task or doc, the matching task or doc (without its body), a snippet, and a rank.

All task rows come first, then all doc rows. Cadence ranks tasks and docs separately, and each block is ordered by its own rank, highest first. A task's rank and a doc's rank are not on the same scale, so compare rank only between rows of the same type. Do not sort the whole list by rank.

limit applies to each type separately. It defaults to 25 and is capped at 100. With limit=10 you get up to 10 task rows and up to 10 doc rows, so up to twice limit rows in total. A type with no matches contributes no rows.

This example searched for a task key. The keyed task leads the task block with no snippet, another task that mentions the key follows it, and then the doc block:

{
  "results": [
    { "type": "task", "task": { "key": "OPS-42", "…": "…" }, "snippet": null, "rank": 1.6 },
    { "type": "task", "task": { "key": "OPS-57", "…": "…" }, "snippet": "Follow-up to <mark>OPS-42</mark> once the rollback is confirmed", "rank": 0.6 },
    { "type": "doc", "doc": { "…": "…" }, "snippet": "The fix shipped under <mark>OPS-42</mark> changed the release checklist", "rank": 0.4 }
  ]
}

An unknown space key is refused with 404 and space_not_found.

For where the bearer token comes from, see Authentication. For the other refusals, such as a 401 for a missing token or a 403 when you have no role in the space, see HTTP API § Errors.

On this page