From 3e09e875fd3410f6a12e103365dd5df928414449 Mon Sep 17 00:00:00 2001 From: fullstackjam Date: Fri, 26 Jun 2026 00:05:43 +0800 Subject: [PATCH] chore: remove unused check-mcp.sh diagnostic script check-mcp.sh has shipped since the initial public release but was never wired into the skill's runtime. `git log -S check-mcp -- '*SKILL.md'` is empty across all history, and the skill verifies MCP health via the native `list_tools` endpoint (SKILL.md -> "Status"), not a shell script. It is referenced by no runtime path: not SKILL.md, CI, the bats suite, dev-smoke.sh, or either installer. Removing it: - drops the skill's only python3 dependency (parsing ~/.claude.json) - shrinks the skill's on-disk read footprint to zero -- it no longer reads any agent config file or AGENTKEY_API_KEY value from disk - removes the credential-read pattern that required a SECURITY.md carve-out and a ClawScan false-positive note Also updates the now-dangling references: SECURITY.md (helper-script list, file table, scanner notes), the release-please ClawScan note, the PR-template checkbox, and the directory-tree comments in README / README_zh / CLAUDE.md. While restructuring SECURITY.md's scanner-notes list, also corrects a pre-existing self-contradiction in that block: item 1 claimed check-update.sh compares the release tag against skills/agentkey/version.txt, but the script compares against an embedded constant (LOCAL_VERSION) and reads no file -- now consistent with the same doc's line 35. Typed `chore:` so an internal cleanup does not trigger a user-facing plugin release. --- .claude/CLAUDE.md | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 1 - .github/workflows/release-please.yml | 2 +- README.md | 2 +- SECURITY.md | 13 ++-- docs/README_zh.md | 2 +- skills/agentkey/scripts/check-mcp.sh | 92 ---------------------------- 7 files changed, 10 insertions(+), 104 deletions(-) delete mode 100755 skills/agentkey/scripts/check-mcp.sh diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index ab96c95..1c3d507 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -23,7 +23,7 @@ agentkey/ ├── .mcp.json # Auto-registers AgentKey MCP when installed as a plugin ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules (end-user facing) -│ ├── scripts/ # check-mcp / check-update helpers +│ ├── scripts/ # check-update helper │ └── version.txt # Managed by release-please only — must live inside the skill so it survives `npx skills add` └── scripts/ └── uninstall.sh # End-user cleanup helper diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 124a88e..7821be4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -27,7 +27,6 @@ **Any change:** - [ ] No knowledge added to `SKILL.md` (routing logic only) - [ ] Reference guides follow the standard structure (see `CONTRIBUTING.md`) -- [ ] `check-mcp.sh` still works if `.mcp.json` was touched --- diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 59abdd2..2c28aa3 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -89,4 +89,4 @@ jobs: --slug agentkey \ --version "$VERSION" \ --changelog "$CHANGELOG" \ - --clawscan-note "Expected behavior: this is an MCP-adapter skill. (1) SKILL.md routes the agent to the remote AgentKey HTTP MCP endpoint (https://api.agentkey.app/v1/mcp) for real-time data (web search, social, on-chain). (2) scripts/check-update.sh makes a read-only curl to the GitHub Releases API to notify when a newer skill version exists; it never modifies the install. (3) scripts/check-mcp.sh reads local agent config files (e.g. ~/.claude.json) and runs 'claude mcp list' to detect whether the MCP is registered and an API key is present. This is local config inspection and version checking, not credential exfiltration; the API key is user-provided and stays in standard local MCP config." + --clawscan-note "Expected behavior: this is an MCP-adapter skill. (1) SKILL.md routes the agent to the remote AgentKey HTTP MCP endpoint (https://api.agentkey.app/v1/mcp) for real-time data (web search, social, on-chain). (2) scripts/check-update.sh makes a read-only curl to the GitHub Releases API to notify when a newer skill version exists; it never modifies the install. This is version checking, not credential exfiltration; the API key is user-provided and stays in standard local MCP config." diff --git a/README.md b/README.md index 9bea54a..246ea9a 100644 --- a/README.md +++ b/README.md @@ -368,7 +368,7 @@ agentkey/ ├── .mcp.json # Used when installed as a plugin ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules -│ ├── scripts/ # check-mcp / check-update helpers +│ ├── scripts/ # check-update helper │ └── version.txt # Managed by release-please └── scripts/ ├── install.sh # One-command installer (mac/linux) diff --git a/SECURITY.md b/SECURITY.md index 08f106b..4d90cd5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -30,24 +30,24 @@ We follow coordinated disclosure. Once a fix is available, we publish a security ### What this skill does on your machine -The skill ships two helper scripts that the agent invokes: +The skill ships one helper script that the agent invokes: - **`skills/agentkey/scripts/check-update.sh`** — **notify-only**. At most every 60 minutes (12 hours once an upgrade is known), it calls `https://api.github.com/repos/chainbase-labs/agentkey/releases/latest`, compares the tag against a version constant embedded in the script itself (synced at release time by release-please via `extra-files`), and prints `UPGRADE_AVAILABLE ` if they differ. The script does **no** filesystem traversal — there is no `dirname`/`..` path resolution, no read of `version.txt`, no dependency on `CLAUDE_PLUGIN_ROOT`. It also honors a snooze file (`~/.config/agentkey/update-snoozed`, escalating 24h/48h/7d backoff) and a disable file (`~/.config/agentkey/update-disabled`); both are read-only from this script's perspective. The script never runs `git`, never writes to anything except its TMPDIR cache, and never executes downloaded code. When the agent sees `UPGRADE_AVAILABLE` it surfaces an `AskUserQuestion` prompt (Yes / Always / Not now / Never). The actual update — `npx skills update agentkey` — runs only after the user picks "Yes" or "Always", or if the user has previously opted into auto-upgrade via `AGENTKEY_AUTO_UPGRADE=1` or `~/.config/agentkey/auto-upgrade`. The agent invokes that command via its own Bash tool, not via this script. -- **`skills/agentkey/scripts/check-mcp.sh`** — reads `~/.claude.json` and `~/.env.local` to verify the AgentKey MCP server is registered and the API key is present. **Read-only**; no network egress; output is a single status code. + +The skill verifies MCP health by calling the MCP `list_tools` endpoint directly (see SKILL.md → "Status"); it does **not** read any agent config file or `AGENTKEY_API_KEY` value from disk. ### Files the skill reads or writes | Path | Mode | Purpose | |---|---|---| -| `~/.claude.json` | read | Detect MCP registration; read `AGENTKEY_API_KEY` env value | -| `~/.env.local` | read | Fallback location for `AGENTKEY_API_KEY` | | `${TMPDIR}/agentkey-update-check` | read/write | Cache for the update check | | `~/.config/agentkey/auto-upgrade` | written by the agent on user's "Always keep me up to date" choice; read by Step 0 to skip the prompt | Persistent auto-upgrade opt-in | | `~/.config/agentkey/update-snoozed` | written by the agent on user's "Not now" choice; read by `check-update.sh` to suppress reminders | Snooze state (` `) | | `~/.config/agentkey/update-disabled` | written by the agent on user's "Never ask again" choice; read by `check-update.sh` to exit silently | Permanent disable for update checks | | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%/Claude/...` (Windows) | written by the separate `npx -y @agentkey/cli --auth-login` command, **not** by the skill | MCP registration | +| `~/.claude.json` | written by `--auth-login` (`claude mcp add`), **not** by the skill | Claude Code MCP registration + `AGENTKEY_API_KEY` storage | | `~/.cursor/mcp.json` | written by `--auth-login`, **not** by the skill | MCP registration | ### Network egress from the skill @@ -71,9 +71,8 @@ The skill ships two helper scripts that the agent invokes: ## Scanner false-positive notes -Automated scanners (VirusTotal, ClawScan) may flag this skill as `Suspicious` due to two intentional patterns. We document them here so reviewers can verify intent: +Automated scanners (VirusTotal, ClawScan) may flag this skill as `Suspicious` due to one intentional pattern. We document it here so reviewers can verify intent: -1. **`check-update.sh` contacts GitHub.** Pattern may match "remote-controlled binary update" heuristics. **Why this is intentional:** the script is notify-only — it issues a single `GET https://api.github.com/repos/chainbase-labs/agentkey/releases/latest`, compares the tag against `skills/agentkey/version.txt`, prints a one-line status, and exits. It never writes anywhere except the cache file at `${TMPDIR}/agentkey-update-check`, never invokes `git`, and never executes downloaded code. Update execution lives entirely in the agent's interactive layer (`AskUserQuestion` → `npx skills update`), gated by explicit user consent or a previously persisted opt-in flag. -2. **`check-mcp.sh` reads `*API_KEY*` env values.** Pattern matches "credential harvesting" heuristics. **Why this is intentional:** the read is local-only, never transmitted, and exists purely to confirm `AGENTKEY_API_KEY` is configured before the agent attempts an MCP call. The script's only output is a one-word status code (`MCP_OK` / `MCP_NO_KEY` / `MCP_NOT_CONFIGURED`); the key value itself is discarded. +1. **`check-update.sh` contacts GitHub.** Pattern may match "remote-controlled binary update" heuristics. **Why this is intentional:** the script is notify-only — it issues a single `GET https://api.github.com/repos/chainbase-labs/agentkey/releases/latest`, compares the tag against a version constant embedded in the script itself, prints a one-line status, and exits. It never writes anywhere except the cache file at `${TMPDIR}/agentkey-update-check`, never invokes `git`, and never executes downloaded code. Update execution lives entirely in the agent's interactive layer (`AskUserQuestion` → `npx skills update`), gated by explicit user consent or a previously persisted opt-in flag. If you operate a scanner and need additional context to triage, please email `support@chainbase.com`. diff --git a/docs/README_zh.md b/docs/README_zh.md index 333290a..1811d09 100644 --- a/docs/README_zh.md +++ b/docs/README_zh.md @@ -368,7 +368,7 @@ agentkey/ ├── .mcp.json # 作为插件安装时使用 ├── skills/agentkey/ │ ├── SKILL.md # 决策树 & 路由规则 -│ ├── scripts/ # check-mcp / check-update 辅助脚本 +│ ├── scripts/ # check-update 辅助脚本 │ └── version.txt # 由 release-please 自动维护 └── scripts/ ├── install.sh # 一键安装脚本(mac/linux) diff --git a/skills/agentkey/scripts/check-mcp.sh b/skills/agentkey/scripts/check-mcp.sh deleted file mode 100755 index 765871e..0000000 --- a/skills/agentkey/scripts/check-mcp.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -# AgentKey — Check MCP registration and API key status -# -# Output codes: -# MCP_OK — server registered and API key found -# MCP_NO_KEY — server registered but API key not found anywhere -# MCP_NOT_CONFIGURED — server not registered at all -set -e - -# --- Helper: check all known key locations --- -check_key_exists() { - # 1. Check ~/.claude.json MCP env (set by `claude mcp add -e AGENTKEY_API_KEY=...`) - # This is the primary cross-platform storage — works on Mac, Linux, and Windows. - if [ -f "$HOME/.claude.json" ]; then - local key_val - key_val=$(python3 -c " -import json, os -try: - with open(os.path.expanduser('~/.claude.json')) as f: - d = json.load(f) - print(d.get('mcpServers', {}).get('agentkey', {}).get('env', {}).get('AGENTKEY_API_KEY', '')) -except Exception: pass -" 2>/dev/null | tr -d '[:space:]') - [ -n "$key_val" ] && return 0 - fi - - # 2. Check ~/.env.local (Mac/Linux fallback, written by setup-key.sh) - local env_file="$HOME/.env.local" - if [ -f "$env_file" ]; then - local key_val - key_val=$(grep "^AGENTKEY_API_KEY=" "$env_file" 2>/dev/null | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'" | tr -d '[:space:]') - [ -n "$key_val" ] && return 0 - fi - - return 1 -} - -# --- Helper: check a JSON config file for agentkey MCP registration --- -check_json_registered() { - local file="$1" - [ -f "$file" ] || return 1 - grep -q "mcpServers" "$file" 2>/dev/null || return 1 - grep -q '"agentkey"' "$file" 2>/dev/null || return 1 - return 0 -} - -# --- Helper: find claude CLI --- -find_claude() { - command -v claude 2>/dev/null && return 0 - for p in "$HOME/.local/bin/claude" "/usr/local/bin/claude" \ - "/opt/homebrew/bin/claude" "$HOME/.npm-global/bin/claude"; do - [ -x "$p" ] && echo "$p" && return 0 - done - return 1 -} - -# ============================================================ -# Step 1: Is agentkey registered anywhere? -# ============================================================ -REGISTERED=0 - -# Check ~/.claude.json (user-scope via `claude mcp add --scope user`) -if check_json_registered "$HOME/.claude.json"; then - REGISTERED=1 -fi - -# Check project .mcp.json as fallback -if [ $REGISTERED -eq 0 ]; then - CLAUDE_BIN=$(find_claude 2>/dev/null || true) - if [ -n "$CLAUDE_BIN" ]; then - MCP_LIST=$("$CLAUDE_BIN" mcp list 2>/dev/null || true) - if echo "$MCP_LIST" | grep -q "agentkey"; then - REGISTERED=1 - fi - fi -fi - -if [ $REGISTERED -eq 0 ]; then - echo "MCP_NOT_CONFIGURED" - exit 1 -fi - -# ============================================================ -# Step 2: Is the API key present anywhere? -# ============================================================ -if check_key_exists; then - echo "MCP_OK" - exit 0 -fi - -echo "MCP_NO_KEY" -exit 1