Skip to content

Instantly share code, notes, and snippets.

@lassoan
Last active June 23, 2026 20:54
Show Gist options
  • Select an option

  • Save lassoan/b2e83a928c8d59a65b3ecd7cff527d4e to your computer and use it in GitHub Desktop.

Select an option

Save lassoan/b2e83a928c8d59a65b3ecd7cff527d4e to your computer and use it in GitHub Desktop.
AGENTS.md for Slicer module development

Helpful instructions for AI agents for 3D Slicer extension development

Overall workflow

Never ask the user to copy-paste code. Instead, use Slicer web server that allows execution of Python code via a web API.

Give these instructions to the user: Go to Web Server module, enable "Slicer API exec" in Advanced section, and click "Start server".

After this, you can connect to Slicer and run Python commands as it is described here: https://slicer.readthedocs.io/en/latest/user_guide/modules/webserver.html#remote-control

Default endpoint: http://localhost:2016/slicer/exec (POST, plain-text Python body). Return values go in __execResult dict → JSON response.

After modifying a module, always reload it in Slicer.

Generating modules

After you generated a module, load the module without restarting Slicer and do basic testing. Then ask the user to test.

You can find useful code snippets in the Slicer Script Repository: https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html

Loading a module without restarting Slicer

curl -s -X POST http://localhost:2016/slicer/exec --data-binary "

import qt

modulePath = r'C:\path\to\MyModule\MyModule.py'   # absolute path to the .py file
searchPath = r'C:\path\to\MyModule'               # directory that contains it
moduleName = 'MyModule'                           # filename without .py extension

factory = slicer.app.moduleManager().factoryManager()

# Step 1 – Register the module file
factory.registerModule(qt.QFileInfo(modulePath))

# Step 2 – Persist the search path so the module loads automatically after restart
settings = slicer.app.revisionUserSettings()
rawSearchPaths = list(settings.value('Modules/AdditionalPaths') or [])
if searchPath not in rawSearchPaths:
    rawSearchPaths.append(searchPath)
    settings.setValue('Modules/AdditionalPaths',
                      slicer.app.toSlicerHomeRelativePaths(rawSearchPaths))

# Step 3 – Instantiate and load
factory.loadModules([moduleName])

# Step 4 – Switch to the module
slicer.util.selectModule(moduleName)

__execResult = {'registered': factory.isRegistered(moduleName)}
"

### Reload module after editing (no Slicer restart)

This is the same function the "Reload" button in Slicer's module panel calls (`ScriptedLoadableModuleWidget.onReload`):

```bash
curl -s -X POST http://localhost:2016/slicer/exec --data-binary "
slicer.util.reloadScriptedModule('LungVolume')
__execResult = {'reloaded': True}
"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment