Skip to content

IDA Plugin Manager

The IDA Plugin Manager handles searching, installing, upgrading, and removing IDA plugins. It works with both IDAPython and native (C/C++) plugins.

Community plugins are indexed from public GitHub repositories and served through the Hex-Rays portal. Hex-Rays also publishes private plugins available to users with active IDA licenses. Browse available plugins at plugins.hex-rays.com.

hcli extension is an alias for hcli plugin, so hcli extension install hint-calls and hcli plugin install hint-calls do the same thing.

Development status

The plugin manager is complete, and we’re now in the process of packaging plugins. Documentation updates are ongoing, and minor adjustments are expected.

Quickstart

❯ hcli plugin search
current platform: macos-aarch64
current version: 9.2

 bookmark-hints    0.1.3             https://github.com/williballenthin/idawilli
 colorize-calls    0.1.3             https://github.com/williballenthin/idawilli
 extensible-hints  0.1.3             https://github.com/williballenthin/idawilli
 hint-calls        0.1.3             https://github.com/williballenthin/idawilli
 oplog             0.1.3  installed  https://github.com/williballenthin/idawilli
 tag-func          0.1.3             https://github.com/williballenthin/idawilli

❯ hcli plugin install hint-calls
Installed plugin: hint-calls==0.1.3

❯ hcli plugin status
 oplog                               0.1.3
 hint-calls                          0.1.3
 (incompatible) yarka                0.7.0  found at: $IDAPLUGINS/yarka/
 (incompatible) IDA Terminal Plugin  0.0.3  found at: $IDAPLUGINS/IDA Terminal Plugin/
 (incompatible) DelphiHelper         1.21   found at: $IDAPLUGINS/DelphiHelper/
 (incompatible) IPyIDA               2.2    found at: $IDAPLUGINS/IPyIDA/
 (legacy) foo.py                            found at: $IDAPLUGINS/foo.py

Incompatible plugins don't work with this version of HCLI.
They might be broken or outdated. Try using `hcli plugin lint /path/to/plugin`.

Legacy plugins are old, single-file plugins.
They aren't managed by HCLI. Try finding an updated version in the plugin repository.

HCLI installs the newest plugin version that supports your platform, your IDA version, and IDA's Python. When no version supports them, the install stops and gives the reason. Versions with the same reason are shown together:

❯ hcli plugin install ida-mcp@https://github.com/HexRaysSA/ida-mcp
Error: cannot resolve ida-mcp@https://github.com/hexrayssa/ida-mcp for macos-aarch64 IDA 9.0: ida-mcp 20260930.0.1 and 24 older versions do not support IDA 9.0

Coming Soon

We plan to provide an IDA-native GUI for listing, installing, upgrading, and removing plugins in a future release.

Python environment

Plugins that declare Python dependencies need a working Python environment. HCLI checks this before installing dependencies. If pip cannot install into IDA's Python, or the packages would not reach IDA, the install stops and points you to hcli ida python doctor for details. Setups that work but that we do not recommend, such as a global Python without a virtual environment, print a warning, and the install continues. See IDA's Python Environment for setup. When pip fails, HCLI shows one line from the pip output, for example pip could not build pminit. Set HCLI_DEBUG=1 to see all of the pip output. HCLI installs only the Python dependencies of the plugin that you install. It makes sure that their versions agree with the Python dependencies of the plugins that are already installed, but it does not install a dependency of those plugins that is missing.

If your Python setup works but does not match the recommended configuration, pass --no-python-environment-check to skip the check:

❯ hcli plugin --no-python-environment-check install <name>

Plugin repositories

HCLI fetches plugins from named repositories. Two are configured by default:

Name Description Authentication
community Community plugins indexed from public GitHub repositories none (anonymous)
hexrays Private plugins published by Hex-Rays required (hcli login)

The community repository is the default. A bare hcli plugin install <name> searches it. To install a private plugin from the hexrays repository, prefix the name:

❯ hcli plugin install hexrays/some-private-plugin

If you're not logged in, the hexrays repository returns a 401 and HCLI tells you to authenticate. Commands that look across all configured repositories, such as hcli plugin search, status, and upgrade, print a yellow warning on stderr for each repository they could not use, with the fix when there is one:

❯ hcli plugin status
 assist                           1.0.0-beta14  not found in repository
 capa                             9.4.0

Warning: Skipping plugins from "hexrays" repository: not logged in. Run 'hcli login' to include them.

If you don't use the hexrays repository, hcli plugin repo remove hexrays stops the warning.

Managing repositories

List, add, remove, or change the default repository:

❯ hcli plugin repo list
hexrays    https://hexrays.plugins.hex-rays.com/plugin-repository.json    reserved
community  https://community.plugins.hex-rays.com/plugin-repository.json  default reserved

❯ hcli plugin repo add my-team https://plugins.example.com/repo.json
added plugin repository 'my-team' -> https://plugins.example.com/repo.json

❯ hcli plugin repo set-default my-team
default plugin repository is now 'my-team'

❯ hcli plugin repo remove my-team
removed plugin repository 'my-team'

The community and hexrays names are reserved and always point to their Hex-Rays URLs. Custom repositories can be added, renamed, or removed freely.

For offline or air-gapped environments like FLARE-VM, you can point HCLI at a local plugin bundle instead of the online repositories. Pass --repo with a path to the bundle archive, or to the directory that extracting it gives, and search, install, and upgrade all resolve from the bundle without network access. pip installs Python dependencies only from the bundle.

❯ hcli plugin --repo ./malware-vm-tools.hcli-plugin-bundle.zip search
❯ hcli plugin --repo ./malware-vm-tools.hcli-plugin-bundle.zip install hint-calls

As a user of IDA...

You'll want to know the HCLI commands:

❯ hcli plugin search 
❯ hcli plugin search [keyword or plugin-name]
❯ hcli plugin install <plugin-name>
❯ hcli plugin install <repo>/<plugin-name>
❯ hcli plugin status
❯ hcli plugin upgrade <plugin-name>
❯ hcli plugin uninstall <plugin-name>
❯ hcli plugin repo list

Plugins are written to $IDAUSR/plugins, which is typically ~/.idapro/plugins on Unix-like systems, where IDA Pro will load them the next time the application is opened.

Plugin dependencies

A plugin can declare other plugins as dependencies in its ida-plugin.json, and so can each of its components. When you install or upgrade such a plugin, HCLI resolves the declared dependencies across all configured repositories and installs them as independent top-level plugins. Dependencies that themselves declare further dependencies are resolved recursively. HCLI selects the newest version of each plugin that supports your platform, IDA version, and IDA's Python version, and whose own required dependencies can also be resolved. Thus hcli plugin install foo can install an older version of foo when the newest version needs a dependency that is not available for your installation. If a required dependency cannot be resolved, the install stops with an error before it writes any files. The error shows the chain of plugins that led to the dependency and why each version was rejected. An optional dependency that cannot be resolved is skipped. When IDA's Python cannot be detected, HCLI skips only the versions that declare requiresPython. The output has one line for each dependency. An optional dependency that HCLI cannot resolve or install is shown as Optional dependency not installed, with a one-line reason. When the plugin installs, the last line starts with Success: and gives the number of dependencies that are not installed.

After the resolution, HCLI installs the plugin first, and then each dependency after the plugins that it requires. When a required dependency fails during its install, for example because of a download or pip error, HCLI removes the plugin again, but the dependencies that installed before the failure stay installed.

If a dependency is already installed and satisfies the version requirement, it is skipped. If the installed version is older than a pinned version, HCLI upgrades it. If the installed version is newer than a pin, HCLI keeps it and logs a warning. Because only one plugin of each name can be installed, HCLI selects a dependency on the name of an installed plugin only from the host of the installed plugin, and a dependency on that name with a different @host fails. A plugin with the same name and host in more than one configured repository is one plugin. When a bare dependency name matches plugins from different hosts, the install stops with an error; the declaring plugin must use the name@host format to disambiguate. HCLI checks this for the dependencies of every version that can install on your IDA installation, required and optional, and also for versions that it does not select. A dependency that an installed plugin satisfies is not checked.

hcli plugin upgrade foo uses the same rules, but only for versions of foo that are newer than the installed one. It installs the newest of them whose dependencies can be resolved. When none can be installed and the installed version matches the spec, it prints that foo is up to date, followed by newer versions cannot be installed here: and the reasons, and exits with success. When the spec excludes the installed version, for example foo==3.0 with 2.0 installed, and no matching version can be installed, the upgrade exits with a failure. An ambiguous dependency name in a newer version is an error, and the upgrade exits with a failure. When the repository has no newer version, HCLI does not check IDA's Python version.

On upgrade, HCLI installs any newly-added dependencies and tells you about any that were removed from the manifest (they stay installed so you can remove them yourself if no longer needed).

On uninstall, HCLI lists installed dependencies and asks whether to remove them:

❯ hcli plugin uninstall my-suite
Uninstalled plugin: my-suite
These plugins were listed as dependencies:
  dep-a    1.0.0
  dep-b    2.3.0
Remove them too? [y/N]

Pass --yes (-y) to confirm automatically in scripts. In non-interactive mode without --yes, dependencies are listed but not removed.

Plugin suites

Some plugins are distributed as a suite: a root plugin that bundles tightly-coupled sub-plugins called components. Components share the suite's lifecycle. When you install or remove a suite, all its components go with it.

hcli plugin status shows a count of components next to each suite. Use --show-components to expand the listing:

❯ hcli plugin status --show-components
 go-analysis-suite  2.0.0  (2 components)
   go-runtime-detector  1.0.0  (component)
   go-string-extractor  1.0.0  (component)

Components cannot be uninstalled individually. To remove a suite and all its components, uninstall the suite root:

❯ hcli plugin uninstall go-analysis-suite
go-analysis-suite manages these plugins:
  go-runtime-detector                1.0.0
  go-string-extractor                1.0.0
Uninstall all? [Y/n]

You can discover interesting plugins via:

HCLI supports installing plugins to be loaded by IDA 9.0 and newer.

Plugin repositories

HCLI ships with two built-in repositories (hexrays and community) that provide the public plugin index. You can add your own named repositories that point to a JSON index file, a local directory of plugin archives, or a plugin bundle zip or its extracted directory.

❯ hcli plugin repo list
❯ hcli plugin repo add <name> <url>
❯ hcli plugin repo remove <name>
❯ hcli plugin repo set-default <name>

Repository URLs use the https:// scheme for remote JSON indexes or file:// for local paths. HCLI infers the repository type from what the path points to: a zip file or a directory containing plugin-bundle.json becomes a bundle repository, another directory becomes a filesystem repository, and anything else is treated as a JSON index.

You can scope plugin references to a specific repository with a repo/ prefix (e.g., hcli plugin install myrepo/plugin-name). Unprefixed references resolve against the default repository.

Offline and air-gapped environments

Environments without internet access (for example, a FLARE-VM instance with host-only networking) can use a plugin bundle as their sole repository. A plugin bundle is a self-contained zip archive with plugins and their Python dependencies for specific platforms. See Plugin Bundles for the format.

To set this up, remove the default repositories (which require network access), add the bundle as a named repository, and set it as the default:

❯ hcli plugin repo remove hexrays
removed plugin repository 'hexrays'

❯ hcli plugin repo remove community
removed plugin repository 'community'

❯ hcli plugin repo add offline file:///path/to/plugin-bundle.zip
added plugin repository 'offline' -> file:///path/to/plugin-bundle.zip

❯ hcli plugin repo set-default offline
default plugin repository is now 'offline'

❯ hcli plugin search
current platform: windows-x86_64
current version: 9.4

 plugin1  1.0.0  ...

❯ hcli plugin install plugin1
Installed plugin: plugin1==1.0.0

Dependencies are installed from the bundle's embedded wheelhouse, so pip does not need network access.

To restore the default configuration later, re-add the built-in repositories with their canonical URLs:

❯ hcli plugin repo add hexrays https://hexrays.plugins.hex-rays.com/plugin-repository.json
❯ hcli plugin repo add community https://community.plugins.hex-rays.com/plugin-repository.json

Disambiguating plugin names

When two plugins share the same bare name in the repository (for example, different forks of the same project), HCLI cannot tell which one you mean from the name alone. The search, install, and upgrade commands will print the ambiguous candidates and ask you to qualify the reference with the plugin's repository URL:

❯ hcli plugin install ida-chat
Error: plugin name 'ida-chat' is ambiguous
Choose one of:
  ida-chat@https://github.com/HexRaysSA/ida-chat-plugin
  ida-chat@https://github.com/tanu360/ida-chat-plugin

You can pin the reference with name@repository-url, and optionally include a version spec:

❯ hcli plugin install ida-chat@https://github.com/HexRaysSA/ida-chat-plugin
❯ hcli plugin install ida-chat==1.0.0@https://github.com/HexRaysSA/ida-chat-plugin

Because plugins install into $IDAUSR/plugins/<name>, only one plugin with a given bare name can be installed at a time. If you need to switch to a different same-named plugin from another repository, uninstall the current one first. Similarly, upgrade will not change the source repository: once a plugin is installed, its repository is recorded in the local metadata and upgrades are anchored to it.

As a plugin author...

Hex-Rays wants to help you package and distribute plugins for IDA! Check out the following resources and don't hesitate to contact us for support:

Plugin authors can declare loose dependencies on other plugins via dependencies, or bundle tightly-coupled sub-plugins via components, in ida-plugin.json. See Plugin packaging and format for details on both fields.