How Claude HUD Reads CLAUDE.md, Rules, MCPs, and Hook Counts from Configuration
Claude HUD aggregates counts for CLAUDE.md files, rules, MCP servers, and hooks by scanning both the user-wide ~/.claude directory and the project-local .claude directory using the countConfigs function in src/config-reader.ts.
Claude HUD is an open-source terminal interface for Claude Code that displays real-time configuration statistics. Understanding how the system reads counts for CLAUDE.md files, rules, MCPs, and hooks from the Claude HUD configuration helps developers debug environment setups and optimize their development workflow.
Configuration Scopes and File Locations
The system operates across two distinct configuration scopes to aggregate counts. The user-wide scope resides at ~/.claude and contains global settings applicable across all projects. The project-local scope uses the .claude directory within the current working directory, or any custom location specified by the CLAUDE_CONFIG_DIR environment variable.
When countConfigs executes in src/config-reader.ts, it resolves both paths and checks for overlapping locations to prevent double-counting. The function uses pathsReferToSameLocation to determine if the user directory and project directory point to identical filesystem locations, skipping redundant scans when they match.
How CLAUDE.md Files Are Detected and Counted
The system identifies CLAUDE.md files by checking for the existence of CLAUDE.md and CLAUDE.local.md across both configuration scopes. In src/config-reader.ts (lines 36‑86 and 71‑85), the logic checks the user home directory, project root, and optional .claude/ sub‑folders for these specific filenames.
Each existing file increments the claudeMdCount variable. The function specifically looks for these two filename variants to support both shared project documentation (CLAUDE.md) and local-only overrides (CLAUDE.local.md).
Counting Rules from Markdown Directories
Rules are markdown files (.md) stored within rules directories. The helper function countRulesInDir() in src/config-reader.ts (lines 76‑92) walks the directory recursively and counts every file ending with the .md extension.
The function executes twice—once for the user’s ~/.claude/rules directory and once for the project’s ./.claude/rules directory—unless the paths overlap. This recursive scanning allows nested rule categorization while maintaining an accurate total count.
Reading MCP Server Configurations
MCP server counts involve parsing JSON configuration files and filtering disabled entries. The system reads from three potential sources: settings.json, side-car JSON files (~/.claude.json and ./.mcp.json), and custom CLAUDE_CONFIG_DIR JSON files.
The helper getMcpServerNames() in src/config-reader.ts (lines 19‑27) parses these files and extracts the keys of the mcpServers object. Disabled servers are filtered using getDisabledMcpServers() (lines 33‑48), which checks both user-scope (disabledMcpServers) and project-scope (disabledMcpjsonServers) exclusion lists.
To prevent duplicates when the same server appears in both user and project configurations, the system stores results in two Set objects—one for user scope and one for project scope—and sums their sizes for the final mcpCount.
Counting Hooks in Settings Files
Hooks are defined within settings.json files as top-level hooks objects. The function countHooksInFile() in src/config-reader.ts (lines 62‑70) reads the specified JSON file and returns the number of keys present in the hooks object.
The system checks three specific locations: the user’s ~/.claude/settings.json, the project’s .claude/settings.json, and the local override .claude/settings.local.json. Each valid hooks object contributes to the total hooksCount.
Rendering Configuration Counts in the Terminal
Once collected, these counts flow to the terminal interface through the rendering pipeline. In src/index.ts (line 54), the main entry point invokes countConfigs and destructures the results:
const { claudeMdCount, rulesCount, mcpCount, hooksCount } = await deps.countConfigs(stdin.cwd);
These values populate the RenderContext defined in src/types.ts, which passes to each line renderer. The environment line in src/render/lines/environment.ts (lines 11‑33) determines visibility based on the display.showConfigCounts setting and an optional environmentThreshold. If the total count exceeds the threshold, the renderer constructs a pipe-separated string such as "2 CLAUDE.md | 5 rules | 3 MCPs | 1 hooks".
Preventing Duplicate Counts Across Scopes
The system implements safeguards against double-counting when configuration scopes overlap. When the project-local .claude directory resolves to the same physical location as the user-wide ~/.claude directory, the pathsReferToSameLocation check prevents redundant scanning.
For MCP servers specifically, the use of Set data structures ensures that identical server entries across user and project configurations only count once toward the total. Disabled server filtering occurs independently for both scopes, ensuring that a server disabled in the user configuration but enabled in the project configuration (or vice versa) respects the specific exclusion lists.
Summary
- Claude HUD reads configuration counts from
src/config-reader.ts, specifically thecountConfigsfunction. - The system scans two scopes: user-wide (
~/.claude) and project-local (.claudeorCLAUDE_CONFIG_DIR). - CLAUDE.md counts include both
CLAUDE.mdandCLAUDE.local.mdfiles across scopes. - Rules are counted recursively from
rules/directories usingcountRulesInDir. - MCP servers are parsed from JSON configs with duplicates prevented via
Setobjects and disabled entries filtered viagetDisabledMcpServers. - Hooks are counted from
hooksobjects insettings.jsonfiles usingcountHooksInFile. - The environment line in
src/render/lines/environment.tsdisplays counts whenshowConfigCountsis enabled and thresholds are met.
Frequently Asked Questions
How does Claude HUD prevent counting the same MCP server twice?
Claude HUD stores MCP server names in two separate Set objects—one for the user scope and one for the project scope. According to the source code in src/config-reader.ts, the final count is the sum of both sets' sizes, ensuring that identical server entries across scopes only contribute once to the total count.
What happens if my project .claude folder is the same as my global ~/.claude folder?
When the project-local configuration directory resolves to the same physical location as the user-wide directory, Claude HUD detects this overlap using the pathsReferToSameLocation helper. The system skips redundant scanning of the overlapping scope to prevent double-counting CLAUDE.md files, rules, and other configuration items.
Can I disable specific MCP servers from being counted in the HUD?
Yes, Claude HUD respects disabled MCP server lists through the getDisabledMcpServers function in src/config-reader.ts. The system checks both user-scope (disabledMcpServers) and project-scope (disabledMcpjsonServers) exclusion lists, filtering out disabled servers before calculating the final MCP count displayed in the terminal.
Where does the environment threshold setting control count visibility?
The environmentThreshold setting works alongside display.showConfigCounts in src/render/lines/environment.ts. If the sum of all configuration counts falls below this threshold value, or if showConfigCounts is disabled, the environment line returns null and hides the counts from the HUD display entirely.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →