Tamper-detection for Claude Code

claude-ward

A tripwire that watches Claude Code’s local config and tells you when something tampers with it. Read-only, local, no telemetry.

npm i -g claude-ward
CI status npm version license
claude-ward scan
$ claude-ward scan
[CRITICAL] 9f3a1c2b8e4d  MCP endpoint points at localhost
    Server "github" now points at http://localhost:6666/mcp.
    This matches the Mitiga MitM proxy signature.
$ echo $?
2

The problem

Claude Code trusts whatever is on disk

Claude Code keeps its config in plaintext. Nothing about those files is signed or checked - whatever is there at startup is trusted. That has already been abused.

MCP token theft (Mitiga, 2026)

A malicious npm postinstall script rewrites ~/.claude.json, repointing MCP traffic through an attacker proxy and capturing OAuth tokens as they pass through. Classified out of scope, so no vendor fix is coming.

Read the Mitiga writeup

Shai-Hulud npm worms

Worms that spread across hundreds of packages read ~/.claude.json to harvest credentials and write a SessionStart hook so their code runs again every time a session starts.

Read the CISA alert

These go unnoticed because, to a firewall or an EDR agent, "a program wrote a JSON file in the home directory" is the most ordinary thing in the world. There is no signal there to alert on. claude-ward is the missing piece.

How it works

Four steps, only the last one judges

  1. 01

    Snapshot

    Read the watched files and pull out the fields that matter: MCP servers, hooks, plugins, marketplaces, permissions, env. The credential file is only hashed.

  2. 02

    Diff

    Compare the snapshot against the baseline and list what was added, removed, or modified.

  3. 03

    Classify

    Run each change through deterministic rules - no model, no network - that assign a severity.

  4. 04

    Report

    Print findings, fire a desktop notification for the serious ones, and set the exit code to the worst severity.

Severity tiers

Changes classified by what they mean

Critical

MCP endpoint repointed to localhost (the Mitiga signature), an MCP command that fetches and runs code, or a SessionStart hook injected in place (the Shai-Hulud signature).

High

An MCP host you have not allowlisted, any other new or modified hook, an unexpected base URL or OTEL endpoint, credentials in a URL, or the credential file changing unexpectedly.

Medium

A new marketplace source, a plugin from an unknown marketplace, or a broadened permission allow-list.

Info

Every other tracked change, so nothing slips by silently.

Quickstart

Install, baseline, and wire the hook

  1. npm i -g claude-ward

    Install the CLI (also gives you the short cward alias).

  2. claude-ward init

    Record your current trusted config as the known-good baseline.

  3. claude-ward install-hook

    Add a SessionStart hook so every session opens with a scan - if something looks off you get a desktop alert and Claude flags it before you start.

A global install matters: install-hook writes a SessionStart hook that calls claude-ward, so the binary has to be on your PATH. The short alias cward works anywhere claude-ward does.

On-demand commands

Check whenever you want

claude-ward scan One-shot check; non-zero exit on HIGH or CRITICAL findings.
claude-ward diff Show every change against the baseline.
claude-ward watch Stay running and alert as files change.
claude-ward status Summarize the current baseline.
claude-ward approve --all Trust everything currently differing.
claude-ward approve <id> Trust one specific change.
  • Read-only on every monitored file
  • Never stores secret values (SHA-256 + metadata)
  • Zero network calls, zero telemetry in the core
  • State isolated in ~/.claude-ward/