Krill MCP & Claude Skill on macOS
Wire Claude Desktop on macOS up to a local krill-mcp server via the mcp-remote stdio bridge, and install the companion Krill Claude skill so every project gets it.
Setting up Claude Desktop on macOS
The main krill-mcp post covers the swarm-side install — apt install krill-mcp on a Pi, paste the bearer into a Custom Connector, done. That works as written for Claude Code and for Claude Desktop on Linux. On macOS, Claude Desktop’s Custom Connector UI rejects http:// URLs outright — it only accepts https://. krill-mcp itself speaks plain HTTP on port 50052; security comes from the PIN-derived bearer, not TLS. So the Custom Connector path doesn’t work on macOS for a LAN-local Krill swarm without a TLS terminator in front.
The clean way around it is the same path the wider MCP ecosystem uses for self-hosted servers: run mcp-remote as a stdio bridge between Claude Desktop and the HTTP MCP endpoint. No certs, no reverse proxy, just one entry in Claude Desktop’s config file.
This post is the macOS-specific recipe. It assumes you already followed the main post and have krill-mcp running on a Pi (or any Debian box on your LAN) with a valid bearer.
Why a bridge?
Three facts in tension:
krill-mcpis HTTP. It’s a small Ktor service on:50052that authenticates every/mcprequest against a 64-char bearer derived from your cluster PIN. There’s no TLS listener — the wire contract isBearerover plain HTTP, intended for LAN traffic.- Claude Desktop on macOS requires HTTPS. The Custom Connector dialog won’t even let you save an
http://URL. (Linux Claude Desktop and Claude Code have no such restriction.) - Claude Desktop does support stdio MCP servers via
~/Library/Application Support/Claude/claude_desktop_config.json. That path doesn’t go through the HTTPS-only UI.
mcp-remote is a tiny Node.js package that speaks MCP over stdio on one end and over HTTP on the other. Drop it into the stdio config and Claude Desktop gets the full MCP tool surface without ever knowing the upstream is HTTP.
1
2
3
4
5
┌──────────────────┐ stdio ┌─────────────┐ HTTP/Bearer ┌──────────────┐
│ Claude Desktop │──────────▶│ mcp-remote │────────────────▶│ krill-mcp │
│ (macOS app) │ JSON-RPC │ (npx, on │ :50052/mcp │ (on Pi) │
└──────────────────┘ │ your Mac) │ └──────────────┘
└─────────────┘
1. Install Node.js
mcp-remote is distributed via npm and run with npx. On macOS the easiest source is Homebrew:
1
brew install node
Verify:
1
2
which npx # /opt/homebrew/bin/npx (Apple Silicon) or /usr/local/bin/npx (Intel)
node --version # v22+ is fine; anything modern works
You don’t need to run npm install for mcp-remote separately — npx -y mcp-remote@latest handles fetching and caching on first launch.
2. Install the companion Claude skill (once, for all projects)
The skill lives in the OSS repo. Clone it somewhere stable on your Mac, then symlink it into ~/.claude/skills/ so it’s picked up by every Claude install on the machine — and so git pull updates the skill without any further action:
1
2
3
cd ~/Code # or wherever you keep source trees
git clone https://github.com/bsautner/krill-oss.git
ln -s "$(pwd)/krill-oss/krill-mcp/skill/krill" ~/.claude/skills/krill
Verify:
1
ls -l ~/.claude/skills/krill # should show the symlink target
Pulling updates is just git pull in the cloned repo — the symlink keeps your skill current with whatever’s on main. If you previously copied the skill (rather than symlinked), remove the static directory first or the symlink command will fail.
3. Grab the bearer token
On the Pi running krill-mcp:
1
sudo krill-mcp-token
That prints the bearer and the Custom Connector URL. The bearer is 64 hex characters. Copy it — you’ll paste it into the next step.
If you’ve never seen krill-mcp-token, you’re on an older build; the bearer is also the contents of /etc/krill-mcp/credentials/pin_derived_key on the Pi. Same value either way.
4. Wire up Claude Desktop’s config
Quit Claude Desktop fully (⌘Q — closing the window isn’t enough; the menu bar icon needs to be gone) so it doesn’t overwrite your edits.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json. If the file doesn’t exist yet, create it. If it does, back it up first and merge the new block into the existing JSON:
1
cp ~/Library/Application\ Support/Claude/claude_desktop_config.json{,.bak.$(date +%Y%m%d-%H%M%S)}
Add (or merge) an mcpServers block. Replace <your-host> with whatever resolves to the Pi on your LAN (e.g. pi-krill-05.local if you’re using mDNS) and <bearer> with the token from step 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"mcpServers": {
"krill": {
"command": "/opt/homebrew/bin/npx",
"args": [
"-y",
"mcp-remote@latest",
"http://<your-host>:50052/mcp",
"--allow-http",
"--transport",
"http-only",
"--header",
"Authorization:Bearer <bearer>"
]
}
}
}
Three details that matter:
- Use the absolute path to
npx. Claude Desktop launches subprocesses with a minimalPATHthat doesn’t include Homebrew./opt/homebrew/bin/npxon Apple Silicon,/usr/local/bin/npxon Intel. If you skip the absolute path you’ll get a silent “MCP server failed to start” with no useful error. --allow-httpis required.mcp-remoterefuses HTTP URLs by default; this flag opts in. Safe for LAN traffic to your own Pi; do not use it for anything traversing the public internet.--transport http-onlytellsmcp-remoteto skip the legacy SSE handshake and go straight to MCP Streamable HTTP.krill-mcpis Streamable-HTTP only, and without this flag you’ll see extra error noise on startup (harmless but ugly).
If you already have other entries under mcpServers, just add krill alongside them. The whole file is a single JSON object — make sure the brackets and commas balance after your edit. A quick sanity check:
1
python3 -m json.tool ~/Library/Application\ Support/Claude/claude_desktop_config.json > /dev/null && echo OK
The config file is mode 600 by default — owner-only — which is the right place to keep the bearer.
5. Launch Claude Desktop
Reopen Claude Desktop. The first launch runs npx -y mcp-remote@latest once and populates the npx cache (~5–10 seconds the first time, instant after that).
Verify the connector is live: open a new chat and ask Claude something like “list my Krill servers” — Claude should call list_servers and come back with the swarm. The krill skill activates automatically as soon as your prompt mentions a Krill swarm, a node type, or a dashboard.
What you’ll see in the logs
mcp-remote’s stderr ends up in Claude Desktop’s MCP log pane. Expect a few lines that look alarming but are benign:
1
Error from remote server: StreamableHTTPError: Failed to open SSE stream: Not Acceptable (406)
mcp-remote always tries to open an SSE notification channel alongside the main JSON-RPC stream, even with --transport http-only. krill-mcp doesn’t implement SSE notifications — it only does the per-call request/response over POST /mcp — so the server returns 406 and mcp-remote logs it as an error. Tool calls are completely unaffected; this is just noise.
If you want to see the actual JSON-RPC traffic, the logs in Claude Desktop → Settings → Developer → MCP Logs show every Local→Remote and Remote→Local frame.
Rotating the bearer
If you change the cluster PIN on a Pi, the bearer rotates with it. After the new PIN is in place, repeat step 3 to print the new token, swap it into the Authorization:Bearer ... arg in claude_desktop_config.json, and restart Claude Desktop. There’s no other state to clean up.
Troubleshooting
- “MCP server failed to start” on launch. Almost always
commandnot found — use the absolute path tonpx(step 4). tools/listworks but tool calls hang. The Pi’s:50052is open from your Mac (trycurl -i http://<host>:50052/healthz) but the bearer is wrong. Re-runsudo krill-mcp-tokenon the Pi and confirm the value matches.curlto:50052from your Mac times out. Firewall or routing. mDNS names need the.localsuffix; if mDNS isn’t resolving (corporate networks sometimes block it), use the Pi’s IP directly.- Claude finds tools but doesn’t seem to understand the swarm. The skill isn’t loaded. Check
~/.claude/skills/krillexists and that you fully quit and relaunched Claude Desktop after creating the symlink.
What this gets you
Once it’s wired up, every prompt that touches a Krill swarm — the four examples in the main post all work the same here — flows through the bridge with no perceptible latency. Claude Desktop on macOS gets parity with Claude Code and with Claude Desktop on Linux. The skill auto-activates on Krill-shaped prompts. And because the skill is symlinked into ~/.claude/skills/, it’s picked up by every project on this Mac without per-project configuration.
- MCP server source: github.com/bsautner/krill-oss/krill-mcp
- Companion skill: github.com/bsautner/krill-oss/krill-mcp/skill/krill
mcp-remote: npmjs.com/package/mcp-remote
Last verified: 2026-04-29