How Tool Availability Is Tracked in Reverse-Skill: Discovery, Indexing, and MCP Verification

Reverse-Skill tracks tool availability through a three-stage pipeline that discovers binaries on the host, generates machine-readable indexes, and verifies MCP registration and service health to determine if a tool is truly ready for use.

The reverse-skill repository maintains a sophisticated inventory system for security and reverse-engineering workflows. Understanding how tool availability is tracked in reverse-skill is essential for ensuring your environment meets the execution requirements for specific skills, from APK decompilation to binary analysis.

The Three-Stage Tracking Pipeline

The repository implements a platform-agnostic detection system that separates raw tool presence from operational capability. This design allows the system to distinguish between a tool being installed versus being fully integrated with the Model-Client-Protocol (MCP) infrastructure.

Stage 1: Host Discovery via tool-discovery.sh

The process begins with kali/scripts/lib/tool-discovery.sh (Kali Linux) or the analogous logic in skills/scripts/refresh-tool-index.sh (Linux/macOS). These scripts scan the host using command -v lookups and explicit path probing to locate each binary.

Each tool is defined in a pipe-delimited catalog format:


name|skill|purpose|version_args|fallback_commands

For example, entries for jadx and radare2 follow this pattern:

"jadx|apk-reverse|Java 反编译|--version|jadx,${HOME}/tools/jadx/bin/jadx,/opt/jadx/bin/jadx"
"r2|radare2|radare2 主分析器|-v|r2,radare2,${HOME}/tools/radare2/bin/r2,/usr/bin/r2"

The resolve_tool() function (lines 64–95 in tool-discovery.sh) iterates over candidate paths and commands. It expands glob patterns like ${HOME}/tools/*/apksigner, checks executable permissions, and falls back to command -v lookups when path probes fail. This dual strategy ensures tools are found whether they reside in system PATH or custom installation directories.

Stage 2: Index Generation with Dual Output

Once discovered, tool metadata is formatted into two synchronized artifacts:

  • tool-index.md: A human-readable Markdown table with columns for Tool, Skill, Purpose, Available, Path, Version, Source, and Install hint.
  • tool-index.json: A machine-readable JSON file consumed by automation scripts and UI components.

The generation logic resides in skills/scripts/refresh-tool-index.sh (lines 58–103). For each entry in the static TOOLS array, the script calls:

  • has_cmd and cmd_path to determine availability and location
  • run_version to execute version arguments and capture output
  • install_hint to suggest installation commands for missing binaries

Missing tools are explicitly marked with available=no and empty version fields, ensuring the index accurately reflects the current host state.

Stage 3: MCP-Aware Capability Verification

The final stage enriches the basic index with service-health and registration checks. This occurs in a Python block within refresh-tool-index.sh (starting at line 37) that processes bootstrap-manifest.json.

The system validates four dimensions of readiness:

  1. Tool Presence: Whether the binary exists (from Stage 1)
  2. MCP Registration: Whether the tool's MCP server is listed in client configs (~/.claude/mcp.json or ~/.codex/config.toml)
  3. TCP Connectivity: Whether the advertised servicePort accepts connections
  4. HTTP Handshake: Whether the MCP server responds to JSON-RPC requests at the /mcp endpoint

The verificationMode field in the bootstrap manifest dictates the final logic:

  • registration-only: Ready if registered in client configs
  • service-and-registration: Ready only if both registered and TCP port is open
  • service-or-registration: Ready if either condition is met
  • npm-mcp: Requires both registration and a functioning npx runtime

Core Implementation Details

Version Extraction and Source Attribution

When resolve_tool() locates a binary, it calls get_tool_version to execute the tool with predefined version arguments (e.g., --version or -v). The first line of output is captured and sanitized for the index.

The system records the discovery source to aid debugging:

  • command: Found via command -v in shell PATH
  • path: Located via explicit filesystem probe
  • missing: Binary not found via any method

Capability Status Calculation

The Python enrichment block performs the final readiness calculation using data from bootstrap-manifest.json:

for cap in capabilities:
    name = cap.get('name')
    bootstrap_kind = cap.get('bootstrapKind', '')
    mcp_names = cap.get('mcpNames') or []
    service_port = cap.get('servicePort')
    verification_mode = cap.get('verificationMode', '')

    registered = any(n in registered_names for n in mcp_names) if mcp_names else False
    service_online = tcp_open(service_port) if service_port else False
    mcp_http_verified = mcp_http_handshake(service_port) if service_online else False

    tool_ready = tool_available.get(name, False)
    runtime_ready = tool_available.get('npx', False) if bootstrap_kind == 'npm-mcp' else tool_ready

    if verification_mode == 'registration-only':
        ready = registered
    elif verification_mode == 'service-and-registration':
        ready = registered and service_online
    elif verification_mode == 'service-or-registration':
        ready = registered or service_online
    elif bootstrap_kind == 'npm-mcp':
        ready = registered and runtime_ready
    else:
        ready = registered or tool_ready

This logic allows reverse-skill to report nuanced states, such as "Tool installed but MCP server not registered" or "MCP registered but service offline."

Practical Code Examples

Resolving Tool Paths in Kali

The resolve_tool() function in tool-discovery.sh demonstrates the fallback resolution strategy:

resolve_tool() {
    local entry="$1"
    IFS='|' read -r name skill purpose version_args fallbacks <<< "$entry"
    IFS=',' read -ra candidates <<< "$fallbacks"

    for candidate in "${candidates[@]}"; do
        # Expand globs like ${HOME}/tools/*/apksigner

        local expanded=$(compgen -G "$candidate" 2>/dev/null | head -n1) || expanded=""
        if [[ -n "$expanded" && -x "$expanded" ]]; then
            local ver=$(get_tool_version "$expanded" "$version_args")
            echo "${name}|${skill}|${purpose}|yes|${expanded}|${ver}|path"
            return
        fi
        # Fallback to command lookup

        local cmd_path=$(command -v "$candidate")
        if [[ -n "$cmd_path" ]]; then
            local ver=$(get_tool_version "$cmd_path" "$version_args")
            echo "${name}|${skill}|${purpose}|yes|${cmd_path}|${ver}|command"
            return
        fi
    done
    echo "${name}|${skill}|${purpose}|no|||missing"
}

Generating Markdown Rows

The main loop in refresh-tool-index.sh constructs the inventory table:

for entry in "${TOOLS[@]}"; do
    IFS='|' read -r name skill purpose commands version_spec probes <<< "$entry"
    available="no"; path=""; version=""; source=""
    if [[ "$commands" != "none" ]]; then
        IFS=',' read -ra cmd_list <<< "$commands"
        for cmd in "${cmd_list[@]}"; do
            if has_cmd "$cmd"; then
                available="yes"
                path=$(cmd_path "$cmd")
                source="command"
                break
            fi
        done
    fi
    # …probe handling omitted for brevity…

    [[ -z "$path" ]] && path="—"
    [[ -z "$version" ]] && version="—"
    hint=$(install_hint "$name")
    echo "| $name | $skill | $purpose | $available | $path | $version | $source | $hint |"
done >> "$OUTPUT_MD"

Summary

  • Reverse-Skill tracks tool availability through a coordinated pipeline of discovery, indexing, and capability verification.
  • The tool-discovery.sh script performs host scanning using both command -v lookups and explicit path globbing to locate binaries.
  • Results are persisted to tool-index.json (machine-readable) and tool-index.md (human-readable) via refresh-tool-index.sh.
  • Capability status is determined by checking MCP registration in ~/.claude/mcp.json/~/.codex/config.toml and verifying TCP/HTTP service health against bootstrap-manifest.json definitions.
  • The system respects distinct verification modes (registration-only, service-and-registration, etc.) to accurately report whether a tool is truly ready for automated use.

Frequently Asked Questions

How does reverse-skill find tools that are not in the system PATH?

The discovery scripts check both command -v and explicit fallback paths defined in the tool catalog. For example, jadx is searched not only as a command but also at ${HOME}/tools/jadx/bin/jadx and /opt/jadx/bin/jadx. The compgen -G command expands glob patterns, allowing the system to find tools installed in versioned directories without knowing the exact path.

What is the difference between "available" and "ready" in the tool index?

Available indicates the binary exists on the filesystem and is executable. Ready indicates the full operational capability is online, which may require MCP registration in client config files and active TCP service listeners. A tool can be available but not ready if its MCP server is unregistered or offline.

Where does reverse-skill store MCP registration information?

The system reads client-specific configuration files: ~/.claude/mcp.json for Claude-based agents and ~/.codex/config.toml for CodeX-based agents. These files are parsed during the capability enrichment stage to build a registered_names set used in readiness calculations.

Can the refresh scripts install missing tools automatically?

No. According to the repository's design philosophy, the refresh scripts are detection-only and never modify the host system. When a tool is missing, the index includes an install hint generated by the install_hint() function, but the actual installation must be performed manually or through separate bootstrap procedures.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →