The agent check-up

An inventory of what your AI-agent setup already has — plugins, skills, MCP servers, hooks, permissions — scored by RepoGates. It reads; it never runs a program, never changes a file, and never blocks anything. ← All documentation

The single sentence. The check-up reads your AI-agent configuration on your machine and sends RepoGates identifiers, never contents. It reads; it never runs a program, never changes a file, and never blocks anything. The full list of what leaves and what never leaves is below, verbatim, and on the privacy page.

1. What it is

Everything else RepoGates does is about what is about to be fetched — a repository, a model, an extension, a skill. The check-up is about what an agent installation already has: the plugins installed and the marketplace each came from, the skills, commands and subagents on the machine, the MCP servers and hooks that run, the permission rules in force, the instruction files that exist. It is a read-only inventory, scored by RepoGates. Each plugin's, skill's and MCP server's source is assessed through the same rosters every RepoGates verdict uses (the 15 skill and plugin checks, the 22 on a repository); the served rule set is applied to the files on the machine — hidden Unicode, a launch line that fetches and runs, an API base URL override, the instruction shapes — and the permission posture is stated as what it is: a choice, never a critical finding. The answer is one score for the run, one per agent, one per item, with the findings that decided it and a fix for each.

It is part of every paid plan — Personal, Premium and Team — and not of the free trial. In this version Claude Code and Claude Desktop are read in full. Cursor, Windsurf, Codex CLI, Gemini CLI, Cline, VS Code and OpenClaw are detected — present or absent, with the paths looked at — and not inventoried: nothing under them is opened, nothing about them is assessed, and they have no score. Not inventoried is not a pass. An agent not in that list is reported as not present.

2. Install and run

Inside Claude Code, /repogates:checkup (plugin 0.9.0) runs it and reads the result. Anywhere else, the repogates-checkup command line — Python 3.11 or newer, no dependencies — is served as a wheel from this site and nowhere else; there is no PyPI package to install, and the install line names the exact file:

uvx --from https://repogates.com/cli/repogates_checkup-0.1.0-py3-none-any.whl repogates-checkup

Its SHA-256 is published beside it, at /cli/repogates_checkup-0.1.0-py3-none-any.whl.sha256 and on the CLI page, so the bytes you run are the bytes that were built (shasum -a 256 -c against the downloaded wheel). With pipx instead of uv: pipx run --spec <the same URL> repogates-checkup. The Claude Code command finds uvx or pipx on the machine and, if neither is there, points you at uv's documentation or pip install --user pipx and stops — it never installs a runner with a curl | sh line.

A RepoGates API token names your account: $REPOGATES_TOKEN, or the first line of ~/.config/repogates/token — the file the plugin's hook reads (create one on the account page). Without a token the check-up runs offline and says so: the bundled rule set, local findings only, nothing sent and nothing written. The token is never printed and never put on a command line.

OptionWhat it does
--agent NAMEOne agent (claude-code, claude-desktop, cursor, windsurf, codex, gemini, cline, vscode, openclaw) or all, the default.
--project DIRA project directory to read — its .mcp.json, CLAUDE.md, AGENTS.md and .claude/ — repeatable, sent as project:N and never as a path. With no home configuration on the runner this is the CI shape: repogates-checkup --project . --json reads a repository's agent files before merge; the exit code gates the job, the JSON is the record. Give the job REPOGATES_TOKEN as a secret for the server's verdicts, or run --offline for the local findings alone.
--jsonThe JSON document instead of the table: {"local": …} offline, {"local": …, "server": …} online. local.inventory is byte for byte what was sent, so you can read it before you trust it.
--offlineThe bundled copy of the rule set (pinned equal to the served one in this repository's tests), the local findings only; nothing is sent and nothing is written. No verdict on any plugin's, skill's or server's source — that is what the server knows.
--label TEXTA label for this run on your account page.
--home DIRRead DIR as the home — a mounted profile, a fixture.
--api-base URLThe API base (default $REPOGATES_API_BASE or https://api.repogates.com).

Exit codes

CodeMeaning
0allow — no finding the policy acts on.
1warn — at least one finding the policy warns on.
2block — at least one finding the policy blocks on.
3not run — no answer: the token was refused, the plan does not include the check-up, the daily allowance (12 runs) is spent, the API was unreachable, the server refused the inventory, or nothing was inventoried — every present agent was only detected, so the run has no score and no action. Not run is never a pass.

Online, the code is the server's action for the run. Offline, it is the worst local severity through the action mapping the rules file carries — absent one, a CRIT blocks and HIGH or MED warns. The MCP server's last_checkup tool reads the stored summary back; no tool on that server reads a machine.

3. What it reads, per agent

These are the files each reader opens, and nothing else. Every file's contents stay on the machine: the rules run on them there, and what leaves is a rule id and a count. A file over 1 MB is not read and is counted. Paths in arguments and permission rules are collapsed before they reach an item.

Claude Code — read in full

  • ~/.claude/settings.json and ~/.claude/settings.local.json — permission rules, hooks, the on/off flags, enabled plugins, extra marketplaces (scopes user and local).
  • The operating system's managed-settings file, scope managed: /Library/Application Support/ClaudeCode/managed-settings.json on macOS, /etc/claude-code/managed-settings.json on Linux, %ProgramData%\ClaudeCode\managed-settings.json on Windows.
  • ~/.claude/CLAUDE.md — instructions.
  • ~/.claude/skills/*/SKILL.md — skills. No provenance file exists for a hand-copied skill, so each is "local, source unknown".
  • ~/.claude/commands/*.md and one level of */*.md — commands.
  • ~/.claude/agents/*.md and one level of */*.md — subagents; the frontmatter's name, tools and model.
  • ~/.claude/plugins/installed_plugins.json and ~/.claude/plugins/known_marketplaces.json.
  • ~/.claude/plugins/marketplaces/<marketplace>/.claude-plugin/marketplace.json — the catalogue, to name each plugin's own source.
  • ~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/ — inside it .claude-plugin/plugin.json, hooks/hooks.json, .mcp.json, skills/*/SKILL.md, commands/*.md, agents/*.md.
  • ~/.claude.jsonmcpServers and projects[*].mcpServers only. The file carries more than eighty keys, among them oauthAccount and machineID; two are read, and a test proves nothing else serialises. The project path that keys each entry is matched against --project for project:N and otherwise the servers are local; the path itself is never kept.
  • Per --project DIR: .mcp.json, CLAUDE.md, AGENTS.md, .claude/settings.json, .claude/settings.local.json, .claude/CLAUDE.md, .claude/skills, .claude/agents, .claude/commands.

Claude Desktop — read in full

  • claude_desktop_config.jsonmcpServers only; the file also carries preferences and a user files path, and neither is read. Every operating system's location under the home is looked at: ~/Library/Application Support/Claude/ (macOS), ~/AppData/Roaming/Claude/ (Windows), ~/.config/Claude/ (Linux).

Detected only in this version — the paths looked at

For these seven the check-up reports present or absent and names the paths it looked at. Nothing under them is opened, nothing about them is assessed, and the agent carries no score. Their readers follow once fixtures exist (the roadmap).

AgentUnder the homeIn a --project
Cursor.cursor/mcp.json, .cursor/skills, .cursor/rules, .cursor.cursor/mcp.json, .cursor/rules, .cursorrules
Windsurf.codeium/windsurf/mcp_config.json, .codeium/windsurf, .windsurf.windsurf/rules, .windsurfrules
Codex CLI.codex/config.toml, .codex/skills, .codex.codex
Gemini CLI.gemini/settings.json, .gemini/extensions, .gemini/skills, .gemini.gemini/settings.json, GEMINI.md
Cline.cline/skills, .cline, and VS Code's globalStorage/saoudrizwan.claude-dev under Library/Application Support/Code/User, .config/Code/User or AppData/Roaming/Code/User.clinerules
VS Code.vscode/agent-plugins, and User/mcp.json under Library/Application Support/Code, .config/Code or AppData/Roaming/Code.vscode/mcp.json, .github/copilot-instructions.md
OpenClaw.openclaw/openclaw.json, .openclaw, .config/openclaw

4. What leaves your machine

The check-up reads your AI-agent configuration on your machine and sends RepoGates identifiers, never contents. What leaves: the names and versions of installed plugins and the marketplace each came from, with its source type and repository or URL hostname; marketplace names and sources; skill, command and subagent names with where each lives (user, project or plugin), a SHA-256 of each SKILL.md that identifies a known skill without revealing it, and a subagent's declared tools and model; for each MCP server its name, transport, the launch program's name and its arguments with every NAME=value, path and token-shaped string replaced, the package it launches (npx -y @scope/pkg@version) and, for a remote server, the hostname only; the names of environment variables and headers a server or hook is given, never their values; each hook's event, matcher, type, program name, redacted arguments and timeout; your permission rules with paths collapsed, your permission mode and the on/off flags; whether CLAUDE.md, AGENTS.md or rules files exist; the findings the served rule set produced on your machine, as a rule id, a count and a file's place in the list, never the matching text; a random check-up id stored in ~/.config/repogates that is not derived from your hardware; and your API token, to name your account. What never leaves: the contents of any file, environment-variable values, tokens, full URLs, your machine's hostname or user name, your home directory path, project paths or names (a project is sent as its position in the list), and any key of ~/.claude.json or claude_desktop_config.json other than mcpServers. RepoGates keeps the identifiers and their verdicts for your account page and deletes them with your account. The check-up reads; it never runs a program, never changes a file, and never blocks anything.

The same list, item by item — every field the checkup/v1 document has, and the document has no other:

  • Marketplace: name, scope, source (type; for github the owner/repo, path and ref; for a URL the hostname and, only when it is a github.com or gitlab.com repository, the repository path; for npm the package name; for an archive the hostname; for a command source the program's basename; path and unknown carry nothing).
  • Plugin: its name@marketplace key, version, scope, the installed commit, its source as above, and the names of the hooks, MCP servers, skills, commands and subagents it ships.
  • Skill and command: name, scope, the SHA-256 of the file, source, findings as rule id and count.
  • Subagent: name, scope, SHA-256, the declared tools and model, findings.
  • MCP server: name, scope, transport, the launch program's basename, its redacted arguments, the package it launches (registry, name, version), a remote server's hostname, the names of its environment variables and headers, findings.
  • Hook: event, matcher, type, the program's basename, redacted arguments, timeout, scope, an http hook's hostname, findings.
  • Permissions: scope, the allow / deny / ask rules with paths collapsed, the default mode, the on/off flags (bypass disabled, auto mode, skip-auto-prompt, hooks disabled, all project MCP), the count of additional directories and of enabled plugins, and each extra marketplace's source type and hostname.
  • Instructions: which file (CLAUDE.md, AGENTS.md, .claude/CLAUDE.md), scope, SHA-256, findings.
  • The run: the schema name, the CLI's name, version, rules version and platform, the random check-up id, your label, and per agent whether it is present and which scopes it has.

Every run prints a sent: line so you see what left, in the CLI's own words:

sent: 9 agents (2 present), 41 items — 3 marketplaces, 6 plugins, 12 skills, 4 commands, 2 subagents, 7 MCP servers, 3 hooks, 2 permissions, 2 instructions — 5 findings as rule ids and counts; 0 file contents, 0 environment values, 0 tokens, 0 full paths; 9,812 bytes

The numbers above are an illustration of the shape; yours are your own. Offline the line reads sent: nothing (offline) — 0 file contents, 0 identifiers, 0 bytes. The server holds the other end of the contract: it validates the document strictly (an unknown key is refused by name) and refuses, before anything is stored, a value that looks like a token or a NAME=value with a value — so a redaction the CLI missed is a 400, not a row. The summary the server keeps for your account page carries identifiers and verdicts only: no arguments, no environment-variable names, no hook lines. The newest thirty runs are kept per account, and all of them are deleted with the account. The check-up registers no device and does not count against your device allowance; its check-up id is random, minted once, and is not a fingerprint.

5. What it cannot see

  • Runtime behaviour — what a plugin's code or an MCP server does once it runs. The check-up reads configuration; the deep scan is the tool that reads a package's files.
  • A skill's origin when no provenance file exists. A skill copied by hand into ~/.claude/skills is "local, source unknown" and is scored on its text alone. If you want provenance, reinstall it from its repository (npx skills add owner/repo).
  • An agent not in the list — reported as not present, not as anything else.
  • The seven detected-only agents' configuration, in this version: Cursor, Windsurf, Codex CLI, Gemini CLI, Cline, VS Code and OpenClaw are present or absent and nothing more. The Cline and OpenClaw shapes in particular are not read.
  • Your installed editor extensions and Docker Desktop extensions. The check-up does not list them. A VS Code Marketplace extension or a Docker Desktop extension is checked before you install it, through the MCP server and the plugin's hook — not in the browser, and not by the check-up.
  • An MCP server whose package declares no repository — "not assessed", never a pass. The launch line still gets the local checks (a fetch piped into a shell is a finding whatever the package).
  • A detected-only agent carries no score. not_inventoried is a status, not a 100; a run whose present agents were all only detected has no score and no action.

A PASS is on the identifiers and the text read, not on anything having been run.

6. How to read the score

The answer has three levels. Per agent, a status: inventoried (present, read, at least one item — with a score, a grade and an action of its own), not_inventoried (present, detected only — score: null, grade unknown, no action) or absent. Per item, a verdict — PASS, REVIEW, BLOCK or NOT_ASSESSED — a score, an action, the basis it was decided on (skill-roster for a plugin or skill source through the 15 checks, repo-22 for a repository, launch-line for an MCP server or hook, posture for permissions, rules for a file's findings) and the check ids that fired. The run: one score and grade over every row, the action the policy takes, the drivers behind it, and partial: true when anything was not assessed.

The arithmetic is the same as every other RepoGates verdict — score_report over the rows, the same profiles for the action — so a check-up score reads like a repository score. Two rules are its own. Posture rows are MED at most — a Bash(*) allow, a bypass mode, every project's MCP servers auto-approved — because each is a choice you made, and the check-up's job is to state it, not to call it critical. And an item the server could not assess is checkup-not-assessed — the run's cold-verdict allowance (40 per run, 120 a day across runs) used up, a source that could not be resolved, a registry that did not answer — an INFO row that keeps the item out of PASS and sets partial; it is never unassessable, which would null the whole run. A campaign-listed key is CRIT whatever else happened.

The checks, their severity and the fix

Titles are the server's; fixes are the served rule set's, quoted as given. The severity column is the row the engine holds for the check (backend/policy/scoring.json); a source verdict's row follows the source's own verdict.

CheckTitleSeverityFix
checkup-plugin-sourcePlugin source verdictCRIT when the source is campaign-listed; HIGH on BLOCK; MED on REVIEW; a note on PASSUninstall the plugin (/plugin uninstall name@marketplace) until its source repository's verdict is PASS, or allowlist it on your account page after reading the findings.
checkup-marketplace-sourceMarketplace source verdictCRIT / HIGH / MED / note, by the marketplace repository's verdictRemove the marketplace (/plugin marketplace remove name) until its repository's verdict is PASS; every plugin it lists is installed on its word.
checkup-mcp-sourceMCP server package source verdictCRIT / HIGH / MED / note, by the package's source repository's verdictRemove the server from the settings file it lives in until the package's source repository is PASS, or pin a version you have read.
checkup-mcp-execMCP server launch line fetches and runsCRITReplace the launch line with a pinned package or an installed program; a fetch piped into a shell runs whatever the URL serves, every start.
checkup-hook-execHook command fetches and runsCRITReplace the hook command with a script on the machine; a hook that fetches and runs does so on every matching tool call.
checkup-hook-http-remoteHook posts tool input off the machineHIGHPoint the http hook at a loopback address or a service you run; each tool call's input is posted to the host named.
checkup-plugin-command-sourcePlugin installed by a shell commandHIGHPrefer a plugin whose marketplace entry names a repository; a command source runs a shell command at install and once per session.
checkup-mcp-unpinnedMCP server package not pinned to a versionMEDPin the package version on the launch line (npx -y @scope/pkg@1.2.3, uvx pkg==1.2.3) so an upstream release cannot change what starts.
checkup-mcp-unknown-hostRemote MCP host outside the registry censusINFO while the served host list is a seed; MED once the full census replaces it; a server whose whole address is a variable sends no host, so this check cannot see itConfirm the remote server's host is the vendor's own before handing it a credential; a host outside the registry census is not thereby malicious.
checkup-mcp-credential-envCredential-named variable to an unknown remoteMEDGive the credential to the remote only after confirming its host; the name of the variable was sent, its value never was.
checkup-posture-bash-wildcardEvery shell command allowed without a promptMED — a choice, statedReplace Bash(*) in the allow list with the commands you mean (Bash(npm test:*)), so a prompt returns for everything else.
checkup-posture-bypassPermission prompts bypassed by defaultMED — a choice, stated; INFO in a project file, where it does not take effectSet defaultMode back to a prompting mode in your user settings; a project file cannot turn bypass on.
checkup-posture-all-project-mcpEvery project's MCP servers start without approvalMED — a choice, statedTurn enableAllProjectMcpServers off and approve each project's .mcp.json servers as you open them.
checkup-posture-autoAuto mode onINFONo change needed; auto mode is your choice, and the check-up states it.
checkup-posture-hooks-disabledAll hooks disabledINFONo change needed unless a hook you rely on is silently off.
checkup-posture-skip-promptAuto-mode prompt skippedINFONo change needed; stated so the setting is not a surprise.
checkup-injection:overrideInstruction shape: override or hide from the userMEDRead the matched file yourself; an instruction that hides something from you has no honest place in a skill.
checkup-injection:* (decode-exec, password-archive, fetch-exec, credential-read, exfil, dynamic-context, permission-bypass, html-comment)Instruction shape: decode and run · password-protected archive · fetch and run · credential read · send off the machine · dynamic context span · permission bypass · hidden HTML commentINFO until the false-positive runRead the matched file yourself before the next session; the check-up sends only the rule id and a count, never the text.
hidden-unicodeHidden Unicode in an agent fileCRITOpen the file in an editor that shows invisible characters and remove them, or remove the file; a leading BOM alone is not a finding.
credential-redirectAPI base URL or key overriddenCRITRemove the ANTHROPIC_BASE_URL / OPENAI_BASE_URL override or the *_API_KEY assignment unless you set it yourself for a proxy you run.
mcp-execLauncher config fetches and runsCRITReplace the launch line with a pinned package or an installed program; never a fetch piped into a shell.
checkup-mcp-no-sourceMCP server names no package or repositoryINFONo change needed; the server launches something the check-up cannot trace to a package or repository, so nothing was assessed.
checkup-skill-unknown-sourceSkill with no known originINFONo change needed; if you want provenance, reinstall the skill from its repository through npx skills add owner/repo.
checkup-not-assessedNot assessedINFO — never a pass; sets partialRun the check-up again later; the server could not look at this item this time.

A subagent whose declared tools include Bash is recorded and is never a finding. The rule set itself — the regex source strings and the posture lists — is served as data by GET /v1/checkup/rules and bundled in the wheel; remote data, never remote code, and the patterns are byte for byte the engine's own.

7. The measurement

Measured on … — the K2e run publishes the false-positive rate of the launch-config and permission findings here before the pricing row goes live. The method is fixed: the official plugin catalogue (anthropics/claude-plugins-official) synthesised into a home and run through the CLI offline and online, findings tallied per check id, every CRIT and HIGH listed by plugin for hand review, and three reference runs — the owner's own machine (counts only), an empty home (no agents present, exit 0 offline) and a minimal home. The gate: 0 critical false positives on the catalogue, or the rule is downgraded before launch. Until that run is published, no number appears here.

The contract above is repeated, verbatim, on the privacy page, in the CLI's README, on the CLI page and in the Claude Code command's own text; a test in this repository pins the key clause on each. The extension's privacy notice version does not change for the check-up: nothing new leaves the extension, and the check-up is a separate, opt-in program you run yourself.

← All documentation · AI agents & MCP guide · Personal user guide · The CLI page