fix(audit): correct MCP detection to check ~/.claude.json
The audit script was looking for MCP config in ~/.claude/mcp.json which doesn't exist. Claude Code actually stores MCP config in ~/.claude.json under projects.<path>.mcpServers. Changes: - audit-scan.sh: Multi-source MCP detection (3 locations with priority) - audit-scan.sh: Fixed count_pattern() bug causing "0\n0" output - claude-setup-audit-prompt.md: Updated bash commands for MCP detection - Version bump: 2.8 → 2.9 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
bafbeae31c
commit
0833e1ca65
4 changed files with 141 additions and 27 deletions
33
CHANGELOG.md
33
CHANGELOG.md
|
|
@ -6,6 +6,39 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.9.0] - 2026-01-12
|
||||
|
||||
### Fixed
|
||||
- **MCP detection bug in audit-scan.sh** (~60 lines modified)
|
||||
- **Root cause**: Script searched for `~/.claude/mcp.json` which doesn't exist
|
||||
- **Actual location**: Claude Code stores MCP config in `~/.claude.json` under `projects.<path>.mcpServers`
|
||||
- **Solution**: Multi-source detection with priority:
|
||||
1. `~/.claude.json` → `projects.<cwd>.mcpServers` (most common)
|
||||
2. `./.claude/mcp.json` (project-level)
|
||||
3. `~/.claude/mcp.json` (legacy global)
|
||||
- JSON output now includes detailed `mcp` section (configured, count, servers, source)
|
||||
- Human output shows server count and source location
|
||||
- **Bug `0\n0` in `claude_md_refs`** (~8 lines)
|
||||
- **Root cause**: `grep -c ... || echo "0"` could produce double output
|
||||
- **Solution**: Rewritten `count_pattern()` function to properly capture and return count
|
||||
|
||||
### Changed
|
||||
- **audit-scan.sh** enhanced (~50 lines)
|
||||
- Added `MCP_SOURCE` variable to track where MCP config was found
|
||||
- Added `MCP_COUNT` variable for server count
|
||||
- Global `mcp.json` message changed from error to info (not required)
|
||||
- JSON output restructured with separate `mcp` object
|
||||
- **claude-setup-audit-prompt.md** updated (~40 lines)
|
||||
- Phase 1.1: Now checks `~/.claude.json` instead of `~/.claude/mcp.json`
|
||||
- Phase 1.2: Complete MCP detection rewrite covering all 3 locations
|
||||
- Glossary: Updated MCP definition to explain config locations
|
||||
- Version: 2.8 → 2.9
|
||||
|
||||
### Stats
|
||||
- 2 files modified (audit-scan.sh, claude-setup-audit-prompt.md)
|
||||
- Bug impact: Scripts now correctly detect MCP servers (was showing "No MCP" even when configured)
|
||||
- Tested: Verified on Méthode Aristote project with 9 MCP servers
|
||||
|
||||
## [2.8.0] - 2026-01-11
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ If this guide saved you time, helped you master Claude Code, or inspired your wo
|
|||
|
||||
---
|
||||
|
||||
*Version 2.8 | January 2026 | Crafted with Claude*
|
||||
*Version 2.9 | January 2026 | Crafted with Claude*
|
||||
|
||||
<!-- SEO Keywords -->
|
||||
<!-- claude code, claude code tutorial, anthropic cli, ai coding assistant, claude code mcp,
|
||||
|
|
|
|||
|
|
@ -95,9 +95,11 @@ https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/english-
|
|||
```bash
|
||||
bash -c '
|
||||
echo "=== GLOBAL CONFIG ==="
|
||||
for f in ~/.claude/CLAUDE.md ~/.claude/settings.json ~/.claude/mcp.json; do
|
||||
for f in ~/.claude/CLAUDE.md ~/.claude/settings.json; do
|
||||
[ -f "$f" ] && echo "✅ $(basename $f)" || echo "❌ $(basename $f)"
|
||||
done
|
||||
# Note: MCP config is now in ~/.claude.json, not ~/.claude/mcp.json
|
||||
[ -f ~/.claude.json ] && echo "✅ ~/.claude.json (contains MCP config)" || echo "❌ ~/.claude.json"
|
||||
|
||||
echo -e "\n=== PROJECT CONFIG ==="
|
||||
for f in ./CLAUDE.md ./.claude/CLAUDE.md ./.claude/settings.json ./.claude/settings.local.json; do
|
||||
|
|
@ -141,18 +143,41 @@ else
|
|||
echo "❌ No hooks directory"
|
||||
fi
|
||||
|
||||
# MCP servers
|
||||
# MCP servers (check all locations)
|
||||
echo -e "\n=== MCP SERVERS ==="
|
||||
if [ -f ~/.claude/mcp.json ]; then
|
||||
if command -v jq &> /dev/null; then
|
||||
jq -r ".mcpServers | keys[]" ~/.claude/mcp.json 2>/dev/null
|
||||
else
|
||||
grep -oE "\"[a-zA-Z0-9_-]+\"\\s*:" ~/.claude/mcp.json | sed "s/\"//g;s/://g"
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
# Check 1: Project-specific MCP in ~/.claude.json (most common)
|
||||
if [ -f ~/.claude.json ] && command -v jq &> /dev/null; then
|
||||
MCP=$(jq -r --arg path "$CURRENT_DIR" ".projects[\$path].mcpServers // {} | keys[]" ~/.claude.json 2>/dev/null)
|
||||
if [ -n "$MCP" ]; then
|
||||
echo "Source: ~/.claude.json (project)"
|
||||
echo "$MCP"
|
||||
fi
|
||||
else
|
||||
echo "❌ No mcp.json"
|
||||
fi
|
||||
|
||||
# Check 2: Project-level .claude/mcp.json
|
||||
if [ -z "$MCP" ] && [ -f ./.claude/mcp.json ]; then
|
||||
echo "Source: .claude/mcp.json"
|
||||
if command -v jq &> /dev/null; then
|
||||
jq -r ".mcpServers // {} | keys[]" ./.claude/mcp.json 2>/dev/null
|
||||
else
|
||||
grep -oE "\"[a-zA-Z0-9_-]+\"[[:space:]]*:" ./.claude/mcp.json | sed "s/\"//g;s/://g"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check 3: Legacy global ~/.claude/mcp.json
|
||||
if [ -z "$MCP" ] && [ -f ~/.claude/mcp.json ]; then
|
||||
echo "Source: ~/.claude/mcp.json (global)"
|
||||
if command -v jq &> /dev/null; then
|
||||
jq -r ".mcpServers // {} | keys[]" ~/.claude/mcp.json 2>/dev/null
|
||||
else
|
||||
grep -oE "\"[a-zA-Z0-9_-]+\"[[:space:]]*:" ~/.claude/mcp.json | sed "s/\"//g;s/://g"
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -z "$MCP" ] && echo "❌ No MCP servers configured for this project"
|
||||
|
||||
# CLAUDE.md quality
|
||||
echo -e "\n=== MEMORY FILE QUALITY ==="
|
||||
if [ -f ./CLAUDE.md ]; then
|
||||
|
|
@ -448,7 +473,7 @@ Here's an example of what the audit report looks like:
|
|||
| **Memory Files** | CLAUDE.md files that provide persistent context to Claude across sessions |
|
||||
| **Single Source of Truth** | Pattern where conventions are documented once and referenced everywhere |
|
||||
| **Tool SEO** | Writing agent/command descriptions so Claude selects the right tool automatically |
|
||||
| **MCP Servers** | Model Context Protocol - external tools that extend Claude's capabilities |
|
||||
| **MCP Servers** | Model Context Protocol - external tools that extend Claude's capabilities. Config stored in `~/.claude.json` per project, or `.claude/mcp.json` at project level |
|
||||
| **Serena** | MCP server for codebase indexation and session memory persistence |
|
||||
| **Context7** | MCP server for official library documentation lookup |
|
||||
| **Hooks** | Scripts that run automatically on Claude events (PreToolUse, PostToolUse, etc.) |
|
||||
|
|
@ -528,4 +553,4 @@ Here's an example of what the audit report looks like:
|
|||
|
||||
---
|
||||
|
||||
*Last updated: January 2026 | Version 2.8 - Optimized with bash scanning*
|
||||
*Last updated: January 2026 | Version 2.9 - Fixed MCP detection (now checks ~/.claude.json)*
|
||||
|
|
|
|||
|
|
@ -68,7 +68,13 @@ get_file_lines() {
|
|||
}
|
||||
|
||||
count_pattern() {
|
||||
[[ -f "$1" ]] && grep -c "$2" "$1" 2>/dev/null || echo "0"
|
||||
if [[ -f "$1" ]]; then
|
||||
local count
|
||||
count=$(grep -c "$2" "$1" 2>/dev/null) || count="0"
|
||||
echo "$count"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Expand home directory
|
||||
|
|
@ -114,18 +120,62 @@ if [[ -d "./.claude/hooks" ]]; then
|
|||
grep -l "PreToolUse" ./.claude/hooks/* 2>/dev/null >/dev/null && HAS_SECURITY_HOOKS="true"
|
||||
fi
|
||||
|
||||
# MCP servers (check global config)
|
||||
# MCP servers detection
|
||||
# Claude Code stores MCP config in multiple locations:
|
||||
# 1. ~/.claude.json under projects.<cwd>.mcpServers (per-project, most common)
|
||||
# 2. ~/.claude/mcp.json (legacy global)
|
||||
# 3. ./.claude/mcp.json (project-level)
|
||||
MCP_SERVERS=""
|
||||
if [[ -f "${GLOBAL_DIR}/mcp.json" ]]; then
|
||||
# Extract server names (works with or without jq)
|
||||
MCP_SOURCE=""
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
# Check 1: Project-specific MCP in ~/.claude.json
|
||||
if [[ -f "${HOME}/.claude.json" ]]; then
|
||||
if command -v jq &> /dev/null; then
|
||||
MCP_SERVERS=$(jq -r '.mcpServers | keys[]' "${GLOBAL_DIR}/mcp.json" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
|
||||
else
|
||||
# Fallback: simple grep
|
||||
MCP_SERVERS=$(grep -oE '"[a-zA-Z0-9_-]+"\\s*:' "${GLOBAL_DIR}/mcp.json" 2>/dev/null | sed 's/"//g;s/://g' | tr '\n' ',' | sed 's/,$//')
|
||||
# Get MCP servers for current project path
|
||||
MCP_SERVERS=$(jq -r --arg path "$CURRENT_DIR" '.projects[$path].mcpServers // {} | keys[]' "${HOME}/.claude.json" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
|
||||
if [[ -n "$MCP_SERVERS" ]]; then
|
||||
MCP_SOURCE="~/.claude.json (project)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check 2: Project-level .claude/mcp.json
|
||||
if [[ -z "$MCP_SERVERS" && -f "./.claude/mcp.json" ]]; then
|
||||
if command -v jq &> /dev/null; then
|
||||
MCP_SERVERS=$(jq -r '.mcpServers // {} | keys[]' "./.claude/mcp.json" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
|
||||
if [[ -n "$MCP_SERVERS" ]]; then
|
||||
MCP_SOURCE=".claude/mcp.json (project)"
|
||||
fi
|
||||
else
|
||||
MCP_SERVERS=$(grep -oE '"[a-zA-Z0-9_-]+"[[:space:]]*:' "./.claude/mcp.json" 2>/dev/null | head -20 | sed 's/"//g;s/://g' | tr '\n' ',' | sed 's/,$//')
|
||||
if [[ -n "$MCP_SERVERS" ]]; then
|
||||
MCP_SOURCE=".claude/mcp.json (project)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check 3: Legacy global ~/.claude/mcp.json
|
||||
if [[ -z "$MCP_SERVERS" && -f "${GLOBAL_DIR}/mcp.json" ]]; then
|
||||
if command -v jq &> /dev/null; then
|
||||
MCP_SERVERS=$(jq -r '.mcpServers // {} | keys[]' "${GLOBAL_DIR}/mcp.json" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
|
||||
if [[ -n "$MCP_SERVERS" ]]; then
|
||||
MCP_SOURCE="~/.claude/mcp.json (global)"
|
||||
fi
|
||||
else
|
||||
MCP_SERVERS=$(grep -oE '"[a-zA-Z0-9_-]+"[[:space:]]*:' "${GLOBAL_DIR}/mcp.json" 2>/dev/null | head -20 | sed 's/"//g;s/://g' | tr '\n' ',' | sed 's/,$//')
|
||||
if [[ -n "$MCP_SERVERS" ]]; then
|
||||
MCP_SOURCE="~/.claude/mcp.json (global)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Count MCP servers
|
||||
MCP_COUNT=0
|
||||
if [[ -n "$MCP_SERVERS" ]]; then
|
||||
MCP_COUNT=$(echo "$MCP_SERVERS" | tr ',' '\n' | grep -c . || echo "0")
|
||||
fi
|
||||
|
||||
# Memory file quality (if exists)
|
||||
CLAUDE_MD_LINES="0"
|
||||
CLAUDE_MD_REFS="0"
|
||||
|
|
@ -143,13 +193,13 @@ fi
|
|||
# === OUTPUT ===
|
||||
|
||||
if [[ "$OUTPUT_MODE" == "json" ]]; then
|
||||
# JSON output
|
||||
# JSON output - ensure all values are properly formatted
|
||||
cat <<EOF
|
||||
{
|
||||
"global": {
|
||||
"claude_md": $GLOBAL_CLAUDE_MD,
|
||||
"settings": $GLOBAL_SETTINGS,
|
||||
"mcp": $GLOBAL_MCP
|
||||
"mcp_json": $GLOBAL_MCP
|
||||
},
|
||||
"project": {
|
||||
"claude_md": $PROJECT_CLAUDE_MD,
|
||||
|
|
@ -169,8 +219,13 @@ if [[ "$OUTPUT_MODE" == "json" ]]; then
|
|||
"has_security_hooks": $HAS_SECURITY_HOOKS,
|
||||
"has_ssot_references": $HAS_SSOT,
|
||||
"claude_md_lines": $CLAUDE_MD_LINES,
|
||||
"claude_md_refs": $CLAUDE_MD_REFS,
|
||||
"mcp_servers": "$MCP_SERVERS"
|
||||
"claude_md_refs": $CLAUDE_MD_REFS
|
||||
},
|
||||
"mcp": {
|
||||
"configured": $([ -n "$MCP_SERVERS" ] && echo "true" || echo "false"),
|
||||
"count": $MCP_COUNT,
|
||||
"servers": "$MCP_SERVERS",
|
||||
"source": "$MCP_SOURCE"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
|
@ -181,7 +236,7 @@ else
|
|||
echo -e "${BLUE}📁 GLOBAL CONFIG${NC} (~/.claude/)"
|
||||
[[ "$GLOBAL_CLAUDE_MD" == "true" ]] && echo -e " ${GREEN}✅${NC} CLAUDE.md" || echo -e " ${RED}❌${NC} CLAUDE.md"
|
||||
[[ "$GLOBAL_SETTINGS" == "true" ]] && echo -e " ${GREEN}✅${NC} settings.json" || echo -e " ${RED}❌${NC} settings.json"
|
||||
[[ "$GLOBAL_MCP" == "true" ]] && echo -e " ${GREEN}✅${NC} mcp.json" || echo -e " ${RED}❌${NC} mcp.json"
|
||||
[[ "$GLOBAL_MCP" == "true" ]] && echo -e " ${GREEN}✅${NC} mcp.json (legacy)" || echo -e " ${YELLOW}⚠️${NC} mcp.json (not required, MCP in ~/.claude.json)"
|
||||
|
||||
echo -e "\n${BLUE}📁 PROJECT CONFIG${NC} (./)"
|
||||
[[ "$PROJECT_CLAUDE_MD" == "true" ]] && echo -e " ${GREEN}✅${NC} CLAUDE.md" || echo -e " ${YELLOW}⚠️${NC} CLAUDE.md (recommended)"
|
||||
|
|
@ -210,9 +265,10 @@ else
|
|||
fi
|
||||
|
||||
if [[ -n "$MCP_SERVERS" ]]; then
|
||||
echo -e " ${GREEN}✅${NC} MCP servers: $MCP_SERVERS"
|
||||
echo -e " ${GREEN}✅${NC} MCP servers ($MCP_COUNT): $MCP_SERVERS"
|
||||
echo -e " ${BLUE}Source:${NC} $MCP_SOURCE"
|
||||
else
|
||||
echo -e " ${YELLOW}⚠️${NC} No MCP servers configured"
|
||||
echo -e " ${YELLOW}⚠️${NC} No MCP servers configured for this project"
|
||||
fi
|
||||
|
||||
echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue