> For the complete documentation index, see [llms.txt](https://docs.tabnine.com/main/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tabnine.com/main/getting-started/tabnine-cli/features/hooks/configuration.md).

# Configuration

Hooks are configured in `settings.json`, **not** in `TABNINE.md`. Tabnine CLI merges configurations from multiple layers (highest to lowest precedence):

1. **Project settings**: `.tabnine/agent/settings.json` in the project root.
2. **User settings**: `~/.tabnine/agent/settings.json`.
3. **System settings**: Platform-specific system config directory.
4. **Extensions**: Hooks defined by installed extensions.

## Configuration schema

```json
{
  "hooksConfig": {
    "enabled": true,
    "disabled": [],
    "notifications": true
  },
  "hooks": {
    "BeforeTool": [
      {
        "matcher": "write_file|replace",
        "sequential": true,
        "hooks": [
          {
            "type": "command",
            "command": "node $TABNINE_PROJECT_DIR/hooks/validate-write.js",
            "name": "validate-write",
            "description": "Validate file writes before execution",
            "timeout": 5000
          }
        ]
      }
    ]
  }
}
```

## `hooksConfig` fields

| Field           | Type       | Default | Description                                                                           |
| --------------- | ---------- | ------- | ------------------------------------------------------------------------------------- |
| `enabled`       | `boolean`  | `true`  | Master toggle for the hooks system. Set to `false` to disable all.                    |
| `disabled`      | `string[]` | `[]`    | List of hook identifiers to skip. Matches against `name` if set, otherwise `command`. |
| `notifications` | `boolean`  | `true`  | Show visual indicators when hooks execute.                                            |

## Hook definition fields

Each event contains an array of **hook definitions**:

| Field        | Type      | Required | Description                                                                                                         |
| ------------ | --------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `matcher`    | `string`  | No       | A regex for tool events (`BeforeTool`, `AfterTool`) or exact string for lifecycle events. Omit to match everything. |
| `sequential` | `boolean` | No       | If `true`, hooks in this group run sequentially. If `false` (default), they run in parallel.                        |
| `hooks`      | `array`   | **Yes**  | An array of **hook configurations** (see below).                                                                    |

## Hook configuration fields

| Field         | Type                     | Required | Description                                                                    |
| ------------- | ------------------------ | -------- | ------------------------------------------------------------------------------ |
| `type`        | `string`                 | **Yes**  | Must be `"command"`. No default — hooks without `type` are silently discarded. |
| `command`     | `string`                 | **Yes**  | The shell command to execute.                                                  |
| `name`        | `string`                 | No       | A friendly identifier for logs and the `disabled` list.                        |
| `description` | `string`                 | No       | A brief explanation of the hook's purpose.                                     |
| `timeout`     | `number`                 | No       | Timeout in **milliseconds**. Default: `60000` (60 seconds).                    |
| `env`         | `Record<string, string>` | No       | Additional environment variables to set for this hook.                         |

## Matchers

The `matcher` field controls which specific tools or triggers fire your hook:

* **Tool events** (`BeforeTool`, `AfterTool`): Matchers are **regular expressions** (e.g., `"write_file|replace"`, `"read_.*"`).
* **Lifecycle events**: Matchers are **exact strings** (e.g., `"startup"` for `SessionStart`).
* **Match all**: Omit `matcher` or set to `".*"` to match everything.

### Tool naming conventions

* **Built-in tools**: Match by their name (e.g., `read_file`, `run_shell_command`, `write_file`, `replace`).
* **MCP tools**: Follow the pattern `mcp_<server_name>_<tool_name>`.

## Multiple hooks

You can define multiple hooks for the same event. By default they run in parallel; set `sequential: true` to run them in order:

```json
{
  "hooks": {
    "BeforeTool": [
      {
        "matcher": ".*",
        "sequential": true,
        "hooks": [
          {
            "type": "command",
            "command": "node ./hooks/validate.js",
            "name": "validate"
          },
          {
            "type": "command",
            "command": "node ./hooks/log.js",
            "name": "log-tool"
          }
        ]
      }
    ]
  }
}
```

You can also define multiple hook definitions per event with different matchers:

```json
{
  "hooks": {
    "BeforeTool": [
      {
        "matcher": "write_file|replace",
        "hooks": [
          {
            "type": "command",
            "command": "node ./hooks/validate-writes.js"
          }
        ]
      },
      {
        "matcher": "run_shell_command",
        "hooks": [
          {
            "type": "command",
            "command": "node ./hooks/validate-commands.js"
          }
        ]
      }
    ]
  }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tabnine.com/main/getting-started/tabnine-cli/features/hooks/configuration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
