From 2a20d6f7cb1705ae9e845ae8bd3fa8c94842c91d Mon Sep 17 00:00:00 2001 From: Arden de Raaij Date: Fri, 13 Nov 2026 17:01:53 +0000 Subject: [PATCH] Rewrite the Claude Desktop setup as a step-by-step walkthrough Claude Desktop is the client a non-developer athlete is most likely to use, and it had the densest instructions: one paragraph that explained an arg-parsing bug and --allow-http before saying what to do, with no path to the config file, no mention of Node.js, of restarting the app, or of how to tell that it worked. It is now numbered steps (install Node, create a token, open the config, paste, quit and reopen, check), followed by troubleshooting and then the reasons behind the config. The snippet uses an https address by default, with --allow-http as an addition for http addresses inside a tailnet. It says up front that "Add custom connector" does not work with this server. Menu labels, server statuses and the log file naming were checked against Claude Desktop 5.11492.2 on macOS. The Windows paths were not. The dashboard button is "New token", not "Create token"; both mentions are corrected. The reachability note no longer assumes a tailnet. --- README.md | 71 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index dc8ed2f..8d3cbf0 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ One instance serves a household: a handful of accounts, all data scoped per user 1. As `admin`, open **Users** and create an account for each athlete (role `user`). 2. Each athlete signs into the **dashboard** with their username + password. 3. In the **[iOS app](https://github.com/aderaaij/loopback-training-app)** ([TestFlight beta](https://testflight.apple.com/join/fV73tucs)), each athlete enters the server URL plus their username + password; the app logs in and stores a per-device token. -4. Optional AI-coach access: each athlete mints a token in the dashboard (**Settings → Create token**) and points their MCP client at `/mcp` on the same address (see [MCP Server](#mcp-server)). +4. Optional AI-coach access: each athlete mints a token in the dashboard (**Settings → New token**) and points their MCP client at `/mcp` on the same address (see [MCP Server](#mcp-server)). Passwords, per-device tokens (revoke one stolen device without touching the rest), and deactivation are all managed in the dashboard. The same operations exist as a CLI fallback: @@ -333,7 +333,7 @@ The server ships with an [MCP](https://modelcontextprotocol.io) endpoint that ex http://:8001/mcp ``` -Each person authenticates with their **own** token in an `Authorization: Bearer` header (mint one in the dashboard: **Settings → Create token**), so the data is scoped to their account — this is the "point your own Claude (or any LLM) at it" path. A request without a bearer token gets a 401. Set `MCP_ENABLED=false` in `.env` to serve no coach endpoint at all. +Each person authenticates with their **own** token in an `Authorization: Bearer` header (mint one in the dashboard: **Settings → New token**), so the data is scoped to their account — this is the "point your own Claude (or any LLM) at it" path. A request without a bearer token gets a 401. Set `MCP_ENABLED=false` in `.env` to serve no coach endpoint at all. ### Connect a client @@ -347,24 +347,53 @@ claude mcp add training --transport http \ --header "Authorization: Bearer " ``` -**Claude Desktop** — bridge remote HTTP via [`mcp-remote`](https://github.com/geelen/mcp-remote) (the `Authorization:${AUTH_HEADER}` form sidesteps an arg-parsing bug with spaces in header values; `--allow-http` is required for plain-http hosts other than localhost — fine here, since tailnet traffic is WireGuard-encrypted end to end). Add to `claude_desktop_config.json`: +**Claude Desktop** + +Claude Desktop cannot send a bearer token to a remote server by itself, so a small helper ([`mcp-remote`](https://github.com/geelen/mcp-remote)) does it. Do not use **Settings → Connectors → Add custom connector**: that flow connects from Anthropic's servers and expects OAuth, so it does not work with this server (see [Reachability](#reachability)). + +1. **Install [Node.js](https://nodejs.org)** (18 or newer) if you don't have it. The helper runs through `npx`, which comes with Node. +2. **Create a token.** In the Loopback dashboard go to **Settings → New token**, name it (e.g. "Claude Desktop") and copy it. It is shown only once. +3. **Open the config file.** In Claude Desktop: **Settings → Developer → Edit config**. This opens `claude_desktop_config.json`: + - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` + - Windows: `%APPDATA%\Claude\claude_desktop_config.json` +4. **Add the server.** If the file is empty, paste this whole block. If it already has an `mcpServers` section, add only the `"training": { … }` entry inside it. + + ```json + { + "mcpServers": { + "training": { + "command": "npx", + "args": [ + "-y", "mcp-remote", + "https:///mcp", + "--header", "Authorization:${AUTH_HEADER}" + ], + "env": { "AUTH_HEADER": "Bearer " } + } + } + } + ``` -```json -{ - "mcpServers": { - "training": { - "command": "npx", - "args": [ - "-y", "mcp-remote", - "http://:8001/mcp", - "--header", "Authorization:${AUTH_HEADER}", - "--allow-http" - ], - "env": { "AUTH_HEADER": "Bearer " } - } - } -} -``` + Replace `https:///mcp` with the address you open the dashboard at, plus `/mcp`, and `` with the token from step 2 (keep the word `Bearer` and the space in front of it). + + If your address starts with `http://` (for example `http://:8001` inside a tailnet), add one more line to `args`, or the helper refuses to connect: + + ```json + "--header", "Authorization:${AUTH_HEADER}", + "--allow-http" + ``` + +5. **Quit Claude Desktop completely and reopen it.** The config is only read at startup, and closing the window is not enough (macOS: Cmd+Q; Windows: quit from the system tray icon). +6. **Check it works.** **Settings → Developer** should list `training` with the status **Running**. Then ask in a new chat: *"What did I run this week?"* + +If it does not connect: + +- **`training` shows Failed or Not responding:** click **View logs** next to it (the file is `mcp-server-training.log`, in `~/Library/Logs/Claude/` on macOS or `%APPDATA%\Claude\logs\` on Windows). The usual causes are invalid JSON (a missing comma) or Node.js not being found. +- **`npx` not found although Node.js is installed:** Claude Desktop does not read your shell profile, so a Node.js installed through a version manager (nvm, fnm, asdf) is invisible to it. Run `which npx` in a terminal and use that full path as `"command"` in place of `"npx"`. +- **401 errors in the log:** the token is wrong, was revoked, or `Bearer ` is missing in front of it. +- **Timeouts:** this computer cannot reach the server. Open the dashboard address in a browser on the same computer to confirm. + +Why the config looks like this: the token goes in `env` and is referenced as `${AUTH_HEADER}` because Claude Desktop on Windows mishandles spaces inside `args` values (on macOS a plain `"Authorization: Bearer "` argument also works). `--allow-http` is needed because `mcp-remote` refuses plain HTTP to anything but localhost; that is acceptable inside a tailnet, where traffic is already encrypted by WireGuard, and not on the open internet. **Cursor** (`~/.cursor/mcp.json`) @@ -407,8 +436,8 @@ header (Cline, the OpenAI Agents SDK's `MCPServerStreamableHttp`, LangChain's behind the client is your choice. Sanity-check a new setup with `npx @modelcontextprotocol/inspector`. -**Reachability:** clients that run on your own machine (the four above) reach the -server directly over the tailnet. Cloud-hosted connectors — claude.ai's web +**Reachability:** clients that run on your own machine (the four above) reach the +server directly, at the same address as the dashboard. Cloud-hosted connectors — claude.ai's web connectors, OpenAI's *hosted* MCP tool — call from the provider's servers instead, so they need a publicly reachable URL ([Tailscale Funnel](https://tailscale.com/kb/1223/funnel) or a reverse proxy), and