# `start_goal_matching`

Starts a background search for one of your goals.

Annotations: `readOnlyHint: false` · `destructiveHint: true` · `idempotentHint: true` · `openWorldHint: false`

## When to use it

Only when you're asked to search. Before starting:

- Resolve the exact goal. Gravity captures its current matching inputs when accepting the search. Optional versions constrain that snapshot.
- Don't start one while `matching.run.status` is `running` or `searchQueued` is true.
- Saving starts no search. Call this separately when the member asked to search.

## Inputs

| Input | Required | Type | Description |
| --- | --- | --- | --- |
| `goalId` | yes | string | UUID of a goal you own |
| `goalScopeVersion` | no | integer | `goal.scopeVersion` from your latest [`get_goal`](/docs/mcp/tools/get_goal) |
| `goalContextRevisionId` | no | string | `goal.contextRevisionId` from your latest [`get_goal`](/docs/mcp/tools/get_goal) |
| `mode` | no | string | `full` (the default), `new-members`, or `failed-networks` |
| `requestId` | yes | string | A new UUID for this action. Reuse it only to retry this exact call. |

## Modes

| Mode | Searches | Existing matches |
| --- | --- | --- |
| `full` | Every searchable network the goal's audience covers, including yours | If the goal was searched before, matches nobody has acted on are replaced. Requested, dismissed, and connector-suggested matches stay. |
| `new-members` | Networks not yet searched for this version of the goal, networks with new information, and networks whose last search failed. With none, it completes at once with nothing new. | Matches nobody has acted on from those networks are replaced |
| `failed-networks` | Only networks left unfinished by a failed search | Kept |

If the goal's latest search failed, any mode retries the unfinished networks. If a search is already running for this version, you get that search's ID and nothing new starts.

## Returns

`{ "status", "message", "matchingRunId", "goalId", "goalScopeVersion", "goalContextRevisionId" }`. The returned versions identify the inputs captured by that search. Success means the request was accepted or an existing run was returned, not that it finished. It does not distinguish a newly created run from a reused run. Errors use the [common error contract](/docs/mcp/errors-and-limits), with a specific code and any known `matchingRunId`. The same request ID and complete arguments reuse its accepted search, including when the initial action reused an existing run. A changed goal returns `version_conflict` and current state. A stopped search is reported without silently restarting it; a separately requested retry uses a new ID.

| Result | Meaning |
| --- | --- |
| `status: "success"` | The search was accepted or an existing run was reused. Follow its current state with the read tools. |
| `version_conflict` | The goal changed since the read. Nothing started; read current versions. |
| `request_id_conflict` | The request ID was used with different arguments. Nothing started; recover the original action or prepare a new one with a new ID. |
| `clarification_required` | The goal needs an answer before searching. Nothing started; read and clarify the goal. |
| `unavailable` | The goal is ended, missing, or inaccessible. Nothing started; resolve from current owned goals. |
| `request_rejected` | The requested mode is not applicable. Nothing started; inspect current goal/search state. |
| `operation_failed` | Search acceptance could not be confirmed. Retain the request ID, recover the same action, and read the current search. |

## Following the search

Check every 30 to 60 seconds with [`get_goal`](/docs/mcp/tools/get_goal) (`matching.run`) or [`get_goal_matches`](/docs/mcp/tools/get_goal_matches) (`search`):

- `running`: still going. `searchProgress` shows how far along it is.
- `complete`: read the matches. If `failedMembers` isn't empty, offer a `failed-networks` retry.
- `failed`: say the search couldn't be completed, and offer a `failed-networks` retry.
- No search (`null`): the goal changed since you started. Read it again.

If it still shows `running` and its progress hasn't moved for about 15 minutes, stop checking and let the member know they can follow it on the goal in Gravity.

## Example

```json start_goal_matching
{
  "goalId": "00000000-0000-4000-a000-000000000001",
  "goalScopeVersion": 2,
  "goalContextRevisionId": "00000000-0000-4000-a000-000000000002",
  "mode": "new-members",
  "requestId": "00000000-0000-4000-a000-000000000002"
}
```

Result (synthetic data):

```json result:start_goal_matching
{
  "status": "success",
  "message": "The search is available in your goal.",
  "matchingRunId": "00000000-0000-4000-a000-000000000002",
  "goalId": "00000000-0000-4000-a000-000000000001",
  "goalScopeVersion": 2,
  "goalContextRevisionId": "00000000-0000-4000-a000-000000000002"
}
```

## Related

- [Matches and searches](/docs/mcp/concepts/matches) explains searches for members.
- [Matching workflow](/docs/mcp/agent-guides/find-matches) shows the whole tool flow.
