diff --git a/docker/kb-rag-mcp-oauth-fix.md b/docker/kb-rag-mcp-oauth-fix.md new file mode 100644 index 0000000..e31e0c3 --- /dev/null +++ b/docker/kb-rag-mcp-oauth-fix.md @@ -0,0 +1,66 @@ +--- +title: "Fix: kb-search MCP server 'needs authentication' after server restart" +description: "Claude Code shows OAuth errors connecting to kb-search MCP after ubuntu-manticore restart. Fix involves reconfiguring with bearer token headers and clearing stale OAuth credentials." +type: troubleshooting +domain: docker +tags: [troubleshooting, kb-rag, claude-code, docker, manticore] +--- + +# Fix: kb-search MCP server 'needs authentication' after server restart + +**Date:** 2026-03-25 +**Severity:** Medium — kb-search MCP unavailable across all Claude Code sessions + +## Problem + +After restarting ubuntu-manticore (crash recovery), the kb-search MCP server showed "needs authentication" in Claude Code's `/mcp` panel. Error message: + +``` +Error: HTTP 404: Invalid OAuth error response: SyntaxError: JSON Parse error: Unexpected EOF. Raw body: +``` + +The server was healthy (`/health` returned OK) but Claude Code was attempting OAuth discovery against a server that only supports static bearer token auth. + +## Root Cause + +Two issues compounded: + +1. **Stale MCP session:** The server restart invalidated all existing MCP sessions. Claude Code clients got "Session not found" errors on reconnect. + +2. **Stale OAuth credential:** Claude Code had a cached OAuth entry in `~/.claude/.credentials.json` under the `mcpOAuth` key (`kb-search|120dc71b28e46913`). This entry caused Claude Code to attempt OAuth discovery (hitting `/.well-known/oauth-authorization-server`) instead of using the static `Authorization: Bearer` header from the MCP config. The server returned 404 on the OAuth endpoint, which Claude Code couldn't parse. + +The stale OAuth entry persisted even after reconfiguring the MCP server with correct `headers` config — **`mcpOAuth` credentials override static headers**. + +## Fix + +1. **Reconfigure MCP with bearer token header** (user scope so it applies globally): + ```bash + claude mcp remove kb-search + claude mcp add-json kb-search \ + '{"type":"http","url":"http://10.10.0.226:8001/mcp","headers":{"Authorization":"Bearer "}}' \ + --scope user + ``` + Token is in `~/docker/md-kb-rag/.env` on manticore (`MCP_BEARER_TOKEN` value). + +2. **Remove stale OAuth credential** from `~/.claude/.credentials.json`: + ```python + import json + f = '/home/cal/.claude/.credentials.json' + d = json.load(open(f)) + oauth = d.get('mcpOAuth', {}) + keys = [k for k in oauth if 'kb-search' in k] + for k in keys: + del oauth[k] + d['mcpOAuth'] = oauth + with open(f, 'w') as fh: + json.dump(d, fh, indent=2) + ``` + +3. **Restart Claude Code** to establish a fresh MCP connection. + +## Lessons + +- Stale `mcpOAuth` entries in `.credentials.json` take priority over static `headers` config — always check and clear these when MCP auth issues occur +- After any server hosting MCP endpoints restarts, all Claude Code sessions need restart to reconnect +- The `--scope user` flag on `claude mcp add-json` is essential — without it, config goes to project-local and won't appear in other projects +- kb-rag uses bearer token auth, NOT OAuth — if Claude Code shows OAuth errors for this server, the config is wrong