MD4AI

How the MD4AI CLI Works

A transparent look at what our scanner does — and doesn't do — on your machine. We believe you should know exactly what you're installing.

Installnpm install -g md4ai
01

What It Scans

The CLI reads only Claude configuration files within your project. It never reads your application source code, tests, or build output.

  • .claude/ — Claude project settings, commands, and hooks
  • CLAUDE.md — project instructions file at the repo root
  • skills.md — skill definitions if present
  • docs/plans/ — plan documents referenced by Claude

For skill detection, it also reads your global ~/.claude/CLAUDE.md and ~/.claude/settings.json.

Directories like node_modules/, .git/, and .turbo/ are always excluded.

View scanned file patterns
# Project-level patterns
.claude/**/*          # Settings, commands, hooks
CLAUDE.md             # Root project instructions
skills.md             # Skill definitions
docs/plans/**/*       # Plan documents

# Machine-wide (skill detection)
~/.claude/CLAUDE.md
~/.claude/settings.json
~/.claude/settings.local.json

# File types discovered
*.md, *.json, *.yaml, *.yml, *.ts, *.js, *.sh, *.py

# Always excluded
node_modules/, .git/, .turbo/, cache/, session-env/
02

What It Sends to the Dashboard

When you run md4ai scan or md4ai link, the following data is uploaded to your dashboard:

  • Dependency graph — which config files reference which others
  • Orphan detection — files not reachable from root configurations
  • Skills inventory — names and sources of discovered skills
  • Stale file list — config files unchanged for over 90 days
  • Config file contents — full text of CLAUDE.md, settings.json, etc.
  • File metadata — sizes and modification dates

A SHA-256 hash of the scan data is computed locally. If nothing has changed since the last sync, no upload occurs.

View example upload shape
{
  "graph_json": {
    "mermaid": "graph TD; ...",
    "nodes": [
      {
        "id": "claude_md",
        "label": "CLAUDE.md",
        "filePath": "CLAUDE.md",
        "type": "root",
        "lastModified": "2026-03-01T10:30:00Z",
        "sizeBytes": 2048
      }
    ],
    "edges": [
      { "from": "claude_md", "to": "settings_json" }
    ]
  },
  "orphans_json": [
    { "path": ".claude/old-hook.json", "sizeBytes": 512 }
  ],
  "skills_table_json": [
    { "name": "commit", "source": "built-in", "machineWide": false }
  ],
  "stale_files_json": [
    { "path": "docs/plans/old-plan.md", "daysSinceModified": 120 }
  ],
  "data_hash": "a1b2c3d4e5f6..."
}
03

What It Never Touches

The scanner is scoped strictly to Claude configuration files. It has no reason to access anything else, and it doesn't.

  • ×Your application source code, tests, or build output
  • ×Environment variables or .env files
  • ×API keys, secrets, or credentials (yours or anyone else's)
  • ×SSH keys or git credentials
  • ×Browser data, cookies, or local storage
  • ×node_modules/ or any dependency files

No telemetry. The CLI sends no analytics, usage tracking, or crash reports. The only network calls are the explicit syncs you trigger.

04

How It Runs

The CLI only runs when you explicitly invoke a command. There are no background processes, daemons, or scheduled tasks.

1

You run a command

md4ai scan, md4ai link, md4ai sync, etc.

2

It scans config files using Node.js filesystem APIs

Pure fs.readFile calls — no shell globbing or recursive walks through your whole project.

3

It uploads the results and exits

No lingering processes. Check your task manager — nothing stays running.

The scanner runs two external commands, both with strict timeouts:

View external commands
# Fetch file timestamps from git (5s timeout)
git log -1 --format=%cI -- <filePath>
git log --diff-filter=A --format=%cI -- <filePath>

# Discover installed Claude plugins (10s timeout)
claude plugin list

# If either command fails, the scanner falls back
# gracefully — git failures use fs.stat() instead,
# and plugin discovery is simply skipped.
05

Credentials & Storage

When you log in via md4ai login, your session tokens are stored locally with strict file permissions.

~/.md4ai/credentials.jsonAuth tokens (Supabase JWT). Mode 0600 — only your user can read it. No passwords are ever stored.
~/.md4ai/state.jsonLast sync timestamps and device name. Mode 0600.

One environment variable is required: MD4AI_SUPABASE_ANON_KEY — this is a public key used to connect to the Supabase backend. It is not a secret.

06

Open Source & Auditable

The entire CLI is open source under the MIT licence. You can read every line of the scanner before you install it.

MIT

Licence

~1,000

Lines of scanner code

6

Dependencies

Installnpm install -g md4ai

Questions? Open an issue on GitHub.