Skip to main content

System and processes

The system tools read the state of a machine. Every tool except network_scan accepts the server argument.

system_status​

read

Returns CPU, memory, disk and uptime for the machine that runs the MCP server, or for a remote server. Inside a container the call is refused. See Run in a container.

Arguments​

ArgumentTypeDescription
serverstringServer from your config to run on. See Run a tool on another server.

Response​

FieldTypeMeaning
schema_versionintegerVersion of the document shape. Always 1.
hostnamestringHost name of the machine.
osstringOperating system, such as linux.
archstringCPU architecture, such as amd64.
uptimestringTime since boot, as text such as 14h 53m.
cpuobjectCPU load.
cpu.usage_percentnumberCPU use, in percent.
cpu.coresintegerNumber of CPU cores.
memoryobjectMemory use.
memory.total_gbnumberTotal memory, in GB.
memory.used_gbnumberMemory in use, in GB.
memory.usage_percentnumberMemory use, in percent.
disksarray of objectsOne entry for / and one for each file system mounted at a path that starts with /home, /mnt or /Volumes.
disks.mountstringMount point.
disks.total_gbnumberSize of the file system, in GB.
disks.used_gbnumberSpace in use, in GB.
disks.usage_percentnumberSpace in use, in percent.
timestringLocal time on the machine when the values were read, in RFC 3339 format.
Examples

Call it with no arguments to read the local machine. The response, with the disk entries of two internal mounts removed:

{
"schema_version": 1,
"hostname": "homelab",
"os": "linux",
"arch": "amd64",
"uptime": "15h 18m",
"cpu": {
"usage_percent": 0,
"cores": 4
},
"memory": {
"total_gb": 7.75,
"used_gb": 3.08,
"usage_percent": 39.8
},
"disks": [
{
"mount": "/",
"total_gb": 19,
"used_gb": 1.3,
"usage_percent": 7
}
],
"time": "2026-10-25T11:36:57-07:00"
}

processes​

read

Lists the top processes by CPU or memory, with the total process count and every zombie process. The output carries process names only, never command lines.

Arguments​

ArgumentTypeDescription
limitintegerNumber of processes to return. 0 returns all of them. Default: 10.
sort_bystringSort key: cpu or mem. Any other value sorts by cpu. Default: cpu.
serverstringServer from your config to run on. See Run a tool on another server.

Response​

FieldTypeMeaning
processesarray of objectsThe top limit processes, highest first.
processes.pidintegerProcess ID.
processes.namestringThe kernel's process name (ps comm), at most 15 characters. A Node.js process shows MainThread.
processes.cpunumberCPU use as ps reports it (pcpu), in percent.
processes.memnumberShare of physical memory in use, in percent.
processes.rssintegerResident memory, in kilobytes.
processes.statestring, optionalProcess state letter from ps, such as S for sleeping or R for running.
processes.zombieboolean, optionaltrue for a zombie process. Left out otherwise.
totalintegerNumber of processes found, before limit is applied.
zombiesarray of objects, optionalEvery zombie process on the machine, whatever limit is. Left out when there are none.
zombies.pidintegerProcess ID.
zombies.namestringThe kernel's process name (ps comm).
zombies.cpunumberCPU use, in percent.
zombies.memnumberMemory share, in percent.
zombies.rssintegerResident memory, in kilobytes.
zombies.statestring, optionalProcess state letter. Z for a zombie.
zombies.zombieboolean, optionalAlways true.
Examples

Ask for the two processes that use the most memory. The response, shortened to the first of six zombie entries:

Arguments:

{
"limit": 2,
"sort_by": "mem"
}

Response:

{
"processes": [
{
"pid": 282567,
"name": "python3",
"cpu": 3.4,
"mem": 26.3,
"rss": 2142168,
"state": "S"
},
{
"pid": 1888,
"name": "dockerd",
"cpu": 4.2,
"mem": 1.2,
"rss": 101252,
"state": "S"
}
],
"total": 123,
"zombies": [
{
"pid": 282919,
"name": "python3",
"cpu": 0,
"mem": 0,
"rss": 0,
"state": "Z",
"zombie": true
}
]
}

open_ports​

read

Lists TCP ports that are listening, with the process behind each one. Without root privileges the process is not readable for many ports, and the result sets missing_process to say so.

Arguments​

ArgumentTypeDescription
serverstringServer from your config to run on. See Run a tool on another server.

Response​

FieldTypeMeaning
portsarray of objectsOne entry per listening socket. A port bound on IPv4 and IPv6 appears twice.
ports.protocolstringTransport protocol. tcp.
ports.addressstringAddress the socket is bound to, such as 0.0.0.0, 127.0.0.1 or [::]. A socket bound to 0.0.0.0 or [::] is reachable from other machines, and a socket bound to a loopback address such as 127.0.0.1 is not.
ports.portstringPort number, as a string.
ports.pidstring, optionalProcess ID holding the socket. Left out when the process is not readable.
ports.processstring, optionalName of the process holding the socket. Left out when the process is not readable. On Linux a published container port shows docker-proxy.
ports.containerstring, optionalContainer that publishes the port, as name (image). inventory_scan fills it in. This tool leaves it out.
missing_processboolean, optionaltrue when at least one port has no process name. Left out otherwise.
Examples

Run as root, the process behind each port is readable. The response, shortened to three ports:

{
"ports": [
{
"protocol": "tcp",
"address": "0.0.0.0",
"port": "8102",
"pid": "383608",
"process": "docker-proxy"
},
{
"protocol": "tcp",
"address": "0.0.0.0",
"port": "8101",
"pid": "396972",
"process": "docker-proxy"
},
{
"protocol": "tcp",
"address": "0.0.0.0",
"port": "22",
"pid": "519",
"process": "sshd"
},
{
"protocol": "tcp",
"address": "[::]",
"port": "8102",
"pid": "383614",
"process": "docker-proxy"
},
{
"protocol": "tcp",
"address": "[::]",
"port": "8101",
"pid": "396983",
"process": "docker-proxy"
},
{
"protocol": "tcp",
"address": "[::]",
"port": "22",
"pid": "519",
"process": "sshd"
}
]
}

Run as an ordinary user, the same call returns ports without pid and process and sets missing_process. The response, shortened to one port:

{
"ports": [
{
"protocol": "tcp",
"address": "0.0.0.0",
"port": "22"
}
],
"missing_process": true
}

network_scan​

read

Discovers devices on the local network. It pings every address on the subnet, reads the ARP table, and resolves host names. The scan runs for up to 30 seconds, so call it when someone asks about the network. The tool takes no server argument.

Arguments​

This tool takes no arguments.

Response​

FieldTypeMeaning
hostnamestring, optionalName from a reverse DNS lookup. Left out when none resolves.
ipstringIPv4 address of the device.
macstringMAC address from the ARP table.
statusstringAlways up.
Examples

The scan needs the arp command on the machine. On a Linux host without it, the call returns an error:

failed to read ARP table: exec: "arp": executable file not found in $PATH

The output is an array with one entry per device, each with the fields above. The array is empty when no device answered.

alerts​

read

Compares CPU, memory and each disk with the thresholds in the alerts: section of your config and returns a status for each. Nothing is sent and nothing is recorded: a running watcher does that.

Arguments​

ArgumentTypeDescription
serverstringServer from your config to run on. See Run a tool on another server.

Response​

FieldTypeMeaning
cpuobjectCPU result.
cpu.statusstringok, warning or critical. critical means the current value is at or over the threshold. warning means it is at or over 90% of the threshold.
cpu.currentnumberCurrent CPU use, in percent.
cpu.thresholdnumberThreshold from the config, in percent.
memoryobjectMemory result.
memory.statusstringok, warning or critical, with the same rule as cpu.status.
memory.currentnumberCurrent memory use, in percent.
memory.thresholdnumberThreshold from the config, in percent.
disksarray of objectsOne entry for / and one for each file system mounted at a path that starts with /home, /mnt or /Volumes.
disks.mountstringMount point.
disks.statusstringok, warning or critical, with the same rule as cpu.status.
disks.currentnumberCurrent space in use, in percent.
disks.thresholdnumberThreshold from the config, in percent.
Examples

With cpu: 1 and memory: 1 in the config's alerts: section, memory is over its threshold. The response, with the disk entries of two internal mounts removed:

{
"cpu": {
"status": "ok",
"current": 0.25,
"threshold": 1
},
"memory": {
"status": "critical",
"current": 40.72,
"threshold": 1
},
"disks": [
{
"mount": "/",
"status": "ok",
"current": 7,
"threshold": 90
}
]
}

alerts_history​

read

Returns the alert and remediation events that a running watcher recorded. Only a watcher writes entries, so an empty array means nothing was recording, not that nothing went wrong.

Arguments​

ArgumentTypeDescription
serverstringServer from your config to run on. See Run a tool on another server.

Response​

FieldTypeMeaning
action_resultstringHow that action ended.
action_takenstringWhat homebutler did about it.
detailsstringDescription of the event.
metricstringThe measurement the rule watches.
rulestringName of the alert rule that fired.
timestampstringWhen the event was recorded, in RFC 3339 format.
Examples

Without a running watcher, the response is an empty array:

[]