> For the complete documentation index, see [llms.txt](https://docs.ox.security/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ox.security/scan-and-analyze-with-ox/scanning/ox-ide-integrations/ox-ide-extension/deploying-the-ox-ide-extension-with-mdm.md).

# Deploying the OX IDE Extension with MDM

Organizations that centrally manage developer workstations can deploy the OX IDE extension across all managed devices using a Mobile Device Management (MDM) solution instead of requiring each developer to install and configure the extension individually.

This deployment method is intended for IT administrators and security teams that want to standardize IDE security across the organization, reduce manual setup, and simplify onboarding. In addition to installing the extension, the deployment can automatically configure the OX API key so developers can start using the extension immediately without performing additional configuration.

The installer supports unattended deployment through MDM platforms such as Jamf, Microsoft Intune, Kandji, and other MDM solutions capable of distributing files and running scripts.

## Supported IDEs

The deployment process supports the following VS Code-based IDEs:

| IDE                | Supported |
| ------------------ | --------- |
| Visual Studio Code | Yes       |
| Cursor             | Yes       |
| Windsurf           | Yes       |
| VSCodium           | Yes       |

## Supported operating systems

| Operating system | Installer                  |
| ---------------- | -------------------------- |
| macOS            | `install-ox-extension.sh`  |
| Linux            | `install-ox-extension.sh`  |
| Windows          | `install-ox-extension.ps1` |

## How the installer works

For each supported IDE detected on a device, the installer:

* Installs the OX IDE extension.
* Configures the OX API key, if provided.
* Preserves the user's existing IDE settings.
* Skips IDEs that are not installed.
* Can safely be run multiple times without affecting existing installations.

If a local VSIX package is provided, the installer uses it. Otherwise, it attempts to install the extension from the appropriate marketplace.

### Recommended deployment method

OX recommends deploying the extension together with the VSIX installation package.

Using a VSIX package provides a consistent installation experience across all supported IDEs and does not depend on marketplace availability or internet connectivity. This approach is the most reliable option for organizations that use multiple VS Code-based IDEs or operate in restricted environments.

Installing the extension directly from the marketplace is supported for Visual Studio Code but may not be available for other supported IDEs.

## Before you begin

Before the deployment process, make sure you have the following files:

| File                                             | Purpose                                                                                                                                             |
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `install-ox-extension.sh`                        | Installer script for macOS and Linux, see [Deployment scripts](#deployment-scripts).                                                                |
| `install-ox-extension.ps1`                       | Installer script for Windows, see [Deployment scripts](#deployment-scripts).                                                                        |
| OX IDE Extension `.vsix` package *(recommended)* | Installs the OX IDE extension locally without relying on marketplace availability. Recommended for consistent deployment across all supported IDEs. |

## Download a VSIX package

If the target machine does not have Internet access or cannot reach the Visual Studio Code Marketplace, download the extension as a VSIX package on another machine and transfer it to the target machine.

**To download the VSIX package:**

1. Open **Visual Studio Code** on a machine that has access to the Visual Studio Code Marketplace.
2. Select OX Security extension from the activity bar or by pressing:
   * **Ctrl+Shift+X** on Windows and Linux.
   * **Cmd+Shift+X** on macOS.
3. Search for the extension that you want to download.

<figure><img src="/files/VyBQqXjs9du1aFCImqZA" alt="" width="563"><figcaption></figcaption></figure>

4. In the search results, right-click the extension and select **Download VSIX**.
5. Choose a destination folder and save the `.vsix` file.
6. Transfer the `.vsix` file to the target machine.

## Deploy on macOS or Linux

1. Distribute the installer script and, optionally, the VSIX package to the target devices using your MDM solution.
2. Make the installer executable:

```bash
chmod +x install-ox-extension.sh
```

3. Run the installer:

```bash
./install-ox-extension.sh --api-key <API_KEY> --vsix ./extension.vsix
```

#### Installer options

| Option            | Description                                                                                                                                              |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--api-key <KEY>` | Configures the OX API key for the extension. If omitted, the extension is installed without configuring authentication.                                  |
| `--vsix <PATH>`   | Installs the extension from the specified VSIX package. If omitted or unavailable, the installer attempts to install the extension from the marketplace. |
| `--ext-id <ID>`   | Overrides the default extension identifier (`oxsecurity.ox-ide`).                                                                                        |

## Deploy on Windows

1. Distribute the installer script and, optionally, the VSIX package to the target devices using your MDM solution.
2. Run the installer:

```powershell
powershell -ExecutionPolicy Bypass -File install-ox-extension.ps1 -ApiKey <API_KEY> -Vsix .\extension.vsix
```

#### Installer options

| Option          | Description                                                                                                                                              |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-ApiKey <KEY>` | Configures the OX API key for the extension. If omitted, the extension is installed without configuring authentication.                                  |
| `-Vsix <PATH>`  | Installs the extension from the specified VSIX package. If omitted or unavailable, the installer attempts to install the extension from the marketplace. |
| `-ExtId <ID>`   | Overrides the default extension identifier (`oxsecurity.ox-ide`).                                                                                        |

### Exit codes

The installer returns one of the following exit codes, which can be used by your MDM solution to verify deployment status.

| Exit code | Description                                                                                           |
| --------- | ----------------------------------------------------------------------------------------------------- |
| `0`       | At least one supported IDE was successfully provisioned, or no supported IDE was found on the device. |
| `1`       | Invalid arguments were supplied or the operating system is not supported.                             |
| `2`       | One or more supported IDEs were found, but none could be successfully provisioned.                    |

## After deployment

Restart the IDE, or reload the IDE window, before the newly installed extension and any configured API key become available.

## Deployment Scripts

{% tabs %}
{% tab title="Installer script for macOS and Linux" %}

```
#!/usr/bin/env bash
#
# install-ox-extension.sh
#
# Universal installer for the OX Security extension on macOS and Linux.
# Intended to be run unattended as part of an MDM (Jamf, Intune, Kandji, ...)
# or any analogous fleet-distribution mechanism.
#
# For every supported VS Code-like editor found on the machine it will:
#   1. Install the extension - from a local .vsix if one is reachable,
#      otherwise by extension id from the editor's marketplace.
#   2. Write the API key into the editor's user settings.json.
#
# Supported editors: VS Code, VSCodium, Cursor, Windsurf.
#
# Usage:
#   ./install-ox-extension.sh --api-key <KEY> [--vsix <PATH>] [--ext-id <ID>]
#   ./install-ox-extension.sh <KEY>                      # API key as positional arg
#
# Options:
#   --api-key <KEY>   API key to write into ox-ide.apiKey (optional; if omitted
#                     the extension is installed but no key is written).
#   --vsix <PATH>     Path to a local extension.vsix. If reachable it is used
#                     instead of the marketplace. If omitted/unreachable the
#                     script falls back to a marketplace install by id.
#   --ext-id <ID>     Marketplace extension id (default: oxsecurity.ox-ide).
#   -h, --help        Show this help.
#
# Exit codes: 0 = at least one editor handled successfully (or nothing to do),
#             1 = bad arguments, 2 = no supported editor handled successfully.

set -u

EXT_ID="oxsecurity.ox-ide"
SETTING_KEY="ox-ide.apiKey"
API_KEY=""
VSIX_PATH=""

# ----------------------------------------------------------------------------
# Argument parsing
# ----------------------------------------------------------------------------
print_usage() {
  sed -n '2,40p' "$0" | sed 's/^# \{0,1\}//'
}

while [ $# -gt 0 ]; do
  case "$1" in
    --api-key) API_KEY="${2:-}"; shift 2 ;;
    --vsix)    VSIX_PATH="${2:-}"; shift 2 ;;
    --ext-id)  EXT_ID="${2:-}"; shift 2 ;;
    -h|--help) print_usage; exit 0 ;;
    -*)        echo "Error: unknown option '$1'" >&2; exit 1 ;;
    *)
      # First bare argument is treated as the API key for convenience.
      if [ -z "$API_KEY" ]; then API_KEY="$1"; shift
      else echo "Error: unexpected argument '$1'" >&2; exit 1; fi
      ;;
  esac
done

# ----------------------------------------------------------------------------
# OS detection -> base directory that holds each editor's "<Editor>/User" dir
# ----------------------------------------------------------------------------
SETTINGS_BASE=""
if [[ "$OSTYPE" == "darwin"* ]]; then
  SETTINGS_BASE="$HOME/Library/Application Support"
elif [[ "$OSTYPE" == "linux"* ]]; then
  SETTINGS_BASE="${XDG_CONFIG_HOME:-$HOME/.config}"
else
  echo "Error: unsupported OS '$OSTYPE' (this script is for macOS/Linux)." >&2
  echo "Use the PowerShell script for Windows." >&2
  exit 1
fi

# Resolve the .vsix to an absolute path and verify it is a readable file.
VSIX_REACHABLE=false
if [ -n "$VSIX_PATH" ]; then
  if [ -f "$VSIX_PATH" ] && [ -r "$VSIX_PATH" ]; then
    case "$VSIX_PATH" in
      /*) : ;;                       # already absolute
      *)  VSIX_PATH="$PWD/$VSIX_PATH" ;;
    esac
    VSIX_REACHABLE=true
    echo "Using local VSIX: $VSIX_PATH"
  else
    echo "Notice: --vsix '$VSIX_PATH' is not reachable; falling back to marketplace."
  fi
fi

# ----------------------------------------------------------------------------
# Editor definitions: "Display Name|cli-command|<Editor> dir name"
# The dir name is the folder under SETTINGS_BASE that contains User/settings.json
# ----------------------------------------------------------------------------
EDITORS=(
  "VS Code|code|Code"
  "VSCodium|codium|VSCodium"
  "Cursor|cursor|Cursor"
  "Windsurf|windsurf|Windsurf"
)

# Locate an editor CLI. Editors may not be on PATH (common with MDM where the
# script runs in a minimal shell), so also probe well-known install locations.
resolve_cli() {
  local cmd="$1"
  if command -v "$cmd" >/dev/null 2>&1; then command -v "$cmd"; return 0; fi

  local candidates=()
  if [[ "$OSTYPE" == "darwin"* ]]; then
    case "$cmd" in
      code)     candidates+=("/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code") ;;
      codium)   candidates+=("/Applications/VSCodium.app/Contents/Resources/app/bin/codium") ;;
      cursor)   candidates+=("/Applications/Cursor.app/Contents/Resources/app/bin/cursor") ;;
      windsurf) candidates+=("/Applications/Windsurf.app/Contents/Resources/app/bin/windsurf") ;;
    esac
  else
    candidates+=("/usr/bin/$cmd" "/usr/local/bin/$cmd" "/snap/bin/$cmd" "/var/lib/flatpak/exports/bin/$cmd")
  fi
  local c
  for c in "${candidates[@]}"; do
    if [ -x "$c" ]; then echo "$c"; return 0; fi
  done
  return 1
}

# Write SETTING_KEY=API_KEY into a settings.json, creating it if needed.
# Prefers jq, then python3, then a sed fallback.
update_settings_key() {
  local settings_file="$1"
  mkdir -p "$(dirname "$settings_file")"
  [ -f "$settings_file" ] || echo "{}" > "$settings_file"

  if command -v jq >/dev/null 2>&1; then
    local tmp; tmp="$(mktemp)"
    if jq --arg k "$SETTING_KEY" --arg v "$API_KEY" '.[$k] = $v' "$settings_file" > "$tmp" 2>/dev/null; then
      mv "$tmp" "$settings_file"; return 0
    fi
    rm -f "$tmp"
  fi

  if command -v python3 >/dev/null 2>&1; then
    SF="$settings_file" SK="$SETTING_KEY" SV="$API_KEY" python3 - <<'PY' && return 0
import json, os
path, key, val = os.environ["SF"], os.environ["SK"], os.environ["SV"]
try:
    with open(path) as f:
        data = json.load(f) or {}
    if not isinstance(data, dict):
        data = {}
except Exception:
    data = {}
data[key] = val
with open(path, "w") as f:
    json.dump(data, f, indent=2)
PY
  fi

  # Last-resort sed fallback (best effort; assumes a simple settings.json).
  if grep -q "\"$SETTING_KEY\"" "$settings_file"; then
    sed -i.bak -E "s/\"$SETTING_KEY\"[ ]*:[ ]*\"[^\"]*\"/\"$SETTING_KEY\": \"$API_KEY\"/" "$settings_file"
  else
    sed -i.bak -E "s/}$/,  \"$SETTING_KEY\": \"$API_KEY\"\n}/" "$settings_file"
  fi
  rm -f "$settings_file.bak"
}

# True if EXT_ID is present in the editor's installed-extensions list.
# The CLI ids are case-insensitive; compare lowercased.
extension_present() {
  local cli="$1"
  "$cli" --list-extensions 2>/dev/null \
    | tr '[:upper:]' '[:lower:]' \
    | grep -qx "$(echo "$EXT_ID" | tr '[:upper:]' '[:lower:]')"
}

# Install the extension into one editor via its CLI.
# A non-zero exit from --install-extension is unreliable across editors (some
# exit 0 even when the id is absent from their registry), so success is
# confirmed by re-reading --list-extensions afterwards.
install_extension() {
  local cli="$1" name="$2"
  if [ "$VSIX_REACHABLE" = true ]; then
    "$cli" --install-extension "$VSIX_PATH" --force >/dev/null 2>&1
    if extension_present "$cli"; then
      echo "  ✓ installed from VSIX"; return 0
    fi
    echo "  ! VSIX install did not take, trying marketplace ($EXT_ID)"
  fi
  "$cli" --install-extension "$EXT_ID" --force >/dev/null 2>&1
  if extension_present "$cli"; then
    echo "  ✓ installed from marketplace ($EXT_ID)"; return 0
  fi
  if [ "$VSIX_REACHABLE" = false ]; then
    echo "  ✗ install failed: '$EXT_ID' not found in this editor's registry" >&2
    echo "    (Cursor/VSCodium/Windsurf use OpenVSX; pass --vsix for a reliable install)" >&2
  else
    echo "  ✗ extension install failed for $name" >&2
  fi
  return 1
}

# ----------------------------------------------------------------------------
# Main loop
# ----------------------------------------------------------------------------
echo "OX Security extension installer (macOS/Linux)"
[ -n "$API_KEY" ] && echo "API key: ${API_KEY:0:8}..." || echo "API key: (none provided, key will not be written)"
echo

ANY_SUCCESS=false
ANY_FOUND=false

for entry in "${EDITORS[@]}"; do
  IFS='|' read -r NAME CMD DIRNAME <<< "$entry"
  SETTINGS_FILE="$SETTINGS_BASE/$DIRNAME/User/settings.json"
  CLI_PATH="$(resolve_cli "$CMD" || true)"

  # "Installed" = CLI is present OR the editor's User dir already exists.
  if [ -z "$CLI_PATH" ] && [ ! -d "$SETTINGS_BASE/$DIRNAME/User" ]; then
    echo "• $NAME: not found, skipping"
    continue
  fi
  ANY_FOUND=true
  echo "• $NAME:"

  ok=true
  if [ -n "$CLI_PATH" ]; then
    install_extension "$CLI_PATH" "$NAME" || ok=false
  else
    echo "  ! CLI not found; cannot install extension (only updating settings)"
    ok=false
  fi

  if [ -n "$API_KEY" ]; then
    if update_settings_key "$SETTINGS_FILE"; then
      echo "  ✓ API key written to $SETTINGS_FILE"
    else
      echo "  ✗ failed to write API key for $NAME" >&2; ok=false
    fi
  fi

  [ "$ok" = true ] && ANY_SUCCESS=true
done

echo
if [ "$ANY_FOUND" = false ]; then
  echo "No supported editors found on this machine. Nothing to do."
  exit 0
fi
if [ "$ANY_SUCCESS" = true ]; then
  echo "Done."
  exit 0
fi
echo "Completed with errors: no editor was fully provisioned." >&2
exit 2
```

{% endtab %}

{% tab title="Installer script for Windows" %}

```
<#
.SYNOPSIS
    Universal installer for the OX Security extension on Windows.

.DESCRIPTION
    Intended to be run unattended as part of an MDM (Intune, etc.) or any
    analogous fleet-distribution mechanism.

    For every supported VS Code-like editor found on the machine it will:
      1. Install the extension - from a local .vsix if one is reachable,
         otherwise by extension id from the editor's marketplace.
      2. Write the API key into the editor's user settings.json.

    Supported editors: VS Code, VSCodium, Cursor, Windsurf.

.PARAMETER ApiKey
    API key to write into ox-ide.apiKey. Optional; if omitted the extension is
    installed but no key is written.

.PARAMETER Vsix
    Path to a local extension.vsix. If reachable it is used instead of the
    marketplace. If omitted/unreachable the script falls back to a marketplace
    install by id.

.PARAMETER ExtId
    Marketplace extension id (default: oxsecurity.ox-ide).

.EXAMPLE
    powershell -ExecutionPolicy Bypass -File install-ox-extension.ps1 -ApiKey 1234567890-NEW-KEY

.EXAMPLE
    powershell -ExecutionPolicy Bypass -File install-ox-extension.ps1 -ApiKey KEY -Vsix .\extension.vsix
#>

[CmdletBinding()]
param(
    [string]$ApiKey = "",
    [string]$Vsix   = "",
    [string]$ExtId  = "oxsecurity.ox-ide"
)

$SettingKey = "ox-ide.apiKey"
$ErrorActionPreference = "Continue"

# ---------------------------------------------------------------------------
# Resolve the .vsix (if any) to an absolute, readable path.
# ---------------------------------------------------------------------------
$VsixReachable = $false
if ($Vsix) {
    if (Test-Path -LiteralPath $Vsix -PathType Leaf) {
        $Vsix = (Resolve-Path -LiteralPath $Vsix).Path
        $VsixReachable = $true
        Write-Host "Using local VSIX: $Vsix"
    } else {
        Write-Host "Notice: -Vsix '$Vsix' is not reachable; falling back to marketplace."
    }
}

# ---------------------------------------------------------------------------
# Editor definitions.
#   Name    : display name
#   Cli     : CLI executable name (resolved on PATH or well-known locations)
#   DirName : folder under %APPDATA% holding User\settings.json
# ---------------------------------------------------------------------------
$Editors = @(
    @{ Name = "VS Code";  Cli = "code";     DirName = "Code" },
    @{ Name = "VSCodium"; Cli = "codium";   DirName = "VSCodium" },
    @{ Name = "Cursor";   Cli = "cursor";   DirName = "Cursor" },
    @{ Name = "Windsurf"; Cli = "windsurf"; DirName = "Windsurf" }
)

# On Windows the editor CLIs are .cmd shims. Probe PATH then common install dirs.
function Resolve-Cli([string]$cli) {
    $cmd = Get-Command "$cli.cmd" -ErrorAction SilentlyContinue
    if ($cmd) { return $cmd.Source }
    $cmd = Get-Command $cli -ErrorAction SilentlyContinue
    if ($cmd) { return $cmd.Source }

    $candidates = switch ($cli) {
        "code"     { @("$env:LOCALAPPDATA\Programs\Microsoft VS Code\bin\code.cmd",
                        "$env:ProgramFiles\Microsoft VS Code\bin\code.cmd") }
        "codium"   { @("$env:LOCALAPPDATA\Programs\VSCodium\bin\codium.cmd",
                        "$env:ProgramFiles\VSCodium\bin\codium.cmd") }
        "cursor"   { @("$env:LOCALAPPDATA\Programs\cursor\resources\app\bin\cursor.cmd") }
        "windsurf" { @("$env:LOCALAPPDATA\Programs\Windsurf\bin\windsurf.cmd",
                        "$env:ProgramFiles\Windsurf\bin\windsurf.cmd") }
        default    { @() }
    }
    foreach ($c in $candidates) {
        if (Test-Path -LiteralPath $c) { return $c }
    }
    return $null
}

function Update-SettingsKey([string]$settingsFile) {
    $dir = Split-Path -Parent $settingsFile
    if (-not (Test-Path -LiteralPath $dir)) {
        New-Item -ItemType Directory -Path $dir -Force | Out-Null
    }

    $settings = [ordered]@{}
    if (Test-Path -LiteralPath $settingsFile) {
        try {
            $raw = Get-Content -LiteralPath $settingsFile -Raw
            if ($raw -and $raw.Trim()) {
                $parsed = $raw | ConvertFrom-Json
                foreach ($p in $parsed.PSObject.Properties) {
                    $settings[$p.Name] = $p.Value
                }
            }
        } catch {
            Write-Host "  ! Could not parse existing settings.json; recreating it"
            $settings = [ordered]@{}
        }
    }

    $settings[$SettingKey] = $ApiKey
    $json = $settings | ConvertTo-Json -Depth 20
    Set-Content -LiteralPath $settingsFile -Value $json -Encoding UTF8
}

# True if ExtId is present in the editor's installed-extensions list.
function Test-ExtensionPresent([string]$cli) {
    $installed = & $cli --list-extensions 2>$null
    if (-not $installed) { return $false }
    return ($installed | Where-Object { $_.Trim().ToLower() -eq $ExtId.ToLower() }).Count -gt 0
}

# Install the extension into one editor via its CLI.
# A zero exit code from --install-extension is unreliable across editors (some
# exit 0 even when the id is absent from their registry), so success is
# confirmed by re-reading --list-extensions afterwards.
function Install-Extension([string]$cli, [string]$name) {
    if ($VsixReachable) {
        & $cli --install-extension $Vsix --force *> $null
        if (Test-ExtensionPresent $cli) { Write-Host "  + installed from VSIX"; return $true }
        Write-Host "  ! VSIX install did not take, trying marketplace ($ExtId)"
    }
    & $cli --install-extension $ExtId --force *> $null
    if (Test-ExtensionPresent $cli) { Write-Host "  + installed from marketplace ($ExtId)"; return $true }
    if (-not $VsixReachable) {
        Write-Host "  x install failed: '$ExtId' not found in this editor's registry"
        Write-Host "    (Cursor/VSCodium/Windsurf use OpenVSX; pass -Vsix for a reliable install)"
    } else {
        Write-Host "  x extension install failed for $name"
    }
    return $false
}

# ---------------------------------------------------------------------------
# Main loop
# ---------------------------------------------------------------------------
Write-Host "OX Security extension installer (Windows)"
if ($ApiKey) {
    $preview = if ($ApiKey.Length -ge 8) { $ApiKey.Substring(0,8) } else { $ApiKey }
    Write-Host "API key: $preview..."
} else {
    Write-Host "API key: (none provided, key will not be written)"
}
Write-Host ""

$anyFound   = $false
$anySuccess = $false

foreach ($ed in $Editors) {
    $userDir      = Join-Path $env:APPDATA (Join-Path $ed.DirName "User")
    $settingsFile = Join-Path $userDir "settings.json"
    $cliPath      = Resolve-Cli $ed.Cli

    if (-not $cliPath -and -not (Test-Path -LiteralPath $userDir)) {
        Write-Host "* $($ed.Name): not found, skipping"
        continue
    }
    $anyFound = $true
    Write-Host "* $($ed.Name):"

    $ok = $true
    if ($cliPath) {
        if (-not (Install-Extension $cliPath $ed.Name)) { $ok = $false }
    } else {
        Write-Host "  ! CLI not found; cannot install extension (only updating settings)"
        $ok = $false
    }

    if ($ApiKey) {
        try {
            Update-SettingsKey $settingsFile
            Write-Host "  + API key written to $settingsFile"
        } catch {
            Write-Host "  x failed to write API key for $($ed.Name): $_"
            $ok = $false
        }
    }

    if ($ok) { $anySuccess = $true }
}

Write-Host ""
if (-not $anyFound) {
    Write-Host "No supported editors found on this machine. Nothing to do."
    exit 0
}
if ($anySuccess) {
    Write-Host "Done."
    exit 0
}
Write-Host "Completed with errors: no editor was fully provisioned."
exit 2
```

{% endtab %}
{% endtabs %}


---

# 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.ox.security/scan-and-analyze-with-ox/scanning/ox-ide-integrations/ox-ide-extension/deploying-the-ox-ide-extension-with-mdm.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.
