xtralab agent skills
Agent skills that teach a coding agent how to work with JupyterLab and xtralab. There are four:
- open starts xtralab in a folder with
uvx xtralab openand opens it in the browser. From a Claude Code session in a terminal,/xtralab:open path/to/worktreeopens that worktree in a browser tab while the session continues. - stop stops the server of a folder with
uvx xtralab stop, so the user does not need to know its port. It also lists the running xtralab servers and stops all of them. - customize-jupyterlab turns plain-English requests like "hide the status bar", "change the theme", "add a language server", or "rearrange the activity bar" into the right config-file edits.
- guided-code-walkthrough drives the running app over xtralab's MCP command bridge: open files, jump to and highlight specific lines, and build a read-only Walkthrough panel of prose, snippets, diagrams, and clickable code links beside the editor, so the agent can show the user something at their own pace instead of only describing it in chat.
All four are built on the Agent Skills open standard so the same files work in Claude Code, Codex CLI, Gemini CLI, GitHub Copilot, Cursor, Goose, OpenCode, and any other skills-compatible client.
This folder is also an agent plugin named xtralab. The plugin installs the four skills and registers the jupyter MCP server, so the agent can drive the running app with no mcp add command.
What's in here
agent-skill/
├── .claude-plugin/
│ └── plugin.json # Claude Code plugin manifest
├── plugin.json # Agent Plugins manifest (Codex, Copilot CLI)
├── mcp.json # the jupyter MCP server, shared by the two manifests
└── skills/
├── open/
│ └── SKILL.md # start xtralab in a folder and open the browser
├── stop/
│ └── SKILL.md # stop the xtralab server of a folder
├── customize-jupyterlab/
│ ├── SKILL.md # configure JupyterLab from plain English
│ └── references/
│ ├── config-paths.md # where configs live, decision tree
│ ├── recipes.md # cookbook of common requests
│ ├── known-plugin-ids.md # commonly-toggled plugin IDs
│ └── adhoc-extensions.md # ship a labextension without a build
└── guided-code-walkthrough/
├── SKILL.md # drive the live app to walk through code
└── references/
├── commands.md # curated MCP command catalog
├── recipes.md # open/highlight/visualize sequences
└── rich-display.md # charts and plots via the kernel
Install
The xtralab repo is its own one-plugin marketplace (via .claude-plugin/marketplace.json at the repo root). For agents with no plugin support, copy or symlink the skill directory into ~/.agents/skills/.
Claude Code (two commands)
claude plugin marketplace add jtpio/xtralab
claude plugin install xtralab@xtralab
The first command registers this repo as a marketplace; the second installs the xtralab plugin from it. Inside Claude Code, the same commands are /plugin marketplace add jtpio/xtralab and /plugin install xtralab@xtralab. Updates land via claude plugin marketplace update xtralab.
The plugin starts the MCP proxy with uvx --from jupyter-server-mcp jupyter-server-mcp-proxy, so uv must be installed. The proxy connects to the xtralab server whose folder contains the folder of the session, and to no other server. See Connect agents with MCP.
Codex CLI and GitHub Copilot CLI (plugin)
The plugin also follows the Agent Plugins format (plugin.json and mcp.json), which Codex CLI and GitHub Copilot CLI read:
codex plugin marketplace add jtpio/xtralab
codex plugin add xtralab@xtralab
copilot plugin marketplace add jtpio/xtralab
copilot plugin install xtralab@xtralab
These two agents start the MCP proxy in the plugin folder, not in the folder of the session, and Codex does not pass the environment of the terminal to it. The proxy finds a server only from a folder inside the project, so the MCP server of the plugin has limits that Claude Code does not have:
| xtralab runs as | Claude Code | GitHub Copilot CLI | Codex CLI |
|---|---|---|---|
| Desktop app (xtralab terminal) | Works | Works | Not found |
| Browser tab | Works | Not found | Not found |
In the desktop app, Copilot gets the URL of the server from the environment of the xtralab terminal. In a browser tab, JUPYTER_SERVER_MCP_URL=<url> copilot does the same; xtralab list prints the URL. When the plugin cannot find the server, register the proxy with the mcp add command of the agent instead: see Connect agents with MCP.
Claude Code (no install, one command — for testing)
git clone https://github.com/jtpio/xtralab.git
claude --plugin-dir ./xtralab/agent-skill
Loads the plugin for this session only. Good for kicking the tires.
Codex CLI, Gemini CLI, Copilot, Cursor, Goose, OpenCode, anything else
Each skill is plain SKILL.md. Drop them into the cross-agent skills directory:
git clone --depth=1 https://github.com/jtpio/xtralab.git /tmp/xtralab
mkdir -p ~/.agents/skills
cp -r /tmp/xtralab/agent-skill/skills/* ~/.agents/skills/
Or for live updates from a working checkout:
mkdir -p ~/.agents/skills
ln -s "$(pwd)/agent-skill/skills/open" ~/.agents/skills/open
ln -s "$(pwd)/agent-skill/skills/stop" ~/.agents/skills/stop
ln -s "$(pwd)/agent-skill/skills/customize-jupyterlab" ~/.agents/skills/customize-jupyterlab
ln -s "$(pwd)/agent-skill/skills/guided-code-walkthrough" ~/.agents/skills/guided-code-walkthrough
Agent-specific paths if ~/.agents/skills/ isn't on the search list:
| Agent | Path it also scans |
|---|---|
| Claude Code | ~/.claude/skills/<name>/ |
| Codex CLI | ~/.codex/skills/<name>/, repo .agents/skills/<name>/ |
| Gemini CLI | repo .agents/skills/<name>/ |
| GitHub Copilot (VS Code / Visual Studio) | per the Agent Skills docs |
| Cursor | manual placement; see docs |
Project-local (xtralab developers)
To pick the skill up automatically inside the xtralab repo itself:
mkdir -p .agents/skills
ln -s ../../agent-skill/skills/open .agents/skills/open
ln -s ../../agent-skill/skills/stop .agents/skills/stop
ln -s ../../agent-skill/skills/customize-jupyterlab .agents/skills/customize-jupyterlab
ln -s ../../agent-skill/skills/guided-code-walkthrough .agents/skills/guided-code-walkthrough
What the skills know
open. After install, /xtralab:open [folder] (or a request such as "open xtralab in this worktree") runs uvx xtralab open <folder>, which:
- Starts an xtralab server for the folder, detached from the agent session, so the server outlives it. The first run downloads xtralab into the uv cache; later runs reuse that environment.
uvx xtralab@latest open <folder>updates xtralab first. - Reuses the server that already serves the folder instead of starting a second one.
- Waits for the server, then prints its URL with the folder, the log file, and the
uvx xtralab stop <port>command. The server opens the browser tab itself. - Keeps settings in the xtralab config folder (the same one as the desktop app), not in
~/.jupyter.
Try it after install: /xtralab:open . in any project, or "start xtralab in the worktree you just created".
stop. /xtralab:stop [folder] (or "stop xtralab for this worktree") runs uvx xtralab stop <folder>, which finds the server by its root folder and shuts it down. A port works too: uvx xtralab stop 8888. Other servers keep running. "Which xtralab servers are running?" runs uvx xtralab list, and "stop all xtralab servers" runs uvx xtralab stop --all. The commands cover xtralab servers only.
customize-jupyterlab. After install, the agent will:
- Run
jupyter --pathsbefore touching anything, to find the right writable config directory. - Never edit files inside a venv / installed package.
- Pick the right config surface (
page_config.d/,default_setting_overrides.d/,jupyter_server_config.d/, orlab/user-settings/) for the request type. - Write a minimal JSON snippet at
99-*.jsonrather than overwriting shipped files. - Tell the user to restart JupyterLab (or quit-and-relaunch the xtralab desktop app) to pick up changes.
- Map xtralab-specific knobs (
xtralab:launcher,xtralab:sidebar) to their dedicated settings instead of blunt plugin-disable.
Try it after install: open a project and ask "change my JupyterLab theme to dark" or "hide the status bar by default".
guided-code-walkthrough. After install, the agent will:
- Drive the running app through the
jupyterMCP server, using onlylist_all_commandsandexecute_command(no edits on disk except notebooks it authors). - Reach for a curated subset of the 480+ frontend commands rather than scanning them all, so it acts precisely.
- Build a read-only Walkthrough panel in the side area with
xtralab:walkthrough: each step carries prose, an optional embedded visual, and an optional code reference that opens the file full-width (no editor split) and highlights it. The tour persists beside the code so the user reads at their own pace instead of chasing the chat. - Open files and paint a persistent line-range highlight with
xtralab:highlight-lines(clearing withxtralab:clear-highlights). - Render Markdown (incl. Mermaid), Vega-Lite charts, HTML, or images into a side panel with
xtralab:show, with no notebook file and no kernel, and fall back to running a notebook only when output must be computed by code. - Check that a frontend is connected before starting.
Try it after install: open a project and ask "walk me through how this module fits together" or "open src/index.ts and highlight the plugin list".
This skill assumes the jupyter MCP server is registered with the agent and a JupyterLab tab is open. The plugin registers the server; for the other install methods, see Connect agents with MCP.
Distribution
The skill is open-standard SKILL.md, so any of these channels work:
| Channel | How | Audience |
|---|---|---|
| Agent Skills marketplace (skills.sh) | submit each skill directory as a public skill; users install with npx skills add | any skills-compatible agent |
| Claude Code community marketplace | submit this directory as a plugin via claude.ai/settings/plugins/submit | Claude Code users |
| Codex plugin marketplace | plugin.json follows the Agent Plugins format that Codex CLI reads; add the repo with codex plugin marketplace add | Codex CLI users |
| As part of xtralab pip release | exclude from the published wheel (skill is not Python code); document the manual install path in xtralab's README | xtralab installers who also use an agent |
As a separate Git repo (xtralab-skills) | move this directory out into its own repo for cleaner versioning | all of the above |
A reasonable order of operations:
- Iterate on the SKILL.md content here, where it's adjacent to the code it describes.
- Submit to the Agent Skills marketplace first (one submission covers every cross-agent client).
- If Claude Code's namespaced plugin install (
/plugin install ...) becomes the dominant install path for xtralab users, add a marketplace listing inclaude-plugins-community. - Consider splitting into its own repo once the skill stabilizes — the plugin manifest already declares
version, so independent releases just need a separate tag stream.
Notes on content
- The plugin version is in
plugin.jsonand in.claude-plugin/plugin.json. Keep the two values the same. SKILL.mdis intentionally short. Detail lives inreferences/*.mdso the agent only loads what it needs.- Recipes prefer xtralab-native settings (
xtralab:sidebar,xtralab:launcher) when they exist, and fall back to upstream JupyterLab plugin IDs otherwise. - The customize-jupyterlab recipes match xtralab's shipped defaults: if you change
page_config.d/00-xtralab.jsonordefault_setting_overrides.d/00-xtralab.jsonin this repo, updaterecipes.mdandknown-plugin-ids.mdin the same change. - The guided-code-walkthrough catalog matches the commands xtralab and JupyterLab register today, including the
xtralab:walkthrough(src/walkthrough/),xtralab:highlight-lines/xtralab:clear-highlights(src/highlight/), andxtralab:show(src/showOutput/) commands this repo contributes. If you add, rename, or change a walkthrough command, updatecommands.mdin the same change.