
Product
PHP and Composer Support Is Now in Beta
Socket’s PHP and Composer support is now in Beta for all customers, with PHP reachability analysis generally available.
Find tool calls that could fire the same effect twice. Reports evidence, renders no verdict. Zero dependencies.
Find tool calls that could fire the same effect twice.
npx fencescan
No install, no dependencies, no network, no config. Scans the current directory and prints what's worth a second look.
An agent that retries a tool call after a timeout doesn't know whether the first attempt landed. The request reached the server, the work happened, the response never came back. Nothing failed loudly — it succeeded twice.
fencescan reads your code and lists the tools where that would cost you
something, alongside what else it found: write call sites, anything that looks
like an idempotency guard, and retry logic.
fencescan /your/mcp-server
42 files · 11 tool declarations found
Tools worth checking (candidates, not verdicts)
money createCampaign src/tools/ads.py:609 · 12 write call(s) in this file
money chargeAccount src/tools/billing.py:88
effect sendTemplate src/tools/whatsapp.py:151
What else is in this codebase
59 write call site(s)
0 idempotency-looking guard(s) ← none found in this repo
14 retry site(s)
Worth a close look: retry logic and no visible dedup key.
It renders no verdict. There is no risk score, no "AT RISK", no severity. An outsider reading a codebase usually cannot prove a double-fire: the guard often lives in a service the code calls or a sibling package, and a function whose name sounds like a write may only build a payload for someone else to sign. Every run prints what it cannot see.
This isn't modesty. An earlier version did print verdicts, and hand-verification killed 4 of its first 7. Each of those failures is now a fixed behaviour with a test:
| It got this wrong | Why | Fixed by |
|---|---|---|
| Said a repo had no idempotency when it shipped a whole module | \b(idempot…) cannot match deriveIdempotencyKey — no word boundary before a mid-word capital. Same blindness hid requestId, clientToken | anchors removed |
| Flagged read-only tools | A flat window after a tool name ran into the next declaration, so reads inherited writes' vocabulary | brace-matched to the tool's own block; a read verb in the name vetoes |
| Found no writes at all | Writes live in shared helpers, not in the tool declaration | collected per file as corroboration, never claimed as "this tool writes" |
Missed method: body ? "POST" : "GET" | String literals were stripped before matching — but the HTTP verb is a literal | matched on the raw line |
If it flags something and you're sure it's wrong, that's worth an issue. A false positive here costs more than a miss.
npx fencescan # scan the current directory
npx fencescan ./server # scan a path
npx fencescan --json # machine-readable
Exit codes: 0 scanned, 2 bad path. It never exits non-zero for findings —
findings are for a human to read, not for a build to fail on.
Recognises MCP-style tool declarations (registerTool, @mcp.tool, Tool(...),
@tool) across TypeScript, JavaScript, Python, Go, Rust, Java and Ruby.
Open each candidate and ask one question: if this ran twice, would anyone notice?
If the answer is no, that's the bug — not the crash you'd have caught.
For fixes: once is an
exactly-once kernel for TypeScript and Python, and
effectfence is an MCP server that
fences tool calls. Both free. If you'd rather someone did the work,
the Fence Audit.
MIT
FAQs
Find tool calls that could fire the same effect twice. Reports evidence, renders no verdict. Zero dependencies.
We found that fencescan demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Product
Socket’s PHP and Composer support is now in Beta for all customers, with PHP reachability analysis generally available.

Product
Socket is bringing experimental protection to Firefox, scanning 97,000+ extensions in Mozilla's official directory for malware and risky updates.

Research
/Security News
Three compromised Rust crates pulled in a malicious dependency that downloaded and executed cross-platform malware during Cargo builds.