Claude Code (CLI)
supported
Registers a local stdio server with the claude CLI. This is the
path the project itself runs on, and bin/install-claude-code.sh does
nothing more than compose and run the command below — no key to type or paste;
the server pairs itself on first use.
Install — the script (dry run first, always)
bin/install-claude-code.sh # prints the exact command
bin/install-claude-code.sh --apply # actually registers it
It is idempotent: if claude mcp list already
names hawkeye it changes nothing. On first tool call afterwards, the server
prints a short device code and a gethawkeye.app/pair URL — open it,
approve the device once, and every following call authenticates with the
resulting token. No --key flag exists any more; it was retired
with the master-key model.
Install — by hand, if you would rather not run a script
claude mcp add hawkeye --scope user -- node /path/to/hawkeye/mcp-server/supervisor.js
supervisor.js, not server.js directly —
it respawns the real server across a self-update without the client noticing.
--scope user registers it for every project, not just this one;
claude mcp add --help lists the other scopes (local, project).
Verify
claude mcp list
Expected: a line naming hawkeye. Then start Claude Code and ask it to call hawk_health.
If the tools do not appear inside a session, the client
did not load the server — restart Claude Code after registering.
Claude Desktop
supported · macOS + Windows
Claude Desktop installs a local stdio server as an .mcpb extension
bundle (the format previously called .dxt): a zip with
manifest.json at its root. Hawkeye builds one from the source tree.
The bundle declares darwin and win32 only — Claude
Desktop ships for macOS and Windows, so advertising Linux here would be false;
on Linux use the Claude Code or Codex CLI cards instead.
Build the bundle
bin/build-mcpb.sh
# -> dist/hawkeye-bridge-<version>.mcpb
The manifest is generated, never hand-written: the
<version> in that filename is
mcp-server/package.json's, and the tool list is regenerated from
the server's own tools/list, so the bundle cannot advertise a tool
the server does not have. Run the command and it prints the exact path.
Install it
Claude Desktop -> Settings -> Extensions -> install the .mcpb file
No key to enter — the dialog only asks for optional fleet-location overrides
The manifest's user_config is now four optional
URL fields (Worker / VM / PC / SOCKS proxy), not a credential — the
master-key field is gone entirely. They default to this project's own fleet; change
them in the same dialog to your machines' tunnels, or the tools will call
somewhere you do not own. On first tool call the server pairs itself: a short
device code and a gethawkeye.app/pair URL appear in the chat, you
approve the device once in a browser, and the resulting token is stored by the
server, not by Claude Desktop.
Verify
# macOS
ls ~/Library/Application\ Support/Claude/Claude\ Extensions
# Windows (PowerShell)
dir "$env:APPDATA\Claude\Claude Extensions"
Expected: the extension listed there, and Hawkeye Bridge visible under Settings -> Extensions.
Then ask Claude for hawk_health in a new chat.
An extension that installed but shows no tools usually means the app needs a
restart.
ChatGPT desktop app — Codex mode, and the Codex CLI
supported
There is no separate “Codex desktop app”: Codex is a mode inside
the ChatGPT desktop app for macOS and Windows, and that mode — like the Codex
CLI — reads ~/.codex/config.toml and runs local stdio MCP servers.
Both are wired by the same file, so one script does both.
Install
bin/install-codex.sh # dry run: prints the exact block
bin/install-codex.sh --apply # writes it (existing file backed up alongside)
Or write it yourself — ~/.codex/config.toml
[mcp_servers.hawkeye]
command = "node"
args = ["/path/to/hawkeye/mcp-server/server.js"]
It must be the user-level
~/.codex/config.toml. The desktop app ignores a project-scoped
.codex/config.toml (openai/codex#13025), which is why the installer
writes the user-level file even when you are inside a repo. No
[mcp_servers.hawkeye.env] table — there is no key to write, in
plaintext or otherwise; the server pairs itself on first tool call instead
(a device code and a gethawkeye.app/pair URL print in the reply,
you approve once in a browser, the token is stored by the server).
Verify
grep -A4 'mcp_servers.hawkeye' ~/.codex/config.toml
Expected: the command and args you just wrote. Restart the app or CLI, then ask for hawk_health.
Any other MCP client
manual setup
Hawkeye is an ordinary stdio MCP server with no client-specific code in it, so
anything that can launch a subprocess and speak MCP over stdin/stdout can use it.
Most clients take one of these two shapes. Point command at a Node
binary and args at mcp-server/server.js — no credential
belongs in either shape below; the server pairs itself on first tool call. The
env block is optional and only for overriding which fleet the server
talks to, shown here so a client that requires the field can still be satisfied.
JSON (the shape most clients use)
{
"mcpServers": {
"hawkeye": {
"command": "node",
"args": ["/path/to/hawkeye/mcp-server/server.js"]
}
}
}
TOML (Codex-style clients)
[mcp_servers.hawkeye]
command = "node"
args = ["/path/to/hawkeye/mcp-server/server.js"]
# optional — only if you run your own control-plane worker
[mcp_servers.hawkeye.env]
HAWK_WORKER = "https://your-worker.example"
Verify — without trusting any client's UI
NODE_BIN="$(bin/require-node-sqlite.sh)" || exit 1
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| "$NODE_BIN" mcp-server/server.js | grep -c '"name":"hawk_health"'
Expected: 1
That is the MCP handshake done by hand: initialize, then
tools/list. It needs no key (only tools/call is gated),
it exits as soon as stdin closes, and it proves the server itself works before
you start blaming a client. Swap the grep for
grep -o '"name":"[a-z_]*"' | sort -u | wc -l and it prints
81.
ChatGPT chat mode, and the mobile apps
not possible today
Said plainly rather than buried: you cannot connect ChatGPT's ordinary
chat mode, or any phone app, to Hawkeye right now. Those surfaces accept
only a remote MCP endpoint (Streamable HTTP/SSE, with OAuth or nothing).
Hawkeye is stdio-only — it runs as a subprocess next to your files — so
there is nothing for them to point at. “ChatGPT works” is true of Codex
mode and false of chat mode, and collapsing the two would be the lie.
No remote MCP endpoint is configured on this deployment, so
there is nothing to paste into a connector field. An operator sets
MCP_REMOTE_URL once such an endpoint exists; until then, use a
computer client above — those are live today.
Why it is not just switched on: Hawkeye is root-equivalent on
the machines it reaches. An internet-facing relay for that, without an
authorization story worked out first, is more attack surface than the feature
is worth.