# MCP tool reference

> Arguments, results and capability requirements for Radiant’s project-scoped MCP tools.

Radiant’s MCP tools let an external assistant discover activity, inspect evidence and work with Meta Agent investigations. Every call is scoped to the connecting credential’s project. Follow [External assistants through MCP](/docs/platform/integrations/mcp.md) for connection and credential setup.

Your client’s `tools/list` response provides the input schemas for its available tools. Unknown fields are rejected. Additional capabilities expose Signal management, shared conversation history and coding handoffs.

## Project context

### `get_project_context`

Takes no arguments. Returns `project_id`, `can_manage_signals`, `can_read_history` and `can_coding_handoffs`. Use it to confirm the project and available capabilities before changing project state.

## Trace discovery and inspection

### `find_traces`

Finds retained traces containing matching operations, including non-agent activity. Optional arguments are `attribute: { key, value }`, exact `span_name`, RFC 3339 `from`/`to`, paired receive-time bounds, `limit` and `cursor`. Attribute values must be strings, numbers or booleans. Resource attribute values are strings.

The start-time window is at most 30 days and defaults to the last 30 days unless paired receive-time bounds are supplied. `limit` accepts 1–100 and defaults to 20.

Returns `result.traces`, `result.has_more` and `result.next_cursor`. Each trace includes matching-operation counts and timestamps alongside totals for the complete retained trace. The complete trace can contain operations outside the discovery filters or time window.

Find traces with an exact application attribute:

```json
{
  "name": "find_traces",
  "arguments": {
    "attribute": { "key": "gen_ai.conversation.id", "value": "conversation-104" },
    "limit": 20
  }
}
```

Pass the returned `result.next_cursor` as `cursor` with the same filters for another page.

### `inspect_trace`

Requires `trace_id`. Optional `span_id` restricts inspection to that operation and its descendants. `limit` accepts 1–200 and defaults to 50; `cursor` continues the same trace or subtree.

Returns span summaries under `result.spans`, including parent relationships, timing and available evidence keys, with `result.has_more` and `result.next_cursor`. Payloads are read separately with `get_span_evidence`.

Inspect one trace, optionally restricted to an agent span and its descendants:

```json
{
  "name": "inspect_trace",
  "arguments": {
    "trace_id": "YOUR_TRACE_ID",
    "span_id": "YOUR_ROOT_SPAN_ID",
    "limit": 50
  }
}
```

Omit `span_id` for the complete trace.

## Agent runs and groups

### `find_agent_runs`

Requires a structured `query` with `source: "agent_runs"`. Supply `query.time_range` unless both top-level receive-time bounds are present. Optional `limit` accepts 1–100 and defaults to 20; `cursor` continues the same query.

Returns identified top-level invocations in `result.agent_runs`, with `result.has_more` and `result.next_cursor`. Use each run’s trace ID and root span ID with `inspect_trace`.

This query finds runs from the `support-agent` service:

```json
{
  "name": "find_agent_runs",
  "arguments": {
    "query": {
      "source": "agent_runs",
      "time_range": {
        "from": "2026-10-28T09:00:00Z",
        "to": "2026-10-28T10:00:00Z"
      },
      "conditions": [
        {
          "operator": "is",
          "field": { "kind": "intrinsic", "field": "service" },
          "value": "support-agent"
        }
      ]
    },
    "limit": 20
  }
}
```

Open a discovered run with `inspect_trace`, using its trace ID and root span ID. Pass `next_cursor` back as `cursor` with the same query to read another page.

### `find_groups`

Requires a structured `query` with `group_by` and start-time bounds, unless paired receive-time bounds are supplied. Sources are `agent_runs` or `spans`. Optional `limit` accepts 1–100 and defaults to 20; `cursor` continues the same query.

Returns `result.groups`, `result.has_more` and `result.next_cursor`. Discovery conditions select groups through their members; summaries cover each complete bounded group. Groups can overlap, so their totals are not necessarily additive.

### `inspect_group`

Requires `selection`, `started_after` and `started_before`. The selection identifies the source, grouping and exact returned JSON value. Optional `limit` accepts 1–200 and defaults to 50; `cursor` continues the same selection and time window.

Returns the selection and paged span summaries in `result`, using the same membership as the Logs execution view. Read payloads with `get_span_evidence`. Follow returned `next_cursor` values to inspect the complete group.

#### Group discovery and inspection example

Group agent activity by a string `gen_ai.conversation.id` recorded by your application:

```json
{
  "name": "find_groups",
  "arguments": {
    "query": {
      "source": "agent_runs",
      "time_range": {
        "from": "2026-10-28T09:00:00Z",
        "to": "2026-10-28T10:00:00Z"
      },
      "group_by": { "kind": "attribute", "field": "gen_ai.conversation.id" },
      "conditions": [
        {
          "operator": "is",
          "field": { "kind": "attribute", "key": "gen_ai.conversation.id" },
          "value": "conversation-104"
        }
      ]
    },
    "limit": 20
  }
}
```

The response’s `result.groups` array contains group values and summary columns. For this example, the relevant value fragment is:

```json
{ "value": "conversation-104" }
```

`selection` accepts `source` (`agent_runs`, the default, or `spans`), `group_by` (`{ "kind": "trace" }` or `{ "kind": "attribute", "field": "KEY" }`), and the exact returned `value`. `value_match` is `typed` by default; `scalar_text` preserves text comparison for historical selections. Optional restrictions are `agent_id` (agent-run source only), `trace_id`, and `filters`, an array of `{ "field": "KEY", "value": "TEXT" }` attribute restrictions.

Construct the inspection selection using the query’s source and grouping, plus that exact returned JSON value:

```json
{
  "name": "inspect_group",
  "arguments": {
    "selection": {
      "source": "agent_runs",
      "group_by": { "kind": "attribute", "field": "gen_ai.conversation.id" },
      "value": "conversation-104",
      "value_match": "typed"
    },
    "started_after": "2026-10-28T09:00:00Z",
    "started_before": "2026-10-28T10:00:00Z",
    "limit": 50
  }
}
```

Inspection reads the complete group membership in the supplied window, including child spans. Discovery conditions choose which groups to return; they are not filters to remove members from the inspected group. Preserve any restrictions in an existing selection, including its source, grouping, typed value and optional agent or trace identity.

For a numeric group value, retain the number: `"value": 104` selects a different typed group from `"value": "104"`. Use `{ "kind": "trace" }` to group by trace identity instead of an attribute.

## Trajectories and evidence

### `get_trajectory`

Supply exactly one of `trace_id` or a group `selection`. A group also requires `started_after` and `started_before`; these bounds are not accepted with a trace ID. Optional `max_steps` accepts 1–1000 and defaults to 400.

Returns the trajectory graph under `result`, including steps and observed or inferred connections. Later steps are omitted first when the step limit is reached. Inferred connections are hypotheses, rather than recorded causal relationships.

Tool arguments, results and result-derived error text are omitted from the graph. Retrieve them with `get_span_evidence`, using the step’s trace and span IDs.

### `get_span_evidence`

Requires `trace_id`, `span_id` and 1–4 `sections`. Each selection names `attributes`, `events`, `resource_attributes` or `metadata`. Optional `pointer` uses JSON Pointer syntax; `offset` defaults to 0 and `limit` accepts 1–24000 Unicode characters, defaulting to 12000.

Returns independently chunked JSON text for each section, with its pointer, offsets and `next_offset`. Concatenate all chunks before parsing the selected value. A pointer selects within the recorded section; it does not parse JSON stored inside a string.

Retrieve specific recorded evidence:

```json
{
  "name": "get_span_evidence",
  "arguments": {
    "trace_id": "YOUR_TRACE_ID",
    "span_id": "YOUR_SPAN_ID",
    "sections": [
      { "section": "attributes", "pointer": "/gen_ai.tool.call.result" },
      { "section": "events" }
    ]
  }
}
```

A `pointer` selects a value using JSON Pointer syntax. Follow each returned `next_offset` to retrieve long values before parsing or judging their completeness.

## Observations and Signals

### `list_observations`

Optional `limit` accepts 1–50 and defaults to 20. Optional `workflow_id` restricts results to attribute-group evidence with key exactly `workflow.id` and a matching string value; it does not match other grouping fields or trace evidence.

Returns `observations` with evidence, review windows and Signal verdicts. Only the provider’s recent findings are searched; this tool has no continuation cursor for older history.

### `list_signals`

Optional `include_inactive` defaults to false. Returns `signals`, including active criteria and drafts; set the option to include retired definitions.

### `create_signal`

Requires `can_manage_signals`, `title` (1–200 characters) and `content` (1–5000 characters). Optional `draft` saves a draft when true; creation otherwise activates the Signal. Optional `client_request_id` accepts 1–200 characters. Reuse it when retrying the same creation to avoid duplicates.

Returns the created definition under `signal`, including its stable `memory_id`. If creation succeeds but its state cannot be confirmed, inspect it with `list_signals` before trying another creation.

### `promote_signal` and `deactivate_signal`

Require `can_manage_signals` and `memory_id`. Promotion activates a draft or reactivates an inactive Signal. Deactivation stops future checks while preserving the definition and past verdicts. Responses return the resulting definition under `signal`.

## Conversation history

These tools require `can_read_history` and read shared conversations only. Private conversations remain excluded. Results are historical evidence; verify claims about current application state against current telemetry.

### `search_meta_agent_conversations`

Optional arguments are literal case-insensitive `query` (up to 256 characters, without control characters), exclusive RFC 3339 creation-time `before`, `offset` (up to 10000), and `limit` (1–50, default 10).

Returns bounded conversation previews and IDs under `result`. Preserve `before` and use `next_offset` to continue the same search.

### `read_meta_agent_conversation`

Requires `conversation_id`. Optional message `offset` accepts up to 10000 and `limit` accepts 1–20, default 10. Messages are returned oldest first. `text_offset` defaults to 0 and accepts up to 1000000; `text_limit` accepts 1–4000 characters per message, default 2000.

Returns recorded messages with turn IDs, event sequences, states and timestamps under `result`. Follow message `next_offset` values. For a long message, request its message offset with `limit: 1` and follow `next_text_offset`. Cite the conversation, turn and message sequence when referring to its evidence.

## Coding handoffs

These tools require `can_coding_handoffs`. Ownership belongs to the claiming MCP credential. See [Coding handoffs](/docs/platform/meta-agent/coding-handoffs.md) for the human workflow.

### `claim_handoff`

Requires `handoff_id` and `agent_name` (1–100 nonblank characters). Returns the prepared task, prompt and investigation context. Retrying with the same credential and display name is safe.

### `ask_meta_agent`

Requires `handoff_id`, `question` (1–20000 nonblank characters) and `client_request_id` (1–200 characters). Returns a durable `request_id` immediately. Reuse the same client request ID and question when retrying.

Questions use the connections and effective permissions of the participant who prepared the handoff, independently of the client’s history capability. Questions needing interactive approval fail with a reason. A question times out after 15 minutes.

### `get_meta_agent_response`

Requires `request_id`. Returns the request state: pending, completed with its response, or failed with an error. Repeated reads do not add activity-log entries.

### `complete_handoff`

Requires `handoff_id`, `status` (`completed` or `failed`) and a nonblank Markdown `summary` up to 60000 characters. Reports the terminal outcome and ends unanswered questions. Exact retries must use the same status and summary; no further work can be recorded after completion.

## Structured queries

* `query.source`

  `agent_runs` selects identified top-level agent runs. Group queries can also use `spans`. The default is `agent_runs`.

* `query.time_range`

  An object with RFC 3339 `from` and `to` timestamps. The lower bound is inclusive and the upper bound exclusive. Required unless both top-level receive-time bounds are supplied. A discovery start-time window can span at most 30 days.

* `query.conditions`

  An optional array of structured conditions. Use `kind: “intrinsic”` with `field` for built-in fields, or `kind: “attribute”` with `key` for telemetry attributes. Equality preserves JSON types.

* `query.search`

  An optional literal substring across identities, names, statuses and attribute values. It defaults to an empty string.

* `query.group_by`

  Required by `find_groups`: a trace grouping or an attribute grouping as shown above.

* `limit` and `cursor`

  Discovery defaults to 20 results and accepts 1–100. Group inspection defaults to 50 spans and accepts 1–200. Follow `next_cursor` with the same query or selection and time bounds.

## Receive-time discovery

`find_traces` accepts `received_after` and `received_before` as top-level arguments alongside `from` and `to`. For `find_agent_runs` and `find_groups`, these are also top-level arguments alongside `query`, not fields inside `query`. All receive-time bounds use RFC 3339 timestamps. Supply both bounds, at most 30 days apart, to find traces that received activity during that period. With both receive-time bounds, `find_traces` applies only explicitly supplied `from`/`to` start-time restrictions; omitted bounds do not default to the last 30 days. For `find_agent_runs` and `find_groups`, `query.time_range` is optional only when both receive-time bounds are supplied.

Receive time helps find new activity added to an older trace. It selects candidate traces or groups, not the span membership to inspect. `inspect_group` still requires explicit `started_after` and `started_before` bounds covering the group’s execution.
