For a more detailed walkthrough including how the rules system works, see the Claude Code setup guide.
The hook scripts require jq and curl to be installed on your machine. These are pre-installed on most macOS and Linux systems. To check:
jq --version
curl --version
If either is missing, install via your package manager (e.g., brew install jq on macOS, apt install jq on Ubuntu/Debian).
Download Greenlight from the App Store and open it. The app will automatically generate a unique device ID and connect to the relay server.
Go to the About tab in the app and tap your Device ID to copy it to the clipboard. You'll need this for the next step.
Download the hook script and place it somewhere on your machine:
curl -o ~/greenlight-hook.sh https://getgreenlight.github.io/greenlight-hook.sh
chmod +x ~/greenlight-hook.sh
Add a hook to your Claude Code per-project settings file (.claude/settings.local.json in your project root):
{
"hooks": {
"PermissionRequest": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/greenlight-hook.sh --device-id YOUR_DEVICE_ID --project myproject --activity"
}
]
}
],
"Notification": [
{
"matcher": "idle_prompt",
"hooks": [
{
"type": "command",
"command": "~/greenlight-hook.sh --device-id YOUR_DEVICE_ID --project myproject"
}
]
}
],
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/greenlight-hook.sh --device-id YOUR_DEVICE_ID --project myproject --activity"
}
]
}
]
}
}
Replace YOUR_DEVICE_ID with the device ID from the app, and myproject with your project's name. The --project flag adds a project badge in the app so you know which project a request is coming from.
The --activity flag streams Claude's transcript to the Activity tab so you can see what Claude is doing in real time. The Notification hook sends a push notification when Claude is idle and waiting for input. The UserPromptSubmit hook starts the transcript streamer immediately when you submit a prompt, so streaming begins right away rather than waiting for the first permission request. All three are optional.
Important: Do not add the hook to your global configuration (~/.claude/settings.json). Claude Code merges global and project settings, so having the hook in both places will send two requests for every action.
Run Claude Code and ask it to do something that requires permission:
claude "list files in /etc"
You should see a request appear in the app!
Greenlight also supports Windsurf via its Cascade Hooks system. For a more detailed walkthrough, see the Windsurf setup guide.
Download the Windsurf-specific hook script:
curl -o ~/greenlight-windsurf.sh https://getgreenlight.github.io/greenlight-windsurf.sh
chmod +x ~/greenlight-windsurf.sh
Create or edit the hooks configuration file at ~/.codeium/windsurf/hooks.json:
{
"hooks": {
"pre_run_command": [{
"command": "~/greenlight-windsurf.sh --device-id YOUR_DEVICE_ID",
"show_output": true
}],
"pre_write_code": [{
"command": "~/greenlight-windsurf.sh --device-id YOUR_DEVICE_ID",
"show_output": true
}],
"pre_read_code": [{
"command": "~/greenlight-windsurf.sh --device-id YOUR_DEVICE_ID",
"show_output": true
}],
"pre_mcp_tool_use": [{
"command": "~/greenlight-windsurf.sh --device-id YOUR_DEVICE_ID",
"show_output": true
}]
}
}
Replace YOUR_DEVICE_ID with the device ID from the app. The project name is detected automatically from the working directory or git repository root.
You can also place a .windsurf/hooks.json file in a project directory for per-project configuration.
Open a project in Windsurf, start a Cascade session, and ask it to run a command or edit a file. You should see the request appear in the app with a windsurf badge.
Both hook scripts support the same options:
| Option | Description | Default |
|---|---|---|
--device-id ID |
Your device ID from the app | Required |
--project NAME |
Project name shown in the app | (auto-detected) |
--activity |
Stream Claude's transcript to the app (Claude Code only, requires Greenlight Pro) | Off |
--server URL |
Relay server URL | https://permit.dnmfarrell.com |
The server URL can also be set via the GREENLIGHT_SERVER environment variable.
Each request can be responded to with four actions:
The Grants tab shows all your "Always Allow" rules grouped by project. Swipe left on any rule to delete it. Rules use pattern matching:
Bash(go build **))rm use exact matching for safetyRead(/home/user/src/**))Greenlight uses Time Sensitive notifications that can break through Focus modes. Make sure notifications are enabled in Settings → Greenlight → Notifications and that Time Sensitive notifications are allowed in your Focus mode settings.
chmod +x).--timeout SECONDS in the hook config.For bug reports, feature requests, or any questions, email greenlight@dnmfarrell.com.