2026-04-23 13:52:31 +08:00
# Requires -Version 5.1
<#
. SYNOPSIS
AgentKey installer for Windows
. DESCRIPTION
Usage:
irm https://agentkey . app/install . ps1 | iex
& ([scriptblock]::Create((irm https://agentkey . app/install . ps1))) -Yes
& ([scriptblock]::Create((irm https://agentkey . app/install . ps1))) -Only "claude-code,cursor"
feat: agent install telemetry (installer side, spec §8.3) (#30)
## Summary
Installer-side half of the agent-install telemetry rollout (spec §8.3).
Adds `--no-telemetry` opt-out, telemetry status banner, and 7-var env
passthrough to `npx -y @agentkey/mcp --auth-login` so the server can
capture `install_completed` with full install context.
- `scripts/install.sh`: `--no-telemetry` flag,
`compute_device_fingerprint()` helper, env exports immediately before
the `--auth-login` invocation
- `scripts/install.ps1`: PowerShell-mirror of the same — `-NoTelemetry`,
SHA-256 fingerprint, `$env:AGENTKEY_*` exports
## Blocked on
**AgentKey-Server PR** that consumes the 7 transparent env vars
(`AGENTKEY_TELEMETRY`, `AGENTKEY_INSTALL_SOURCE`,
`AGENTKEY_DETECTED_AGENTS`, `AGENTKEY_SELECTED_AGENTS`,
`AGENTKEY_INSTALLER_FLAGS`, `AGENTKEY_DEVICE_FINGERPRINT` — plus
implicit skill-version detection on the server side) and capture
`install_completed`. Until that lands, the env passthrough goes to a
process that does nothing with them — harmless, but the telemetry signal
is incomplete.
This PR can be merged independently — it does not break the existing
installer flow either way.
## Test plan
- [x] `bash -n scripts/install.sh` — syntactic check passes
- [x] `bash scripts/install.sh --help` — `--no-telemetry` documented in
Options
- [x] `bash scripts/install.sh --list-agents` — early-return path
unaffected
- [x] `bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp
--yes` — creates `~/.config/agentkey/telemetry-disabled`, prints
"Telemetry: disabled (--no-telemetry)"
- [x] Pre-existing opt-out file recognized — prints "Telemetry: disabled
(~/.config/agentkey/telemetry-disabled exists)"
- [x] Default (no flag / no file) — prints "Telemetry: anonymous usage
stats enabled (re-run with --no-telemetry to opt out)"
- [x] `install.ps1` structural checks (line count, `\$NoTelemetry`
references, single `param(...)` block, brace balance)
- [ ] PowerShell parse on Windows runner (relies on existing
windows-latest CI for any install.ps1-touching PR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:09:36 +08:00
& ([scriptblock]::Create((irm https://agentkey . app/install . ps1))) -NoTelemetry
2026-04-23 13:52:31 +08:00
Behavior mirrors install . sh: checks Node >= 18 (installs via winget/scoop/choco),
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
auto-detects which AI agents are installed and runs `npx skills add` for them,
fix(install): drop remote/local detection, always try browser (#52)
## Summary
Installer was sniffing SSH env vars, `~/.openclaw`, and `\$DISPLAY` to
decide whether to pass `--no-browser` to `@agentkey/cli --auth-login`.
Inspecting the v1.0 CLI source confirms this was unnecessary:
```js
const { device_code, user_code, verification_uri, expires_in } = await res.json();
const authUrl = \`\${verification_uri}?code=\${user_code}\`;
console.log(\` Open this URL to authorize:\`); // ← always prints
console.log(\` \${authUrl}\`);
// ...
if (!noBrowser) { /* best-effort open() */ } // ← only this is gated
```
The CLI **always** prints the auth URL on stdout. `--no-browser` only
adds a terminal QR and skips the `open()`/`xdg-open()`/`start()`
attempt. The CLI's open-browser call is already best-effort — on a
headless host it silently no-ops.
So the installer-side heuristic was:
- **redundant** for the URL (CLI prints it either way)
- **harmful** when it mis-detected (local users on a headless tmux pane
or behind a mis-detected SSH session got the QR flow with no browser
attempt at all, even though their machine could have opened one)
This was the root cause of the reported "no browser pops up on \`curl …
| bash\`" symptom.
## Fix
Drop the heuristic. Always call \`npx -y @agentkey/cli --auth-login\`
(no \`--no-browser\`). The CLI tries \`open\` / \`xdg-open\` /
\`start\`; if that fails the user has the URL right there in the
terminal.
## Removed
- \`detect_remote()\` in \`scripts/install.sh\` / \`Test-RemoteInstall\`
in \`scripts/install.ps1\`
- \`--remote\` / \`--local\` / \`-Remote\` / \`-Local\` flags + their
mutually-exclusive guard + \`FORCE_REMOTE\` / \`FORCE_LOCAL\` state
- \`--no-browser\` passthrough to the CLI
- \"Installing over SSH, inside Docker, …\" details section in README.md
/ docs/README_zh.md — replaced with a one-line callout under the
advanced install options
- Synopsis / help / behavior copy mentioning the old detection logic
Net: **+24 / -174 lines**.
## Test plan
- [ ] On macOS / Linux desktop: \`curl -fsSL
https://agentkey.app/install.sh | bash\` — browser pops up; URL also
visible in terminal as a fallback
- [ ] In an SSH session: same one-liner — \`xdg-open\` no-ops on the
remote host (no harm), URL is right there in terminal; copy it to a
local browser to finish
- [ ] Windows PowerShell: \`irm https://agentkey.app/install.ps1 | iex\`
— \`start\` opens the default browser; URL also visible
- [ ] \`--skip-mcp\` still skips the auth step
- [ ] \`bash -n scripts/install.sh\` passes (verified)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:03:58 +08:00
then `npx @agentkey/cli --auth-login` for device auth . The auth step always
tries to open a local browser AND prints the URL so headless / SSH users can
copy it elsewhere . MCP config is written automatically for Claude Code /
Claude Desktop / Cursor .
2026-04-23 13:52:31 +08:00
#>
[ CmdletBinding ( ) ]
param (
[ switch ] $Yes ,
[ switch ] $Interactive ,
[ string ] $Only ,
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
[ switch ] $AllAgents ,
[ switch ] $ListAgents ,
2026-04-23 13:52:31 +08:00
[ switch ] $SkipSkill ,
[ switch ] $SkipMcp ,
feat: agent install telemetry (installer side, spec §8.3) (#30)
## Summary
Installer-side half of the agent-install telemetry rollout (spec §8.3).
Adds `--no-telemetry` opt-out, telemetry status banner, and 7-var env
passthrough to `npx -y @agentkey/mcp --auth-login` so the server can
capture `install_completed` with full install context.
- `scripts/install.sh`: `--no-telemetry` flag,
`compute_device_fingerprint()` helper, env exports immediately before
the `--auth-login` invocation
- `scripts/install.ps1`: PowerShell-mirror of the same — `-NoTelemetry`,
SHA-256 fingerprint, `$env:AGENTKEY_*` exports
## Blocked on
**AgentKey-Server PR** that consumes the 7 transparent env vars
(`AGENTKEY_TELEMETRY`, `AGENTKEY_INSTALL_SOURCE`,
`AGENTKEY_DETECTED_AGENTS`, `AGENTKEY_SELECTED_AGENTS`,
`AGENTKEY_INSTALLER_FLAGS`, `AGENTKEY_DEVICE_FINGERPRINT` — plus
implicit skill-version detection on the server side) and capture
`install_completed`. Until that lands, the env passthrough goes to a
process that does nothing with them — harmless, but the telemetry signal
is incomplete.
This PR can be merged independently — it does not break the existing
installer flow either way.
## Test plan
- [x] `bash -n scripts/install.sh` — syntactic check passes
- [x] `bash scripts/install.sh --help` — `--no-telemetry` documented in
Options
- [x] `bash scripts/install.sh --list-agents` — early-return path
unaffected
- [x] `bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp
--yes` — creates `~/.config/agentkey/telemetry-disabled`, prints
"Telemetry: disabled (--no-telemetry)"
- [x] Pre-existing opt-out file recognized — prints "Telemetry: disabled
(~/.config/agentkey/telemetry-disabled exists)"
- [x] Default (no flag / no file) — prints "Telemetry: anonymous usage
stats enabled (re-run with --no-telemetry to opt out)"
- [x] `install.ps1` structural checks (line count, `\$NoTelemetry`
references, single `param(...)` block, brace balance)
- [ ] PowerShell parse on Windows runner (relies on existing
windows-latest CI for any install.ps1-touching PR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:09:36 +08:00
[ switch ] $NoTelemetry ,
2026-04-23 13:52:31 +08:00
[ switch ] $Help
)
$ErrorActionPreference = 'Stop'
$SkillRepo = 'chainbase-labs/agentkey'
2026-05-15 16:31:42 +08:00
$CliPackage = '@agentkey/cli'
2026-04-23 13:52:31 +08:00
$NodeMinMajor = 18
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
# ── Agent markers (mirror of install.sh) ──────────────────────────────────
# Subset of vercel-labs/skills' 45 supported agent IDs that have reliable
# Windows-side markers. Sync source:
# https://github.com/vercel-labs/skills (Supported Agents table).
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
#
# IMPORTANT: ids here MUST match the `--only` ids accepted by both
# `npx skills add -a` and `npx -y @agentkey/cli --auth-login --only`.
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
# `claude-desktop` and `dsh` are exceptions. Neither is passed to
2026-08-25 00:55:26 +08:00
# `skills add -a`; DSH reads the global skill installed for `universal`.
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
$DshHome = if ( [ string ] :: IsNullOrWhiteSpace ( $env:DSH_HOME ) ) { Join-Path ( [ Environment ] :: GetFolderPath ( 'UserProfile' ) ) '.dsh' } else { $env:DSH_HOME }
if ( $DshHome -eq '~' ) {
$DshHome = [ Environment ] :: GetFolderPath ( 'UserProfile' )
} elseif ( $DshHome -match '^~[\\/]' ) {
$DshHome = Join-Path ( [ Environment ] :: GetFolderPath ( 'UserProfile' ) ) $DshHome . Substring ( 2 )
}
$DshHome = [ System.IO.Path ] :: GetFullPath ( $DshHome )
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
$AgentMarkers = @ (
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
@ { Id = 'claude-code' ; Markers = @ ( " path: $env:USERPROFILE \.claude.json " , 'cmd:claude' ) }
@ { Id = 'claude-desktop' ; Markers = @ ( " path: $env:LOCALAPPDATA \AnthropicClaude " , " path: $env:APPDATA \Claude\claude_desktop_config.json " , " path: $env:APPDATA \Claude " ) }
@ { Id = 'cursor' ; Markers = @ ( " path: $env:USERPROFILE \.cursor " , 'cmd:cursor' , " path: $env:LOCALAPPDATA \Programs\cursor " ) }
@ { Id = 'codex' ; Markers = @ ( " path: $env:USERPROFILE \.codex " , 'cmd:codex' ) }
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
@ { Id = 'dsh' ; Markers = @ ( " path: $DshHome " , 'cmd:dsh' ) }
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
@ { Id = 'gemini-cli' ; Markers = @ ( " path: $env:USERPROFILE \.gemini " , 'cmd:gemini' ) }
@ { Id = 'opencode' ; Markers = @ ( " path: $env:APPDATA \opencode " , " path: $env:USERPROFILE \.opencode " , 'cmd:opencode' ) }
@ { Id = 'openclaw' ; Markers = @ ( " path: $env:USERPROFILE \.openclaw " , 'cmd:openclaw' ) }
@ { Id = 'qwen-code' ; Markers = @ ( " path: $env:USERPROFILE \.qwen " , 'cmd:qwen' ) }
@ { Id = 'iflow-cli' ; Markers = @ ( " path: $env:USERPROFILE \.iflow " , 'cmd:iflow' ) }
@ { Id = 'windsurf' ; Markers = @ ( " path: $env:USERPROFILE \.codeium\windsurf " , " path: $env:USERPROFILE \.windsurf " , 'cmd:windsurf' ) }
@ { Id = 'warp' ; Markers = @ ( " path: $env:USERPROFILE \.warp " ) }
@ { Id = 'amp' ; Markers = @ ( " path: $env:APPDATA \amp " , 'cmd:amp' ) }
@ { Id = 'crush' ; Markers = @ ( " path: $env:APPDATA \crush " , 'cmd:crush' ) }
@ { Id = 'goose' ; Markers = @ ( " path: $env:APPDATA \goose " , 'cmd:goose' ) }
@ { Id = 'droid' ; Markers = @ ( 'cmd:droid' ) }
@ { Id = 'kode' ; Markers = @ ( 'cmd:kode' ) }
@ { Id = 'kilo' ; Markers = @ ( 'cmd:kilo' ) }
@ { Id = 'kimi-cli' ; Markers = @ ( " path: $env:USERPROFILE \.kimi " , 'cmd:kimi' ) }
@ { Id = 'kiro-cli' ; Markers = @ ( " path: $env:USERPROFILE \.kiro " , 'cmd:kiro' ) }
)
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
# Agent ids excluded from per-agent `skills add -a`: Claude Desktop has no
2026-08-25 00:55:26 +08:00
# skill path, while DSH consumes the global `universal` copy.
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
$SkillsAgentExclusions = @ ( 'claude-desktop' , 'dsh' )
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
# Agent ids whose MCP registration the installer can drive automatically.
# Mirror of MCP_AUTO_AGENTS in install.sh and AGENT_REGISTRY in
# AgentKey-Server/cli/src/lib/mcp-clients.ts. Keep these three in sync.
$McpAutoAgents = @ (
'claude-code' , 'claude-desktop' , 'cursor' , 'codex' , 'gemini-cli' ,
'opencode' , 'qwen-code' , 'iflow-cli' , 'kimi-cli' , 'kiro-cli' ,
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
'windsurf' , 'warp' , 'amp' , 'crush' , 'droid' , 'openclaw' , 'dsh'
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
)
2026-04-23 13:52:31 +08:00
# ── UI helpers ────────────────────────────────────────────────────────────
function Write-Banner {
Write-Host ''
Write-Host ' █████ ██████ ███████ ███ ██ ████████ ██ ██ ███████ ██ ██' -ForegroundColor Cyan
Write-Host ' ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ' -ForegroundColor Cyan
Write-Host ' ███████ ██ ███ █████ ██ ██ ██ ██ █████ █████ ████ ' -ForegroundColor Cyan
Write-Host ' ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ' -ForegroundColor Cyan
Write-Host ' ██ ██ ██████ ███████ ██ ████ ██ ██ ██ ███████ ██ ' -ForegroundColor Cyan
Write-Host ''
Write-Host ' One command. Full internet access for your AI agent.' -ForegroundColor White
Write-Host ' https://agentkey.app' -ForegroundColor DarkGray
Write-Host ''
}
function Write-Step ( $text ) { Write-Host '' ; Write-Host " $text " -ForegroundColor White }
function Write-Info ( $text ) { Write-Host " › $text " -ForegroundColor Gray }
function Write-Ok ( $text ) { Write-Host " ✓ $text " -ForegroundColor Green }
function Write-Warn2($text ) { Write-Host " ! $text " -ForegroundColor Yellow }
function Write-Err ( $text ) { Write-Host " ✗ $text " -ForegroundColor Red }
function Write-Muted($text ) { Write-Host " $text " -ForegroundColor DarkGray }
function Die ( $text ) { Write-Err $text ; exit 1 }
fix(install): drop remote/local detection, always try browser (#52)
## Summary
Installer was sniffing SSH env vars, `~/.openclaw`, and `\$DISPLAY` to
decide whether to pass `--no-browser` to `@agentkey/cli --auth-login`.
Inspecting the v1.0 CLI source confirms this was unnecessary:
```js
const { device_code, user_code, verification_uri, expires_in } = await res.json();
const authUrl = \`\${verification_uri}?code=\${user_code}\`;
console.log(\` Open this URL to authorize:\`); // ← always prints
console.log(\` \${authUrl}\`);
// ...
if (!noBrowser) { /* best-effort open() */ } // ← only this is gated
```
The CLI **always** prints the auth URL on stdout. `--no-browser` only
adds a terminal QR and skips the `open()`/`xdg-open()`/`start()`
attempt. The CLI's open-browser call is already best-effort — on a
headless host it silently no-ops.
So the installer-side heuristic was:
- **redundant** for the URL (CLI prints it either way)
- **harmful** when it mis-detected (local users on a headless tmux pane
or behind a mis-detected SSH session got the QR flow with no browser
attempt at all, even though their machine could have opened one)
This was the root cause of the reported "no browser pops up on \`curl …
| bash\`" symptom.
## Fix
Drop the heuristic. Always call \`npx -y @agentkey/cli --auth-login\`
(no \`--no-browser\`). The CLI tries \`open\` / \`xdg-open\` /
\`start\`; if that fails the user has the URL right there in the
terminal.
## Removed
- \`detect_remote()\` in \`scripts/install.sh\` / \`Test-RemoteInstall\`
in \`scripts/install.ps1\`
- \`--remote\` / \`--local\` / \`-Remote\` / \`-Local\` flags + their
mutually-exclusive guard + \`FORCE_REMOTE\` / \`FORCE_LOCAL\` state
- \`--no-browser\` passthrough to the CLI
- \"Installing over SSH, inside Docker, …\" details section in README.md
/ docs/README_zh.md — replaced with a one-line callout under the
advanced install options
- Synopsis / help / behavior copy mentioning the old detection logic
Net: **+24 / -174 lines**.
## Test plan
- [ ] On macOS / Linux desktop: \`curl -fsSL
https://agentkey.app/install.sh | bash\` — browser pops up; URL also
visible in terminal as a fallback
- [ ] In an SSH session: same one-liner — \`xdg-open\` no-ops on the
remote host (no harm), URL is right there in terminal; copy it to a
local browser to finish
- [ ] Windows PowerShell: \`irm https://agentkey.app/install.ps1 | iex\`
— \`start\` opens the default browser; URL also visible
- [ ] \`--skip-mcp\` still skips the auth step
- [ ] \`bash -n scripts/install.sh\` passes (verified)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:03:58 +08:00
# ── Helpers: agent detection ──────────────────────────────────────────────
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
function Test-AgentMarker {
param ( [ string ] $Marker )
if ( $Marker . StartsWith ( 'cmd:' ) ) {
return [ bool ] ( Get-Command $Marker . Substring ( 4 ) -ErrorAction SilentlyContinue )
}
if ( $Marker . StartsWith ( 'path:' ) ) {
return Test-Path -LiteralPath $Marker . Substring ( 5 )
}
return $false
}
function Get-DetectedAgents {
$hits = New-Object System . Collections . Generic . List [ string ]
foreach ( $entry in $AgentMarkers ) {
foreach ( $m in $entry . Markers ) {
if ( Test-AgentMarker $m ) { $hits . Add ( $entry . Id ) | Out-Null ; break }
}
}
return @ ( $hits | Sort-Object -Unique )
}
2026-04-23 13:52:31 +08:00
# ── Help ──────────────────────────────────────────────────────────────────
if ( $Help ) {
@'
AgentKey installer for Windows
Usage:
irm https://agentkey.app/install.ps1 | iex
& ([scriptblock]::Create((irm https://agentkey.app/install.ps1))) -Yes
Parameters:
-Yes Non-interactive: install skill to every detected agent, no prompts
-Interactive Force interactive mode (fails if console input is redirected)
-Only <a,b,c> Only install skill for these agents (e.g. "claude-code,cursor")
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
-AllAgents Skip auto-detection; let 'skills' CLI install for every detected agent
-ListAgents Print the agents we'd auto-select on this machine and exit
2026-04-23 13:52:31 +08:00
-SkipSkill Skip the skill install step (only run MCP auth)
-SkipMcp Skip the MCP auth step (only install the skill)
feat: agent install telemetry (installer side, spec §8.3) (#30)
## Summary
Installer-side half of the agent-install telemetry rollout (spec §8.3).
Adds `--no-telemetry` opt-out, telemetry status banner, and 7-var env
passthrough to `npx -y @agentkey/mcp --auth-login` so the server can
capture `install_completed` with full install context.
- `scripts/install.sh`: `--no-telemetry` flag,
`compute_device_fingerprint()` helper, env exports immediately before
the `--auth-login` invocation
- `scripts/install.ps1`: PowerShell-mirror of the same — `-NoTelemetry`,
SHA-256 fingerprint, `$env:AGENTKEY_*` exports
## Blocked on
**AgentKey-Server PR** that consumes the 7 transparent env vars
(`AGENTKEY_TELEMETRY`, `AGENTKEY_INSTALL_SOURCE`,
`AGENTKEY_DETECTED_AGENTS`, `AGENTKEY_SELECTED_AGENTS`,
`AGENTKEY_INSTALLER_FLAGS`, `AGENTKEY_DEVICE_FINGERPRINT` — plus
implicit skill-version detection on the server side) and capture
`install_completed`. Until that lands, the env passthrough goes to a
process that does nothing with them — harmless, but the telemetry signal
is incomplete.
This PR can be merged independently — it does not break the existing
installer flow either way.
## Test plan
- [x] `bash -n scripts/install.sh` — syntactic check passes
- [x] `bash scripts/install.sh --help` — `--no-telemetry` documented in
Options
- [x] `bash scripts/install.sh --list-agents` — early-return path
unaffected
- [x] `bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp
--yes` — creates `~/.config/agentkey/telemetry-disabled`, prints
"Telemetry: disabled (--no-telemetry)"
- [x] Pre-existing opt-out file recognized — prints "Telemetry: disabled
(~/.config/agentkey/telemetry-disabled exists)"
- [x] Default (no flag / no file) — prints "Telemetry: anonymous usage
stats enabled (re-run with --no-telemetry to opt out)"
- [x] `install.ps1` structural checks (line count, `\$NoTelemetry`
references, single `param(...)` block, brace balance)
- [ ] PowerShell parse on Windows runner (relies on existing
windows-latest CI for any install.ps1-touching PR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:09:36 +08:00
-NoTelemetry Disable anonymous usage telemetry (writes
%USERPROFILE%\.config\agentkey\telemetry-disabled so
the skill stays opted-out across runs)
2026-04-23 13:52:31 +08:00
-Help Show this help
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
Behavior:
The installer auto-detects which AI agents are on this machine and
fix(install): drop remote/local detection, always try browser (#52)
## Summary
Installer was sniffing SSH env vars, `~/.openclaw`, and `\$DISPLAY` to
decide whether to pass `--no-browser` to `@agentkey/cli --auth-login`.
Inspecting the v1.0 CLI source confirms this was unnecessary:
```js
const { device_code, user_code, verification_uri, expires_in } = await res.json();
const authUrl = \`\${verification_uri}?code=\${user_code}\`;
console.log(\` Open this URL to authorize:\`); // ← always prints
console.log(\` \${authUrl}\`);
// ...
if (!noBrowser) { /* best-effort open() */ } // ← only this is gated
```
The CLI **always** prints the auth URL on stdout. `--no-browser` only
adds a terminal QR and skips the `open()`/`xdg-open()`/`start()`
attempt. The CLI's open-browser call is already best-effort — on a
headless host it silently no-ops.
So the installer-side heuristic was:
- **redundant** for the URL (CLI prints it either way)
- **harmful** when it mis-detected (local users on a headless tmux pane
or behind a mis-detected SSH session got the QR flow with no browser
attempt at all, even though their machine could have opened one)
This was the root cause of the reported "no browser pops up on \`curl …
| bash\`" symptom.
## Fix
Drop the heuristic. Always call \`npx -y @agentkey/cli --auth-login\`
(no \`--no-browser\`). The CLI tries \`open\` / \`xdg-open\` /
\`start\`; if that fails the user has the URL right there in the
terminal.
## Removed
- \`detect_remote()\` in \`scripts/install.sh\` / \`Test-RemoteInstall\`
in \`scripts/install.ps1\`
- \`--remote\` / \`--local\` / \`-Remote\` / \`-Local\` flags + their
mutually-exclusive guard + \`FORCE_REMOTE\` / \`FORCE_LOCAL\` state
- \`--no-browser\` passthrough to the CLI
- \"Installing over SSH, inside Docker, …\" details section in README.md
/ docs/README_zh.md — replaced with a one-line callout under the
advanced install options
- Synopsis / help / behavior copy mentioning the old detection logic
Net: **+24 / -174 lines**.
## Test plan
- [ ] On macOS / Linux desktop: \`curl -fsSL
https://agentkey.app/install.sh | bash\` — browser pops up; URL also
visible in terminal as a fallback
- [ ] In an SSH session: same one-liner — \`xdg-open\` no-ops on the
remote host (no harm), URL is right there in terminal; copy it to a
local browser to finish
- [ ] Windows PowerShell: \`irm https://agentkey.app/install.ps1 | iex\`
— \`start\` opens the default browser; URL also visible
- [ ] \`--skip-mcp\` still skips the auth step
- [ ] \`bash -n scripts/install.sh\` passes (verified)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:03:58 +08:00
pre-selects them for skill installation. The auth step always tries
to open a browser and also prints the URL — so SSH / WinRM / Docker
/ OpenClaw users can copy the URL to any device with a browser.
2026-04-23 13:52:31 +08:00
'@
exit 0
}
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
if ( $ListAgents ) {
$detected = Get-DetectedAgents
if ( $detected . Count -gt 0 ) { $detected -join " `n " | Write-Output }
else { Write-Host 'no agents detected on this host' -ForegroundColor Yellow }
exit 0
}
2026-04-23 13:52:31 +08:00
Write-Banner
# ── 1. Preflight ──────────────────────────────────────────────────────────
Write-Step '1. Preflight'
# Platform guard
if ( -not $IsWindows -and $PSVersionTable . PSVersion . Major -ge 6 ) {
Die 'This script targets Windows. On macOS/Linux use install.sh instead.'
}
Write-Ok 'Platform: windows'
# Resolve interactive mode. PowerShell's `iex` runs in the current session, so
# Read-Host works natively even under `irm | iex`. The only thing we need to
# guard is truly redirected input (scheduled tasks, CI with redirected stdin).
$InputRedirected = $false
try { $InputRedirected = [ Console ] :: IsInputRedirected } catch { $InputRedirected = $false }
$Mode = $null
if ( $Yes ) { $Mode = 'noninteractive' }
elseif ( $Interactive ) {
if ( $InputRedirected ) { Die '-Interactive requested but console input is redirected.' }
$Mode = 'interactive'
}
elseif ( $InputRedirected ) {
$Mode = 'noninteractive'
Write-Warn2 'No interactive console detected — falling back to -Yes'
}
else {
$Mode = 'interactive'
}
Write-Ok " Mode: $Mode "
feat: agent install telemetry (installer side, spec §8.3) (#30)
## Summary
Installer-side half of the agent-install telemetry rollout (spec §8.3).
Adds `--no-telemetry` opt-out, telemetry status banner, and 7-var env
passthrough to `npx -y @agentkey/mcp --auth-login` so the server can
capture `install_completed` with full install context.
- `scripts/install.sh`: `--no-telemetry` flag,
`compute_device_fingerprint()` helper, env exports immediately before
the `--auth-login` invocation
- `scripts/install.ps1`: PowerShell-mirror of the same — `-NoTelemetry`,
SHA-256 fingerprint, `$env:AGENTKEY_*` exports
## Blocked on
**AgentKey-Server PR** that consumes the 7 transparent env vars
(`AGENTKEY_TELEMETRY`, `AGENTKEY_INSTALL_SOURCE`,
`AGENTKEY_DETECTED_AGENTS`, `AGENTKEY_SELECTED_AGENTS`,
`AGENTKEY_INSTALLER_FLAGS`, `AGENTKEY_DEVICE_FINGERPRINT` — plus
implicit skill-version detection on the server side) and capture
`install_completed`. Until that lands, the env passthrough goes to a
process that does nothing with them — harmless, but the telemetry signal
is incomplete.
This PR can be merged independently — it does not break the existing
installer flow either way.
## Test plan
- [x] `bash -n scripts/install.sh` — syntactic check passes
- [x] `bash scripts/install.sh --help` — `--no-telemetry` documented in
Options
- [x] `bash scripts/install.sh --list-agents` — early-return path
unaffected
- [x] `bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp
--yes` — creates `~/.config/agentkey/telemetry-disabled`, prints
"Telemetry: disabled (--no-telemetry)"
- [x] Pre-existing opt-out file recognized — prints "Telemetry: disabled
(~/.config/agentkey/telemetry-disabled exists)"
- [x] Default (no flag / no file) — prints "Telemetry: anonymous usage
stats enabled (re-run with --no-telemetry to opt out)"
- [x] `install.ps1` structural checks (line count, `\$NoTelemetry`
references, single `param(...)` block, brace balance)
- [ ] PowerShell parse on Windows runner (relies on existing
windows-latest CI for any install.ps1-touching PR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:09:36 +08:00
# Resolve telemetry intent: -NoTelemetry overrides everything; existing
# %USERPROFILE%\.config\agentkey\telemetry-disabled file means already-opted-out.
$TelemetryOptOutFile = Join-Path $env:USERPROFILE '.config\agentkey\telemetry-disabled'
if ( $NoTelemetry ) {
New-Item -ItemType Directory -Path ( Split-Path $TelemetryOptOutFile ) -Force | Out-Null
New-Item -ItemType File -Path $TelemetryOptOutFile -Force | Out-Null
Write-Ok 'Telemetry: disabled (-NoTelemetry)'
} elseif ( Test-Path -LiteralPath $TelemetryOptOutFile ) {
Write-Ok " Telemetry: disabled ( $TelemetryOptOutFile exists) "
} else {
Write-Info 'Telemetry: anonymous usage stats enabled (re-run with -NoTelemetry to opt out)'
}
2026-04-23 13:52:31 +08:00
# Node check
function Get-NodeMajor {
try {
$v = ( & node - -version ) 2 > $null
if ( $v -match '^v(\d+)\.' ) { return [ int ] $Matches [ 1 ] }
} catch { }
return 0
}
function Install-Node {
Write-Info " Installing Node.js LTS ... "
if ( Get-Command winget -ErrorAction SilentlyContinue ) {
winget install -e - -id OpenJS . NodeJS . LTS - -silent - -accept -source -agreements - -accept -package -agreements | Out-Null
} elseif ( Get-Command scoop -ErrorAction SilentlyContinue ) {
scoop install nodejs-lts | Out-Null
} elseif ( Get-Command choco -ErrorAction SilentlyContinue ) {
choco install nodejs-lts -y | Out-Null
} else {
Die 'No package manager found (winget/scoop/choco). Install Node.js LTS manually: https://nodejs.org/'
}
# Refresh PATH so this session sees the newly installed node
$env:Path = [ System.Environment ] :: GetEnvironmentVariable ( 'Path' , 'Machine' ) + ';' +
[ System.Environment ] :: GetEnvironmentVariable ( 'Path' , 'User' )
Write-Ok 'Node.js installed'
}
$nodeMajor = Get-NodeMajor
if ( $nodeMajor -ge $NodeMinMajor ) {
Write-Ok " Node.js: v $nodeMajor .x "
} else {
if ( $nodeMajor -gt 0 ) { Write-Warn2 " Node.js v $nodeMajor found but v $NodeMinMajor + is required " }
if ( $Mode -eq 'interactive' ) {
Write-Host ''
Write-Host " Node.js v $NodeMinMajor + is required but not found. " -ForegroundColor White
$reply = Read-Host ' Install it now? [Y/n]'
if ( $reply -match '^(n|no)$' ) { Die 'Node.js required. Aborting.' }
}
Install-Node
}
if ( -not ( Get-Command npx -ErrorAction SilentlyContinue ) ) {
Die 'npx not found after Node install — please reopen your terminal or reinstall Node.js.'
}
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
# Resolve target agent list — shared between the skill step and the MCP step.
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
# $AllTargets — every detected agent, including local exceptions
# $SkillTargets — $AllTargets minus ids excluded from `skills add -a`
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
# $McpTargets — $AllTargets filtered to ids the MCP CLI knows how to write
$AllTargets = @ ( )
if ( $Only ) {
$AllTargets = @ ( $Only -split ',' | Where-Object { $_ -ne '' } )
Write-Info " Targeting agents from -Only: $( $AllTargets -join ', ' ) "
} elseif ( $AllAgents ) {
Write-Info " Installing for every agent the 'skills' CLI detects (-AllAgents) "
} else {
$AllTargets = @ ( Get-DetectedAgents )
if ( $AllTargets . Count -gt 0 ) {
Write-Ok " Detected agents on this host: $( $AllTargets -join ', ' ) "
Write-Muted '(override with -Only <ids>, or use -AllAgents)'
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
} else {
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
Write-Info " No agents auto-detected — letting 'skills' CLI scan. "
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
}
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
}
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
$SkillTargets = @ ( $AllTargets | Where-Object { $_ -notin $SkillsAgentExclusions } )
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
$McpTargets = @ ( $AllTargets | Where-Object { $_ -in $McpAutoAgents } )
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
$DshSelected = $AllTargets -contains 'dsh'
$DshConfigured = $false
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
# ── 2. Install the AgentKey skill ─────────────────────────────────────────
if ( $SkipSkill ) {
Write-Step '2. Install the AgentKey skill'
Write-Muted 'Skipped (-SkipSkill)'
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
} elseif ( $AllTargets . Count -gt 0 -and $SkillTargets . Count -eq 0 -and -not $DshSelected ) {
# DSH never enters this branch: `-Only dsh` must still run the global
2026-08-25 00:55:26 +08:00
# `skills add -g -a universal` path, without passing dsh to `-a`.
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
Write-Step '2. Install the AgentKey skill'
Write-Muted " Skipped — selected targets ( $( $AllTargets -join ',' ) ) are MCP-only (no skill install path). "
} else {
Write-Step '2. Install the AgentKey skill'
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
$skillsArgs = @ ( '-y' , 'skills' , 'add' , $SkillRepo , '-g' )
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
if ( $SkillTargets . Count -gt 0 ) {
2026-04-23 13:52:31 +08:00
$skillsArgs + = '-a'
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
$skillsArgs + = $SkillTargets
2026-08-25 00:55:26 +08:00
} elseif ( $DshSelected ) {
$skillsArgs + = @ ( '-a' , 'universal' , '-s' , 'agentkey' )
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
}
# Always pass -y in noninteractive mode AND when we already resolved
# an explicit target list — there's nothing left to ask the user.
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
if ( $Mode -eq 'noninteractive' -or $AllTargets . Count -gt 0 ) {
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
$skillsArgs + = '-y'
2026-04-23 13:52:31 +08:00
}
& npx @skillsArgs
if ( $LASTEXITCODE -ne 0 ) { Die " Failed to install skill via 'skills' CLI " }
feat: server-beacon skill-update path for non-Bash clients (#39)
## Summary
Fixes the silent-update-failure mode where Claude Desktop (and any MCP
client without a Bash tool) gets stuck on whatever skill version shipped
at first install. On this developer's Desktop the skill had been frozen
at `0.1.2` since April — no upgrade ever fired.
Root cause is structural: SKILL.md Step 0's update check uses an inline
` ```bash ``` ` block. Claude Code executes it; Desktop reads it as
documentation. So the entire upgrade flow is dead code on Desktop. This
PR routes the version check through the MCP server instead (always-on,
available to every client), and tightens a couple of correctness bugs in
the existing install/uninstall path while we're here.
Companion PR: chainbase-labs/AgentKey-Server (server-side
`agentkey_skill_meta` tool).
## What's in here
1. **Protocol** (`protocol/skill-meta-v1.md` +
`skill-meta-v1.schema.json` + 4 fixtures) — versioned,
additive-evolution wire format for an MCP meta tool that returns
`{skill_version_latest, client_detected, update_command, update_doc_url,
…}`. Spec lives in this repo (single source of truth); server vendors a
copy and CI on both sides diffs them.
2. **SKILL.md** — Step 0 now has 0.A (beacon, cross-client) → 0.B
(inline bash, Code-only compat) → 0.C (MCP tool sanity check). Step B
branches every persistence option on whether Bash is available, with
explicit no-Bash fallback text that tells the user what didn't get saved
and the exact terminal command to persist it manually. Step C points the
non-shell fallback at GitHub Releases (we don't have a docs site).
3. **install/uninstall scripts** — `npx skills remove
chainbase-labs/agentkey` was the wrong invocation: the CLI takes the
skill name (`agentkey`), exits 0 on no-match, and made the uninstaller
falsely report success. Same class of silent-success bug in `install.sh`
when `git clone` fails mid-run. Both fixed; added post-install
filesystem verification.
4. **README / README_zh** — accurate per-client update story, including
a one-time bootstrap command for users currently stuck on a pre-1.4.0
skill on Desktop.
5. **CI** (`protocol-validate.yml`) — every fixture validates against
the schema, schema rejects 4 known-bad payloads (regression guard), spec
doc references every fixture (forces docs ↔ artifact sync).
6. **`docs/SERVER-IMPLEMENTATION.md`** — handoff doc for the server PR.
## How verified
- 4/4 fixtures pass schema; 4/4 bad payloads correctly rejected
- All cross-references in spec doc resolve
- `verify-version-sync` awk still extracts `1.3.0` from SKILL.md
frontmatter
- Companion server PR exercises the actual MCP handshake (initialize +
tools/list + tools/call); response is valid v1 JSON
- Real GitHub Releases fetch + ETag caching works on the server side
## Test plan
- [ ] CI green (`protocol-validate.yml` and `verify-version-sync.yml`
both pass)
- [ ] Companion server PR merged + new `@agentkey/mcp` published
- [ ] Release-please cuts `v1.4.0` from this branch
- [ ] On Claude Code: existing inline-bash Step 0 still fires for users
on `v1.3.x`; they get prompted to update normally
- [ ] On Claude Desktop with a pre-1.4.0 skill: user runs the README
bootstrap command once to land `v1.4.0`; from that point on, every
subsequent version is auto-discovered via the meta tool
- [ ] On Cursor / Codex: meta tool returns the `npx skills update -g
agentkey` recipe; user upgrades via shell
## Notes for the reviewer
- This is **additive**: Claude Code's existing inline-bash path is
unchanged, so no regression risk there. The protocol's
`protocol_version: 1` + immortal `update_doc_url` fallback make future
v2 servers safely degradable for v1 skills.
- Claude Desktop deliberately has no `update_command` recipe yet —
Desktop installs skills into a sandboxed `~/Library/Application
Support/Claude/local-agent-mode-sessions/skills-plugin/<UUID>/...` path
that no external CLI can reach, and we don't have a first-party
installer script. The skill rule's "no command → point at GitHub
Releases" fallback handles this until one exists. Adding a Desktop
recipe later is a non-breaking change (one row in the server's `RECIPES`
map).
2026-05-12 17:46:55 +08:00
# The skills CLI sometimes prints "Installation failed" and still
# exits 0 (e.g. network error during git clone). Verify the skill
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
# actually landed on disk before declaring success. Paths must mirror
# the `path:` markers in $AgentMarkers: most agents live under
# %USERPROFILE%\.<agent>, but amp / crush / goose / opencode live
# under %APPDATA%\<agent>.
feat: server-beacon skill-update path for non-Bash clients (#39)
## Summary
Fixes the silent-update-failure mode where Claude Desktop (and any MCP
client without a Bash tool) gets stuck on whatever skill version shipped
at first install. On this developer's Desktop the skill had been frozen
at `0.1.2` since April — no upgrade ever fired.
Root cause is structural: SKILL.md Step 0's update check uses an inline
` ```bash ``` ` block. Claude Code executes it; Desktop reads it as
documentation. So the entire upgrade flow is dead code on Desktop. This
PR routes the version check through the MCP server instead (always-on,
available to every client), and tightens a couple of correctness bugs in
the existing install/uninstall path while we're here.
Companion PR: chainbase-labs/AgentKey-Server (server-side
`agentkey_skill_meta` tool).
## What's in here
1. **Protocol** (`protocol/skill-meta-v1.md` +
`skill-meta-v1.schema.json` + 4 fixtures) — versioned,
additive-evolution wire format for an MCP meta tool that returns
`{skill_version_latest, client_detected, update_command, update_doc_url,
…}`. Spec lives in this repo (single source of truth); server vendors a
copy and CI on both sides diffs them.
2. **SKILL.md** — Step 0 now has 0.A (beacon, cross-client) → 0.B
(inline bash, Code-only compat) → 0.C (MCP tool sanity check). Step B
branches every persistence option on whether Bash is available, with
explicit no-Bash fallback text that tells the user what didn't get saved
and the exact terminal command to persist it manually. Step C points the
non-shell fallback at GitHub Releases (we don't have a docs site).
3. **install/uninstall scripts** — `npx skills remove
chainbase-labs/agentkey` was the wrong invocation: the CLI takes the
skill name (`agentkey`), exits 0 on no-match, and made the uninstaller
falsely report success. Same class of silent-success bug in `install.sh`
when `git clone` fails mid-run. Both fixed; added post-install
filesystem verification.
4. **README / README_zh** — accurate per-client update story, including
a one-time bootstrap command for users currently stuck on a pre-1.4.0
skill on Desktop.
5. **CI** (`protocol-validate.yml`) — every fixture validates against
the schema, schema rejects 4 known-bad payloads (regression guard), spec
doc references every fixture (forces docs ↔ artifact sync).
6. **`docs/SERVER-IMPLEMENTATION.md`** — handoff doc for the server PR.
## How verified
- 4/4 fixtures pass schema; 4/4 bad payloads correctly rejected
- All cross-references in spec doc resolve
- `verify-version-sync` awk still extracts `1.3.0` from SKILL.md
frontmatter
- Companion server PR exercises the actual MCP handshake (initialize +
tools/list + tools/call); response is valid v1 JSON
- Real GitHub Releases fetch + ETag caching works on the server side
## Test plan
- [ ] CI green (`protocol-validate.yml` and `verify-version-sync.yml`
both pass)
- [ ] Companion server PR merged + new `@agentkey/mcp` published
- [ ] Release-please cuts `v1.4.0` from this branch
- [ ] On Claude Code: existing inline-bash Step 0 still fires for users
on `v1.3.x`; they get prompted to update normally
- [ ] On Claude Desktop with a pre-1.4.0 skill: user runs the README
bootstrap command once to land `v1.4.0`; from that point on, every
subsequent version is auto-discovered via the meta tool
- [ ] On Cursor / Codex: meta tool returns the `npx skills update -g
agentkey` recipe; user upgrades via shell
## Notes for the reviewer
- This is **additive**: Claude Code's existing inline-bash path is
unchanged, so no regression risk there. The protocol's
`protocol_version: 1` + immortal `update_doc_url` fallback make future
v2 servers safely degradable for v1 skills.
- Claude Desktop deliberately has no `update_command` recipe yet —
Desktop installs skills into a sandboxed `~/Library/Application
Support/Claude/local-agent-mode-sessions/skills-plugin/<UUID>/...` path
that no external CLI can reach, and we don't have a first-party
installer script. The skill rule's "no command → point at GitHub
Releases" fallback handles this until one exists. Adding a Desktop
recipe later is a non-breaking change (one row in the server's `RECIPES`
map).
2026-05-12 17:46:55 +08:00
$userHome = [ Environment ] :: GetFolderPath ( 'UserProfile' )
$candidatePaths = @ (
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
( Join-Path $userHome '.agents\skills\agentkey' ) ,
( Join-Path $userHome '.claude\skills\agentkey' ) ,
( Join-Path $userHome '.cursor\skills\agentkey' ) ,
( Join-Path $userHome '.codex\skills\agentkey' ) ,
( Join-Path $userHome '.gemini\skills\agentkey' ) ,
( Join-Path $userHome '.opencode\skills\agentkey' ) ,
( Join-Path $userHome '.openclaw\skills\agentkey' ) ,
( Join-Path $userHome '.qwen\skills\agentkey' ) ,
( Join-Path $userHome '.iflow\skills\agentkey' ) ,
( Join-Path $userHome '.windsurf\skills\agentkey' ) ,
( Join-Path $userHome '.warp\skills\agentkey' ) ,
( Join-Path $userHome '.kimi\skills\agentkey' ) ,
( Join-Path $userHome '.kiro\skills\agentkey' ) ,
# APPDATA-rooted agents (parity with install.sh's $HOME/.config/<agent>)
( Join-Path $env:APPDATA 'amp\skills\agentkey' ) ,
( Join-Path $env:APPDATA 'crush\skills\agentkey' ) ,
( Join-Path $env:APPDATA 'goose\skills\agentkey' ) ,
( Join-Path $env:APPDATA 'opencode\skills\agentkey' )
feat: server-beacon skill-update path for non-Bash clients (#39)
## Summary
Fixes the silent-update-failure mode where Claude Desktop (and any MCP
client without a Bash tool) gets stuck on whatever skill version shipped
at first install. On this developer's Desktop the skill had been frozen
at `0.1.2` since April — no upgrade ever fired.
Root cause is structural: SKILL.md Step 0's update check uses an inline
` ```bash ``` ` block. Claude Code executes it; Desktop reads it as
documentation. So the entire upgrade flow is dead code on Desktop. This
PR routes the version check through the MCP server instead (always-on,
available to every client), and tightens a couple of correctness bugs in
the existing install/uninstall path while we're here.
Companion PR: chainbase-labs/AgentKey-Server (server-side
`agentkey_skill_meta` tool).
## What's in here
1. **Protocol** (`protocol/skill-meta-v1.md` +
`skill-meta-v1.schema.json` + 4 fixtures) — versioned,
additive-evolution wire format for an MCP meta tool that returns
`{skill_version_latest, client_detected, update_command, update_doc_url,
…}`. Spec lives in this repo (single source of truth); server vendors a
copy and CI on both sides diffs them.
2. **SKILL.md** — Step 0 now has 0.A (beacon, cross-client) → 0.B
(inline bash, Code-only compat) → 0.C (MCP tool sanity check). Step B
branches every persistence option on whether Bash is available, with
explicit no-Bash fallback text that tells the user what didn't get saved
and the exact terminal command to persist it manually. Step C points the
non-shell fallback at GitHub Releases (we don't have a docs site).
3. **install/uninstall scripts** — `npx skills remove
chainbase-labs/agentkey` was the wrong invocation: the CLI takes the
skill name (`agentkey`), exits 0 on no-match, and made the uninstaller
falsely report success. Same class of silent-success bug in `install.sh`
when `git clone` fails mid-run. Both fixed; added post-install
filesystem verification.
4. **README / README_zh** — accurate per-client update story, including
a one-time bootstrap command for users currently stuck on a pre-1.4.0
skill on Desktop.
5. **CI** (`protocol-validate.yml`) — every fixture validates against
the schema, schema rejects 4 known-bad payloads (regression guard), spec
doc references every fixture (forces docs ↔ artifact sync).
6. **`docs/SERVER-IMPLEMENTATION.md`** — handoff doc for the server PR.
## How verified
- 4/4 fixtures pass schema; 4/4 bad payloads correctly rejected
- All cross-references in spec doc resolve
- `verify-version-sync` awk still extracts `1.3.0` from SKILL.md
frontmatter
- Companion server PR exercises the actual MCP handshake (initialize +
tools/list + tools/call); response is valid v1 JSON
- Real GitHub Releases fetch + ETag caching works on the server side
## Test plan
- [ ] CI green (`protocol-validate.yml` and `verify-version-sync.yml`
both pass)
- [ ] Companion server PR merged + new `@agentkey/mcp` published
- [ ] Release-please cuts `v1.4.0` from this branch
- [ ] On Claude Code: existing inline-bash Step 0 still fires for users
on `v1.3.x`; they get prompted to update normally
- [ ] On Claude Desktop with a pre-1.4.0 skill: user runs the README
bootstrap command once to land `v1.4.0`; from that point on, every
subsequent version is auto-discovered via the meta tool
- [ ] On Cursor / Codex: meta tool returns the `npx skills update -g
agentkey` recipe; user upgrades via shell
## Notes for the reviewer
- This is **additive**: Claude Code's existing inline-bash path is
unchanged, so no regression risk there. The protocol's
`protocol_version: 1` + immortal `update_doc_url` fallback make future
v2 servers safely degradable for v1 skills.
- Claude Desktop deliberately has no `update_command` recipe yet —
Desktop installs skills into a sandboxed `~/Library/Application
Support/Claude/local-agent-mode-sessions/skills-plugin/<UUID>/...` path
that no external CLI can reach, and we don't have a first-party
installer script. The skill rule's "no command → point at GitHub
Releases" fallback handles this until one exists. Adding a Desktop
recipe later is a non-breaking change (one row in the server's `RECIPES`
map).
2026-05-12 17:46:55 +08:00
)
$agentkeyFound = $false
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
foreach ( $abs in $candidatePaths ) {
if ( Test-Path ( Join-Path $abs 'SKILL.md' ) ) {
feat: server-beacon skill-update path for non-Bash clients (#39)
## Summary
Fixes the silent-update-failure mode where Claude Desktop (and any MCP
client without a Bash tool) gets stuck on whatever skill version shipped
at first install. On this developer's Desktop the skill had been frozen
at `0.1.2` since April — no upgrade ever fired.
Root cause is structural: SKILL.md Step 0's update check uses an inline
` ```bash ``` ` block. Claude Code executes it; Desktop reads it as
documentation. So the entire upgrade flow is dead code on Desktop. This
PR routes the version check through the MCP server instead (always-on,
available to every client), and tightens a couple of correctness bugs in
the existing install/uninstall path while we're here.
Companion PR: chainbase-labs/AgentKey-Server (server-side
`agentkey_skill_meta` tool).
## What's in here
1. **Protocol** (`protocol/skill-meta-v1.md` +
`skill-meta-v1.schema.json` + 4 fixtures) — versioned,
additive-evolution wire format for an MCP meta tool that returns
`{skill_version_latest, client_detected, update_command, update_doc_url,
…}`. Spec lives in this repo (single source of truth); server vendors a
copy and CI on both sides diffs them.
2. **SKILL.md** — Step 0 now has 0.A (beacon, cross-client) → 0.B
(inline bash, Code-only compat) → 0.C (MCP tool sanity check). Step B
branches every persistence option on whether Bash is available, with
explicit no-Bash fallback text that tells the user what didn't get saved
and the exact terminal command to persist it manually. Step C points the
non-shell fallback at GitHub Releases (we don't have a docs site).
3. **install/uninstall scripts** — `npx skills remove
chainbase-labs/agentkey` was the wrong invocation: the CLI takes the
skill name (`agentkey`), exits 0 on no-match, and made the uninstaller
falsely report success. Same class of silent-success bug in `install.sh`
when `git clone` fails mid-run. Both fixed; added post-install
filesystem verification.
4. **README / README_zh** — accurate per-client update story, including
a one-time bootstrap command for users currently stuck on a pre-1.4.0
skill on Desktop.
5. **CI** (`protocol-validate.yml`) — every fixture validates against
the schema, schema rejects 4 known-bad payloads (regression guard), spec
doc references every fixture (forces docs ↔ artifact sync).
6. **`docs/SERVER-IMPLEMENTATION.md`** — handoff doc for the server PR.
## How verified
- 4/4 fixtures pass schema; 4/4 bad payloads correctly rejected
- All cross-references in spec doc resolve
- `verify-version-sync` awk still extracts `1.3.0` from SKILL.md
frontmatter
- Companion server PR exercises the actual MCP handshake (initialize +
tools/list + tools/call); response is valid v1 JSON
- Real GitHub Releases fetch + ETag caching works on the server side
## Test plan
- [ ] CI green (`protocol-validate.yml` and `verify-version-sync.yml`
both pass)
- [ ] Companion server PR merged + new `@agentkey/mcp` published
- [ ] Release-please cuts `v1.4.0` from this branch
- [ ] On Claude Code: existing inline-bash Step 0 still fires for users
on `v1.3.x`; they get prompted to update normally
- [ ] On Claude Desktop with a pre-1.4.0 skill: user runs the README
bootstrap command once to land `v1.4.0`; from that point on, every
subsequent version is auto-discovered via the meta tool
- [ ] On Cursor / Codex: meta tool returns the `npx skills update -g
agentkey` recipe; user upgrades via shell
## Notes for the reviewer
- This is **additive**: Claude Code's existing inline-bash path is
unchanged, so no regression risk there. The protocol's
`protocol_version: 1` + immortal `update_doc_url` fallback make future
v2 servers safely degradable for v1 skills.
- Claude Desktop deliberately has no `update_command` recipe yet —
Desktop installs skills into a sandboxed `~/Library/Application
Support/Claude/local-agent-mode-sessions/skills-plugin/<UUID>/...` path
that no external CLI can reach, and we don't have a first-party
installer script. The skill rule's "no command → point at GitHub
Releases" fallback handles this until one exists. Adding a Desktop
recipe later is a non-breaking change (one row in the server's `RECIPES`
map).
2026-05-12 17:46:55 +08:00
$agentkeyFound = $true
break
}
}
if ( -not $agentkeyFound ) {
2026-08-25 00:55:26 +08:00
Die " Skill install reported success but no agentkey SKILL.md was created — likely a network or git clone failure. Retry: npx -y skills add $SkillRepo -g -a universal -s agentkey -y "
feat: server-beacon skill-update path for non-Bash clients (#39)
## Summary
Fixes the silent-update-failure mode where Claude Desktop (and any MCP
client without a Bash tool) gets stuck on whatever skill version shipped
at first install. On this developer's Desktop the skill had been frozen
at `0.1.2` since April — no upgrade ever fired.
Root cause is structural: SKILL.md Step 0's update check uses an inline
` ```bash ``` ` block. Claude Code executes it; Desktop reads it as
documentation. So the entire upgrade flow is dead code on Desktop. This
PR routes the version check through the MCP server instead (always-on,
available to every client), and tightens a couple of correctness bugs in
the existing install/uninstall path while we're here.
Companion PR: chainbase-labs/AgentKey-Server (server-side
`agentkey_skill_meta` tool).
## What's in here
1. **Protocol** (`protocol/skill-meta-v1.md` +
`skill-meta-v1.schema.json` + 4 fixtures) — versioned,
additive-evolution wire format for an MCP meta tool that returns
`{skill_version_latest, client_detected, update_command, update_doc_url,
…}`. Spec lives in this repo (single source of truth); server vendors a
copy and CI on both sides diffs them.
2. **SKILL.md** — Step 0 now has 0.A (beacon, cross-client) → 0.B
(inline bash, Code-only compat) → 0.C (MCP tool sanity check). Step B
branches every persistence option on whether Bash is available, with
explicit no-Bash fallback text that tells the user what didn't get saved
and the exact terminal command to persist it manually. Step C points the
non-shell fallback at GitHub Releases (we don't have a docs site).
3. **install/uninstall scripts** — `npx skills remove
chainbase-labs/agentkey` was the wrong invocation: the CLI takes the
skill name (`agentkey`), exits 0 on no-match, and made the uninstaller
falsely report success. Same class of silent-success bug in `install.sh`
when `git clone` fails mid-run. Both fixed; added post-install
filesystem verification.
4. **README / README_zh** — accurate per-client update story, including
a one-time bootstrap command for users currently stuck on a pre-1.4.0
skill on Desktop.
5. **CI** (`protocol-validate.yml`) — every fixture validates against
the schema, schema rejects 4 known-bad payloads (regression guard), spec
doc references every fixture (forces docs ↔ artifact sync).
6. **`docs/SERVER-IMPLEMENTATION.md`** — handoff doc for the server PR.
## How verified
- 4/4 fixtures pass schema; 4/4 bad payloads correctly rejected
- All cross-references in spec doc resolve
- `verify-version-sync` awk still extracts `1.3.0` from SKILL.md
frontmatter
- Companion server PR exercises the actual MCP handshake (initialize +
tools/list + tools/call); response is valid v1 JSON
- Real GitHub Releases fetch + ETag caching works on the server side
## Test plan
- [ ] CI green (`protocol-validate.yml` and `verify-version-sync.yml`
both pass)
- [ ] Companion server PR merged + new `@agentkey/mcp` published
- [ ] Release-please cuts `v1.4.0` from this branch
- [ ] On Claude Code: existing inline-bash Step 0 still fires for users
on `v1.3.x`; they get prompted to update normally
- [ ] On Claude Desktop with a pre-1.4.0 skill: user runs the README
bootstrap command once to land `v1.4.0`; from that point on, every
subsequent version is auto-discovered via the meta tool
- [ ] On Cursor / Codex: meta tool returns the `npx skills update -g
agentkey` recipe; user upgrades via shell
## Notes for the reviewer
- This is **additive**: Claude Code's existing inline-bash path is
unchanged, so no regression risk there. The protocol's
`protocol_version: 1` + immortal `update_doc_url` fallback make future
v2 servers safely degradable for v1 skills.
- Claude Desktop deliberately has no `update_command` recipe yet —
Desktop installs skills into a sandboxed `~/Library/Application
Support/Claude/local-agent-mode-sessions/skills-plugin/<UUID>/...` path
that no external CLI can reach, and we don't have a first-party
installer script. The skill rule's "no command → point at GitHub
Releases" fallback handles this until one exists. Adding a Desktop
recipe later is a non-breaking change (one row in the server's `RECIPES`
map).
2026-05-12 17:46:55 +08:00
}
2026-04-23 13:52:31 +08:00
Write-Ok 'Skill installed'
}
# ── 3. MCP authentication ────────────────────────────────────────────────
2026-05-15 17:19:24 +08:00
# Always run auth-login. The CLI itself decides whether the existing token
# can be reused or a fresh device-code flow is needed — the installer no
# longer second-guesses by sniffing config files (which produced false
# positives across the stdio → HTTP schema change).
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
if ( $SkipMcp ) {
Write-Step '3. Register the MCP server'
Write-Muted 'Skipped (-SkipMcp)'
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
} elseif ( $AllTargets . Count -gt 0 -and $McpTargets . Count -eq 0 ) {
# User selected ONLY MCP-incompatible agents (goose / kode / kilo via
# -Only). Running auth-login without --only would silently register MCP
# in every detected agent, overriding the user's explicit scope. Skip
# rather than over-register. See PR #41 B1.
Write-Step '3. Register the MCP server'
Write-Muted " Skipped — selected agents ( $( $AllTargets -join ',' ) ) need manual MCP setup (see SKILL.md Fallback section). "
feat(install): auto-detect agents, route MCP auth to QR mode for remote installs (#18)
## Summary
Two end-to-end improvements to `install.sh` / `install.ps1`, mirrored
across both:
### 1. Agent auto-detection
Probe well-known config dirs and binaries for ~18 of
[vercel-labs/skills](https://github.com/vercel-labs/skills)' 45
supported agents (`claude-code`, `cursor`, `codex`, `gemini-cli`,
`opencode`, `openclaw`, `qwen-code`, `iflow-cli`, `windsurf`, `warp`,
`amp`, `crush`, `goose`, `droid`, `kode`, `kilo`, `kimi-cli`,
`kiro-cli`).
When detection finds anything, the `skills add` step gets `-a id1,id2,…`
instead of dumping the user into the multi-select. New flags:
- `--list-agents` — preview what we'd auto-select (and exit)
- `--all-agents` — skip our detection, let `skills` CLI scan everything
- `--only` — manual override (unchanged)
### 2. Local-vs-remote MCP auth routing
The current `--auth-login` always auto-opens a browser. On SSH sessions,
Docker containers, and OpenClaw remote channels (where the user is on a
phone), that silently launches a browser they can't see — leaving them
stuck on "Waiting for authorization…".
Detection (any signal fires ⇒ remote):
| Signal | Notes |
|---|---|
| `$HOME/.openclaw` exists | OpenClaw runtime — most reliable single
signal |
| `$SSH_CONNECTION` / `$SSH_TTY` | Generic SSH session |
| Linux without `$DISPLAY` / `$WAYLAND_DISPLAY` | Headless |
When remote, pass `--no-browser` to the MCP CLI, which prints URL + ANSI
QR for the user to scan with a phone.
New flags:
- `--remote` / `--local` — force either mode
- `--force-mcp` — re-auth even if AgentKey is already configured
Also adds an idempotency short-circuit: if any known MCP config already
has an `agentkey` block with a valid-looking API key, skip the auth step
entirely (`--force-mcp` to override).
### 3. Docs
`README.md` + `docs/README_zh.md` updated to document the new flags and
add a dedicated **"Installing over SSH / Docker / OpenClaw"** section.
## Companion PRs (server side)
The MCP-server changes that this installer routes to ship in a chain of
three PRs against `chainbase-labs/AgentKey-Server`:
| PR | Status | What it adds |
|---|---|---|
| [#2](https://github.com/chainbase-labs/AgentKey-Server/pull/2) |
merged | `--no-browser` / `--qr` / `--no-qr` flags + `qrcode-terminal`
dep (v0.3.5 source bump) |
| [#3](https://github.com/chainbase-labs/AgentKey-Server/pull/3) |
merged | Bump to 0.3.6 — npm `0.3.5` had been published from a pre-merge
commit and shipped stale `dist/` |
| [#4](https://github.com/chainbase-labs/AgentKey-Server/pull/4) | open
| Fix QR not rendering in `--no-browser` (CJS interop bug —
`qrcode-terminal`'s `generate` lives on `.default` under NodeNext); bump
to 0.3.7 |
**This installer needs `@agentkey/mcp@0.3.7`** to be on npm for the QR
flow to actually work. Sequence:
1. Merge #4 ✅
2. Maintainer runs `cd mcp-server && npm publish` (no npm-publish CI
workflow) ✅
3. Merge this PR — `npx -y @agentkey/mcp` will then pull 0.3.7+ and the
`--remote` path renders the QR
This installer change is **forward-compatible**: it can land anytime —
older `@agentkey/mcp` versions silently ignore the unknown
`--no-browser` flag, so worst case a remote user gets the old
browser-opens-on-the-wrong-host UX until the new mcp publishes.
## Test plan
Verified end-to-end on macOS against a local build of
`@agentkey/mcp@0.3.7` (server PR #4):
- [x] Bash syntax check passes (`bash -n install.sh`)
- [x] `install.sh --help` renders all 5 new flag rows
- [x] `install.sh --list-agents` correctly prints detected agents on
test host (10 agents incl. `openclaw`)
- [x] `install.sh --remote --local` exits with code 1 (mutex)
- [x] `install.sh --skip-skill` short-circuits with "AgentKey is already
configured…" when configs have agentkey
- [x] `install.sh --remote --skip-skill --force-mcp` end-to-end: prints
`Detected remote install context — printing QR + URL instead of opening
a browser here`, then `reason: $HOME/.openclaw exists (OpenClaw
runtime)`, launches mcp CLI, renders 16-row ANSI QR, polls — no `open`
process spawned
- [x] All 4 mcp 0.3.7 flag combinations behave correctly (`--no-browser`
/ `--no-browser --no-qr` / `--qr` / no-flags back-compat)
- [ ] `install.ps1` not lint-checked locally (no pwsh on test host);
logic is a strict mirror of bash — needs Windows smoke before merge
- [ ] Inside a real OpenClaw container — confirm `~/.openclaw` triggers
as expected
## Why now
Users running the installer via OpenClaw / Claude Code remote channels
(on a phone) currently see a black-hole UX: the browser opens on the
wrong machine and the install process appears to hang. The detection
here removes the manual `--remote` flag for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-27 21:55:57 +08:00
} else {
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
# Pin MCP registration to the same agent list the skill step targeted.
# When McpTargets is empty (auto-detect found nothing), let
# `@agentkey/cli` do its own detection — same fallback we use for skill
# install. Older CLI versions silently ignore --only, so this is
# forward-compatible.
$authArgs = @ ( '--auth-login' )
if ( $McpTargets . Count -gt 0 ) {
$authArgs + = '--only'
$authArgs + = ( $McpTargets -join ',' )
}
fix(install): drop remote/local detection, always try browser (#52)
## Summary
Installer was sniffing SSH env vars, `~/.openclaw`, and `\$DISPLAY` to
decide whether to pass `--no-browser` to `@agentkey/cli --auth-login`.
Inspecting the v1.0 CLI source confirms this was unnecessary:
```js
const { device_code, user_code, verification_uri, expires_in } = await res.json();
const authUrl = \`\${verification_uri}?code=\${user_code}\`;
console.log(\` Open this URL to authorize:\`); // ← always prints
console.log(\` \${authUrl}\`);
// ...
if (!noBrowser) { /* best-effort open() */ } // ← only this is gated
```
The CLI **always** prints the auth URL on stdout. `--no-browser` only
adds a terminal QR and skips the `open()`/`xdg-open()`/`start()`
attempt. The CLI's open-browser call is already best-effort — on a
headless host it silently no-ops.
So the installer-side heuristic was:
- **redundant** for the URL (CLI prints it either way)
- **harmful** when it mis-detected (local users on a headless tmux pane
or behind a mis-detected SSH session got the QR flow with no browser
attempt at all, even though their machine could have opened one)
This was the root cause of the reported "no browser pops up on \`curl …
| bash\`" symptom.
## Fix
Drop the heuristic. Always call \`npx -y @agentkey/cli --auth-login\`
(no \`--no-browser\`). The CLI tries \`open\` / \`xdg-open\` /
\`start\`; if that fails the user has the URL right there in the
terminal.
## Removed
- \`detect_remote()\` in \`scripts/install.sh\` / \`Test-RemoteInstall\`
in \`scripts/install.ps1\`
- \`--remote\` / \`--local\` / \`-Remote\` / \`-Local\` flags + their
mutually-exclusive guard + \`FORCE_REMOTE\` / \`FORCE_LOCAL\` state
- \`--no-browser\` passthrough to the CLI
- \"Installing over SSH, inside Docker, …\" details section in README.md
/ docs/README_zh.md — replaced with a one-line callout under the
advanced install options
- Synopsis / help / behavior copy mentioning the old detection logic
Net: **+24 / -174 lines**.
## Test plan
- [ ] On macOS / Linux desktop: \`curl -fsSL
https://agentkey.app/install.sh | bash\` — browser pops up; URL also
visible in terminal as a fallback
- [ ] In an SSH session: same one-liner — \`xdg-open\` no-ops on the
remote host (no harm), URL is right there in terminal; copy it to a
local browser to finish
- [ ] Windows PowerShell: \`irm https://agentkey.app/install.ps1 | iex\`
— \`start\` opens the default browser; URL also visible
- [ ] \`--skip-mcp\` still skips the auth step
- [ ] \`bash -n scripts/install.sh\` passes (verified)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:03:58 +08:00
Write-Step '3. Register the MCP server'
Write-Info 'Opening your browser for AgentKey device authentication ...'
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
if ( $McpTargets . Count -gt 0 ) {
Write-Muted " Will register MCP in: $( $McpTargets -join ', ' ) "
} else {
Write-Muted " If a browser doesn't open (SSH / WinRM / Docker / headless), the auth URL is also printed below — open it on any device to finish. "
}
2026-04-23 13:52:31 +08:00
Write-Host ''
feat: agent install telemetry (installer side, spec §8.3) (#30)
## Summary
Installer-side half of the agent-install telemetry rollout (spec §8.3).
Adds `--no-telemetry` opt-out, telemetry status banner, and 7-var env
passthrough to `npx -y @agentkey/mcp --auth-login` so the server can
capture `install_completed` with full install context.
- `scripts/install.sh`: `--no-telemetry` flag,
`compute_device_fingerprint()` helper, env exports immediately before
the `--auth-login` invocation
- `scripts/install.ps1`: PowerShell-mirror of the same — `-NoTelemetry`,
SHA-256 fingerprint, `$env:AGENTKEY_*` exports
## Blocked on
**AgentKey-Server PR** that consumes the 7 transparent env vars
(`AGENTKEY_TELEMETRY`, `AGENTKEY_INSTALL_SOURCE`,
`AGENTKEY_DETECTED_AGENTS`, `AGENTKEY_SELECTED_AGENTS`,
`AGENTKEY_INSTALLER_FLAGS`, `AGENTKEY_DEVICE_FINGERPRINT` — plus
implicit skill-version detection on the server side) and capture
`install_completed`. Until that lands, the env passthrough goes to a
process that does nothing with them — harmless, but the telemetry signal
is incomplete.
This PR can be merged independently — it does not break the existing
installer flow either way.
## Test plan
- [x] `bash -n scripts/install.sh` — syntactic check passes
- [x] `bash scripts/install.sh --help` — `--no-telemetry` documented in
Options
- [x] `bash scripts/install.sh --list-agents` — early-return path
unaffected
- [x] `bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp
--yes` — creates `~/.config/agentkey/telemetry-disabled`, prints
"Telemetry: disabled (--no-telemetry)"
- [x] Pre-existing opt-out file recognized — prints "Telemetry: disabled
(~/.config/agentkey/telemetry-disabled exists)"
- [x] Default (no flag / no file) — prints "Telemetry: anonymous usage
stats enabled (re-run with --no-telemetry to opt out)"
- [x] `install.ps1` structural checks (line count, `\$NoTelemetry`
references, single `param(...)` block, brace balance)
- [ ] PowerShell parse on Windows runner (relies on existing
windows-latest CI for any install.ps1-touching PR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:09:36 +08:00
# Telemetry context for install_completed. Opt-out is honored at the
# SOURCE: when AGENTKEY_TELEMETRY=0, no other context env vars are
# exported — hostname-derived fingerprint, agent lists, and installer
2026-05-15 16:31:42 +08:00
# flags are never computed nor passed to the child `npx @agentkey/cli`
feat: agent install telemetry (installer side, spec §8.3) (#30)
## Summary
Installer-side half of the agent-install telemetry rollout (spec §8.3).
Adds `--no-telemetry` opt-out, telemetry status banner, and 7-var env
passthrough to `npx -y @agentkey/mcp --auth-login` so the server can
capture `install_completed` with full install context.
- `scripts/install.sh`: `--no-telemetry` flag,
`compute_device_fingerprint()` helper, env exports immediately before
the `--auth-login` invocation
- `scripts/install.ps1`: PowerShell-mirror of the same — `-NoTelemetry`,
SHA-256 fingerprint, `$env:AGENTKEY_*` exports
## Blocked on
**AgentKey-Server PR** that consumes the 7 transparent env vars
(`AGENTKEY_TELEMETRY`, `AGENTKEY_INSTALL_SOURCE`,
`AGENTKEY_DETECTED_AGENTS`, `AGENTKEY_SELECTED_AGENTS`,
`AGENTKEY_INSTALLER_FLAGS`, `AGENTKEY_DEVICE_FINGERPRINT` — plus
implicit skill-version detection on the server side) and capture
`install_completed`. Until that lands, the env passthrough goes to a
process that does nothing with them — harmless, but the telemetry signal
is incomplete.
This PR can be merged independently — it does not break the existing
installer flow either way.
## Test plan
- [x] `bash -n scripts/install.sh` — syntactic check passes
- [x] `bash scripts/install.sh --help` — `--no-telemetry` documented in
Options
- [x] `bash scripts/install.sh --list-agents` — early-return path
unaffected
- [x] `bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp
--yes` — creates `~/.config/agentkey/telemetry-disabled`, prints
"Telemetry: disabled (--no-telemetry)"
- [x] Pre-existing opt-out file recognized — prints "Telemetry: disabled
(~/.config/agentkey/telemetry-disabled exists)"
- [x] Default (no flag / no file) — prints "Telemetry: anonymous usage
stats enabled (re-run with --no-telemetry to opt out)"
- [x] `install.ps1` structural checks (line count, `\$NoTelemetry`
references, single `param(...)` block, brace balance)
- [ ] PowerShell parse on Windows runner (relies on existing
windows-latest CI for any install.ps1-touching PR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:09:36 +08:00
# process. The server treats AGENTKEY_TELEMETRY=0 as a hard skip.
if ( $NoTelemetry -or ( Test-Path -LiteralPath $TelemetryOptOutFile ) ) {
$env:AGENTKEY_TELEMETRY = '0'
} else {
$env:AGENTKEY_TELEMETRY = '1'
$_hn = [ System.Net.Dns ] :: GetHostName ( )
$_user = $env:USERNAME
$_input = " $_hn |windows| $_user "
$_bytes = [ System.Text.Encoding ] :: UTF8 . GetBytes ( $_input )
$_sha = [ System.Security.Cryptography.SHA256 ] :: Create ( )
$_hash = ( $_sha . ComputeHash ( $_bytes ) | ForEach-Object { $_ . ToString ( 'x2' ) } ) -join ''
$DeviceFingerprint = $_hash . Substring ( 0 , 16 )
$DetectedAgents = Get-DetectedAgents
$env:AGENTKEY_INSTALL_SOURCE = 'one_liner'
$env:AGENTKEY_DETECTED_AGENTS = ( $DetectedAgents -join ',' )
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
$env:AGENTKEY_SELECTED_AGENTS = ( $AllTargets -join ',' )
feat: agent install telemetry (installer side, spec §8.3) (#30)
## Summary
Installer-side half of the agent-install telemetry rollout (spec §8.3).
Adds `--no-telemetry` opt-out, telemetry status banner, and 7-var env
passthrough to `npx -y @agentkey/mcp --auth-login` so the server can
capture `install_completed` with full install context.
- `scripts/install.sh`: `--no-telemetry` flag,
`compute_device_fingerprint()` helper, env exports immediately before
the `--auth-login` invocation
- `scripts/install.ps1`: PowerShell-mirror of the same — `-NoTelemetry`,
SHA-256 fingerprint, `$env:AGENTKEY_*` exports
## Blocked on
**AgentKey-Server PR** that consumes the 7 transparent env vars
(`AGENTKEY_TELEMETRY`, `AGENTKEY_INSTALL_SOURCE`,
`AGENTKEY_DETECTED_AGENTS`, `AGENTKEY_SELECTED_AGENTS`,
`AGENTKEY_INSTALLER_FLAGS`, `AGENTKEY_DEVICE_FINGERPRINT` — plus
implicit skill-version detection on the server side) and capture
`install_completed`. Until that lands, the env passthrough goes to a
process that does nothing with them — harmless, but the telemetry signal
is incomplete.
This PR can be merged independently — it does not break the existing
installer flow either way.
## Test plan
- [x] `bash -n scripts/install.sh` — syntactic check passes
- [x] `bash scripts/install.sh --help` — `--no-telemetry` documented in
Options
- [x] `bash scripts/install.sh --list-agents` — early-return path
unaffected
- [x] `bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp
--yes` — creates `~/.config/agentkey/telemetry-disabled`, prints
"Telemetry: disabled (--no-telemetry)"
- [x] Pre-existing opt-out file recognized — prints "Telemetry: disabled
(~/.config/agentkey/telemetry-disabled exists)"
- [x] Default (no flag / no file) — prints "Telemetry: anonymous usage
stats enabled (re-run with --no-telemetry to opt out)"
- [x] `install.ps1` structural checks (line count, `\$NoTelemetry`
references, single `param(...)` block, brace balance)
- [ ] PowerShell parse on Windows runner (relies on existing
windows-latest CI for any install.ps1-touching PR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:09:36 +08:00
$env:AGENTKEY_INSTALLER_FLAGS = ( $PSBoundParameters . Keys | ForEach-Object { " - $_ " } ) -join ','
$env:AGENTKEY_DEVICE_FINGERPRINT = $DeviceFingerprint
}
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
& npx -y $CliPackage @authArgs
2026-04-23 13:52:31 +08:00
if ( $LASTEXITCODE -ne 0 ) {
Write-Err 'MCP auth failed.'
feat(installer): unify skill + MCP agent registration (16 agents) (#41)
## Summary
- Drive both `npx skills add -a` and `@agentkey/mcp --auth-login --only`
from a single detected-agent list. MCP registration now follows the same
per-host auto-detection that skill install already does, expanding MCP
auto-registration from 3 clients to **16**.
- Fix the longstanding `claude-code` marker bug: it included Claude
Desktop's config dir, causing skills CLI to target a nonexistent Claude
Code on Desktop-only machines. `claude-desktop` is now its own id
(MCP-only) — passed to `--auth-login --only` but never to `skills add`.
- Detect Claude Desktop via `/Applications/Claude.app` /
`%LOCALAPPDATA%\AnthropicClaude` so "installed but never launched" still
registers (Linux still requires the config dir).
- New `scripts/dev-smoke.sh` — sandboxed 4-phase regression suite, 42
assertions, ~10s, never touches real `$HOME`. Run before any PR touching
install/uninstall scripts.
## Depends on
[chainbase-labs/AgentKey-Server#9](https://github.com/chainbase-labs/AgentKey-Server/pull/9)
— adds `--only <ids>` to `@agentkey/mcp --auth-login`. Older CLI
versions silently ignore the flag, so this PR is forward-compatible
either way.
## Uninstaller (the bigger gap before this)
The previous uninstaller only cleaned 3 config paths and only knew the
`mcpServers.<name>` JSON shape. With 13 new agents using 4 different
schema dialects, that left AgentKey configured everywhere after
uninstall.
- Expanded MCP cleanup to **14 JSON paths + codex TOML**, covering all
16 auto-registered agents
- Schema-agnostic JSON scrub: walks the tree and drops dict keys whose
name EXACTLY matches our server names. Handles `mcpServers.<name>` /
`mcp.<name>` / `amp.mcpServers.<name>` / `projects.X.mcpServers.<name>`
in one pass
- Codex TOML splice via awk / PowerShell (no parser dep) — drops
`[mcp_servers.agentkey]` + legacy quoted block, preserves sibling
sections
- `droid mcp remove` + `openclaw mcp unset` for CLI-registered agents
- **Exact-match** server names (not substring) so user keys like
`agentkey-helper` are preserved (regression test included in dev-smoke)
## Bugs fixed during review
| Where | Bug |
|---|---|
| install.sh:487 | Unbound `$TARGETS` variable (renamed during refactor)
— `set -u` would have made this fatal |
| install.ps1 | `$SkillTargets.Count` used where `$AllTargets.Count` was
meant — diverged from install.sh behavior |
| install.sh | `--only claude-desktop` ran `skills add -a` with no
filter, defeating the user's `--only` intent. Now correctly skips the
skill step |
| install.sh helpers | Leaked-scope loop vars (`_ids`, `_id`) — declared
`local -a` |
## Test plan
- [x] `scripts/dev-smoke.sh` — 42 passing / 0 failing (Phase 1 unit
tests + Phase 2 installer + Phase 3 writer schemas + Phase 4 uninstaller
w/ false-positive guard)
- [x] `bash -n` clean for install.sh + uninstall.sh
- [x] `--list-agents` correctly lists `claude-desktop` as a separate id
- [x] `--only claude-desktop --skip-mcp --yes` walks the new "MCP-only,
skip skill" branch
- [x] Auto-detect path tested via `bash -x` trace under `set -u` (no
unbound-variable explosion)
- [x] Uninstaller decoy fixtures: `agentkey-helper`, `other-svr`,
`[mcp_servers.other]`, `[unrelated_section]` all preserved after scrub
- [ ] Windows: `install.ps1` / `uninstall.ps1` syntax-checked but not
runtime-tested (no Windows box handy — happy to test if reviewer has
one)
---------
Co-authored-by: Bruce <bruce@checkabc.me>
2026-05-20 10:07:11 +08:00
Write-Muted " Retry manually: npx -y $CliPackage $( $authArgs -join ' ' ) "
2026-04-23 13:52:31 +08:00
exit 1
}
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
$DshConfigured = $McpTargets -contains 'dsh'
2026-04-23 13:52:31 +08:00
Write-Ok 'MCP server registered'
}
# ── 4. Summary ───────────────────────────────────────────────────────────
Write-Step '✨ Installation complete'
Write-Host ''
Write-Host ' Next steps' -ForegroundColor White
feat: add DeepSeek Harness and Kimi MCP routing (#96)
## What changed
- teach the one-line macOS/Linux and Windows installers to detect DSH,
install the AgentKey skill globally, and invoke the DSH device-code MCP
writer without passing `dsh` to `skills add -a`
- remove only top-level AgentKey managed blocks during uninstall while
preserving marker-prefix collisions, YAML block scalars, malformed
blocks, and unrelated patches
- add a DSH-specific Skill setup branch explaining why DSH rc.7 must use
device-code Bearer authentication instead of generic MCP OAuth
- document the home-level patch, safe legacy migration, symlink-profile
behavior, HMR limits, tool-policy limits, and actual readiness checks in
English and Chinese
- route the Kimi plugin through the client-attributed
`https://api.agentkey.app/kimi/v1/mcp` alias while keeping its native
OAuth flow and the same AgentKey MCP surface
- add macOS/Linux Bats coverage, an attributed endpoint contract, and a
Windows PowerShell marker regression gate
## Why
DSH users need one global AgentKey integration across current and future
profiles without selecting an AgentKey preset. DSH 0.1.0-rc.7 cannot
complete the generic header-free MCP OAuth flow, so the public setup and
self-repair guidance must consistently route DSH through `@agentkey/cli
--auth-login --only dsh`.
Kimi uses a client-attributed MCP path so Server telemetry and routing
can identify the originating client without changing Kimi's OAuth or
tool behavior.
## User impact
After the Server and CLI dependency are released, DSH users can run the
normal one-line installer or the documented two-step flow. They verify
success by checking the `agentkey` Loader row and then calling
`find_tools`, `describe_tool`, and `execute_tool`; Mounted/active alone
is not treated as a successful MCP connection.
Kimi plugin users continue to authenticate with the existing native
OAuth command; only the remote path changes to the attributed alias.
## Validation
- `bats tests/` (41/41)
- `bash -n scripts/install.sh`
- `bash -n scripts/uninstall.sh`
- Windows marker regression is configured on `windows-latest`
- `git diff --check`
## Release dependency
- Server/CLI implementation:
https://github.com/chainbase-labs/AgentKey-Server/pull/241
- deploy and verify the Server routes first
- publish and canary `@agentkey/cli@1.0.4` second
- release these installers, Skill changes, Kimi route, and public
documentation last
This is a CLI-managed DSH MCP integration, not a native installable DSH
plugin.
---------
Co-authored-by: Allen <0xfatdog@gmail.com>
2026-08-23 04:04:57 +08:00
if ( $DshConfigured ) {
Write-Muted '1. Running DSH profiles hot-apply the home patch; start stopped DSH profiles and restart other clients.'
} else {
Write-Muted '1. Restart your agent (Claude Code / Cursor / etc.)'
}
2026-04-23 13:52:31 +08:00
Write-Muted '2. Ask it something that needs the internet:'
Write-Host ' "What has Musk been tweeting about lately?"' -ForegroundColor Cyan
Write-Host ''
Write-Host ' Docs https://agentkey.app/docs' -ForegroundColor White
Write-Host ' Uninstall irm https://agentkey.app/uninstall.ps1 | iex' -ForegroundColor White
Write-Host ''