Build a custom local tool

Define, register, and run your own command-line tool inside a local pentest.

What you’ll build

A custom local tool that wraps a command-line binary and runs on your machine during a pentest. You will define the tool as JSON, register it with the CLI, attach it to a phase and an agent, supply its API key, verify your environment, and run a local pentest that uses it.

Local tools have execution_mode: "local": the agent decides when to call the tool and with what arguments, but the command itself executes on your host. That keeps credentials and network access on your side.

Anatomy of a tool definition

A tool is a JSON object with a few key fields:

  • command — the template to run, with {param} placeholders.
  • parameters — a JSON-Schema object; every placeholder in command must be declared here, and anything in required must appear as a placeholder.
  • requires_api_key — the name of an environment variable the tool needs (optional).
  • bootstrap — a one-shot init command run once the API key is set (optional).
  • timeout_seconds — per-invocation timeout (optional).

Prerequisites

  • The Rank CLI installed and authenticated.
  • The tool’s binary installed locally (here, the shodan CLI).
npm install -g @aleex-rank/cli
rank auth set rk_...

Steps

  1. Write the tool definition. Save this as custom_local_tool.json. The single {ip_address} placeholder is declared and marked required; the tool needs a Shodan API key and bootstraps the shodan CLI once that key is set.

    {
      "name": "shodan_host_lookup",
      "description": "Look up open ports, service banners and known CVEs for an IP address using the Shodan CLI.",
      "command": "shodan host {ip_address}",
      "execution_mode": "local",
      "requires_api_key": "SHODAN_API_KEY",
      "bootstrap": "shodan init {SHODAN_API_KEY}",
      "timeout_seconds": 120,
      "parameters": {
        "type": "object",
        "required": ["ip_address"],
        "properties": {
          "ip_address": {
            "type": "string",
            "description": "IPv4 or IPv6 address to look up on Shodan."
          }
        }
      }
    }
  2. Register the tool. Create it from the file. The CLI validates the schema and prints the new tool ID.

    rank tools create -f custom_local_tool.json
  3. Attach it to a phase and an agent. Local tools are assigned to a phase first, then to the agent that should call them.

    rank tools phase-assign <toolId> --phase 1
    rank tools assign <toolId> <agentId>
  4. Set the API key. Store the secret locally. Setting a key that a bootstrap depends on triggers the bootstrap automatically (here, shodan init).

    rank env set SHODAN_API_KEY=your_shodan_key
  5. Verify your environment. doctor checks that the binaries your assigned tools need are installed and on PATH.

    rank doctor --pentest <pentestId>
  6. Run the pentest locally. Local mode requires guided mode; the tool’s command executes on your machine when an agent calls it.

    rank pentest run <pentestId> --local

Run it

Save the following as custom_local_tool.json, then register it with the CLI:

rank tools create -f custom_local_tool.json
{
  "name": "shodan_host_lookup",
  "description": "Look up open ports, service banners and known CVEs for an IP address using the Shodan CLI.",
  "command": "shodan host {ip_address}",
  "execution_mode": "local",
  "requires_api_key": "SHODAN_API_KEY",
  "bootstrap": "shodan init {SHODAN_API_KEY}",
  "timeout_seconds": 120,
  "parameters": {
    "type": "object",
    "required": ["ip_address"],
    "properties": {
      "ip_address": {
        "type": "string",
        "description": "IPv4 or IPv6 address to look up on Shodan."
      }
    }
  }
}

To learn how tools, agents, and phases fit together, see Agents, tools & MCP.