{"slug": "postman-silently-installed-ai-plugins-in-its-own-update-i-built-a-one-command", "title": "Postman silently installed AI plugins in its own update. I built a one-command diff for your dev-tool trust surface", "summary": "A developer built toolwatch, an open-source CLI that snapshots a developer-tool trust surface — VS Code extensions, Claude Code plugins and hooks, Cursor extensions, Postman plugin directories, shell startup files, git hooks and remote MCP endpoints — and diffs it across updates, exiting non-zero when trust-relevant changes appear. The tool was prompted by Postman 12.33.4, which silently auto-installed Claude Code and Codex AI plugins, wrote a trusted hash for its own SessionStart hook and opened a remote MCP connection, surfacing via bug report postman-app-support#14370 and a Hacker News thread at 1,391 points. toolwatch offers snapshot, diff, check (a CI gate against a committed baseline) and watch commands, requires Node 20+, has zero runtime dependencies and is installed from source since no npm package is published yet.", "body_md": "Postman 12.33.4 shipped an update that silently auto-installed Claude Code and Codex AI plugins, wrote a trusted hash for its own SessionStart hook, and opened a remote MCP connection. Users found out from a bug report, not from the tool: postman-app-support#14370, marked SEVERE, 453 reactions, and the hottest Hacker News story of the week at 1,391 points and 461 comments.\n\nNo vendor audits itself. After any dev-tool update, the question nobody answers for you is simple: what did the tool I updated yesterday do differently? I built [toolwatch](https://github.com/techdevfun/toolwatch) to answer it in one command.\n\ntoolwatch snapshots your dev-tool trust surface, then diffs it across updates. One snapshot, one diff, one exit code.\n\n```\ntoolwatch snapshot --out before.json\n# ... update your tools ...\ntoolwatch snapshot --out after.json\ntoolwatch diff before.json after.json   # exit 1 when something trust-relevant changed\n```\n\nIt also has `check` against a baseline (the CI gate) and `watch`, which repeats the check until something drifts.\n\nWhat gets snapshotted:\n\n| Collector | What it records | \n|---|---|\n| VS Code | extensions (name, version, hash) and MCP servers in settings | \n| Claude Code | plugins, hooks (event, matcher, command hash), MCP servers | \n| Cursor | extensions and MCP servers | \n| Postman | plugin directories under the app data dir | \n| Shell | startup files ( `.bashrc` ,`.zshrc` ,`.profile` ), hashed, never copied | \n| Git hooks | `.git/hooks` of repos passed via`--repos` (opt-in, default off) | \n| Remote endpoints | scheme and host of every configured MCP endpoint (no credentials, ever) | \n\nEach collector reports `ok`, `not-installed`, or `error` and never crashes on a missing tool. A snapshot is one JSON file with a sha256 fingerprint of the whole surface.\n\nThe demo below replays the Postman 12.33.4 shape through the real pipeline (reconstructed fixtures with recorded provenance, not anyone's real config):\n\nAnd the diff output, captured from the real CLI:\n\n``` bash\n$ toolwatch diff before.json after.json\n+ ADDED   claude-hook          claude-code:hook:SessionStart:*\n           command postman-ai-bridge --session-start --trusted-hash a1b2c3d4\n+ ADDED   claude-mcp-server    claude-code:mcp:postman-remote\n           http https://mcp.postman.example\n+ ADDED   postman-plugin       postman:plugin:claude-code\n           version 1.0.0 · dir .config/Postman/plugins\n+ ADDED   postman-plugin       postman:plugin:codex\n           version 1.0.0 · dir .config/Postman/plugins\n+ ADDED   remote-endpoint      endpoint:https://mcp.postman.example\n           via claude-code mcp server \"postman-remote\" (http)\n~ CHANGED vscode-extension     esbenp.prettier-vscode\n           version 12.4.0\n        -> version 12.5.0\n\n6 change(s): 5 added, 1 changed, 0 removed.\n\nDRIFT: 6 trust-relevant change(s) — review, then re-baseline with 'toolwatch snapshot'.\nexit: 1\n```\n\nTwo design choices worth noting. A version bump shows as one `CHANGED` row (old version to new version), not as an add/remove pair, so routine updates stay readable. And by default only additions and changes gate the exit code; removals are reported but exit 0, unless you pass `--strict`. The idea is that a legitimate update bumping a version should not train you to ignore the gate.\n\nCommit a `baseline.json` from a known-good machine, then fail the build when the runner's trust surface drifts:\n\n```\n- run: node dist/cli.js check --baseline baseline.json\n```\n\nI compared against the closest tools before building, and toolwatch loses on their home turf:\n\nThe wedge: none of them answers \"what did the dev tool I updated yesterday do differently\" across the whole trust surface in one local command with zero setup. That is the one thing toolwatch does.\n\nInstall from source for now (no published npm package yet):\n\n```\ngit clone https://github.com/techdevfun/toolwatch.git\ncd toolwatch\nnpm install\nnpm run build\nnode dist/cli.js --help\n```\n\nNode 20 or later. Zero runtime dependencies. TypeScript, strict mode. The test suite is 38 tests (25 unit, 13 end-to-end) plus a live smoke test, and CI runs it on Node 20 and 22.\n\nWindows collector paths, VS Code Insiders paths, alerting channels for `watch` (email, webhook; currently exit code only), an HTML report for a diff, and an npm package once the maintainer token decision lands.\n\nThe code is MIT licensed at [github.com/techdevfun/toolwatch](https://github.com/techdevfun/toolwatch). If a tool update has ever surprised you after the fact, snapshot before the next one and see what it actually changed.", "url": "https://wpnews.pro/news/postman-silently-installed-ai-plugins-in-its-own-update-i-built-a-one-command", "canonical_source": "https://dev.to/techdevfun/postman-silently-installed-ai-plugins-in-its-own-update-i-built-a-one-command-diff-for-your-3487", "published_at": "2026-11-05 12:07:20+00:00", "updated_at": "2026-11-05 12:19:27.533362+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "developer-tools", "ai-tools", "ai-safety"], "entities": ["Postman", "toolwatch", "Claude Code", "Codex", "Cursor", "VS Code", "Hacker News", "GitHub"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/postman-silently-installed-ai-plugins-in-its-own-update-i-built-a-one-command", "markdown": "https://wpnews.pro/news/postman-silently-installed-ai-plugins-in-its-own-update-i-built-a-one-command.md", "text": "https://wpnews.pro/news/postman-silently-installed-ai-plugins-in-its-own-update-i-built-a-one-command.txt", "jsonld": "https://wpnews.pro/news/postman-silently-installed-ai-plugins-in-its-own-update-i-built-a-one-command.jsonld"}}