MCP Server
Set up @hwip/mcp-server so your agent can reach your phone.
Your agent calls hwip_ask; the question lands on your phone as buttons and a text field; your
reply comes back into the same tool call and the agent keeps going.
@hwip/mcp-server is the agent side of that round trip, plus one-way notifications, clipboard,
files, channel broadcasts, and messages to other agent sessions — all over the
Model Context Protocol. It works with Claude Code, Cursor,
Windsurf, Gemini CLI, and any MCP client.
It needs the Hwip app signed in on an iPhone. With no app signed in, nothing is sent and the tool says so.
Setup
The easiest way to set up the agents on your machine in one go:
npm install -g @hwip/cli
hwip installThat saves credentials to ~/.hwip/config.json and configures your agents automatically. The MCP
server reads from that file — no environment variables needed. It needs Node 18.17 or later. On
Node 22 or later hwip_ask hears the answer over a WebSocket the moment it is given; on older
Node it polls.
Install the CLI globally so hwip cc works and hooks skip an npx cold start.
npx @hwip/cli install is a notifications-only alternative. See the CLI for the full
install.
Claude Code, by hand
Install the server once, so each session starts the hwip-mcp binary directly:
npm install -g @hwip/mcp-serverThen add this to ~/.claude/settings.json:
{
"mcpServers": {
"hwip": {
"command": "hwip-mcp"
}
}
}Without a global install, "command": "npx", "args": ["-y", "@hwip/mcp-server"] works too. It only
starts slower, because every session resolves the package first.
No env block is needed — credentials come from ~/.hwip/config.json, written by hwip install.
Add environment variables only to override the file, for example a second account:
"env": { "HWIP_API_KEY": "ak_other_account" }Cursor and other MCP clients
{
"command": "hwip-mcp"
}Or "command": "npx", "args": ["-y", "@hwip/mcp-server"] without a global install.
Environment variables
| Variable | Required | Description |
|---|---|---|
HWIP_API_KEY | Yes* | API key from Settings → API Keys |
HWIP_HOOK_ID | No | Hook ID. Only needed for hwip_ask |
HWIP_DEVICE_ID | No | Default target device for hwip_notify, hwip_clipboard and hwip_file. A call's own targetDeviceId wins. Omit to send to all devices. hwip_ask does not use it |
HWIP_BASE_URL | No | API base URL (default: https://api.hwip.app/v1). A base URL that answers with a redirect is refused, because requests that carry your API key never follow one |
HWIP_WS_URL | No | Deprecated. WebSocket endpoint. wsUrl in ~/.hwip/config.json wins over it and is where the value belongs; it is read only when the file has none. It will stop being read |
HWIP_DISABLE_SESSION_CACHE | No | Set to 1 or true to skip writing the session-id handoff file under ~/.cache/hwip/. Useful for read-only filesystems, ephemeral CI runners, or sandboxes that audit filesystem writes. The plugin's stop hook still works without it |
HWIP_SESSION_ID | No | Override the session id attached to pushes, which controls grouping in the app. Auto-detected from the newest Claude Code transcript when unset |
* If the environment variables are not set, the server reads ~/.hwip/config.json, created by
hwip install or hwip login. Unresolved ${...} interpolations are also treated as unset.
Without an API key the server stops at start and says why.
The config file
~/.hwip/config.json holds apiKey, baseUrl, wsUrl, hookId and deviceId. For every key
except wsUrl the environment variable wins. The server checks the file before reading it:
- If another user owns it, or anyone can write it, the file is ignored and a line on stderr says
so. Run
chmod 600 ~/.hwip/config.json. - If the group can read or write it, or others can read it, it is used with a warning.
- A key from the file does not follow a different
HWIP_BASE_URL. If the variable names another origin, the server stops at start untilHWIP_API_KEYis set too, or the variable is unset.
API key permissions
The API key needs these scopes:
push:read— forhwip_listpush:write— forhwip_notify,hwip_clipboard,hwip_dismiss,hwip_dismiss_all,hwip_file,hwip_agent_sendhook:write— forhwip_askdevice:write— forhwip_session_renamechannel:read— forhwip_channelsand thehwip://channelsresource
hwip_agent_list and hwip_agent_read need no scope: they run the local hwip CLI and never call
the API.
Create an API key with the MCP preset in Settings → API Keys to get the right permissions.
Encryption
End-to-end encryption is always on; there is no switch. hwip_notify and hwip_file seal what
they send, hwip_ask seals the question and its answer, and hwip_agent_send seals the message
for the target computer. hwip_clipboard and hwip_broadcast are not sealed, so do not use
them for secrets.
Nothing falls back to plaintext. A send that cannot be sealed sends nothing and returns an error that names the reason. The threat model and its limits are documented once, under CLI → Encryption.
Two things are specific to this server:
- Its keypair lives in
~/.hwip/device-keys.json, shared withhwip listener. - When this machine is missing from the account's device list, the server puts its public key there before the first sealed send.