# UI Commands Tool

Control the chat interface, switch agents, show notifications, and interact with users via the UICommand MCP tool.

# UI Commands Tool

The `UICommand` tool lets agents control the chat interface. Available as a built-in MCP tool at `mcp__teamday-ui__UICommand`.

Agents use it to discover other agents, hand off conversations, show notifications, ask structured questions, and request user confirmations.

---

## Actions

| Action | Purpose | Waits for Response? |
|--------|---------|:---:|
| `listAgents` | Discover available agents in the space | No |
| `switchAgent` | Hand off conversation to another agent | No |
| `showNotification` | Display a toast notification | No |
| `askConfirmation` | Yes/No confirmation dialog | Yes |
| `askQuestion` | Multi-choice question card | Yes |
| `openModal` | Open settings, agent picker, or cover picker | No |
| `closeModal` | Close all open modals | No |
| `openPanel` | Open side panel (files, terminal, chats) | No |
| `navigate` | Navigate to a different route | No |
| `requestToolAccess` | Request user to enable a disabled tool | Yes |
| `disableTool` | Disable a tool for the space | No |
| `requestReauth` | Request re-authentication for an expired MCP | No |

---

## Agent Discovery & Handoff

### Discovering Agents

**Always call `listAgents` before switching.** This returns all agents available in the current space.

```json
{
  "action": "listAgents"
}
```

Returns a list of agents with their IDs, names, and roles.

### Switching Agents

Hand off the conversation to a specialist:

```json
{
  "action": "switchAgent",
  "target": "agent-sarah-seo"
}
```

### Handoff Pattern

The correct sequence is:

1. Call `listAgents` to discover available agents
2. Find the right specialist from the list
3. Call `switchAgent` with the agent's ID

```json
// Step 1
{ "action": "listAgents" }

// Step 2: Agent finds "agent-sarah-seo" in the response

// Step 3
{ "action": "switchAgent", "target": "agent-sarah-seo" }
```

---

## Notifications

Show a toast notification in the UI:

```json
{
  "action": "showNotification",
  "target": "Report generated successfully!",
  "params": {
    "type": "success"
  }
}
```

**Notification types:** `success`, `error`, `info`, `warning`

---

## User Interaction

### Confirmation Dialog

Ask the user a yes/no question before proceeding with an action:

```json
{
  "action": "askConfirmation",
  "waitForResult": true,
  "params": {
    "title": "Delete all draft posts?",
    "message": "This will permanently remove 12 draft blog posts. This action cannot be undone.",
    "destructive": true
  }
}
```

Set `destructive: true` for dangerous actions --- the UI will show a red confirmation button.

### Structured Questions

Present the user with multiple-choice options:

```json
{
  "action": "askQuestion",
  "waitForResult": true,
  "params": {
    "questions": [
      {
        "header": "Report Format",
        "question": "Which format should I use for the weekly report?",
        "options": [
          { "label": "PDF", "description": "Formatted document with charts" },
          { "label": "Markdown", "description": "Plain text, easy to edit" },
          { "label": "HTML Dashboard", "description": "Interactive charts and filters" }
        ]
      }
    ]
  }
}
```

This renders as a card with clickable options. The agent receives the user's selection and can act on it.

---

## Modals & Panels

### Open a Modal

```json
{
  "action": "openModal",
  "target": "spaceSettings"
}
```

**Available modals:** `spaceSettings`, `agentPicker`, `coverPicker`

### Open a Side Panel

```json
{
  "action": "openPanel",
  "target": "files"
}
```

**Available panels:** `files`, `terminal`, `chats`

### Close Modals

```json
{
  "action": "closeModal"
}
```

---

## Tool Access Management

### Requesting Access to a Disabled Tool

When an agent needs a tool that's been disabled for the space:

```json
{
  "action": "requestToolAccess",
  "target": "WebSearch",
  "waitForResult": true
}
```

The user sees a prompt asking them to enable the tool. The agent waits for the decision.

### Disabling a Tool

If the user asks to turn off a tool:

```json
{
  "action": "disableTool",
  "target": "WebSearch"
}
```

---

## Re-authentication

When an MCP integration's OAuth token has expired:

```json
{
  "action": "requestReauth",
  "target": "google-analytics"
}
```

The user is prompted to reconnect the integration through the OAuth flow.

---

## Navigation

Navigate the user to a different page:

```json
{
  "action": "navigate",
  "target": "/settings/billing"
}
```

---

## Parameters Reference

| Parameter | Type | Description |
|-----------|------|-------------|
| `action` | enum | The UI action to perform (see table above) |
| `target` | string | Target for the action: agent ID, modal name, route path, panel name, or notification message |
| `params` | object | Additional parameters (notification type, question options, etc.) |
| `waitForResult` | boolean | Wait for user response (for confirmations and questions) |

---

## How It Works

The UICommand tool works differently from other MCP tools. When the agent calls it:

1. **Agent makes the tool call** --- the computer service acknowledges it
2. **Frontend intercepts the call** --- the chat UI watches for UICommand tool calls in the response stream
3. **UI executes the command** --- the frontend performs the action (shows notification, opens modal, etc.)
4. **Result flows back** --- for `waitForResult` actions, the user's response is sent back to the agent

This means UI commands execute on the user's browser, not on the server. The agent simply describes what should happen, and the frontend does the work.

---

## Best Practices

- **Always `listAgents` before `switchAgent`** --- agent IDs can change, don't hardcode them
- **Use `askConfirmation`** for destructive operations (deleting files, overwriting data)
- **Use `askQuestion`** when the user has a meaningful choice that affects the workflow
- **Keep notifications brief** --- they disappear after a few seconds
- **Use `waitForResult: true`** only when you need the user's answer to continue
- **Set `destructive: true`** on confirmations that involve deletion or irreversible changes
