---
title: "AI agents and MCP | Kilobat Docs"
url: "https://kilobat.app/docs/agents"
description: "The MCP server, agent hooks, the agent network log, agent skills and keeping the Mac awake."
---

# AI agents and MCP

The MCP server, agent hooks, the agent network log, agent skills and keeping the Mac awake.

Step-by-step setup for [Claude Code](https://kilobat.app/agents/claude-code), [Codex](https://kilobat.app/agents/codex), [Cursor](https://kilobat.app/agents/cursor), [Gemini CLI](https://kilobat.app/agents/gemini-cli), [Claude Desktop](https://kilobat.app/agents/claude-desktop), [Windsurf](https://kilobat.app/agents/windsurf), [Cline](https://kilobat.app/agents/cline), [Zed](https://kilobat.app/agents/zed), [Hermes Agent](https://kilobat.app/agents/hermes), [OpenClaw](https://kilobat.app/agents/openclaw), [OpenCode](https://kilobat.app/agents/opencode), [GitHub Copilot CLI](https://kilobat.app/agents/copilot-cli) and [any MCP client](https://kilobat.app/agents/mcp-client) is in [Set up Kilobat in your AI agent](https://kilobat.app/agents).

Give an agent like Claude Code, Codex or Cursor this prompt:

```
Install the Kilobat CLI with `brew install seifip/kilobat/kilobat`. Run `kilobat diagnose --json`, `kilobat status --json` and `kilobat scan --json`, then tell me what is slowing my connection and how to fix it. Ask me before changing DNS, profiles or rules.
```

## MCP server

`kilobat mcp` speaks the Model Context Protocol over stdio. Add it to Claude Code:

```
claude mcp add kilobat -- kilobat mcp
```

Or add it to any client that reads an `mcpServers` config:

```
{ "mcpServers": { "kilobat": { "command": "kilobat", "args": ["mcp"] } } }
```

Read-only tools: `get_status`, `diagnose_network`, `diagnose_connection`, `get_conditions`, `get_updaters`, `get_uploads`, `get_data_pack`, `get_wifi`, `scan_wifi`, `suggest_wifi_channel`, `get_usage_report`, `compare_usage`, `get_app_bandwidth`, `get_access_policy`, `get_network_history`, `list_sessions`, `agent_network_log` (every host an agent and its commands contacted), `benchmark_dns`, `check_url`, `list_connections`, `list_devices`, `trace_route`, `get_route_history`, `compare_speed_tests`, `get_exit_path` (it asks Cloudflare for your public IP only when the agent passes `public_ip`), `check_vpn_leaks` (the leak test, which asks outside services), `list_networks`, `get_fastest_dns` (the fastest DNS per network from the app’s quiet runs), `list_rules`, `list_approvals`, `list_blocked_connections`, `explain_verdict` (every rule that matches a host or app, and the one that decides), `check_host_reputation` (whether a host is on a malware, phishing, scam or tracker list, checked on this Mac), `get_protection_status`, `run_stutter_test` and `get_game_ping` (they only send pings), `get_nearby_radios`, `get_captive_portal` (a Wi-Fi sign-in page, the same as `kilobat portal --json`), `service_status` (it asks the public status pages of the services named, or of the apps running) and `create_support_report` (the report for your provider, which the agent hands to you). They return the same JSON as the CLI. `run_speedtest` uses data, `run_lan_test` moves data on your own network for five seconds and asks first, and `keep_awake` and `release_awake` hold off idle sleep for a set time without changing settings; `keep_awake` with `lid_closed` keeps the Mac running with the lid shut too, once you allowed it, and asks you first. Change tools (`set_profile`, `set_app_rule`, `set_new_app_mode`, `decide_approval`, `block_destination`, `set_budget`, `set_data_pack`, `set_app_quota`, `set_network_cost`, `set_updater_pause`, `set_kill_switch`, `set_protection`, which also tells the agent never to turn Protection off to get its own request through, `hold_upload`, which holds another app’s upload, `set_dns`, which also flushes the cache, `set_fastest_dns`, `set_dns_fallback`, and `set_airdrop_visibility`, which opens AirDrop settings) are marked as changes, and their descriptions tell the agent to ask you first.

## Connect agents

Without help, Kilobat goes by an agent's traffic and CPU, so a quiet agent may be done or waiting for you. Its hooks tell Kilobat which project a run belongs to, when it waits for you and when it is done. Each hook runs `kilobat agent-event`, which prints nothing, returns at once and always exits 0, so it can't break the agent. If the app isn't running, events wait in a small file it reads when it opens. Kilobat reads session ids, folders and short status text, never prompts or replies. Merge these with any hooks you already have.

**Claude Code**, in `~/.claude/settings.json`. Each hook gets JSON on stdin with the session id and folder, which `--stdin-json` reads. A permission or input prompt means waiting; Stop means done once background tasks finish; a rate limit means waiting until it resets.

```
{
  "hooks": {
    "SessionStart": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent claude --stdin-json" }] }],
    "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent claude --stdin-json" }] }],
    "Notification": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent claude --stdin-json" }] }],
    "Stop": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent claude --stdin-json" }] }],
    "StopFailure": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent claude --stdin-json" }] }],
    "SessionEnd": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent claude --stdin-json" }] }]
  }
}
```

**Codex**, simplest: `notify` in `~/.codex/config.toml`. Codex passes a JSON argument after each turn, which `--json-arg` reads. It only says done, and Codex runs one `notify` program.

```
notify = ["kilobat", "agent-event", "done", "--agent", "codex", "--json-arg"]
```

For waiting too, use Codex hooks in `~/.codex/hooks.json` instead, and trust them with `/hooks`:

```
{
  "hooks": {
    "SessionStart": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent codex --stdin-json" }] }],
    "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent codex --stdin-json" }] }],
    "PermissionRequest": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent codex --stdin-json" }] }],
    "Stop": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent codex --stdin-json" }] }]
  }
}
```

**Gemini CLI**, in `~/.gemini/settings.json`. Gemini CLI runs as `node`, so Kilobat can't tie its traffic to the run, but the state comes through.

```
{
  "hooks": {
    "SessionStart": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent gemini --stdin-json" }] }],
    "BeforeAgent": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent gemini --stdin-json" }] }],
    "Notification": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent gemini --stdin-json" }] }],
    "AfterAgent": [{ "hooks": [{ "type": "command", "command": "kilobat agent-event --agent gemini --stdin-json" }] }]
  }
}
```

**Cline** (CLI, SDK and Kanban): install Kilobat's plugin, which adds one file to Cline's plugin store and changes no other settings. `cline plugin uninstall kilobat` removes it.

```
cline plugin install https://kilobat.app/agents/cline/kilobat.ts
```

It reports a run working, done, failed while Cline stays open, cancelled, rate-limited once Cline's own retries run out, and waiting while Cline asks you a question. It waits for subagents and teammates before calling a run done. Cline's approval prompts aren't visible to plugins, so traffic and CPU detection covers those.

Any other agent can call `kilobat agent-event start|working|waiting|done|failed --agent <name> --session <id> --cwd <folder>` from its own hooks. Add `--verbose` to see what happened when you try it by hand.

## Agent network log

While Claude Code, Codex, Cursor, Gemini CLI, Aider, Windsurf, Claude Desktop, ChatGPT or another agent runs, Kilobat records every host it and the processes it starts contacted: `npm`, `pip`, `uv`, `curl`, `git`, `brew`, MCP servers, also when a shell sits in between. Each session, from when the agent's process starts until it and everything it started exit, lists the hosts by the process that connected, most sent first, with the port and protocol, first and last seen, bytes sent and received and the number of connections, and the project folder the agent ran in. It's in History › Agent network log, and the menu shows one line while an agent runs, such as “Claude Code · 14 hosts · 2.1 MB up”. Copy as Markdown puts a session's table on the clipboard for an issue or a review.

Flags say what deserves a second look, never that something is wrong: *first time* (no agent on this Mac contacted that host before; well-known registries such as registry.npmjs.org, pypi.org and github.com, and the agent's own service, are never called new), *plain HTTP* (port 80), *large upload* (over 10 MB to one host other than the agent's own service, so Claude Code sending its context to Anthropic isn't flagged), *address only* (no hostname known) and *share or tunnel* (a short list of paste sites, file shares such as transfer.sh, tunnels such as ngrok and trycloudflare.com, and request catchers such as webhook.site). Only flagged shows just those.

How it works: Kilobat already reads macOS's per-connection network statistics every second (the same as `nettop`), with each connection's process. It recognises agents by their executable, the package an interpreter runs (`node …/@openai/codex`, `python3 -m aider`) or the app's own executable, and follows each agent's process tree: the kernel tells it the moment a process in the tree forks, so a `curl` that runs for a tenth of a second is placed while it runs, and processes reparented to launchd stay the agent's. The nearest agent wins, so Claude Code run in Cursor's terminal is Claude Code's. Hostnames come from Kilobat's network filter when it's on (the name an app asked for), from looking up well-known developer hosts and the hosts in an agent's `curl` or `git` URLs with your Mac's resolver and matching the addresses, or from reverse DNS, which is marked because it's the server's name, not the one the app asked for. Without any of these the row shows the address.

What it can't see: traffic that macOS services make for a process (DNS lookups go through mDNSResponder, downloads through `nsurlsessiond`), Docker containers and VMs (their traffic leaves through Docker's or the VM's own process), and agents inside an editor that run in its extension host, such as Cline or Copilot in VS Code, which can't be told apart from the editor. In Cursor and Windsurf, commands you type into their terminal count as the app's. A connection that opens and closes between two one-second samples still counts toward the session's bytes, without a host. A process that starts and exits before the kernel's fork notice is handled can be missed. The log is recorded with Kilobat Pro, only on this Mac, in `~/Library/Application Support/Kilobat/agent-network-log.json`, kept 30 days and never sent anywhere; Clear offers the last hour, today or everything.

With [Protection](https://kilobat.app/docs/blocking#protection) on, connections Kilobat refused show in the session too, marked Blocked with the list or agent-guard rule, even though they carried no bytes.

In the terminal, `kilobat agent-log` prints the latest session, or the agent's own when an agent runs it; `--all`, `--since 2h`, `--agent claude`, `--flagged` and `--json` narrow it. Reading is free, and `kilobat agent-log --watch` records live in the terminal without the app or Pro, saving nothing. Agents call the read-only MCP tool `agent_network_log`, which with no arguments returns their own session, so an agent can check what an install it ran talked to.

## Clear history or forget a site

In Settings › Data & privacy, *Forget a site* removes a host from Blocked attempts, the agent network log, agent runs’ and awake sessions’ destinations, and Protection’s notification memory. Include subdomains to also remove names such as www.example.com. Clear site history removes the same records for the last hour, since midnight or entirely. Blocked attempts and the agent network log also have their own Clear menus; a host row’s context menu offers Forget. Clearing history keeps your rules and protection settings. Future activity can be recorded again.

In Terminal, use `kilobat history forget example.com --subdomains --json` or `kilobat history clear --hour` (`--today` and `--all` are also available). The command asks the app to erase its live records when it is running, or edits the saved histories when it is closed. MCP `clear_history` does the same, only when you ask the agent to erase history. Deletion cannot be undone; the result counts entries removed from each history.

## While an app is in front

For reading or presenting, the teacup’s While an App Is in Front keeps the Mac awake only while the app you pick is the one in front, and lets it sleep again as soon as you switch away. Keep the screen on in the teacup decides whether the screen stays on too, as it does for everything Kilobat keeps awake. Kilobat follows macOS’s own app-switch events: it doesn’t poll, move the mouse or fake activity, so it can’t make you look present to monitoring software. It ends when the app quits, when you turn it off, or on battery at 20% (or the floor you set for lid-closed runs), and it never holds the lid. It has its own hold, so switching apps or quitting the app never ends an awake session or an agent run. From the terminal: `kilobat awake --while-frontmost Keynote --display`.

## While plugged in

Turn on Stay awake while plugged in (Settings › Awake & agents), or While Plugged In in the teacup, and plugging in the power adapter keeps the Mac awake until you unplug it, as the strip’s “Awake while plugged in” says. Keep the screen on decides whether the screen stays on too. Turn it off and it stays off until you next plug in, even if Kilobat restarts. Kilobat hears the switch from macOS’s own power-source notification, without polling. Unplugging ends only the session plugging in started: one you started yourself, a download you’re waiting on, an app in front, an agent run or a hold from the terminal carries on. It never keeps the Mac running with the lid closed. From the terminal: `kilobat settings awake-on-power on`, and `kilobat settings keep-screen-on on` for the screen; `kilobat conditions --json` reports it as `awakeOnPower`.

## Running with the lid closed

Closing the lid sleeps the Mac, even while Kilobat keeps it awake, unless you allow running with the lid closed in Settings › Awake & agents. That installs a small helper that runs as root; macOS asks you to allow it in System Settings › General › Login Items. With it on, a working agent run keeps the Mac going with the lid shut, and so does an awake session when you tick With the Lid Closed Too in the teacup menu. An agent waiting for you holds it only with Keep awake while an agent waits on, and for 30 minutes at most.

A closed Mac in a bag can overheat and run its battery flat, so the helper itself lets the Mac sleep at your battery floor (20% by default), when the Mac runs hot, as soon as it’s unplugged if you choose power only, after the longest stretch you set (8 hours at most), and a minute after Kilobat quits. If the helper or the Mac restarts while holding, it puts the setting back first. Kilobat shows how each hold ended, for example “Let the Mac sleep: battery at 20%”.

From the terminal, `kilobat awake --lid-closed` asks the app for the same hold and says why when it can’t; the hold ends with the command. Agents use `keep_awake` with `lid_closed`, which its description tells them to confirm with you first. `kilobat conditions --json` reports `lidClosedAllowed` and the current `lidHold`.

## Agent skills

Nine Agent Skills teach coding agents to troubleshoot a Mac's network and keep long runs going with Kilobat. They interpret its measurements, explain what is uncertain and ask before changing settings. Install them together; the `kilobat` skill sends the agent to the one that fits.

```
npx skills add seifip/kilobat-skills
```

|  |  |
|---|---|
| [kilobat](https://github.com/seifip/kilobat-skills/tree/main/skills/kilobat) | Start here. Setup, safety rules and which skill fits the question. |
| [mac-network-troubleshooting](https://github.com/seifip/kilobat-skills/tree/main/skills/mac-network-troubleshooting) | Slow or unreliable internet with an unclear cause: finds the failing layer. |
| [mac-wifi-troubleshooting](https://github.com/seifip/kilobat-skills/tree/main/skills/mac-wifi-troubleshooting) | Weak or dropping Wi-Fi, crowded channels, the best spot for the Mac or router. |
| [mac-hotspot-data-saver](https://github.com/seifip/kilobat-skills/tree/main/skills/mac-hotspot-data-saver) | Phone hotspots and data caps: what uses data, Travel profile, budgets. |
| [mac-dns-troubleshooting](https://github.com/seifip/kilobat-skills/tree/main/skills/mac-dns-troubleshooting) | Slow lookups, resolver benchmarks, switching DNS, captive portals. |
| [video-call-network-check](https://github.com/seifip/kilobat-skills/tree/main/skills/video-call-network-check) | Stuttering calls and game streams: latency spikes, jitter, loss, bufferbloat and background uploads. |
| [mac-bandwidth-monitor](https://github.com/seifip/kilobat-skills/tree/main/skills/mac-bandwidth-monitor) | Which apps use the connection, usage history and where they connect. |
| [mac-app-firewall](https://github.com/seifip/kilobat-skills/tree/main/skills/mac-app-firewall) | Block or allow apps, domains and IPs; ask about new apps and answer them. |
| [mac-agent-runs](https://github.com/seifip/kilobat-skills/tree/main/skills/mac-agent-runs) | Long agent runs: keep the Mac awake, check conditions, connect agent hooks, see when a run finished, waits for you or stalled. |

Install the Kilobat CLI separately with the Homebrew command above, or connect its MCP server. The CLI requires macOS 14 or later; the Homebrew source build requires Xcode 16 or later. See the [skills on skills.sh](https://skills.sh/seifip/kilobat-skills) or [read their source and references](https://github.com/seifip/kilobat-skills).

## Siri and Shortcuts

Ask Siri about your connection and Kilobat answers from its own checks, in a sentence or two, with a card of the numbers. Say the app’s name in the question, as Siri needs: “Why is my internet slow in Kilobat?” runs a fresh check and names the cause: “Your Wi-Fi is fine; your provider’s line is losing 4% of packets since 9:05 PM. It’s in your provider report.” The others: “Is my connection OK in Kilobat?”, “Why did my call freeze in Kilobat?” (the last call report), “Is Slack down in Kilobat?” (any service with a status page Kilobat reads, or “Are my apps down in Kilobat?” for the ones you’re using), “What’s using my internet in Kilobat?”, “How much data have I used in Kilobat?”, “Am I ready for my call in Kilobat?”, “Is my VPN leaking in Kilobat?” and “Test speed with Kilobat”. The same questions work from Spotlight, and each is an action in the Shortcuts app that hands its answer to the next step: the network status with its health, cause, latency and loss; the call report; the services and whether they report an outage; today’s data as a size. Shortcuts’ Use Model action can take those results to Apple Intelligence. Without Kilobat Pro, Siri says what’s wrong and how the line measures, how many times a call froze and whether a service is down; Pro adds why and what to do. [Ready-made shortcuts](https://kilobat.app/shortcuts) build on the same actions.
