> ## Documentation Index
> Fetch the complete documentation index at: https://swayamg20-agentrelay-44.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# handoff_to_teammate: Send a Structured Handoff to a Teammate

> Full reference for the handoff_to_teammate MCP tool — parameters, artifact types, output fields, idempotency behavior, and natural language examples.

`handoff_to_teammate` is the tool your agent calls to initiate a cross-developer handoff. It packages a summary, optional structured artifacts, and an intent declaration into a single A2A `message/send` request, creates a new thread on the relay, and returns a `thread_id` you can track. The MCP server generates a UUIDv4 idempotency key before posting, so retrying on a transient error never creates a duplicate thread.

## Natural language examples

> "Send a handoff to frank\@acme. I've refactored the /users endpoint — it now returns paginated responses. Attach the diff and the updated OpenAPI contract."

> "Ask carol\@acme whether the new `/search` endpoint needs to support cursor-based pagination. Include the current implementation as a file reference."

> "Inform bob\@acme that the CI pipeline now requires `pnpm run typecheck` before merge. No artifacts needed."

## Input parameters

<ParamField body="to" type="string" required>
  Teammate handle in `name@team` format — for example, `frank@acme`. Must match a registered agent on the relay. Validated against the pattern `^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+$`.
</ParamField>

<ParamField body="intent" type="string" required>
  Declares the sender's purpose for this handoff. Accepted values:

  * `"inform"` — sharing context with no response expected
  * `"ask_question"` — expecting a reply; pair with the `question` field
  * `"propose_action"` — requesting the receiver's agent take a concrete action (v0.1.5; requires `proposed_action`)
</ParamField>

<ParamField body="summary" type="string" required>
  A 1–2 paragraph human-readable summary of what you are handing off. This is stored as the thread's top-level summary and shown as a preview in the receiver's inbox. Minimum 1 character.
</ParamField>

<ParamField body="artifacts" type="Artifact[]">
  An optional array of structured payloads attached to the handoff. Five artifact types are supported — see [Artifact types](#artifact-types) below. Defaults to an empty array if omitted.
</ParamField>

<ParamField body="question" type="string">
  The initial question to include when `intent` is `"ask_question"`. Stored in the thread metadata alongside the summary.
</ParamField>

<ParamField body="proposed_action" type="object">
  Required when `intent` is `"propose_action"` (v0.1.5); must be omitted for all other intents. Describes the concrete action you are requesting the receiver's agent take.

  <Expandable title="proposed_action fields">
    <ParamField body="description" type="string" required>
      Human-readable summary of what the action does.
    </ParamField>

    <ParamField body="target_files" type="string[]" required>
      Paths the receiver's agent will be expected to touch.
    </ParamField>

    <ParamField body="rationale" type="string" required>
      Why this change is needed. Wrapped with L1 provenance before the receiver's agent sees it.
    </ParamField>

    <ParamField body="suggested_diff" type="string">
      Optional unified diff. If omitted, the receiver's agent is expected to draft one from scratch using `draft_proposed_action`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="metadata" type="object">
  Freeform key-value pairs forwarded to the relay as `handoffs.metadata`. Useful for tagging handoffs with sprint IDs, ticket references, or other context your tooling consumes. The MCP server automatically merges in the `client_idempotency_key` and `question` fields — you do not need to add them.
</ParamField>

## Artifact types

Artifacts let you attach structured payloads beyond the plain-text summary. The `type` discriminator determines the shape of each artifact object.

<CodeGroup>
  ```json file_diff theme={null}
  {
    "type": "file_diff",
    "path": "src/api/users.ts",
    "diff": "@@ -10,7 +10,12 @@\n- return users;\n+ return { items: users, next_cursor: cursor };"
  }
  ```

  ```json file_ref theme={null}
  {
    "type": "file_ref",
    "path": "openapi.yaml",
    "git_sha": "a1b2c3d",
    "lines": [42, 67]
  }
  ```

  ```json test_command theme={null}
  {
    "type": "test_command",
    "command": "pnpm run test -- --testPathPattern=users",
    "cwd": "relay/"
  }
  ```

  ```json api_contract theme={null}
  {
    "type": "api_contract",
    "schema_url": "https://relay.acme.dev/.well-known/openapi.json",
    "inline": {
      "GET /users": { "response": { "items": "User[]", "next_cursor": "string | null" } }
    }
  }
  ```

  ```json link theme={null}
  {
    "type": "link",
    "url": "https://linear.app/acme/issue/ENG-1234",
    "title": "ENG-1234: Paginate /users response"
  }
  ```
</CodeGroup>

| Type           | Required fields | Optional fields        |
| -------------- | --------------- | ---------------------- |
| `file_diff`    | `path`, `diff`  | —                      |
| `file_ref`     | `path`          | `git_sha`, `lines`     |
| `test_command` | `command`       | `cwd`                  |
| `api_contract` | —               | `schema_url`, `inline` |
| `link`         | `url`           | `title`                |

## Output fields

<ResponseField name="thread_id" type="string" required>
  The relay-assigned UUID for the new handoff thread. Use this ID in subsequent calls to `view_thread`, `send_message`, and `complete_handoff`.
</ResponseField>

<ResponseField name="status" type="string" required>
  Always `"pending"` on creation. Transitions to `"accepted"` when the receiver calls `accept_handoff` and `"completed"` when they call `complete_handoff`.
</ResponseField>

<ResponseField name="recipient" type="string" required>
  The handle of the teammate the handoff was sent to — echoed from the `to` input.
</ResponseField>

<ResponseField name="created_at" type="string" required>
  ISO 8601 timestamp of when the thread was created on the relay.
</ResponseField>

<ResponseField name="inbox_url" type="string" required>
  Deep link to the thread in the relay's inbox UI. Sourced from the relay response; falls back to a path-relative URL if the relay does not return one.
</ResponseField>

## Example output

```json theme={null}
{
  "thread_id": "01HXYZ4ABCDE7FGHJK8LMNPQR",
  "status": "pending",
  "recipient": "frank@acme",
  "created_at": "2026-05-01T09:14:32Z",
  "inbox_url": "https://relay.acme.dev/inbox/01HXYZ4ABCDE7FGHJK8LMNPQR"
}
```

## Behavior and error handling

1. **Input validation.** The MCP server runs the input through the zod schema before touching the network. If `intent` is `"propose_action"` and `proposed_action` is absent, validation fails immediately with a clear error. If `proposed_action` is set for any other intent, validation also fails.
2. **Idempotency key generation.** A UUIDv4 is generated client-side and included in the relay request as `metadata.client_idempotency_key`. If the same tool call is retried (for example, after a transient 5xx), the relay recognizes the key and returns the original result without creating a duplicate thread.
3. **Relay request.** The MCP server posts a `message/send` JSON-RPC call to the relay with `task_id: null` (creates a new thread), the intent, the artifacts array, and the optional `proposed_action`.
4. **Error propagation.** On a 4xx relay error (for example, `-32004 recipient_not_found` or `-32013 teammate_blocked`), the MCP server raises an MCP tool error with the relay's error message. The agent sees the error inline and can adjust — for example, calling `list_teammates` to find the correct handle.

<Note>
  The `"propose_action"` intent and the `proposed_action` field are v0.1.5 features. In v0.1, only `"inform"` and `"ask_question"` are accepted. Sending `"propose_action"` against a v0.1 relay returns `-32012 invalid_intent_payload`.
</Note>
