skills/setup-check/SKILL.md
Audit Claude Code configuration for issues, overlaps, unused components, update status, and misconfigurations. Use when the user (1) asks to check or audit their setup, (2) wants to find duplicate or conflicting skills, hooks, plugins, or rules, (3) asks what is broken or needs cleanup, (4) wants to check Claude Code or plugin updates, (5) asks to review MCP servers or memory state, or (6) invokes /setup-check with optional scope (all, updates, skills, hooks, plugins, rules, settings, security, mcp, memory, overlaps).
npx skillsauth add azmym/agent-skills setup-checkInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Audit Claude Code configuration and report issues, overlaps, update status, and cleanup recommendations.
Parse from $ARGUMENTS. Default: all.
| Arg | Scope |
|-----|-------|
| all | Full audit (all categories below, including updates) |
| updates | Claude Code CLI + plugin version/update checks |
| skills | Skills: duplicates, broken symlinks, unused, placeholders |
| hooks | Hooks: conflicts, broken paths, event collisions |
| plugins | Plugins: disabled, stale cache, version tracking |
| rules | Rules: contradictions, overlap with plugin behavior |
| settings | Settings files: duplicates, conflicting keys (health only) |
| security | Security: broad permissions, skipped prompts, orphaned MCP perms |
| mcp | MCP servers: empty configs, duplicate servers |
| memory | Memory: empty dirs, stale entries, index mismatches |
| overlaps | Cross-category overlap detection only |
Multiple args supported: /setup-check skills plugins runs both.
In addition to category args, the user can pass a quoted free-text string as a goal message:
/setup-check "ready for production?"
/setup-check settings "security hardening"
If an argument is not a recognized category keyword, treat it as a goal message. The goal triggers an additional Goal Assessment section in the output (see below).
You MUST read ALL of these paths for the relevant category. Do not skip any. Missing a path means missing findings.
Updates:
claude --version to get current version)npm view @anthropic-ai/claude-code version 2>/dev/null for latest published version; requires network)~/.claude/plugins/installed_plugins.json (plugin versions, gitCommitSha, lastUpdated)~/.claude/plugins/cache/ (all cached versions; detect stale ones not matching active installPath)claude plugins update <name>@<marketplace> -s <scope> output (authoritative source for update availability; the scope flag is required and must come from each plugin's scope field in installed_plugins.json)~/.claude/plugins/known_marketplaces.json (installed marketplaces with per-marketplace lastUpdated timestamps; used to detect which marketplaces changed after a refresh)claude plugin marketplace list --json output (authoritative current marketplace set; read-only)~/.claude/skills/setup-check/.last-checked.json (state file: last-briefed CLI version and dismissed config keys; created on first run if absent)Skills:
~/.claude/skills/ (symlinks; check for broken links with ls -la)~/.agents/skills/ (source directories; compare against symlinks for orphans)~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/skills/ and .../agents/ (plugin-provided; the nesting is marketplace/plugin/version, so glob accordingly)Hooks:
~/.claude/plugins/cache/*/hooks/hooks.json (glob ALL versions, not just active)~/.claude/plugins/installed_plugins.json to identify stale vs activePlugins:
~/.claude/plugins/installed_plugins.json (installed list with versions)~/.claude/settings.json > enabledPlugins (enabled/disabled state)~/.claude/plugins/cache/ (all cached versions; detect stale ones)Rules:
~/.claude/rules/*.md (read every rule file)Settings:
~/.claude/settings.json (main; lower precedence)~/.claude/settings.local.json (local overrides; higher precedence, wins on conflicts)Security:
~/.claude/settings.json (check skipDangerousModePermissionPrompt, permissions)~/.claude/settings.local.json (check permissions for broad Bash(<command>:*) patterns)~/.claude.json → mcpServers (user-scope, authoritative), project-level .mcp.json, ~/.claude/.mcp.json (if present), claude mcp list stdout (fallback)MCP:
~/.claude.json → mcpServers key (user-scope servers; authoritative location)~/.claude/.mcp.json (legacy/optional; often absent).mcp.json files in workspace directoriesMemory:
~/.claude/projects/<current-project-path>/memory/ (project memory)MEMORY.md in that directory (index file)Execution order within this category: (0) marketplace refresh, (1) CLI version check, (2) CLI version-upgrade brief, (3) plugin version freshness, (4) stale plugin cache. Steps 0 and 2 are new. Never abort the audit on a failure in any step; degrade to an i or ⚠ finding and continue.
~/.claude/plugins/known_marketplaces.json and record each marketplace's lastUpdated timestamp BEFORE updating (this is the baseline for change detection).claude plugin marketplace update (no name argument updates all marketplaces). Capture stdout, stderr, and exit code.known_marketplaces.json AFTER and compare each marketplace's lastUpdated:
⬆ <marketplace> refreshed (pulled latest from <repo>)✓ <marketplace> already current⚠ <marketplace> refresh failed (<reason>) -> Run 'claude plugin marketplace update <name>' manuallyi Marketplace refresh skipped (<reason>) and continue to the CLI version check. Do NOT abort.known_marketplaces.json lastUpdated is the durable record of what was actually pulled. Stdout is used only to surface failures.claude --version to get current version. Then run npm view @anthropic-ai/claude-code version 2>/dev/null to get the latest published version. Compare the two. If npm is unavailable or network fails, report current version as i (INFO) only with message "Could not check for updates".~/.claude/skills/setup-check/.last-checked.json. Schema: { "lastBriefedVersion": "<semver>", "lastBriefedAt": "<YYYY-MM-DD>", "dismissedKeys": ["<key>", ...] }.lastBriefedVersion as the CURRENT version, write a fresh file silently, and do NOT brief (no baseline to diff against on first run). Emit i CLI config baseline initialized at v<current> (no brief on first run).claude --version to lastBriefedVersion using semantic (numeric major.minor.patch) comparison, not string comparison:
current == lastBriefedVersion: skip the brief; emit ✓ CLI config up to date (briefed at v<x>).current < lastBriefedVersion (downgrade): skip the brief; emit i CLI downgraded (v<old> -> v<current>), no new-config brief; rewrite the state file to current.current > lastBriefedVersion: run the brief (continue below).gemini_search_grounded MCP tool asking which settings.json keys and environment variables were added to Claude Code between v<lastBriefedVersion> and v<current>, and for each whether it works when Claude Code runs on Amazon Bedrock. Request citations. For each returned option, record: name, type (setting or env), one-line purpose, default if known, Bedrock flag (compatible / not compatible / unknown), and source citation URL.~/.claude/settings.json. Drop options listed in dismissedKeys. Only genuinely-new, not-yet-declined options proceed.i CLI upgraded v<old> -> v<new>, but config brief unavailable (Gemini/network) -> Re-run /setup-check updates when online. Do NOT advance the state file (retry next run). Continue the audit.✓ CLI upgraded v<old> -> v<new>, no new user-facing config; advance the state file to current.✓ compatible = sources confirm it works under Bedrock, or it is provider-neutral; ✗ not compatible = explicitly Anthropic-API-only or Vertex-only, or documented as ignored under Bedrock; ? unknown = no authoritative source either way (state this plainly, do not guess).AskUserQuestion multi-select listing the surfaced options; each label carries its Bedrock badge. Options flagged ✗ not compatible are shown but pre-excluded from the add list with the note "not added, incompatible with your Bedrock setup" (user can override via the "Other" path). ? unknown options are selectable with a label warning they are unverified for Bedrock.update-config skill to add the key to ~/.claude/settings.json with a sensible default (for an env type, add it under the env block). The update-config skill is responsible for preserving the rest of the file and writing valid JSON; if it reports a failure or the resulting file would be invalid JSON, do NOT advance the state file for that option, skip the write, and emit ⚠ Could not add "<key>" to settings.json (<reason>) -> Add it manually. Confirm each successful write: ✓ Added "<key>" to settings.json (<value>).dismissedKeys in the state file.lastBriefedVersion to current and lastBriefedAt to today ONLY after the add/decline pass completes. If the user aborts mid-brief, do NOT advance (the brief reappears next run, no silent loss).installed_plugins.json:
version is "unknown", flag as ⚠ (WARN) with recommendation to reinstall for version trackingscope field (values: user, project, local, managed) from its entry in installed_plugins.json. claude plugins update defaults to -s user, so the scope flag MUST be passed explicitly for non-user scopes or the command will fail with "Plugin X is not installed at scope user".claude plugins update <name>@<marketplace> -s <scope> for each plugin (the plugin key in installed_plugins.json is already in name@marketplace format). Parse the output:
✓ with current version⬆ with old and new versions-s project, then -s user as fallbacks before giving uplastUpdated: flag plugins not updated in 30+ days as i (INFO, "not updated in N days, possibly stale")gitCommitSha against the marketplace repo HEAD. Marketplace repos contain multiple plugins, so repo HEAD advances when any plugin changes, causing false positives for unrelated plugins.name@marketplace identifier so users can copy-paste directly into commands~/.claude/plugins/cache/<marketplace>/<plugin>/ where more than one version directory exists. The active version is the one matching installPath in installed_plugins.json. Other directories are stale cache. Flag as ⚠ (WARN) with recommendation to clean up.ls -la ~/.claude/skills/ and verify each target exists~/.agents/skills/ with no symlink in ~/.claude/skills/api-docs-generator/api-documentation-generator, android-design-guidelines/mobile-android-design, kubernetes-specialist/kubernetes-best-practicesslack-messaging vs plugin providing slack:slack-messaging)~/workspace/ for project indicators (go.mod, build.gradle, package.json, Cargo.toml, etc.). If ~/workspace/ does not exist, skip this check and note it as iUserPromptSubmit handlers)installPath in installed_plugins.json)enabledPlugins: false entries (candidates for removal)"version": "unknown" (cannot track updates)installPathinstalled_plugins.json but missing from enabledPlugins or vice versasettings.json and settings.local.json with identical values (redundant)skipDangerousModePermissionPrompt set to true in settingsBash(<command>:*) patterns that allow arbitrary arguments (especially python3:*, osascript:*, chmod:*, xargs:*)mcp__<server>__*) for servers not found in any configured source. Important: Claude Code stores user-scope MCP servers in ~/.claude.json under the mcpServers key, NOT in ~/.claude/.mcp.json (which often does not exist). Build the known-server set from multiple sources in this order: (a) mcpServers keys in ~/.claude.json, (b) mcpServers keys in any project-level .mcp.json in the current workspace, (c) mcpServers keys in ~/.claude/.mcp.json if it exists, (d) fallback: parse claude mcp list stdout (lines like ^ <name>: ... - [✓✗] ...). Flag a permission as orphaned only when <server> is absent from ALL sources.mcpServers in ~/.claude.json, no project .mcp.json, no ~/.claude/.mcp.json)~/.claude.json and a project .mcp.json)MEMORY.mdMEMORY.md references files that do not exist, or files exist but are not in the indexWhen running overlaps, you need data from ALL categories. Read all scan paths from every category, then run ONLY the cross-category checks below (not per-category checks like broken symlinks).
Scoring note: Overlap findings are cross-category views of issues already counted in their source categories. Do NOT count overlap findings toward either score. They appear in the report for visibility but have zero weight.
This section only appears when the user provides a quoted goal message in the arguments. It is NOT a standard check category; it is generated after all other checks complete.
How it works:
Output structure:
┌─ GOAL ASSESSMENT ───────────────────────────────────
│
│ Goal: "<user's quoted message>"
│
│ ✓ <relevant positive finding>
│ ⚠ <relevant warning> -> <recommendation>
│ ✗ <relevant error> -> <how to fix>
│
│ Verdict: <one-line readiness assessment>
│
└─────────────────────────────────────────────────────
Examples of how to interpret goal messages:
"ready for production?" - focus on errors, security settings, broken configs, stale versions"security hardening" - focus on broad permissions, MCP orphaned permissions, security flags, unknown versions"clean up unused stuff" - focus on disabled plugins, stale cache, placeholder skills, duplicates, orphans"starting a new React project" - focus on relevant skills available, missing skills for React ecosystem, MCP servers for dev toolingVerdict tone: Be direct and honest. Examples:
Use this exact structure. Do not wrap the report in markdown code blocks. Render all box-drawing characters directly as plain text output.
╭─────────────────────────────────────────────────────
│ Claude Code Setup Check
│ YYYY-MM-DD | Scope: <scope>
│ Claude Code v<version>
╰─────────────────────────────────────────────────────
Replace YYYY-MM-DD with today's date, <scope> with the selected scope (e.g., "all", "skills, plugins"), and <version> with the output of claude --version.
Displayed immediately after the header, stacked on two lines:
Health: N.N / 10 ████████░░░░ <Label>
Security: N.N / 10 ████████░░░░ <Label>
Health Score Calculation:
Health measures functional correctness. Only health-classified findings contribute.
| Severity | Tier | Weight | |----------|------|--------| | ERROR (✗) | Major | -2.0 | | ERROR (✗) | Minor | -1.0 | | WARN (⚠) | Major | -0.7 | | WARN (⚠) | Minor | -0.3 | | INFO (i) | -- | -0.1 | | OK (✓) | -- | 0.0 | | UPDATE (⬆) | -- | 0.0 |
Formula: health_score = max(0.0, min(10.0, 10.0 - sum_of_health_penalties))
Health Labels:
Security Score Calculation:
Security measures how locked-down the permission model is. These are intentional preferences, not defects, so no ✗ ERROR is used; all findings are ⚠ WARN with recalibrated weights.
| Finding | Indicator | Weight |
|---------|-----------|--------|
| skipDangerousModePermissionPrompt enabled | ⚠ | -1.0 |
| Broad permission (each Bash(<command>:*) pattern) | ⚠ | -0.5 |
| Orphaned MCP permissions (server not configured) | ⚠ | -0.5 |
| Credential files with loose permissions | ⚠ | -0.5 |
Formula: security_score = max(0.0, min(10.0, 10.0 - sum_of_security_penalties))
Security Labels:
Progress bar (both scores): 12 characters wide. Calculate filled blocks as round(score / 10 * 12). Use █ for filled and ░ for empty.
Each category renders as a left-bordered section with its name and finding count in the header:
┌─ CATEGORY NAME (N findings) ────────────────────────
│
│ ✓ Finding with no issues
│ i Informational note (details inline)
│ ⚠ Problem description (specifics) -> Recommendation
│ ✗ Broken config (specifics) -> How to fix
│
└─────────────────────────────────────────────────────
Indicators (use these exact symbols, not text tags):
✓ = OK (check passed, no issues)⚠ = WARN (actionable recommendation)✗ = ERROR (broken configuration, must fix)i = INFO (informational, no action needed)⬆ = Update available (used only in the Updates section)Formatting rules:
indicator + description + (details) + -> recommendation. Do not wrap findings across multiple lines. Use concise language to keep lines compact.✓ 88 symlinks intact, no broken links⚠ 3 plugins "unknown" version (frontend-design, playwright, skill-creator) -> Reinstall for version tracking✗ Broken symlink: my-skill -> missing target -> Remove or recreate symlink⬆ prompt-improver@severity1-marketplace updated (0.5.1 -> 0.6.0) -> Was auto-updated by check-> to attach the recommendation directly on the same line✓ No issues foundi <path> not found, skipping and continue. Do not error out.Severity rules (applies to health categories):
✗ (ERROR): Broken symlinks, missing scripts, corrupted configs, CLI not found⚠ (WARN): Duplicates, overlaps, disabled plugins, stale cache, available updates, unknown versionsi (INFO): Version not checked (network unavailable), tech stack mismatch, empty memory, component not updated in 30+ days✓ (OK): Category or sub-check passed with no issuesSeverity rules (Security category):
⚠ (WARN): All security findings (broad permissions, skipped prompts, orphaned MCP perms, credential exposure)✓ (OK): All security checks passed✗ ERROR in Security; these are intentional preferences, not broken configurationTier classification (determines weight, see Scores section above):
Use this table to classify each health finding as major or minor for health score calculation. Security findings are NOT in this table; they use the Security Score weights above.
| Check | Tier |
|-------|------|
| Corrupted/unparseable config files | Major |
| CLI not found / claude --version fails | Major |
| Broken hook commands (script doesn't exist) | Major |
| Broken skill symlinks | Minor |
| Missing scan paths for critical configs | Minor |
| Check | Tier | |-------|------| | Contradicting rules | Major | | Conflicting settings keys (different values) | Major | | Stale plugin cache (old versions in cache/) | Minor | | Disabled plugins still installed | Minor | | Unknown plugin versions | Minor | | Semantic duplicate skills | Minor | | Plugin collisions (standalone + plugin-provided) | Minor | | Duplicate settings keys (identical values) | Minor | | Orphaned skill sources (no symlink) | Minor | | Placeholder skills | Minor | | Stale hooks from old plugin versions | Minor | | Event collisions (multiple hooks on same event) | Minor | | Rule overlaps with plugin behavior | Minor | | Empty MCP configs | Minor | | Duplicate MCP servers across scopes | Minor | | Memory index mismatches | Minor | | Marketplace refresh failed (single marketplace) | Minor |
No tier distinction. All INFO findings use the flat -0.1 weight. New Updates INFO findings: marketplace refresh skipped (whole command failed), CLI config brief unavailable (Gemini/network), CLI downgraded, CLI config baseline initialized on first run.
These render in the Updates section but contribute nothing to the health score, matching the existing treatment of plugin updates:
| Check | Indicator |
|-------|-----------|
| Marketplace refreshed | ⬆ |
| Marketplace already current | ✓ |
| CLI config up to date | ✓ |
| CLI upgraded, no new config | ✓ |
| Config option added to settings.json | ✓ |
When the CLI version-upgrade brief (Updates step 2) surfaces new options, render this interactive block inside the Updates section before continuing. It is not a scored finding line; only the resulting ✓/i outcome lines are scored.
┌─ CLI CONFIG BRIEF ──────────────────────────────────
│
│ Claude Code upgraded: v<old> -> v<new>
│ <N> new config options found. Each is flagged for Amazon Bedrock.
│
│ 1. settings.json: "<key>" [Bedrock: ✓ compatible]
│ <one-line purpose>. Default: <default>.
│ Source: <citation url>
│
│ 2. env: <VAR_NAME> [Bedrock: ✗ not compatible]
│ <one-line purpose>. (Vertex/Anthropic-API only.)
│ Source: <citation url>
│
│ 3. settings.json: "<key>" [Bedrock: ? unknown]
│ <one-line purpose>. Bedrock support not documented.
│ Source: <citation url>
│
└─────────────────────────────────────────────────────
After rendering, present the AskUserQuestion multi-select described in Updates step 2, write approved options, and emit the per-option ✓ Added ... confirmations as normal findings within the Updates section.
When all is selected, render sections in this order:
When a single category is selected, show only that category section plus the summary.
╭─────────────────────────────────────────────────────
│ Summary
├─────────────────────────────────────────────────────
│
│ Health: ✓ OK: N ✗ ERROR: N major, N minor ⚠ WARN: N major, N minor i INFO: N
│ Security: ✓ OK: N ⚠ WARN: N
│
│ Top Recommendations:
│
│ 1. Most impactful recommendation
│ 2. Second most impactful
│ 3. Third
│ 4. Fourth
│ 5. Fifth
│
╰─────────────────────────────────────────────────────
Summary counts formatting:
✗ ERROR: 1 major, 2 minor⚠ WARN: 3 minor✗ ERROR: 0⚠ WARN: 3✓ OK: all clearRank recommendations across both dimensions by severity (health ERROR first, then health WARN, then security WARN), and within the same severity by impact. Show up to 5 recommendations.
all or updates is selected) in this sub-order: (0) claude plugin marketplace update to refresh all marketplaces, comparing known_marketplaces.json lastUpdated before/after; (1) claude --version and npm view for the CLI version check; (2) the CLI version-upgrade config brief: read ~/.claude/skills/setup-check/.last-checked.json, and if the current version is higher, call gemini_search_grounded for new Bedrock-flagged settings/env options, present the brief, write approved options via the update-config skill, and advance the state file; (3) read installed_plugins.json and run claude plugins update <name>@<marketplace> -s <scope> for each plugin (scope read from the plugin's entry); (4) detect stale plugin cache.all or overlaps is selected).tools
Reports which skills, hooks, rules, plugins, and MCP tools were activated during a Claude Code prompt or session. Use when the user asks "what was used", "which skills ran", "show me what fired", or invokes /used. Also triggers when the user wants transparency into Claude's behavior for a given prompt.
development
Interact with Slack via the Web API. Read, summarize, search, post messages, react, pin, and manage channels. Use when the user (1) shares a Slack URL, (2) asks to read or summarize a channel, (3) searches Slack messages, (4) asks to send/post a message, (5) asks to react to or pin a message, (6) looks up a user, or (7) mentions a Slack channel by name (e.g., "#channel-name"). Also triggers for Slack threads, daily standups, conversation digests, or any Slack interaction.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------