Filed 8 days after Claude Code mods
Mods run as you. Read what they call first.
Claude Code mods aren’t sandboxed. The validate command lists what a mod hooks, calls and reads before it runs, but not where its data goes.
Source Anthropic, Claude Code mods 4 min read
A mod can do whatever you can do on your machine, and Anthropic’s advice to individuals stops at trusting the source. That is a list of names. A second check sits underneath it, it is free, and the launch post doesn’t mention it.
Anthropic’s own words: mods run with the same access to your machine as Claude Code itself. “They aren’t sandboxed, and you should only install mods from sources you trust.”
Here is my take. Before you install a mod, run claude plugin validate on its folder. It prints what the mod hooks, which calls it makes and which environment variables it reads, and it does that without starting a session. Read it like the permission list of a phone app. Then know what it leaves out: where the data goes.
The callRevisit Apr 1, 2027
By 1 Apr 2027, claude plugin validate prints the URL or the command of every http.fetch and process.run call, not only the call’s name.
OpenWhen the date comes, this box says held or missed, with the link that proves it.
How far a mod reaches
79 events
A mod can hook 79 events in Claude Code and make 61 kinds of call on your machine. Counted from the type definitions that ship with version 2.1.293.
The events include every tool call, every prompt you submit and every message Claude appends. The calls include reading a file by any absolute path, writing a file, running a command, fetching a URL and reading an environment variable. A file call takes an absolute path as given, so the call itself doesn’t keep a mod inside the project folder.
What validate prints
I ran it on four mods in my own folder. Each report was a few lines. The mod that hands work to a fresh chat hooks 4 events and makes 16 calls, among them a file write, and reads two environment variables, HOME and USERPROFILE. The mod that swaps a long dash for a comma makes none. You can read a report like that in a minute, and you can tell a mod that draws a panel from one that touches your files.
Then I wrote two mods built to do harm. I never installed or ran either. The first reads ANTHROPIC_API_KEY on session start and posts it to a URL. Validate passed it. The report said calls: $.env.get, $.http.fetch and env reads: ANTHROPIC_API_KEY. Nothing in it says the key leaves the machine, or where to.
The second runs curl on an SSH key file through $.process.run. Validate passed that too. The report said calls: $.process.run and nothing more: not the command, not the file, not the address.
So the report is a disclosure. It names the doors and says nothing about who is on the other side.
What it refuses
I also tried two ways to hide a call: giving $ another name, and spelling a call with a computed property name. Validate refused both and printed an error. A mod can’t get a call past the list by writing it oddly. That is two ways tried, and there may be a third.
Where I draw the line
The call list is the line.
- Calls like
ui.toastandstate.getdraw and remember. Install after a skim. env.getandfs.writeneed a reason in the mod’s description. If it is missing, ask why.http.fetchandprocess.runcan send anything out or run anything. Open the source and read the arguments, or skip the mod.
This is the same habit as putting a check in code, not in a rules file. The list of calls is a check you can run. Trusting the source is a rule you hope you kept.
What this test can’t tell you
It is four mods I wrote and two I built to fail: a small test. I didn’t run a hostile mod, so I don’t know what Claude Code asks you at the moment it runs. Anthropic says Team and Enterprise plans load a built-in mod, sec-default, first, to stop other mods from risky actions such as overriding your deny rules. I didn’t test it. And validate reads the source on disk: I didn’t test a mod that fetches more code after you install it.
1. Get the mod's folder without installing it. 2. Run claude plugin validate <folder>. 3. Read the calls line. Anything beyond drawing and remembering needs a reason. 4. Read the env reads line. A name that looks like a key or a token needs a reason in the description. 5. If you see http.fetch or process.run, open the source and read the arguments. The report doesn't print them. 6. Run it again after every update, because a new version can add a call. 7. Keep to sources you trust. This check sits on top of that, not in its place.
My four reports and two probes are saved with their outputs. When validate starts printing the arguments, I run them again.
