Skip to content

Adding a Tool

Melvin PETIT edited this page Jun 17, 2026 · 1 revision

Adding a Tool

The most common contribution. The registry + dispatcher design means you wire almost nothing, define one function and add one line.

1. Decide category and type

  • Categorysoc, grc, integration, ot. Pick the module whose role matches. If it fits two, pick the one with the smaller current count.
  • Typedocker (ships or can use a compose file) or cli (a binary installed via apt/pip/curl). Choose cli only when upstream offers no usable Docker image; most tools should be docker.

2. Write the deployer

CLI tool

# in lib/deploy_<category>.sh
deploy_foo() {
    log_message step "Installing Foo (one-liner role)..."
    ensure_command_absent foo || return 0
    pip_install foo || { wait_enter; return 1; }     # or apt-get / curl
    mark_cli_installed "foo"
    show_access_info "Foo" \
        "Command: foo" \
        "Usage:   foo --help"
    log_message success "Foo installed"
}

Docker tool

deploy_bar() {
    local dir
    dir=$(tool_dir "bar")
    mkdir -p "$dir"

    log_message step "Deploying Bar..."

    local admin_password
    admin_password=$(gen_password 16)

    cat > "${dir}/docker-compose.yml" << EOF
services:
  bar:
    image: barproject/bar:1.2.3          # pin a real version, not :latest
    container_name: medusa-bar
    restart: unless-stopped
    ports:
      - "8086:80"                        # check Ports-Reference first
    environment:
      BAR_ADMIN_PASSWORD: ${admin_password}
    volumes:
      - ./data:/var/lib/bar
EOF

    mkdir -p "${dir}/data"
    compose_in_dir "$dir" up -d

    show_access_info "Bar" \
        "URL:      http://localhost:8086" \
        "User:     admin" \
        "Password: ${admin_password}"
    save_credentials "bar" \
        "URL: http://localhost:8086" "Username: admin" "Password: ${admin_password}"
    log_message success "Bar deployed"
}

Tool that clones an upstream repo

deploy_baz() {
    local dir
    dir=$(tool_dir "baz")
    log_message step "Deploying Baz..."
    git clone --depth 1 https://github.com/org/baz.git "$dir"
    [[ -f "${dir}/template.env" ]] && cp "${dir}/template.env" "${dir}/.env"
    compose_in_dir "$dir" up -d
    show_access_info "Baz" "URL: http://localhost:9000"
    log_message success "Baz deployed"
}

3. Register it

One line in lib/core.sh, next to the existing entries:

register_tool "foo" "integration" "cli" "One-liner shown in the menu"

The menu, dashboard, medusa deploy foo and medusa list integration all pick it up automatically through the registry and the deploy_* dispatcher.

4. (Optional) Add a guided sub-menu

For CLI tools that benefit from a menu (like yara, nmap, trivy), add run_<tool> in lib/run_cli.sh. dispatch_run resolves it the same way dispatch_deploy resolves the deployer, no extra registration.

run_foo() {
    if ! command_exists foo; then
        log_message error "foo is not installed — use the Install option"
        wait_enter; return
    fi
    while true; do
        _run_menu "FOO" "Quick scan" "Full scan" "Generate report"
        [[ "${_run_choice,,}" == "b" ]] && return
        case "$_run_choice" in
            1) local t; t=$(prompt_value "Target" "127.0.0.1"); foo --quick "$t" ;;
            *) log_message error "Invalid choice"; sleep 1; continue ;;
        esac
        wait_enter
    done
}

Do / Don't

Don't Do
cd "$dir" && docker compose up -d compose_in_dir "$dir" up -d
image: foo:latest pin a real version tag
echo -e "${RED}ERROR..." log_message error "..."
Hardcode a password gen_password 16 + save_credentials
Skip mark_cli_installed always call it after a CLI install
docker compose up (no -d) always -d, or the menu loop blocks
Reuse a port already taken check Ports-Reference first
read -p for a defaulted value prompt_value "Label" "default"

Checklist before the PR

bash -n medusa.sh lib/*.sh
shellcheck medusa.sh lib/*.sh
./medusa.sh list <your_category>     # your tool appears
./medusa.sh deploy <your_tool>       # it actually works

Then update the relevant tool catalog page and Ports-Reference so the next contributor sees it.


Next: Architecture · Contributing

Clone this wiki locally