Skip to main content
agentx scan reads your agent clients’ directories, their MCP configuration files and your skill library, then prints what it finds. It writes nothing, and it never starts an MCP server unless you ask for a handshake.

Scan the machine

How to read it:
  • The first line counts the whole machine. A skill, server or plugin that several configurations share counts once.
  • Each agent configuration then gets a section. Its first line shows the client name, its id, its configuration directory, whether it is enabled, and how many skills, servers and plugins it has.
  • skills: lists every skill the configuration can see, one per line: the skill name, the kind of placement, the scope and the path the client reads. A skill that comes from a plugin ends with the plugin’s name.
  • servers: appears when the configuration declares MCP servers, one per line: the name, the transport (stdio, sse or streamable-http) and the command line or URL.
  • plugins: appears when the configuration has plugins, one per line: the name, the version, how many skills and servers the plugin provides here, and (disabled) when the client has turned it off.
In a terminal the names are bold, the block labels cyan, the kind and scope dim, enabled green, (disabled) yellow and a plugin marker magenta, so the names and states stand out from the paths. Skill names and server command lines come from files agentx did not write. agentx replaces any control characters in them with spaces, and prints a path that holds one in quotes with escapes; see Output and exit codes. A configuration is detected when its configuration directory exists, such as ~/.claude for Claude Code or ~/.cursor for Cursor.

Read the kind

See who reads what

A client can read other clients’ directories. Cursor reads ~/.claude/skills and ~/.codex/skills next to its own ~/.cursor/skills, so a skill you put in the Claude Code directory appears under Cursor too. Some clients, such as Codex and Gemini CLI, read the library at ~/.agents/skills directly, so every library skill appears under them without any link in their own directories.

Read the servers

agentx reads the user-scope MCP configuration of Claude Code (~/.claude.json), Codex (~/.codex/config.toml), Cursor (~/.cursor/mcp.json), Gemini CLI (~/.gemini/settings.json), Windsurf (~/.codeium/windsurf/mcp_config.json) and GitHub Copilot (~/.copilot/mcp-config.json). Other clients contribute skills only. The inventory shows the command and arguments of a local server and the URL of a remote one. It never shows the values of environment variables or headers, so a scan does not print your secrets. The same server declared in two clients is one server with two occurrences: agentx recognises a remote server by its address and a local npx, uvx, pipx or docker server by its package or image, whatever the version. A server that cannot be identified that way is unique to this machine. A configuration file that cannot be parsed is reported as a warning and the scan continues.

Handshake the servers

A handshake starts or connects to every MCP server and records the tools, prompts and resources it offers. Each server gets ten seconds. agentx runs each server the way the client that declares it does:
  • A local server starts in its declared cwd, with the environment variables its declaration sets. A relative cwd resolves against the plugin’s directory for a plugin’s server, else against the directory you run agentx in.
  • Placeholders such as ${API_KEY} are filled in from your environment, in the syntax of the client that declares the server: ${VAR} for Claude Code, ${env:VAR} for Cursor and Windsurf, $VAR or ${VAR} for Gemini CLI and Copilot CLI. The inventory shows the declaration as written.
  • agentx does not send the credentials Claude Code never sends to a remote server, such as AWS_SECRET_ACCESS_KEY, nor any ANTHROPIC_* or CLAUDE_* variable. Run with --verbose to see which variables were held back.
  • A remote server receives its declared headers at its declared URL. agentx never tries another URL. For Codex, env_http_headers and bearer_token_env_var are read from your environment.
  • A server on the older sse transport is handshaken over SSE. A streamable HTTP server that refuses the opening request with 400, 404 or 405, and no MCP error, is tried once more over SSE at the same URL.
  • A server you turned off in its client, shown with (disabled), is never started. agentx reads this from Codex (enabled = false), Gemini CLI (mcp.excluded, mcp.allowed and gemini mcp disable) and Copilot CLI (/mcp disable). Claude Code, Cursor and Windsurf keep it outside the files agentx reads.
No environment value or header is ever printed. What a server exposed becomes its signature. Two servers with the same command or address but different tools get different signatures, so the inventory tells them apart; the same server declared in two clients with the same tools stays one server. The signatures are kept in handshakes.json in agentx home. A later scan without --handshake shows them until the next handshake replaces them.

Fix a failed handshake

A server that fails its handshake shows no tool count. Its row says why, a warning names its file, and a hint says what to do. The server keeps its previous signature and the scan still succeeds.

Read the plugins

Plugins are listed under the configuration they are installed in, with their version. The skills and MCP servers a plugin provides appear in the configuration’s list like any other, marked with the plugin’s name. A skill that is installed both standalone and through a plugin is one skill with two placements. A plugin’s version is what its manifest or install record says. For a Codex or Cursor plugin without one, the cache directory name stands in: local, a commit id or a release tag. A plugin manifest that cannot be read is reported as a warning naming the file, and the plugin is still listed by its directory name.

Include a project

Adds the skills found in the project’s own skills directories, such as .claude/skills, .cursor/skills and .agents/skills, with scope project. The project is only read. Without the flag, only user scope is scanned.

Rescan after a change

Names the configuration that changed. The whole machine is scanned either way, so the output is always complete. An id that is not detected exits with code 5 and lists the detected ids.

Warnings

The --- block at the top of a SKILL.md is read as YAML, so name and description are picked up however they are written: on one line, quoted, as a | or >- block, or continued on the indented lines under the key. A metadata: block or any other nested key is ignored. A frontmatter block far larger or more deeply nested than any real skill is refused unread, so a repository cannot make a scan run out of memory. A broken symlink, a SKILL.md whose block is not valid YAML or a symlink that points outside its skill does not stop the scan. Each one is reported on stderr as warning: ... and the skill is skipped or named after its directory. Several broken symlinks in one skills directory are reported as one warning that names the directory and lists the links:
Delete the listed links to clear the warning.