Discovery and Launch
This notebook demonstrates how to find running MITK Workbench instances and start new ones programmatically.
You will learn how to:
Discover running Workbench instances with
mw.discover()Connect to a discovered instance
Launch a new Workbench with
mw.launch()Work with multiple Workbench instances
Shut down a launched Workbench
Prerequisites:
For discovery: at least one running MITK Workbench with the REST API enabled
For launch: the
MITK_WORKBENCHenvironment variable pointing to the Workbench executable, or pass the path explicitly
1. Discover running instances
mw.discover() probes localhost ports 8080-8099 (by default) for running MITK Workbench REST servers. Probes run concurrently, so scanning 20 ports takes about as long as a single probe.
Each found instance is returned as a ready-to-use Workbench handle.
[1]:
import mitk_workbench_remote as mw
instances = mw.discover()
print(f"Found {len(instances)} running Workbench instance(s):\n")
for wb in instances:
info = wb.info
print(f" {wb.url} — {info.name} (MITK {info.mitk_version})")
Found 1 running Workbench instance(s):
http://localhost:8080 — MITK Workbench REST API (MITK 2026.06.00)
2. Use a discovered instance
The returned Workbench handles work exactly like those from mw.connect(). Pick one and use it.
[2]:
import numpy as np
if instances:
wb = instances[0]
node = wb.show(
np.random.default_rng(42).random((32, 32, 32), dtype=np.float32),
name="Discovery Demo",
)
print(f"Showed data in {wb.url}")
node.remove()
else:
print("No instances found — start a Workbench and re-run this cell.")
Showed data in http://localhost:8080
3. Connecting to an auth-enabled instance
A Workbench can be configured to require authentication: in the REST API preferences, set requireAuth=true and a non-empty apiToken. Every request then needs an Authorization: Bearer <token> header, which connect() adds when you pass token:
secured = mw.connect("http://localhost:8080", token="your-api-token")
print(secured.info.name)
launch() (section 5) does this automatically: it generates a random token and wires it into the returned handle. You only need to pass a token yourself when connecting to an already-running instance that was secured manually.
Caveat for ``discover()``: discovery probes /health, which is exempt from authentication, so auth-enabled instances are still found. But the returned handles carry no token, and discovery cannot tell whether an instance requires auth (the server does not advertise it). The first non-exempt call against a secured instance therefore raises AuthenticationError. If you know an instance is secured, reconnect with the token:
secured = mw.connect(wb.url, token="your-api-token")
4. Custom port range
Pass a custom port range if your Workbench is on a non-default port.
[3]:
# Scan a wider range
found = mw.discover(ports=range(8080, 8200), timeout=1.0)
print(f"Found {len(found)} instance(s) in port range 8080-8199")
Found 1 instance(s) in port range 8080-8199
5. Launch a new Workbench
mw.launch() starts a new MITK Workbench process with the REST API enabled. It waits for the server to become healthy, then returns a connected Workbench handle.
The executable is resolved from:
The
executableargument (if given)The
MITK_WORKBENCHenvironment variable
A secure random API token is generated automatically and passed to the process through the MITK_REST_API_TOKEN environment variable, so it is never written to disk while requireAuth still enforces it. The port is auto-selected from the 8080-8099 range unless specified.
MITK Workbench is single-instance. If a Workbench is already running, starting the executable again hands off to that instance and exits without bringing up a REST server on the new port. launch() detects this and raises a clear error telling you to connect to the running instance instead (sections 1-2). Pass new_instance=True to force a separate, isolated instance anyway (next cell).
[4]:
import os
import mitk_workbench_remote as mw
# Point MITK_WORKBENCH at a Workbench build whose REST API is available.
# Adjust this path to your own installation.
os.environ["MITK_WORKBENCH"] = (
r"YOUR_MITK_INSTALL_PATHD/MitkWorkbench.bat"
)
try:
wb_new = mw.launch(timeout=30)
print(f"Launched at {wb_new.url} (MITK {wb_new.info.mitk_version})")
print(f" Managed process: {wb_new.is_launched_remotely}")
except mw.errors.MitkError as e:
# Most common cause: a Workbench is already running (single-instance), or
# MITK_WORKBENCH is unset / points at a build without the REST API.
wb_new = None
print(f"Could not launch: {e}")
print("Tip: connect to a running instance with mw.discover() / mw.connect(),")
print("or pass new_instance=True to force a separate instance.")
except FileNotFoundError as e:
wb_new = None
print(f"Executable not found: {e}")
Launched at http://localhost:8080 (MITK 2026.06.00)
Managed process: True
Forcing a second, isolated instance
When a Workbench is already open and you want a separate one under REST control, pass new_instance=True:
wb_extra = mw.launch(new_instance=True)
The forced instance runs from a throwaway storage directory (MITK does not remove it afterwards) and, like every launched instance, receives its API token through the environment rather than on disk. When nothing is running, new_instance has no effect — an ordinary launch() already gives you a fresh instance.
6. Shutdown
wb.shutdown() terminates a Workbench that was started with mw.launch(). It also closes the underlying transport session.
Only instances started by launch() can be shut down — calling shutdown() on a connect()-ed handle raises MitkError. Use wb.is_launched_remotely to check.
[5]:
if wb_new is not None:
print(f"Shutting down {wb_new.url} ...")
wb_new.shutdown()
print("Done.")
else:
print("No launched instance to shut down.")
Shutting down http://localhost:8080 ...
Done.