Claude Code privacy: what it sends, and how to keep personal data out

Claude Code does not only send what you type. Every file it reads and every command output becomes part of the conversation, and the whole conversation goes to the API with every request. Here is what that means for customer data in your repository, and how to keep it on your machine.

Updated 28 September 2026 · Serkan Korkut

What Claude Code sends

  • Your prompts, and CLAUDE.md and any other instructions loaded at start.
  • The full contents of every file the Read tool opens.
  • The output of every shell command it runs, such as grep, cat or a test run.
  • Results from MCP tools, such as a database query or a ticket lookup.

All of it stays in the conversation, and Claude Code sends the conversation with every request. It does not upload your whole codebase, only what it reads. But what it reads goes in full.

A typical leak

You ask "is invoice 1042 overdue?". Claude runs grep 1042 data/customers.csv to find it. The matching rows, with the customer's name, email, phone and account number, are now in the conversation and on their way to the API. You never pasted anything.

Option 1: keep sensitive files out

Deny rules in .claude/settings.json stop the Read tool from opening paths you name:

{
  "permissions": {
    "deny": ["Read(./.env)", "Read(./data/customers/**)"]
  }
}

This works for files you know about. A shell command can still print them, so it does not help when the data is mixed into logs, fixtures or query results.

Option 2: mask it with mask2ai

mask2ai is a free, open source Claude Code plugin. It replaces personal data with placeholders such as __PII_EMAIL_ae44b4__ before anything reaches the model, and puts the real values back where you need them.

/plugin marketplace add serkankorkut/mask2ai
/plugin install mask2ai@mask2ai

It uses six Claude Code hooks:

HookWhat mask2ai does
UserPromptSubmitBlocks a prompt that contains personal data and offers a masked copy to send instead
PostToolUseMasks file contents, command output and MCP results before the model sees them
PreToolUsePuts real values back into file edits and commands, so they still work. Redirects PDF and image reads to masked copies on macOS
MessageDisplayShows real values in the reply on your screen
SessionStart, SessionEndAnnounces that masking is on, and deletes the local placeholder map when the session ends
mask2ai in Claude Code: a prompt with an email is blocked, a CSV is read with 13 values masked, and the reply shows the real values

Check it yourself

The repository ships a script that starts a fake Anthropic API on localhost, points the real claude binary at it, and fails if a real value appears in any request:

git clone https://github.com/serkankorkut/mask2ai.git
cd mask2ai
node demo/prove.js

It ends with PROOF OK: nothing personal reached the API, only placeholders. when nothing leaked.

Questions

Is Claude Code safe to use with sensitive data?

Claude Code itself runs on your machine, but everything it reads goes to the API in full. Sensitive data in files, logs or query results is sent unless you keep it out. Deny rules block the files you know about. PII masking with mask2ai covers the rest, because it works on whatever the tools return.

What is PII masking in Claude Code?

Replacing personally identifiable information with placeholders in prompts and tool output before they reach the model, and putting the real values back in tool input and on screen. mask2ai does this with Claude Code hooks, so Claude can still edit files and run commands that contain the real values.

Does Claude Code send my whole codebase to Anthropic?

No. It sends what it reads or runs during the session: your prompts, the files it opens, command output and tool results. Those go in full, with every request.

How do I stop Claude Code from reading a file?

Add a deny rule such as Read(./.env) under permissions.deny in .claude/settings.json. Shell commands can still print the file, so for data spread across many files, masking works better.

Where does mask2ai keep the real values?

In a local file under the plugin's data directory, one per session, readable only by you, and deleted when the session ends. Nothing is sent anywhere else.

Does it work with MCP tools?

Yes. MCP tool results pass through the same PostToolUse hook, so personal data in them is masked before the model sees it.