Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Build, manipulate, execute, validate, and version-control Jupyter notebooks programmatically. Use when working with .ipynb files, creating notebooks from code, running parameterised analyses, diffing/merging notebooks in git, stripping outputs, or converting notebooks to other formats. Triggers on: jupyter, notebook, ipynb, nbformat, nbconvert, nbclient, papermill, nbdime, cell, kernel, execute notebook, parameterise, notebook diff, notebook merge.
.claude/skills/marcinmiklitz-jupyter-notebooks/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -11% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -31% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 22% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 53% | 0% |
Programmatic notebook operations from CLI only (no Jupyter UI):
Python requirement: 3.9+.
Scripts require these Python packages:
nbformat, nbclient, nbconvert, nbdimepapermill, nbstripoutEach script declares its own dependencies via PEP 723 inline metadata (the # /// script block at the top of each file). Read this block to determine exactly which packages a script needs.
Run the preflight check to verify environment readiness:
bashpython scripts/nb_preflight.py --mode auto
This script has no dependencies (stdlib only). It supports --mode auto|python|uv:
auto (default): succeed if either Python-mode or uv-mode is ready,python: check interpreter package availability directly,uv: verify uv run readiness by smoke-testing all script --help entrypoints.It emits a JSON report to stdout with ok, ok_python, ok_uv, ok_execute, and mode-specific details.
If packages are missing:
pyproject.toml, requirements.txt, Pipfile, uv.lock, poetry.lock, or similar).nb_preflight.py to confirm.Do not skip or abandon a script because its dependencies are not currently installed. Resolve them first.
Run scripts with whatever Python interpreter the project environment provides:
bashpython scripts/<tool>.py [args]
If the project uses a tool that handles PEP 723 inline metadata automatically (e.g. uv run), that works too — the metadata block in each script is compatible.
nb_execute.py) requires a Jupyter kernel (typically ipykernel).scripts/nb_create.py: Create notebook from blank/template/script; inject script as one cell into existing notebook.scripts/nb_cells.py: Cell CRUD, reorder, metadata/tags, bulk ops, regex search.scripts/nb_execute.py: Execute with nbclient (default), selective range execution, or papermill mode.scripts/nb_validate.py: Schema validation + operational lint checks for CI/pre-commit.scripts/nb_convert.py: Convert notebook to html/pdf/latex/script/markdown/rst/slides.scripts/nb_metadata.py: Notebook/cell metadata and tag management.scripts/nb_outputs.py: Output listing, size checks, stripping, image extraction, clear execution counts.scripts/nb_diff.py: nbdime-backed diff (text/json) and three-way merge.scripts/nb_create.py.scripts/nb_cells.py; details in references/cell-operations.md.scripts/nb_execute.py; decision guidance in references/execution-guide.md.scripts/nb_execute.py --papermill; patterns in references/papermill-patterns.md.scripts/nb_validate.py; rules in references/validation-and-linting.md.scripts/nb_convert.py.scripts/nb_metadata.py; schema map in references/metadata-reference.md.scripts/nb_outputs.py; guidance in references/output-handling.md.scripts/nb_diff.py; setup in references/versioning-guide.md.references/error-handling.md.nb_create.pynb_cells.pynb_execute.pynb_validate.pynb_convert.pynb_metadata.pynb_outputs.pynb_diff.pyCreate from template:
bashpython scripts/nb_create.py --template data-analysis --output notebooks/0.1-mmk-initial-eda.ipynb
Add a code cell:
bashpython scripts/nb_cells.py --input notebooks/0.1-mmk-initial-eda.ipynb add --cell-type code --source "print('hello')"
Execute selective range (cornerstone pattern):
bashpython scripts/nb_execute.py --input notebooks/0.1-mmk-initial-eda.ipynb --start-index 3 --end-index 7
Validate for CI:
bashpython scripts/nb_validate.py --input notebooks/0.1-mmk-initial-eda.ipynb --forbid-outputs
Convert to markdown:
bashpython scripts/nb_convert.py --input notebooks/0.1-mmk-initial-eda.ipynb --to markdown --output reports/eda.md
Scripts follow a consistent contract:
0 success, 1 error.nb_validate.py: 0 no issues, 1 issues found, 2 runtime/tool failure.<step>-<owner>-<description>.ipynbnbstripout + nbdime together for repository hygiene and readable diffs..gitattributes is provided in assets/.gitattributes.example.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 13,065 | 1,524 | -88% | 1 | 1 | 0% | 2,019 | 1,793 | -11% | 0 | 0 | — |
case-02 | fail→fail | 11,905 | 5,165 | -57% | 1 | 1 | 0% | 2,808 | 1,904 | -32% | 0 | 0 | — |
case-03 | fail→fail | 18,590 | 5,017 | -73% | 1 | 1 | 0% | 4,050 | 1,843 | -54% | 0 | 0 | — |
case-04 | fail→pass | 13,949 | 2,176 | -84% | 1 | 1 | 0% | 2,870 | 1,986 | -31% | 0 | 0 | — |
case-05 | fail→pass | 7,423 | 3,108 | -58% | 1 | 1 | 0% | 1,691 | 2,056 | +22% | 0 | 0 | — |
case-06 | fail→fail | 6,192 | 5,012 | -19% | 1 | 1 | 0% | 1,307 | 1,901 | +45% | 0 | 0 | — |
case-07 | fail→pass | 7,825 | 3,096 | -60% | 1 | 1 | 0% | 1,527 | 2,166 | +42% | 0 | 0 | — |
case-08 | fail→pass | 6,229 | 2,520 | -60% | 1 | 1 | 0% | 1,313 | 2,005 | +53% | 0 | 0 | — |
case-09 | fail→pass | 5,818 | 1,845 | -68% | 1 | 1 | 0% | 1,072 | 1,880 | +75% | 0 | 0 | — |
case-10 | fail→pass | 13,709 | 3,102 | -77% | 1 | 1 | 0% | 2,617 | 1,974 | -25% | 0 | 0 | — |
case-11 | fail→pass | 7,508 | 2,740 | -64% | 1 | 1 | 0% | 1,552 | 2,090 | +35% | 0 | 0 | — |
case-12 | pass→pass | 4,884 | 3,190 | -35% | 1 | 1 | 0% | 952 | 2,141 | +125% | 0 | 0 | — |
case-13 | fail→pass | 21,587 | 1,801 | -92% | 1 | 1 | 0% | 1,499 | 1,850 | +23% | 0 | 0 | — |
case-14 | pass→pass | 4,808 | 2,713 | -44% | 1 | 1 | 0% | 826 | 1,994 | +141% | 0 | 0 | — |
case-15 | fail→pass | 6,289 | 2,847 | -55% | 1 | 1 | 0% | 1,364 | 2,057 | +51% | 0 | 0 | — |
case-16 | fail→pass | 8,299 | 2,518 | -70% | 1 | 1 | 0% | 1,732 | 1,898 | +10% | 0 | 0 | — |
case-17 | fail→pass | 8,106 | 3,078 | -62% | 1 | 1 | 0% | 1,599 | 2,141 | +34% | 0 | 0 | — |
case-18 | pass→pass | 8,382 | 3,805 | -55% | 1 | 1 | 0% | 1,444 | 2,341 | +62% | 0 | 0 | — |
case-19 | pass→pass | 4,705 | 1,117 | -76% | 1 | 1 | 0% | 813 | 1,707 | +110% | 0 | 0 | — |
case-20 | fail→pass | 5,049 | 4,656 | -8% | 1 | 1 | 0% | 1,013 | 2,429 | +140% | 0 | 0 | — |
case-21 | pass→pass | 10,768 | 9,483 | -12% | 1 | 1 | 0% | 2,350 | 3,591 | +53% | 0 | 0 | — |
case-22 | pass→pass | 11,655 | 9,004 | -23% | 1 | 1 | 0% | 2,482 | 3,424 | +38% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 18 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +59 percentage points is the difference between those two pass rates over the 18 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.