sync: auto-sync from GURU-5070 at 2026-06-06 15:46:17
Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-06 15:46:17
This commit is contained in:
111
session-logs/2026-06-06-mike-mcp-gitauth-reinstall-tailscale.md
Normal file
111
session-logs/2026-06-06-mike-mcp-gitauth-reinstall-tailscale.md
Normal file
@@ -0,0 +1,111 @@
|
||||
## User
|
||||
- **User:** Mike Swanson (mike)
|
||||
- **Machine:** GURU-5070
|
||||
- **Role:** admin
|
||||
|
||||
## Session Summary
|
||||
|
||||
Started from a `/doctor` report flagging the `ticktick` MCP server as failed ("Connection closed"). Diagnosed it as a missing-dependency crash, not an OAuth issue: the local stdio server `mcp-servers/ticktick/ticktick_mcp.py` is launched with bare `python` (Python 3.12) and that interpreter was missing `httpx` and (behind a try/except) `mcp`. Installed both into 3.12, created `mcp-servers/ticktick/requirements.txt`, and verified the server starts clean. The server now shows "Pending approval" (normal trust prompt) instead of crashing.
|
||||
|
||||
Mike then stated a hard requirement: git must never sit at an interactive credential prompt — his objection to Git for Windows is the Git Credential Manager popups that hang automation, not the tooling itself. Discovered a live symptom: a backgrounded Gitea Agent push was hung on a GCM prompt (commit unpushed). Stopped it, pushed via the vault Gitea API token, then built a durable, fleet-wide non-interactive auth solution: `setup-git-auth.sh` (primes the `store` credential helper from the vault token, scoped per-repo by origin host, only seizing the helper from GCM `manager`), a backgrounded `SessionStart` hook, and `GIT_TERMINAL_PROMPT=0` / `GCM_INTERACTIVE=Never` in `settings.json` env. Corrected an earlier wrong memory (had attributed the dislike to the bash/path-mangling layer). All subsequent pushes this session used native `git.exe` via PowerShell with zero prompts.
|
||||
|
||||
Mike disclosed the machine was recently reinstalled and asked to install anything missing. Found the reinstall installed Python deps into only one of the machine's two interpreters (`py`/3.14 for vault+scripts vs `python`/3.12 for MCP servers), which is exactly why ticktick (3.12) and `vault get-field` (3.14, missing PyYAML) were both broken. Installed PyYAML into `py`, `websocket-client` into `py` (cdp.py), and persisted `grok` to the User PATH. Ollama `list` came back empty, but the 5 expected models (47.8 GB) were intact on `D:\OllamaModels` — the tray app just needed a few seconds to hydrate; restarting it loaded all 5. No 48 GB re-download. Then amended the recovery script `windows-bootstrap.ps1` (Phase 7 both interpreters + pyyaml/websocket-client; Phase 3 persist grok PATH; Phase 6 prime git auth; Phase 8 full model set + hydration guard) and documented the gotchas in `machines/guru-5070.md`.
|
||||
|
||||
Finally, Mike asked for help managing Tailscale for a tech-inept two-machine client. Recommended one tailnet per client (never merge into ACG's own), MSP holds Admin, devices enrolled as tagged nodes via pre-auth keys pushed from GuruRMM. Authored `wiki/patterns/tailscale-client-management.md` + `tailscale-client-enroll.ps1` (idempotent unattended Windows MSI install + tagged auth-key join). Scanned GuruRMM for the client (Robert Wolkin): found client `Wolkin, Robert`/site `Main` with 3 online Win11 Home agents. Mike clarified scope: connect RSW-Laptop -> front for file + printer sharing; DESKTOP-V1JT1SE is Bob's personal machine (out of scope). Created the `robert-wolkin` client stub, then added a reusable "files + printer over Tailscale (Windows)" section (SMB over the tailnet, the 445-firewall-on-Tailscale-interface gotcha, local-account auth on Home, MagicDNS FQDN, Point-and-Print via RMM, Taildrive alternative).
|
||||
|
||||
## Key Decisions
|
||||
|
||||
- **ticktick fix is dependency install, not OAuth.** "Connection closed" on a local stdio MCP server = process crash before handshake. `/mcp` authenticate would not have helped.
|
||||
- **Non-interactive git auth via repo-local `store` helper, not global change.** Kept global GCM untouched for other repos; scoped the credential to each repo's actual origin host. `GIT_TERMINAL_PROMPT=0` enforced via committed settings.json so even an unprimed machine fails fast instead of hanging.
|
||||
- **Conservative helper override.** `setup-git-auth.sh` only switches the helper to `store` when it is empty or GCM `manager`, so a Mac osxkeychain setup is left alone — safe to run fleet-wide via SessionStart hook.
|
||||
- **Two-interpreter Python installs in bootstrap.** Root cause of the reinstall breakage; de-dupe by `sys.executable` so a single install isn't run twice.
|
||||
- **Did not re-download Ollama models.** Confirmed manifests + 47.8 GB on `D:\OllamaModels`; an empty `ollama list` right after login is a hydration-timing artifact, not "models gone."
|
||||
- **One tailnet per client.** Isolation, billing, offboarding, IdP blast radius. Never merge a client into ACG's tailnet or share one tailnet across clients.
|
||||
- **SMB over Tailscale for Wolkin (not Taildrive).** A shared printer forces SMB regardless, so use SMB for both files and printer; no subnet router because files/printer live on a node.
|
||||
- **Session log to root** (`session-logs/`) — multi-topic (machine maintenance + git infra + a client), no single article implied; wiki articles were hand-authored inline during the session.
|
||||
|
||||
## Problems Encountered
|
||||
|
||||
- **ticktick MCP "Connection closed":** missing `httpx` then `mcp` in Python 3.12. Installed both; server starts clean.
|
||||
- **Gitea Agent background push hung:** GCM credential prompt invisible in background. Stopped the agent (TaskStop), pushed with the vault API token, then made auth non-interactive permanently.
|
||||
- **`git credential approve` rejected input:** PowerShell piping mangled the multiline credential ("missing protocol field"). Wrote directly to `~/.git-credentials` idempotently instead.
|
||||
- **PowerShell commit failed on embedded double quotes:** `"see each other"` in a commit message split into stray pathspecs (PS 5.1 native-arg quoting bug). Used `git commit -F <msgfile>` / avoided embedded quotes.
|
||||
- **`vault get-field` returned empty:** `yaml-query.py` (run via `py`/3.14) missing PyYAML. Installed pyyaml; added a `get`+grep fallback to setup-git-auth.sh.
|
||||
- **Ollama `list` empty despite 47.8 GB on disk:** tray app server hydration delay (also the app vs CLI env). Restarted; all 5 models loaded. Documented as a bootstrap Phase 8 guard.
|
||||
- **GuruRMM showed 3 agents, Mike expected 2:** clarified DESKTOP-V1JT1SE is Bob's personal machine, out of Tailscale scope.
|
||||
|
||||
## Configuration Changes
|
||||
|
||||
Created:
|
||||
- `mcp-servers/ticktick/requirements.txt` — `httpx>=0.28`, `mcp>=1.27`
|
||||
- `.claude/scripts/setup-git-auth.sh` — non-interactive git auth primer
|
||||
- `.claude/memory/feedback_git_noninteractive_auth.md` — feedback memory (replaced the deleted `feedback_avoid_git_for_windows.md`)
|
||||
- `wiki/patterns/tailscale-client-management.md` — MSP Tailscale pattern
|
||||
- `wiki/patterns/tailscale-client-enroll.ps1` — GuruRMM enrollment script
|
||||
- `wiki/clients/robert-wolkin.md` — client stub
|
||||
|
||||
Modified:
|
||||
- `.claude/agents/gitea.md` — "Non-interactive auth" guidance block
|
||||
- `.claude/settings.json` — `env` (GIT_TERMINAL_PROMPT=0, GCM_INTERACTIVE=Never) + SessionStart hook for setup-git-auth.sh
|
||||
- `.claude/bootstrap/windows-bootstrap.ps1` — Phases 3, 6, 7, 8 amended
|
||||
- `.claude/machines/guru-5070.md` — Known issues (interpreter split, ollama hydration, grok PATH, git auth)
|
||||
- `.claude/memory/MEMORY.md` — index pointer
|
||||
- `wiki/index.md` — Patterns + Clients rows
|
||||
|
||||
Deleted:
|
||||
- `.claude/memory/feedback_avoid_git_for_windows.md` (superseded, never committed)
|
||||
|
||||
Machine state (not in repo):
|
||||
- Python 3.12 (`python`): installed `httpx`, `mcp`
|
||||
- Python 3.14 (`py`): installed `pyyaml`, `websocket-client`
|
||||
- User PATH: appended `~\.grok\bin` (also `~\.local\bin`, `%APPDATA%\npm`)
|
||||
- `~/.git-credentials`: two store entries (internal + public Gitea hosts); stale `%3a3000` entry removed
|
||||
- Ollama: restarted; 5 models loaded from `D:\OllamaModels`
|
||||
|
||||
## Credentials & Secrets
|
||||
|
||||
- **Gitea shared push account:** `azcomputerguru`, API token used for non-interactive push. Vault: `services/gitea.sops.yaml` field `credentials.api.api-token` (also `credentials.password`). Token cached locally in `C:\Users\guru\.git-credentials` (plaintext, local-only, scoped to `172.16.3.20:3000` + `git.azcomputerguru.com`).
|
||||
- **GuruRMM API admin:** vault `infrastructure/gururmm-server.sops.yaml` fields `credentials.gururmm-api.admin-email` / `admin-password`.
|
||||
- No new secrets created. Tailscale auth key for Wolkin not yet generated (pending Mike standing up the tailnet).
|
||||
|
||||
## Infrastructure & Servers
|
||||
|
||||
- **Gitea (internal):** `http://172.16.3.20:3000` (origin for claudetools push this session). Public: `https://git.azcomputerguru.com` (vault repo origin).
|
||||
- **GuruRMM API:** `http://172.16.3.30:3001` (JWT auth).
|
||||
- **MariaDB:** `172.16.3.30:3306` (firewall opened to 172.16.0.0/22 per incoming coord message; not exercised this session).
|
||||
- **GURU-5070 interpreters:** `py` -> Python 3.14 (`C:\Users\guru\AppData\Local\Programs\Python\...`); `python` -> Python 3.12.
|
||||
- **Ollama:** `OLLAMA_MODELS=D:\OllamaModels`, `OLLAMA_HOST=0.0.0.0:11434`. Models: nomic-embed-text, qwen3:8b, qwen3:14b, codestral:22b, qwen3.6:latest.
|
||||
|
||||
### Robert Wolkin (GuruRMM)
|
||||
- Client: `Wolkin, Robert` | Site: `Main` | site_id `2bb05f85-9fc8-4a7e-a5e5-ffe0c46431ac`
|
||||
- Agents (Win 11 Home 25H2 build 26200, agent v0.6.57, all online 2026-06-06):
|
||||
- DESKTOP-V1JT1SE — `30f6af79-ab19-4ed3-9ebc-71b2bffc2d27` — Bob's personal machine (OUT of Tailscale scope)
|
||||
- RSW-Laptop — `043fd673-35a2-4d3d-8f91-ed73ce70cc1e` — Tailscale node (connects to front)
|
||||
- front — `877d311a-4b24-462c-97b1-d2a0f7730a71` — Tailscale node (file + printer host)
|
||||
|
||||
## Commands & Outputs
|
||||
|
||||
- ticktick crash: `python ticktick_mcp.py` -> `ModuleNotFoundError: No module named 'httpx'`, then `[ERROR] MCP package not installed`.
|
||||
- Installs: `python -m pip install httpx`; `python -m pip install mcp`; `py -m pip install pyyaml`; `py -m pip install websocket-client`.
|
||||
- Non-interactive push pattern: `$env:GIT_TERMINAL_PROMPT='0'; git -C D:\ClaudeTools push origin main` (succeeds silently; PS 5.1 wraps git stderr as NativeCommandError on success — trust `$LASTEXITCODE`).
|
||||
- Prime creds: append `http://azcomputerguru:<token>@172.16.3.20:3000` to `~/.git-credentials` + repo-local `credential.helper=store`.
|
||||
- Ollama fix: stop `ollama`/`ollama app`, start `ollama app.exe`, wait ~10s -> `ollama list` shows 5 models.
|
||||
- GuruRMM lookup: `POST /api/auth/login` then `GET /api/agents`, filter `.client_name=="Wolkin, Robert"`.
|
||||
- Firewall rule (planned for `front`): `New-NetFirewallRule -DisplayName "Tailscale SMB (files+print)" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 445 -RemoteAddress 100.64.0.0/10`.
|
||||
|
||||
## Pending / Incomplete Tasks
|
||||
|
||||
- **ticktick MCP:** restart session or `/mcp` reconnect to approve (currently "Pending approval"). Crash resolved.
|
||||
- **grok:** on persistent User PATH but not callable in THIS already-running session; fine in new shells.
|
||||
- **Tailscale (Wolkin):** Mike to stand up the tailnet on Robert's account, assign himself Admin, enable MagicDNS, set `tag:wolkin` ACL, generate reusable+pre-approved tagged auth key. Then: vault the key at `clients/robert-wolkin/tailscale-authkey.sops.yaml`, enroll RSW-Laptop + front via the enroll script, push post-connect SMB config.
|
||||
- **OPEN ITEM (blocks printer step):** confirm whether the printer is USB-attached to `front` (Windows print share over SMB) or a separate network printer (install by IP on laptop, or subnet router on front).
|
||||
- **Offered, not yet done:** stage the 4 RMM jobs (firewall + share/account on front; drive map + printer on laptop); wire enroll script into a GuruRMM script library vs ad-hoc.
|
||||
- **Pre-existing WIP** (not from this session): `.claude/bootstrap/backup-to-bundle.ps1`, `restore-at-risk-work.ps1` (modified), `projects/msp-tools/guru-connect` (untracked) — swept by sync.sh `add -A`.
|
||||
|
||||
## Reference Information
|
||||
|
||||
- Commits (origin/main, pushed): `f3a175e` ticktick requirements; `9ff5a9f0` gitea agent auth docs; `162145b5` git-auth automation; `fd30af6a` bootstrap amendments + machine doc; `8d7e3805` tailscale pattern + script; `5c7e196b` wolkin stub; `32e71a13` wolkin RMM detail + scope; `f7540550` SMB files+printer pattern.
|
||||
- Vault paths: `services/gitea.sops.yaml` (`credentials.api.api-token`), `infrastructure/gururmm-server.sops.yaml` (`credentials.gururmm-api.*`).
|
||||
- Tailscale docs: subnet routers `tailscale.com/docs/features/subnet-routers`; kernel-vs-netstack `/docs/reference/kernel-vs-userspace-routers`; Windows MSI `/docs/install/windows/msi`; run unattended `/docs/how-to/run-unattended`; auth keys `/kb/1085/auth-keys`; firewall ports `/kb/1082/firewall-ports`; Taildrive `/docs/features/taildrive`.
|
||||
- Tailscale MSI silent props: `TS_UNATTENDEDMODE=always`, `TS_NOLAUNCH`, `TS_LOGINURL`, `INSTALLDIR` (no auth-key property — use `tailscale up --authkey`).
|
||||
- Wiki: `wiki/patterns/tailscale-client-management.md`, `wiki/patterns/tailscale-client-enroll.ps1`, `wiki/clients/robert-wolkin.md`.
|
||||
Reference in New Issue
Block a user