Toolbox App Help

Plugin support for the Toolbox App

This tutorial guides you from a clean Gradle project to a running Toolbox App plugin.

Prerequisites

Before you start developing a plugin, ensure that the following requirements are met:

  • The latest version of the Toolbox App is downloaded.

    For more information, refer to Toolbox builds.

  • JDK version 21 is required on the host machine to be able to start the Toolbox CLI.

  • Kotlin

  • You are authenticated in the Toolbox App with your personal account.

Sample plugin

You can use a small bootstrap project as an example.

Gradle setup (Kotlin DSL)

Currently, the plugin SDK consists of an API JAR file, and a special nightly build of the Toolbox App with the Remote Development integration enabled.

To begin developing a plugin, we recommend creating a Gradle-based project.

Obtain plugin SDK

  • Add the following code to your build.gradle.kts:

    repositories { maven("https://packages.jetbrains.team/maven/p/tbx/toolbox-api") } dependencies { // Use specific versions that are compatible with your Toolbox App build compileOnly("com.jetbrains.toolbox:core-api:1.XX.XXXXX") compileOnly("com.jetbrains.toolbox:ui-api:1.XX.XXXXX") compileOnly("com.jetbrains.toolbox:remote-dev-api:1.XX.XXXXX") compileOnly("com.jetbrains.toolbox:localization-api:1.XX.XXXXX") }

    This will add the required dependencies.

Declare entry point (ServiceLoader)

Create a file in your plugin JAR at META-INF/services/com.jetbrains.toolbox.api.remoteDev.RemoteDevExtension:

com.example.toolbox.MyRemoteDevExtension

In Gradle, you can create such a file in the resources directory. The com.example.toolbox.MyRemoteDevExtension class must have a public no-arg constructor and implement the RemoteDevExtension interface.

You can read more about service loading in the Java documentation.

For discovery and loading details, the Toolbox App uses ServiceLoader to find RemoteDevExtension in your jars and validates the extension.json file before loading (see the internal flow). The external plugin discovery and loading sequence uses extension.json, constructs a classloader from your JAR files, then calls ServiceLoader.load(RemoteDevExtension, pluginClassLoader).

Create extension.json

Place it next to your jars in the plugin folder. See 06-Schemas-and-Extension.md for fields. Check the minimal example:

{ "id": "com.example.toolbox.myplugin", "version": "1.0.0", "meta": { "readableName": "My Plugin", "description": "Remote Dev integration", "vendor": "Example Inc.", "url": "https://example.com/myplugin" }, "apiVersion": "1.6.0" }

Minimal implementation

class MyRemoteDevExtension : RemoteDevExtension { override fun createRemoteProviderPluginInstance(serviceLocator: ServiceLocator): RemoteProvider = MyRemoteProvider(serviceLocator) } class MyRemoteProvider( private val services: ServiceLocator ) : RemoteProvider("My Provider") { override val canCreateNewEnvironments = true override val isSingleEnvironment = false private val _envs = MutableStateFlow<LoadableState<List<RemoteProviderEnvironment>>>( LoadableState.Ready(emptyList()) ) override val environments: Flow<LoadableState<List<RemoteProviderEnvironment>>> = _envs override fun setVisible(visibilityState: ProviderVisibilityState) { /* throttle background work if not visible */ } override suspend fun handleUri(uri: URI) { /* deep links if needed */ } }

A simple SSH environment

class SshDemoEnvironment(id: String) : RemoteProviderEnvironment(id) { override val nameFlow = MutableStateFlow("Demo host") override val state = MutableStateFlow<RemoteEnvironmentState>(StandardRemoteEnvironmentState.Disconnected) override val description = MutableStateFlow(EnvironmentDescription("Demo host")) override suspend fun getContentsView(): EnvironmentContentsView = SshEnvironmentContentsView { object : SshConnectionInfo { override val host = "host.example.com" override val port = 22 override val userName = "ubuntu" } } override fun setVisible(visibilityState: EnvironmentVisibilityState) { /* load/cache */ } }

Add instances of SshDemoEnvironment to your provider’s environments flow.

Development layout

Place your plugin under the Toolbox App plugin folder for development:

~/Library/Caches/JetBrains/Toolbox/plugins/<plugin-id>

~/.local/share/JetBrains/Toolbox/plugins/<plugin-id>

%LocalAppData%/JetBrains/Toolbox/cache/plugins/<plugin-id>

For more information, see a small bootstrap project as an example.

It is also possible to use the jetbrains://gateway/installUnsigned?file=/path/to/directory URL to install the plugin. Note that this link works only in developer builds.

The content is as follows:

  • Your plugin JAR(s)

  • extension.json

  • META-INF/services/com.jetbrains.toolbox.api.remoteDev.RemoteDevExtension inside the JAR

  • Optional icon.svg

Run and iterate

  1. Start the Toolbox App.

  2. Go to Manage providers and select your provider.

  3. Use 07-Debugging-and-Tools.md to attach a debugger when needed.

11 September 2025