Control Claude Code from your Apple Watch.
Speak prompts, see live activity, interrupt tasks — so you can touch grass while shipping code.
Uses your existing Claude subscription with zero additional API cost.
┌──────────────┐ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Claude Code │──WS───> │ Anthropic │ <──WS── │ Relay Server │ <─HTTP─ │ Apple Watch │
│ (terminal) │ <──WS── │ (relay API) │ ──WS──> │ (Node.js) │ ──SSE─> │ (SwiftUI) │
└──────────────┘ └─────────────┘ └──────────────┘ └─────────────┘
Why a relay? watchOS restricts WebSocket APIs to audio streaming apps only. The relay bridges Anthropic's WebSocket protocol to standard HTTP/SSE, which watchOS fully supports.
WatchCode bridges Claude Code's Remote Control WebSocket protocol to HTTP/SSE so watchOS can consume it. The relay server connects to Anthropic's API on behalf of the Watch, transforms raw session events into a compact format, and streams them over SSE.
The Watch app provides:
- Voice dictation to send prompts
- Live event feed showing Claude's responses, tool calls, and results
- Interrupt button to stop Claude mid-task
- Configurable relay URL and shared secret auth
| Component | Path | Description |
|---|---|---|
| Relay Server | server/ |
Node.js/Express bridge from WebSocket to HTTP/SSE |
| Web Client | client/ |
React interface for relay management and testing |
| Watch App | WatchCode/ |
SwiftUI watchOS app (Xcode project) |
- Node.js 20+
- An active Claude subscription with Claude Code
- Xcode 26+ (for the Watch app)
- An Apple Watch running watchOS 26+
npm install
cp server/.env.example server/.envEdit server/.env:
# Anthropic OAuth refresh token (recommended — auto-refreshes the access token)
# Extract from Keychain:
# security find-generic-password -s "Claude Code-credentials" -w \
# | python3 -c "import sys,json; print(json.loads(sys.stdin.read())['claudeAiOauth']['refreshToken'])"
ANTHROPIC_REFRESH_TOKEN=
# Or provide a short-lived access token directly (expires in ~10 hours, not recommended for deployment)
ANTHROPIC_TOKEN=
# Optional: your Anthropic org UUID (run: claude auth status)
ANTHROPIC_ORG_UUID=
# Shared secret for Watch app auth (generate: openssl rand -hex 32)
WATCHCODE_SECRET=
# Server port
PORT=3847# Development (with hot reload)
npm run dev:server
# Production
npm run build && npm start- Open
WatchCode/WatchCode.xcodeprojin Xcode - Select each target (
WatchCodeandWatchCode Watch App) and set your development team and bundle identifier under Signing & Capabilities - Build and run on your Apple Watch
- In the Watch app's Settings, enter your relay server URL and shared secret
A browser-based interface to the relay for testing and monitoring.
cp client/.env.example client/.envEdit client/.env:
# Must match the WATCHCODE_SECRET on the server
VITE_WATCHCODE_SECRET=your_secret_herenpm run dev:clientThe relay server can be deployed to any Node.js host (Railway, Fly.io, Render, etc.).
| Variable | Required | Description |
|---|---|---|
ANTHROPIC_REFRESH_TOKEN |
Recommended | Long-lived OAuth refresh token (auto-refreshes access tokens) |
ANTHROPIC_TOKEN |
Fallback | Short-lived OAuth access token (expires in ~10 hours) |
ANTHROPIC_ORG_UUID |
No | Anthropic organization UUID |
WATCHCODE_SECRET |
Recommended | Shared secret for request authentication |
PORT |
No | Server port (default: 3847) |
When no WATCHCODE_SECRET is set, the relay runs in open mode (suitable for local development only).
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/sessions |
List available Remote Control sessions |
POST |
/api/connect |
Connect to a session |
GET |
/api/sessions/:id/events |
SSE stream of session events |
POST |
/api/sessions/:id/message |
Send a user message |
POST |
/api/sessions/:id/control |
Send control commands (interrupt, etc.) |
DELETE |
/api/connections/:id |
Disconnect from a session |
GET |
/api/status |
Server health and active connections |
All endpoints require the x-watchcode-secret header when WATCHCODE_SECRET is configured.
- Automatic token refresh. When
ANTHROPIC_REFRESH_TOKENis set, the server refreshes access tokens automatically before they expire. - No credential storage. OAuth tokens are kept in memory and never written to disk by the relay.
- Shared secret auth. The
WATCHCODE_SECRETprevents unauthorized access to your relay. - TLS required in production. Deploy behind HTTPS to protect tokens in transit.
See ARCHITECTURE.md for detailed system design, protocol reference, and data flow diagrams.
MIT © 2026 Eric Li
