owlette docs
reference

hoot tools reference

Complete reference for all 52 public web hoot tools from web/lib/mcp-tools.ts, organized by tier.


tier system

tiertypeapprovalcount
1Read-onlyAuto-approved16
2Process & machine managementAuto-approved25
3PrivilegedRequires user confirmation11

Server-side tools (get_site_logs, get_system_presets, deploy_software, update_process, add_process, delete_process, create_talon, list_talons, set_talon_enabled, schedule_followup, cancel_followup) execute in the Next.js server process. They do not route through the agent command queue. Talons are site-level records and follow-ups are chat records, so neither is ever relayed to a machine.


execution-mode matrix

Web hoot chooses an execution path by tool name in web/lib/hoot-utils.server.ts. Server-side tools run in the Next.js server process. Legacy command tools write existing machine command types. Firestore tools create mcp_tool_call entries for the agent to execute. Local Agent SDK MCP is separate: agent/src/cortex_tools.py exposes only the tools returned by _make_tier1_tools, _make_tier2_tools, and _make_tier3_tools.

tooltierweb hoot executionlocal Agent SDK MCP
get_site_logs1Server-sideNot exposed
get_system_info1Firestore mcp_tool_callYes, direct
get_process_list1Firestore mcp_tool_callYes, direct
get_running_processes1Firestore mcp_tool_callYes, direct
get_gpu_processes1Firestore mcp_tool_callDefined, but not returned
get_network_info1Firestore mcp_tool_callYes, direct
get_disk_usage1Firestore mcp_tool_callYes, direct
get_event_logs1Firestore mcp_tool_callYes, direct
get_service_status1Firestore mcp_tool_callYes, direct
get_agent_config1Firestore mcp_tool_callYes, direct
get_agent_logs1Firestore mcp_tool_callYes, direct
get_agent_health1Firestore mcp_tool_callYes, direct
get_system_presets1Server-sideNot exposed
check_pending_reboot1Firestore mcp_tool_callNot exposed
schedule_followup1Server-sideNot exposed
cancel_followup1Server-sideNot exposed
restart_process2Legacy command-mappedYes, IPC
kill_process2Legacy command-mappedYes, IPC
start_process2Legacy command-mappedYes, IPC
set_launch_mode2Legacy command-mappedYes, IPC
update_process2Server-sideNot exposed
add_process2Server-sideNot exposed
delete_process2Server-sideNot exposed
capture_screenshot2Firestore mcp_tool_callYes, IPC
manage_process2Firestore mcp_tool_callNot exposed
manage_windows_service2Firestore mcp_tool_callNot exposed
configure_gpu_tdr2Firestore mcp_tool_callNot exposed
manage_windows_update2Firestore mcp_tool_callNot exposed
suppress_setup_screens2Firestore mcp_tool_callNot exposed
manage_notifications2Firestore mcp_tool_callNot exposed
configure_power_plan2Firestore mcp_tool_callNot exposed
manage_scheduled_task2Firestore mcp_tool_callNot exposed
network_reset2Firestore mcp_tool_callNot exposed
registry_operation2Firestore mcp_tool_callNot exposed
clean_disk_space2Firestore mcp_tool_callNot exposed
get_event_logs_filtered2Firestore mcp_tool_callNot exposed
manage_windows_feature2Firestore mcp_tool_callNot exposed
show_notification2Firestore mcp_tool_callNot exposed
create_talon2Server-sideNot exposed
list_talons2Server-sideNot exposed
set_talon_enabled2Server-sideNot exposed
run_command3Firestore mcp_tool_callYes, direct
run_powershell3Firestore mcp_tool_callYes, direct
run_python3Firestore mcp_tool_callNot exposed
read_file3Firestore mcp_tool_callYes, direct
write_file3Firestore mcp_tool_callYes, direct
list_directory3Firestore mcp_tool_callYes, direct
execute_script3Firestore mcp_tool_callYes, direct
deploy_software3Server-sideNot exposed
reboot_machine3Legacy command-mappedNot exposed
shutdown_machine3Legacy command-mappedNot exposed
cancel_reboot3Legacy command-mappedNot exposed

Local Agent SDK coverage is intentionally smaller than the web registry: at maximum tier it returns 21 tools, and at the default max_tier=2 it returns 15. agent/src/cortex_tools.py defines a get_gpu_processes wrapper, but the function is omitted from the returned tier-1 list, so local Agent SDK hoot does not expose it today. agent/src/mcp_tools.py also contains internal handlers that are not public web hoot tools, including get_display_layout and apply_display_topology.


tier 1: read-only tools

get_site_logs

Get activity logs across all machines in the site. Useful for finding errors, crashes, and events across the fleet. Server-side — queries Firestore directly.

parametertyperequireddescription
levelstringNoFilter: error, warning, info
hoursnumberNoLook back this many hours (default: 24)
limitnumberNoMax logs to return (default: 50)
actionstringNoFilter by action type, e.g. process_crash, agent_started

get_system_info

Get comprehensive system information including hostname, OS (with correct Windows 10/11 detection), CPU model and usage, memory (used/total GB), disk (used/total GB), GPU model, driver version, VRAM (used/total GB), GPU load %, uptime, and agent version.

parametertyperequireddescription
(none)

get_process_list

Get all owlette-configured processes with their current status, PID, launch mode, executable path, file path / command arguments, working directory, and whether they are running.

parametertyperequireddescription
(none)

get_running_processes

Get all running OS processes with CPU and memory usage. Can filter by name.

parametertyperequireddescription
name_filterstringNoFilter by process name (case-insensitive)
limitnumberNoMax results (default: 50, max: 200)

Returns: Processes sorted by memory usage with name, PID, CPU%, memory%.


get_gpu_processes

Get per-process GPU memory (VRAM) usage via Windows Performance Counters — same data source as Task Manager. Shows dedicated and shared GPU memory per process, sorted by usage. Works cross-vendor (NVIDIA, AMD, Intel) and for all GPU APIs (DirectX, OpenGL, CUDA, Vulkan).

parametertyperequireddescription
(none)

get_network_info

Get network interfaces with IP addresses, netmasks, and link status.

parametertyperequireddescription
(none)

get_disk_usage

Get disk usage for all drives including total, used, free space and percentage.

parametertyperequireddescription
(none)

get_event_logs

Get Windows event log entries from Application, System, or Security logs.

parametertyperequireddescription
log_namestringNoApplication, System, or Security (default: Application)
max_eventsnumberNoMax entries (default: 20, max: 100)
levelstringNoFilter: Error, Warning, Information

get_service_status

Get the status and start type of a Windows service. Returned start_type disambiguates "stopped" states: automatic (should be running), demand_start (stopped-is-normal idle state, e.g. wuauserv/BITS), disabled (intentionally off).

parametertyperequireddescription
service_namestringYesWindows service name to query

get_agent_config

Get the current owlette agent configuration (sensitive fields stripped).

parametertyperequireddescription
(none)

get_agent_logs

Get recent owlette agent log entries.

parametertyperequireddescription
max_linesnumberNoMax lines (default: 100, max: 500)
levelstringNoFilter: ERROR, WARNING, INFO, DEBUG

get_agent_health

Get agent health status including connection state and health probe results.

parametertyperequireddescription
(none)

get_system_presets

Get available software deployment presets managed by the site admin. Returns installer URLs, silent install flags, verification paths, and other deployment parameters for software like TouchDesigner, Unreal Engine, media players, etc. Use this before deploy_software to find the correct preset and parameters. Server-side — queries Firestore directly.

parametertyperequireddescription
software_namestringNoFilter by name (case-insensitive partial match), e.g. TouchDesigner
categorystringNoFilter by category, e.g. Creative Software, Media Server

check_pending_reboot

Detect whether a system reboot is currently pending (from Windows Update, Component Based Servicing, pending file rename operations, or SCCM client). Read-only diagnostic — use during incident investigations, after a suspected update, or when the machine is behaving unusually. The agent also emits a site-level auto-alert the first time it detects a pending reboot (idempotent via a flag file).

parametertyperequireddescription
(none)

Returns: pending (bool), reasons (array), last update install time, next scheduled update run time (if available).


schedule_followup

Schedule a follow-up turn on this conversation. At the scheduled time hoot is re-opened in the same chat with note injected as the instruction, acts on it, and reports back — the way a promise to "check back in ten minutes" actually happens, since a turn ends when the assistant stops typing. Server-side — the follow-up is a chat record (cortex-followups/{id}, a data-at-rest name), acted on by the cron sweep and never relayed to a machine.

parametertyperequireddescription
notestringYesWhat the follow-up turn should do, written as a self-contained instruction to hoot's future self — the conversation is not in view when it fires. Max 1000 characters
delay_minutesnumberExactly one of delay_minutes / atFire this many minutes from now: 1 to 10080 (one minute to seven days)
atstringExactly one of delay_minutes / atFire at this absolute ISO 8601 timestamp with a timezone offset (e.g. 2026-01-31T14:00:00Z). Must be in the future and within seven days
watch_command_idstringNoId of a machine command already dispatched in this conversation. The follow-up then fires as soon as that command finishes, or at its scheduled time, whichever comes first

Returns: followup_id, fires_at (ISO), and watch_command_id when one was passed. Keep followup_id — cancel_followup needs it.

Pass exactly one of delay_minutes and at — both, or neither, is rejected with invalid_schedule rather than silently picking a winner. Out-of-range values return invalid_delay_minutes, at_in_the_past, or at_too_far_out.

Early fire. watch_command_id is a shortcut, not a replacement for the schedule — the scheduled time stays the backstop. The sweep resolves the watched command from the machine's commands/completed document and treats only the terminal statuses (completed, failed, error, cancelled) as finished; the agent's non-terminal running marker does not fire it. A follow-up scheduled against more than one machine — a subset of a site, or a site-wide chat — has no single command whose finish means the work is done, so the id is ignored there and the follow-up waits for its scheduled time.

Firing. The follow-up pass rides the once-a-minute talons cron sweep (/api/cron/talons). Each sweep scans the 25 soonest scheduled follow-ups and starts at most 10 turns; a backlog drains over the following minutes. An early fire is therefore only found while the follow-up sits inside that scan window — past it, the follow-up still fires at its own scheduled time.

Tier 3 always waits for a person inside a fired follow-up. The turn runs with forceTier3Approval, which overrides the site's requireTier3Approval setting: a site that lets an operator auto-run tier 3 while they watch has not agreed to it running while nobody does. The model may still reach for a tier-3 tool — the turn simply parks at approval-requested until the owner comes back to the chat.

Where it fires. A follow-up fires on the machines the scheduling turn was targeting, not on whatever the chat is pointed at when it comes due — the selection may have moved since the promise was made. A site-wide follow-up stays dynamic: a machine added in the meantime is included. The target is re-validated at fire time, so machines that have left the site, gone offline, or had hoot switched off are dropped from it; if nothing is left the follow-up is marked failed with the reason on the record rather than dispatched.

Other fire-time guarantees. Site access is re-resolved on every fire and never trusted from scheduling time, so a user removed or demoted in the meantime cannot keep driving tools through a promise they left behind; the chat must still exist and still belong to the same user (chat_deleted / chat_owner_mismatch). A follow-up never supersedes a live turn — if someone is mid-conversation the doc goes back to scheduled and the next sweep retries.

Where it is not available. The tool requires a user chat: unattended hoot (autonomous dispatch, talon directives) runs as a system actor with no chat to re-open and no user whose access could be re-resolved, and gets followup_unavailable. Both follow-up tools are also withheld from the public conversations API — that surface's chatId is a chat_conversations id while the sweep resolves chats/{chatId}, so a follow-up scheduled there could never fire (it would fail closed as chat_deleted). Withholding the tools is deliberate: better no promise than one the sweep silently breaks.


cancel_followup

Cancel a scheduled follow-up before it fires. Use it when the thing the follow-up was going to check has already been settled in the conversation, or when the operator asks for it to be dropped. Server-side — reaches the same store helper as DELETE /api/hoot/followups/{followupId}, which is what the chip above the composer calls.

parametertyperequireddescription
followup_idstringYesThe id returned by schedule_followup. Never guess one

Ownership is enforced inside the store transaction (the Admin SDK bypasses firestore.rules, so that is the only gate every caller passes through): only the user who scheduled a follow-up can cancel it, and only while it is still scheduled. Failure results are followup_not_found (404), followup_forbidden (403, it belongs to another user), and followup_not_scheduled (409, it already fired or was cancelled — a cancel that loses the race with the sweep's claim lands here). Like schedule_followup, it is unavailable to unattended hoot and withheld from the public conversations API.


tier 2: process & machine management tools

These execute immediately without user confirmation. Owlette-configured process control tools (restart_process, kill_process, start_process, set_launch_mode) wrap existing commands. Process config tools (update_process, add_process, delete_process) run server-side through the same validated action functions as the dashboard, and the talon tools (create_talon, list_talons, set_talon_enabled) run server-side through the same talon store as the talon editor. The rest are purpose-built with validated parameters and narrower blast radius than raw shell scripts.

restart_process

Restart an owlette-configured process by name.

parametertyperequireddescription
process_namestringYesMust match a configured process name

kill_process

Kill/stop a running owlette-configured process.

parametertyperequireddescription
process_namestringYesMust match a configured process name

start_process

Start a stopped owlette-configured process.

parametertyperequireddescription
process_namestringYesMust match a configured process name

set_launch_mode

Set the launch mode for a process.

parametertyperequireddescription
process_namestringYesMust match a configured process name
modestringYesoff (not managed), always (24/7 with crash recovery), or scheduled
schedulesarrayWhen mode=scheduledSchedule blocks with days and time ranges

Schedule block format:

{
  "days": ["mon", "tue", "wed", "thu", "fri"],
  "ranges": [
    { "start": "09:00", "stop": "18:00" }
  ]
}

update_process

Update an owlette-configured process by name. Only fields provided in the tool call are changed. Runs server-side through updateProcess; the agent picks up the config change through the existing config listener and launch-mode diff.

parametertyperequireddescription
process_namestringYesCurrent configured process name
namestringNoNew display name
exe_pathstringNoFull path to the executable
file_pathstringNoProject file path or command arguments
cwdstringNoWorking directory
prioritystringNoLow, Normal, High, or Realtime
visibilitystringNoNormal or Hidden
time_delaystringNoLaunch delay in seconds, stored as a string
time_to_initstringNoInitialization timeout in seconds, stored as a string
relaunch_attemptsstringNoCrash relaunch attempt count, stored as a string
launch_modestringNooff, always, or scheduled
schedulesarrayWhen setting launch_mode=scheduledSchedule blocks with days and time ranges
schedulePresetIdstring or nullNoNamed schedule preset id, or null to clear

add_process

Create a new owlette-managed process on the target machine. Runs server-side through createProcess; the new process defaults to launch_mode: "off" unless a launch mode is supplied.

parametertyperequireddescription
namestringYesDisplay name for the process
exe_pathstringYesFull path to the executable
file_pathstringNoProject file path or command arguments
cwdstringNoWorking directory
prioritystringNoLow, Normal, High, or Realtime
visibilitystringNoNormal or Hidden
time_delaystringNoLaunch delay in seconds, stored as a string
time_to_initstringNoInitialization timeout in seconds, stored as a string
relaunch_attemptsstringNoCrash relaunch attempt count, stored as a string
launch_modestringNooff, always, or scheduled
schedulesarrayWhen setting launch_mode=scheduledSchedule blocks with days and time ranges
schedulePresetIdstring or nullNoNamed schedule preset id, or null to clear

delete_process

Delete an owlette-configured process by name. Runs server-side through deleteProcess. Deleting a process removes it from the machine config; it does not terminate an already-running OS process. Use kill_process first when the running process should also be stopped.

parametertyperequireddescription
process_namestringYesConfigured process name to delete

capture_screenshot

Capture a screenshot of the remote machine's desktop. Returns the image for visual analysis — use to diagnose display issues, verify process state, or see what's currently on screen.

parametertyperequireddescription
monitornumberNo0 = all monitors combined (default), 1 = primary, 2 = second, etc.

manage_process

Kill, suspend, or resume OS processes by name pattern. Works on any process, not just Owlette-managed ones. Safer than run_command + taskkill: validated params, no shell, refuses to touch critical system processes (lsass, winlogon, csrss, etc.) via an internal blocklist.

parametertyperequireddescription
name_patternstringYesProcess name with .exe or glob (e.g. chrome.exe, FreeFileSync*)
actionstringYeskill, suspend, or resume
match_exactbooleanNoExact match (default true) vs glob via fnmatch
forcebooleanNoFor kill: force immediately (default true), else graceful first

manage_windows_service

Full services.msc parity — start, stop, restart, pause/continue, set startup type, configure failure recovery, or get full service details in one call. Use set_recovery to configure auto-restart on crash (critical for unattended media installations). Use get_details to query status, startup type, binary path, dependencies, and recovery config at once.

parametertyperequireddescription
service_namestringYesService name (not display name)
actionstringYesstart, stop, restart, pause, continue, set_startup, set_recovery, get_details
startup_typestringFor set_startupauto, auto_delayed, manual, disabled
first_failurestringFor set_recoveryrestart, run_program, reboot, none
second_failurestringFor set_recoverySame options as first_failure
subsequent_failuresstringFor set_recoveryAction on third and later failures
restart_delay_msnumberNoDelay before recovery action (default: 60000)
reset_counter_daysnumberNoDays with no failures before counter resets (default: 1)
reboot_messagestringNoBroadcast message if action is reboot
run_program_pathstringIf any action is run_programProgram to run on failure

configure_gpu_tdr

Configure Windows GPU Timeout Detection and Recovery. Writes TdrDelay (and optionally TdrDdiDelay) to the registry. Critical for TouchDesigner / Unreal / Unity installations with heavy shader work — the default 2-second timeout causes silent crashes on complex GPU operations. A reboot is required for changes to take effect.

parametertyperequireddescription
timeout_secondsnumberYesTdrDelay in seconds (2-300). Default Windows value is 2; heavy creative workloads usually need 10-60
ddi_timeout_secondsnumberNoOptional TdrDdiDelay in seconds (2-300). Max time GPU can spend in Present/Draw calls

manage_windows_update

Pause, resume, or schedule Windows Update. Pause before live events; use set_active_hours to block auto-reboot during quiet hours; set_scheduled_install for exact install timing; set_feature_deferral / set_quality_deferral to delay rollouts. Windows Update is the #1 threat to unattended 24/7 installations.

parametertyperequireddescription
actionstringYesget_status, pause, resume, set_active_hours, set_scheduled_install, set_restart_deadline, set_feature_deferral, set_quality_deferral
pause_daysnumberFor pauseDays to pause (1-35)
start_hour / end_hournumberFor set_active_hoursHours (0-23)
day_of_weeknumberFor set_scheduled_install0 = every day, 1-7 = Sun–Sat
hournumberFor set_scheduled_installHour of day (0-23)
deadline_daysnumberFor set_restart_deadlineDays before force reboot (2-14)
daysnumberFor deferral actionsFeature (0-365) or quality (0-30) deferral days

suppress_setup_screens

Suppress the full-screen Windows setup screens that hijack the display at sign-in after updates: the "Choose privacy settings" experience, the Windows Welcome Experience, "Let's finish setting up your device" (SCOOBE), and the Edge first-run tour. Writes the machine-wide policies plus the per-user keys for every existing profile (mounting signed-out profiles' hives) and the Default profile, so future accounts inherit the suppression. apply is idempotent — feature updates are known to reset these keys, so re-assert on a schedule (the update guard talon preset does exactly this).

parametertyperequireddescription
actionstringYesget_status (read-only per-profile drift report) or apply (write all suppression keys)

manage_notifications

Control Windows toast notifications and Focus Assist. Essential for kiosks and video walls where a surprise "Updates are ready" toast would interrupt an exhibit. Use disable_all_toasts to fully silence the system, enable_focus_assist with alarms_only for total silence, or disable_for_app to silence a specific app.

parametertyperequireddescription
actionstringYesget_status, disable_all_toasts, enable_focus_assist, disable_focus_assist, disable_for_app
app_namestringFor disable_for_appApp identifier (e.g. Microsoft.WindowsStore, MSTeams)
focus_modestringFor enable_focus_assistpriority_only or alarms_only

configure_power_plan

Set Windows power plan and disable sleep/hibernate/screen blanking. Required for any 24/7 unattended installation — default power settings will sleep the machine, blank the screen, or hibernate, all of which break live deployments.

parametertyperequireddescription
planstringNohigh_performance, balanced, or ultimate_performance (omit to keep current)
disable_sleepbooleanNoSet standby timeout to Never on both AC and battery
disable_hibernatebooleanNoDisable hibernation (removes hiberfil.sys)
disable_screen_blankingbooleanNoDisable monitor timeout

manage_scheduled_task

Full Task Scheduler parity — list, enable, disable, delete, run_now, stop, create new tasks, get details, and get run history. Use create for weekly memory-flush reboots, boot-time media app launches, or event-triggered restarts.

parametertyperequireddescription
actionstringYeslist, enable, disable, delete, run_now, stop, create, get_details, get_history
task_namestringFor non-list actionsTask name; can include folder path (e.g. \Folder\TaskName)
name_filterstringFor listSubstring filter
descriptionstringNoFor create: human-readable description
triggerobjectFor create{type: "boot"|"logon"|"once"|"daily"|"weekly"|"on_event"|"on_idle", ...}. Additional fields depend on type
task_actionobjectFor create{type: "run_program", program, arguments?, working_directory?}
principalobjectFor create{run_as: SYSTEM|LOCAL_SERVICE|NETWORK_SERVICE|current_user, run_level: highest|limited}
settingsobjectNo{start_when_available, execution_time_limit_minutes, restart_count, restart_interval_minutes, run_only_if_network_available, allow_start_on_batteries, hidden, multiple_instances, delete_expired_task_after_days}

network_reset

Flush DNS, renew IP lease, restart a network adapter, or reset the winsock stack. Common fix for NDI dropouts, Firebase connectivity loss, DNS resolution issues at venue networks. reset_winsock requires a reboot to fully take effect.

parametertyperequireddescription
actionstringYesflush_dns, renew_ip, restart_adapter, reset_winsock
adapter_namestringFor restart_adapterAdapter name (e.g. Ethernet, Wi-Fi)

registry_operation

Read, write, or delete Windows registry values. Restricted to an allowlist of safe registry paths (Winlogon, GraphicsDrivers, WindowsUpdate, Notifications, Power, Services, etc.) — system hives like SAM, SECURITY, and Cryptography are blocked.

parametertyperequireddescription
actionstringYesread, write, delete
hivestringYesHKLM (machine) or HKCU (current user)
key_pathstringYesKey path under hive (must match an allowed prefix)
value_namestringFor write/deleteOmit for read to enumerate all values in the key
value_datastringFor writeData to write (dword as "8", binary as hex string, etc.)
value_typestringFor writestring, dword, binary, expand_string, multi_string

clean_disk_space

Clean temp files, Windows temp, prefetch cache, recycle bin, or Owlette logs with an age filter. Use dry_run=true to preview what would be deleted.

parametertyperequireddescription
targetstringYestemp, windows_temp, prefetch, recycle_bin, owlette_logs
older_than_daysnumberNoOnly delete files older than N days (default: 7). Ignored for recycle_bin
dry_runbooleanNoReturn counts/sizes without deleting (default: false)

get_event_logs_filtered

Fast filtered event log query via Get-WinEvent -FilterHashtable. Orders of magnitude faster than get_event_logs when searching for specific crashes, process sources, or event IDs.

parametertyperequireddescription
log_namestringYesApplication, System, Security, Setup
process_namestringNoFilter by provider/source name
event_idnumberNoSpecific event ID (e.g. 41 for unexpected shutdown, 1000 for app crash)
hours_backnumberNoLook back this many hours (1-168, default: 24)
levelstringNoCritical, Error, Warning, Information, Verbose
max_eventsnumberNoMax events (1-200, default: 50)

manage_windows_feature

Add, remove, or list Windows Optional Features (DISM, e.g. NetFx3, OpenSSH-Server), Windows Capabilities (FoD, e.g. OpenSSH.Client), or AppX Packages (Store apps like OneDrive, Xbox Game Bar, Cortana, Teams). Critical features for Owlette itself are blocklisted and cannot be disabled. AppX install is not supported.

parametertyperequireddescription
typestringYesoptional_feature, capability, appx_package
actionstringYeslist, install, remove
namestringFor install/removeFeature/capability/package name
all_usersbooleanNoFor appx_package remove: also remove provisioning package (default: false)
name_filterstringFor listSubstring filter

show_notification

Display an on-screen message on the remote machine — useful when a technician is physically nearby. Toast style is a subtle corner notification; modal style uses msg.exe to block the screen briefly. Opposite of manage_notifications, which suppresses notifications.

parametertyperequireddescription
messagestringYesNotification body
titlestringNoNotification title
stylestringNotoast (default, subtle corner) or modal (blocking msg.exe box)
duration_secondsnumberNoFor modal: how long the box stays up (default: 5)

create_talon

Create a talon on this site — a saved automation of trigger → optional condition → outputs. See talons for the product-level picture. Server-side — talons are site-level records written through the same store as the dashboard editor, never relayed to a machine.

Confirm before calling. A talon runs unattended against real machines, so hoot is instructed never to call this from a vague request: it states back the exact talon it intends to create — trigger, condition, every output, the machines in scope, the cooldown — and waits for the operator to confirm.

parametertyperequireddescription
namestringYesShort lowercase name shown in the dashboard, 80 characters or fewer
triggerobjectYesWhat makes the talon fire — one of the four shapes below
outputsarrayYes1 to 5 output entries, executed in order
descriptionstringNoLowercase note about what the talon is for, 500 characters or fewer
conditionobjectNoGate evaluated after the trigger fires. Defaults to {"type":"none"}
scopeobjectNo{"machineIds":["..."]}. Omit for every machine in the site
cooldownMinutesnumberNoMinimum minutes between runs, 0-1440 (default: 60)
enabledbooleanNoWhether the talon is armed as soon as it is created (default: true)

Trigger shapes (exactly one form):

{"type": "schedule", "entries": [{"id": "e1", "days": ["mon", "wed"], "time": "09:00"}]}
{"type": "schedule", "intervalMinutes": 30}
{"type": "threshold", "metric": "cpu_percent", "operator": ">", "value": 90}
{"type": "event", "eventTypes": ["process_crash", "machine_offline"], "delayMinutes": 2}
  • schedule / entries — 24-hour HH:MM in the site's timezone, up to 50 entries. entries and intervalMinutes are mutually exclusive.
  • schedule / intervalMinutes — 5 to 1440 minutes, but 15 minutes minimum when the condition is a visual_check.
  • threshold — metrics cpu_percent, memory_percent, disk_percent, gpu_percent, cpu_temp, gpu_temp, network_latency, network_packet_loss; operators >, <, >=, <=. Threshold talons ride the existing alert pipeline: one fires when an alert rule fires and the breach matches the talon's own metric, operator, and bound — so a threshold talon does nothing until a matching alert rule exists.
  • event — process_crash, machine_offline, process_start_failed, process_restarted, exe_missing, and the display_* events. Event triggers only: delayMinutes (0-1440) waits that long after the event before running, e.g. letting a restarted app finish booting before a visual_check looks at it.

Condition — {"type":"none"} (default), or {"type":"visual_check","expectation":"the lobby wall is playing the loop, not showing a desktop","monitor":0}, which captures a fresh screenshot and asks a vision model whether the expectation holds. expectation is 500 characters or fewer; monitor is 0 for all displays combined, 1 for primary.

Output entries — each entry is an object keyed by type:

fieldapplies todescription
typeallemail, webhook, cortex, or command
urlwebhookAn https URL. Private, loopback, and link-local addresses are rejected (DNS-resolving SSRF check at authoring time, re-validated at send time)
directivecortexWhat hoot should do when the talon fires, 1000 characters or fewer
commandTypecommandrestart_process, start_process, or stop_process
processNamecommandThe configured process name to act on
processIdcommandThe configured process id, when hoot already holds it

type: "cortex" is the hoot output — the wire literal is a deliberate survivor of the cortex → hoot rename (it is persisted on every talon and every talon-run summary, and the MCP tool schema is itself a published contract). Every label a human reads says hoot. See web/lib/hoot/WIRE_NAMES.md class B.

Refusals. A command output takes the same privilege as issuing the command by hand — site admins only, refused with command_output_forbidden (403) both in the tool and again in the store. A visual_check condition or a cortex output spends the talon author's own LLM key, so authoring one without a saved key returns llm_key_required (400). Exceeding 20 talons on the site returns talon_limit_reached (409). Validation rejects unknown top-level fields outright, so the model can never stamp a server-owned field onto the document; field-level failures come back as invalid_talon with field_errors rather than throwing and taking the turn down.

Returns: talon_id, name, enabled, next_run_at.

Unattended hoot cannot call this tool: authoring a talon is standing fleet policy that outlives the incident, so create_talon is excluded from the autonomous investigator's tool list regardless of tier.


list_talons

List the talons on this site, ordered by name. Call it before set_talon_enabled to get a talon id, and before create_talon so an existing talon is not duplicated.

parametertyperequireddescription
(none)

Returns: count, plus per talon talon_id, name, enabled, trigger (the normalized object, not a prose summary, so the exact metric / interval / event values are available for follow-up calls), outputs (types only), last_run_status, last_run_at, next_run_at.

Read-only, so unlike the two writing talon tools this one stays available to unattended hoot.


set_talon_enabled

Arm or disarm an existing talon. Disabling leaves the talon in place — it does not delete it.

parametertyperequireddescription
talon_idstringYesAs returned by list_talons or create_talon. Never guessed
enabledbooleanYestrue to arm, false to disarm

Enabling recomputes nextRunAt from now in the site's timezone, so a talon that sat disabled for a while does not fire the moment it comes back, and re-checks the author's LLM key when the talon has a visual_check condition or a hoot output (llm_key_required if it is gone). Either edge clears a system-set disable reason, so a re-armed talon does not still claim it was switched off. Like create_talon, this tool is excluded from unattended hoot.

Returns: talon_id, name, enabled, next_run_at.


tier 3: privileged tools

These require explicit user confirmation before execution.

run_command

Execute a shell command on the remote machine.

parametertyperequireddescription
commandstringYesMust start with an allowed command
user_sessionbooleanNoRun in the logged-in user's desktop session (needed for GUI/display access)

Returns: stdout, stderr, exit code.

Allowed commands (first word must be one of):

ipconfig, systeminfo, hostname, whoami, tasklist, netstat, ping, tracert, nslookup, dir, type, echo, set, ver, wmic, sc, net, reg, nvidia-smi, dxdiag

This is the default set (DEFAULT_ALLOWED_COMMANDS); it is overridable via config.mcp.allowed_commands. A running command can be cancelled from its tool card, which kills the process tree on the machine.


run_powershell

Execute a PowerShell command on the remote machine.

parametertyperequireddescription
scriptstringYesPowerShell script to execute
user_sessionbooleanNoRun in the logged-in user's desktop session

Returns: stdout, stderr, exit code.

No command restrictions — every invocation is audit-logged to the site events feed and the local [MCP-AUDIT] log. Fixed 25-second timeout; for long-running work use execute_script. A running command can be cancelled from its tool card, which kills the process tree on the machine.


run_python

Execute Python code on the remote machine in the user's desktop session.

parametertyperequireddescription
codestringYesPython code to execute

Sandboxed execution (since v2.6.5). When invoked via this tool, code runs with:

  • Restricted __builtins__ — eval, exec, compile, globals, locals, breakpoint, input, exit, quit are all removed. open, print, getattr/setattr, and common types/exceptions remain available.
  • Gated imports — only a curated subset of the standard library is importable: math, json, re, datetime, time, random, collections, itertools, functools, operator, string, textwrap, decimal, fractions, statistics, copy, pprint, base64, hashlib, hmac, struct, io, csv, pathlib, typing, dataclasses, enum, abc. Dangerous modules — os, subprocess, shutil, ctypes, socket, and third-party packages like psutil or mss — raise ImportError with guidance to use execute_script or run_command instead.
  • No filesystem access beyond output_dir — the code can open() files it writes into the provided output_dir variable, but cannot reach the rest of the filesystem without going through a gated import.

The LLM cannot escape this sandbox. Internal first-party callers (e.g. the agent's own screenshot capture path in agent/src/session_exec.py) pass trusted=True, which restores full builtins and unrestricted imports; that flag is not reachable from the LLM-exposed tool schema.

Returns: stdout from print(), plus any files written to output_dir.


read_file

Read the contents of a file on the remote machine.

parametertyperequireddescription
pathstringYesAbsolute file path (max 100KB)

write_file

Write content to a file on the remote machine.

parametertyperequireddescription
pathstringYesAbsolute file path
contentstringYesContent to write

list_directory

List the contents of a directory with file sizes and modification dates.

parametertyperequireddescription
pathstringYesAbsolute directory path

execute_script

Execute a PowerShell script on the remote machine with no command restrictions. Use for software installs, diagnostics, stress tests, service management, registry edits, or any other admin task. For most routine sysadmin scenarios, prefer a purpose-built Tier 2 tool (e.g. manage_windows_service, registry_operation, clean_disk_space) — execute_script is the escape hatch when no purpose-built tool fits.

parametertyperequireddescription
scriptstringYesPowerShell script to execute (can be multi-line)
timeout_secondsnumberNoTimeout in seconds (default: 120, capped at 3300 / 55 min) — set higher for long operations like installs
working_directorystringNoOptional working directory for script execution

Returns: stdout, stderr, exit code.

Timeouts are capped at 3300 seconds (55 minutes) so a result stays retrievable; for jobs that run longer than that, launch the work detached (e.g. a background job or scheduled task) and check back in a follow-up turn rather than blocking the tool call. A running execute_script can be cancelled from its tool card — the process tree is killed within a few seconds and the card resolves to "cancelled by user".


deploy_software

Deploy and install software on the remote machine using the full deployment pipeline: download installer, run silent install, verify installation, and track progress. Creates a tracked deployment visible on the Deployments page. Server-side — orchestrated by the server, not the agent directly.

Requires user confirmation before execution. hoot will summarize the deployment plan (software, version, install path, parallel install status, processes to close) and wait for explicit approval before proceeding.

parametertyperequireddescription
software_namestringYesSoftware name, e.g. TouchDesigner, Unreal Engine
versionstringNoVersion string, e.g. 2025.32280. Required for version-specific software
preset_idstringNoSystem preset ID from get_system_presets
installer_urlstringNoDirect HTTPS installer URL (overrides preset URL)
installer_namestringNoInstaller filename (auto-derived from URL if omitted)
silent_flagsstringNoSilent install flags (overrides preset value)
close_processesarrayNoProcess names to terminate before install, e.g. ["TouchDesigner.exe"]
parallel_installbooleanNoInstall alongside existing versions (auto-enabled for TouchDesigner)
timeout_minutesnumberNoMax installation time in minutes (default: 40)

TouchDesigner specifics: Download URL is auto-constructed from version number. parallel_install is automatically enabled to prevent the installer from removing existing builds. Use the full installer, not the WebInstaller.

Silent flag formats by installer type:

  • Inno Setup: /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /DIR="path"
  • NSIS: /S /D=path
  • MSI: /quiet /norestart INSTALLDIR="path"

reboot_machine

Reboot the remote machine with a 30-second countdown delay. Can be cancelled from the dashboard or via cancel_reboot within the countdown window.

parametertyperequireddescription
(none)

shutdown_machine

Shut down the remote machine with a 30-second countdown delay. The machine will NOT automatically restart.

parametertyperequireddescription
(none)

cancel_reboot

Cancel a pending reboot or shutdown. Must be called within the 30-second countdown window.

parametertyperequireddescription
(none)

security model

tool execution flow

LLM decides to call a tool
  |
  +-- Tier 3: pause for in-chat approval (when the per-site approval gate is on)
  |     +-- User approves: continue to the tool-name execution path
  |     +-- User denies: return "denied by user"
  |
  +-- Server-side tools
  |     +-- get_site_logs / get_system_presets query Firestore on the web server
  |     +-- deploy_software creates deployment records and install commands server-side
  |     +-- update_process / add_process / delete_process call process action functions server-side
  |     +-- create_talon / list_talons / set_talon_enabled call the talon store server-side
  |     +-- schedule_followup / cancel_followup write the chat's follow-up records;
  |         the once-a-minute cron sweep fires them, with tier 3 forced to wait
  |         for approval and site access re-resolved at fire time
  |
  +-- Legacy command-mapped tools
  |     +-- Write existing command types such as restart_process or reboot_machine
  |     +-- Agent handles the legacy command and writes completion state
  |
  +-- Firestore mcp_tool_call tools
        +-- Create an mcp_tool_call command in Firestore
        +-- Agent receives and executes the MCP tool
        +-- Agent writes result to completed queue
        +-- Turn runner polls for the result (bounded by the tool's own timeout)

The turn runs server-side, detached from the browser connection — it keeps executing and its results still land in the chat even if the connection drops or the page reloads, and the client reattaches to stream it. Long-running shell tools (run_command, run_powershell, execute_script) can be cancelled from their tool card mid-flight: the agent kills the process tree and the card resolves to "cancelled by user". The whole turn can be stopped server-side from the chat.

command allowlists

run_command enforces an allowlist on the agent side. Even if a command is sent via Firestore, the agent rejects it if the first command isn't in the allowlist. run_powershell has no allow-list — it accepts arbitrary PowerShell, with accountability provided by mandatory audit logging (site events feed + local [MCP-AUDIT] log). run_python enforces its sandbox on the agent side — the LLM cannot override the import gate or restore blocked builtins.

tier 2 blocklists

Tier 2 tools enforce per-tool blocklists to prevent self-inflicted outages:

  • manage_process — critical system processes (lsass, winlogon, csrss, etc.) cannot be killed
  • registry_operation — SAM, SECURITY, and Cryptography hives are unreachable; only an allowlist of safe key prefixes is permitted
  • manage_windows_feature — core Windows features Owlette depends on (NetFx4, WMI-*, PowerShell*) cannot be removed
  • create_talon — command outputs are site-admin only, and webhook URLs that resolve to private, loopback, or link-local addresses are rejected

Agent-executed Tier 2 tools emit structured [MCP-AUDIT] log entries for each invocation. Server-side process config tools use the process mutation audit path with actor cortex:user_<userId>. Talon tools emit talon_mutated rows with the same actor, via: "cortex", and the originating chat id. The follow-up tools emit no mutation row of their own — the follow-up document is the record, and the DELETE /api/hoot/followups/{followupId} route behind the composer chip audits its own cancels as chat_mutated / verb cancel_followup.

agent-side limits

  • Subprocess timeout: 25 seconds (default; overridable per-tool where applicable)
  • Max output size: 50KB
  • Screenshot max size: 10MB

On this page