Skip to main content

An opinionated JupyterLab meta-package that bundles a curated set of extensions, ships a path-first file browser, renders jupyterlab-git's text, notebook and image diffs with its own viewers, and applies a quieter default workspace configuration.

Project description

xtralab-logo

An opinionated JupyterLab meta-package for use with coding agents.

It bundles a curated set of JupyterLab extensions, a path-first file browser, rich git diffs for text, notebooks, and images, an agent launcher, and a quieter default workspace.

xtralab screenshot

Install

pip install xtralab

Usage

As a JupyterLab package

Once installed, start JupyterLab the usual way:

jupyter lab

As a desktop app

A standalone Electron build is also available, packaged as a DMG on macOS and an AppImage on Linux. Each tagged release ships installers on the releases page, and builds from main are uploaded as workflow artifacts on the Actions tab. See CONTRIBUTING.md for the desktop app architecture and local build instructions.

On macOS the build is not notarized yet (it has no Apple Developer ID), so Gatekeeper blocks it on first launch, and agent notifications fall back to osascript, appearing as "Script Editor". In the meantime you can self-sign it for free: this lets it launch and gives native notifications instead, branded as xtralab and clickable to jump to the terminal that fired them. Create a code-signing certificate once in Keychain Access (Certificate Assistant, Create a Certificate, with Identity Type "Self Signed Root" and Certificate Type "Code Signing") named xtralab-selfsign, then sign the app you copied out of the DMG:

codesign --force --deep --sign "xtralab-selfsign" --timestamp=none "/Applications/xtralab.app"
xattr -dr com.apple.quarantine "/Applications/xtralab.app"

macOS prompts once to let codesign use the key; choose Always Allow. None of this will be needed once the app ships with a Developer ID signature.

What's included

xtralab builds on ajlab, the agent-ready JupyterLab base. On top of it, xtralab pulls in JupyterLab 4.6+ with jupyterlab-git, jupyterlab-lsp, jupyterlab-quickopen, jupyterlab-search-replace, jupyterlab-vim, and a set of light and dark themes (jupyterlab-cursor-light, jupyterlab-cursor-dark, jupyterlab-day, jupyterlab-night). See pyproject.toml for the full list and pinned versions.

The bundled xtralab labextension then adds:

  • A path-first file browser in the left sidebar, with @pierre/trees file-type icons that also carry over to document tabs and the jupyterlab-git panel.
  • Rich git diffs in the jupyterlab-git panel, using @pierre/diffs for text and notebooks and a 2-up / swipe / onion-skin view for images.
  • An agent launcher with a prompt box, buttons for the agents installed on your machine (Claude, Codex, Antigravity, Copilot, Goose, OpenCode, Kiro, Mistral Vibe), a collapsible list of changed files, and an Open row for a terminal, notebook, console, or your terminal editor (Neovim or Vim).
  • A Terminals panel listing the running terminal sessions, each badged with the agent or editor detected inside it. Open terminal tabs in the main area carry the same icon.
  • Sidebar toggle buttons in the top bar for the left and right areas.

xtralab also ships a set of opinionated defaults: unused UI is hidden for a quieter workspace, the activity bar sits at the top, and autocompletion, continuous LSP hinting, code folding, and gitignore-aware quick open are on by default. See the bundled labconfig overrides for the full set.

Connecting agents to Jupyter (MCP)

xtralab runs a Model Context Protocol server inside JupyterLab, provided by jupyter-server-mcp. To let a coding agent drive JupyterLab through it, register the bundled jupyter-server-mcp-proxy console script with the agent:

claude mcp add jupyter -- jupyter-server-mcp-proxy
codex mcp add jupyter -- jupyter-server-mcp-proxy
copilot mcp add jupyter -- jupyter-server-mcp-proxy

Run this from a terminal inside xtralab, so the proxy inherits the server environment and discovers the running server automatically. No port is needed, and a single registration keeps working across restarts. The launcher also surfaces these commands with copy buttons, filtered to the agents you have installed.

See the jupyter-server-mcp README for other MCP clients.

Agent skill

xtralab ships an Agent Skills entry at agent-skill/ that teaches any coding agent how to customize JupyterLab from plain-English requests like "hide the status bar", "change the theme", or "add a language server". The same SKILL.md file works with Claude Code, Codex CLI, Gemini CLI, GitHub Copilot, and other tools that read the Agent Skills format.

For Claude Code, this repository doubles as a one-plugin marketplace. Inside a Claude Code session:

/plugin marketplace add jtpio/xtralab
/plugin install xtralab-skills@xtralab

For agents that read from ~/.agents/skills/, such as Codex CLI or Gemini CLI, clone and copy the skill directory:

git clone --depth=1 https://github.com/jtpio/xtralab.git /tmp/xtralab
mkdir -p ~/.agents/skills
cp -r /tmp/xtralab/agent-skill/skills/customize-jupyterlab ~/.agents/skills/

See agent-skill/README.md for additional install paths, the list of supported agents, and what the skill knows.

Language servers

xtralab ships jupyterlab-lsp with two language servers pre-registered:

  • Python, using ty, which is bundled and works out of the box.

  • TypeScript and JavaScript, using typescript-language-server, which you install yourself:

    npm install -g typescript-language-server typescript
    

    Restart JupyterLab afterwards to pick it up.

To enable another server (bash, yaml, json, pyright, and more), install its binary and drop a JSON spec into a jupyter_server_config.d/ directory. For pip install xtralab, run jupyter --paths to find one (typically ~/.jupyter/jupyter_server_config.d/). For the desktop app, use ~/Library/Application Support/xtralab/jupyter/config/jupyter_server_config.d/ on macOS or ~/.config/xtralab/jupyter/config/jupyter_server_config.d/ on Linux.

{
  "LanguageServerManager": {
    "language_servers": {
      "bash-language-server": {
        "version": 2,
        "argv": ["bash-language-server", "start"],
        "languages": ["bash", "sh"],
        "mime_types": ["text/x-sh", "application/x-sh"],
        "display_name": "bash-language-server"
      }
    }
  }
}

See the jupyterlab-lsp documentation for the full spec.

Customizing the launcher

Open Settings → Settings Editor → xtralab launcher to override, hide, or add launcher entries. Both lists below merge with xtralab's defaults by id.

Agents

Edit the agents array:

{
  "agents": [
    // Hide an agent
    { "id": "kiro", "enabled": false },

    // Override an agent's command (e.g. point Claude at a shell alias)
    { "id": "claude", "command": "cl", "requireAvailable": false },

    // Add a new agent; promptArgs: [] appends the prompt as a positional arg
    { "id": "aider", "label": "Aider", "command": "aider", "promptArgs": [] }
  ]
}

Fields: id (required), label, caption, command, promptArgs (how the prompt is spliced: [] for positional, ["--flag"] for flagged, null to opt out), iconSvg, rank, enabled, requireAvailable.

Editors

The Open section's terminal-editor tile (Neovim, falling back to Vim) is configured the same way through an editors array:

{
  "editors": [
    // Hide Neovim so the tile falls back to Vim (or disappears if Vim
    // isn't installed either)
    { "id": "nvim", "enabled": false },

    // Add Helix, preferred over the built-ins
    {
      "id": "helix",
      "label": "Helix",
      "command": "hx",
      "rank": -1,
      "iconSvg": "<svg>…</svg>"
    }
  ]
}

The launcher shows a single tile: the first editor, by rank, whose command is on PATH. Disable both built-ins (nvim, vim) to remove the tile entirely. Fields: id (required), label, caption, command, iconSvg, rank, enabled, requireAvailable.

Contributing

See CONTRIBUTING.md for the development setup, the Electron desktop app architecture, and the build pipeline.

License

BSD-3-Clause

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xtralab-0.10.0.tar.gz (2.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xtralab-0.10.0-py3-none-any.whl (2.3 MB view details)

Uploaded Python 3

File details

Details for the file xtralab-0.10.0.tar.gz.

File metadata

  • Download URL: xtralab-0.10.0.tar.gz
  • Upload date:
  • Size: 2.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for xtralab-0.10.0.tar.gz
Algorithm Hash digest
SHA256 ce02664878c1f76761d4d35e714ad42e476a1c7b216b86ed87b67477fef7c343
MD5 4ec3a5ee79495b23d590e6e348eb2f6c
BLAKE2b-256 3e1bb6ef3aa12ded77d94d800d0fa0b1f21118972df8eaafc3800ce5746bdfa0

See more details on using hashes here.

File details

Details for the file xtralab-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: xtralab-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for xtralab-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 497269ad49b5c821db7a70717bcf55da946f3f8aed3135e797fd3d84a6212705
MD5 babf98a0e021ceb402acaafab2bd8a92
BLAKE2b-256 1bcfdd575f93b0c332cfec78471de6aaeec65d6d2dc06de2694ca0d3f7db2400

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page