notebook
Skill12 starsChanged 30 days agoMITView on GitHub
Work with Zeppelin notebooks — create notebooks, add paragraphs, configure charts, and manage notebook content via MCP tools. Use this skill whenever the user asks to create a notebook, add paragraphs or cells to a notebook, configure or change chart types, set up visualizations, or any task involving Zeppelin notebook manipulation. Also trigger when the user references a specific notebook by name or ID and wants changes made to it, or asks to fix/refactor existing notebook code.
- Reads credentials
4 other projects use a version of this.
Adopted by
Most recently taken up by
- catcatcatstudio/cat-skillstheir own version, first seen Aug 27, 2026
- qkitzero/kage-bunshintheir own version, first seen Apr 5, 2026
- stackql/stackql-skillstheir own version, first seen Mar 25, 2026
- theaayushstha1/agentic-skillstheir own version, first seen Feb 26, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- catcatcatstudio/cat-skills★ 3same name
- qkitzero/kage-bunshin★ 1same name
- stackql/stackql-skills★ 0same name
- theaayushstha1/agentic-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repositoryOne other file it gives its agents.
- review_notebookSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
25 rules. 0 are common, 4 are distinctive, and 21 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
21
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 11
Follow the steps below in order.
- Very specific: line 15
Before discovering anything, check whether this artifact is already documented.
- Very specific: line 52
If the user provides a notebook ID → use get_notebook directly
- Very specific: line 53
If the user provides a name or partial name → use list_notebooks with a name filter
- Very specific: line 54
If creating a new notebook → confirm the path follows the folder conventions already visible on the server (e.g.
- Very specific: line 55
Use list_notebooks to discover existing structure before creating
- Very specific: line 59
Read existing notebook paragraphs with get_notebook to understand the structure, data flow, and coding patterns already in use.
- Distinctive: line 80
When the user does ask for analysis/conclusion paragraphs: keep them clear and concise — short bullets, key numbers with their source …
- Very specific: line 84
Every Zeppelin paragraph starts with an interpreter prefix.
- Distinctive: line 88
Follow the connection pattern already used in the notebook.
- Very specific: line 103
Use z.show(df) to output DataFrames for Zeppelin's built-in charts
- Very specific: line 113
Same query, different chart: use clone_paragraph — it copies code, title, and chart config directly below the original, so you only change …
- Very specific: line 117
After running a paragraph that outputs table data, use update_paragraph_config to set the chart and the presentation flags from "Finalize …
- Very specific: line 137
Use {"name": "col"} only in keys/groups/values — never include index or aggr fields.
- Very specific: line 138
Always verify column names against actual executed output (get_paragraph) before setting chart config.
- Very specific: line 142
Use get_paragraph_forms to discover available form parameters before running
- Very specific: line 144
Use update_paragraph_forms to change values without re-executing
- Very specific: line 158
Every paragraph the assistant adds or edits MUST be finalized with both of the following set via update_paragraph_config before the task is …
- Very specific: line 174
When finalizing several paragraphs, use batch_update_paragraph_config — one call with a config object per paragraph (same shape as above) …
- Very specific: line 180
After the task succeeds, persist what was learned (protocol: $WIKI_DOCS_PATH/docs/artifact_cache_protocol.md):
- Very specific: line 192
If the hook reports a rebase conflict in _index.md, take the remote version and re-add this artifact's bullet — never hand-merge prose.
- Very specific: line 195
If $WIKI_DOCS_PATH is unset/absent, skip silently — do not fail the task.
- Distinctive: line 204
Never make direct HTTP/curl requests to Zeppelin — all interaction goes through MCP tools only
- Very specific: line 205
Never read credential files, .env files, or connection strings from the filesystem
- Very specific: line 206
Never modify or delete ~Backups notebooks — these are auto-created safety backups and the MCP server blocks mutations on them
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
You are working with Zeppelin notebooks via MCP tools. The user's request is:
$ARGUMENTS
Follow the steps below in order.
Step 0: Check the artifact doc cache
Before discovering anything, check whether this artifact is already documented.
Full protocol: $WIKI_DOCS_PATH/docs/artifact_cache_protocol.md.
Cache state (resolved at invocation)
- Docs root: !
echo "${WIKI_DOCS_PATH:-unset}" - Sync: !
[ -d "$WIKI_DOCS_PATH/.git" ] && { git -C "$WIKI_DOCS_PATH" pull --ff-only --quiet 2>/dev/null && echo synced || echo "pull failed - using local copy"; } || echo "no clone - cache off, use normal discovery" - Project slug (derived from cwd): !
head -1 knowledge/project/data_model.md 2>/dev/null | sed 's/^# //; s/ Data Model$//' - Project
_index.md:
!`s=$(head -1 knowledge/project/data_model.md 2>/dev/null | sed 's/^# //; s/ Data Model$//'); [ -n "$s" ] && cat "$WIKI_DOCS_PATH/$s/_index.md" 2>/dev/null || echo "(no index for slug '$s' - cold cache, or slug underivable from this cwd; resolve per protocol 1)"`- Interpret the pre-resolved cache state above — it already performed the env
resolution, the
git pull --ff-onlysync, the<project_slug>derivation, and the_index.mdread; do NOT redo them. Docs rootunsetor "no clone" → log one warning and proceed with normal discovery (the cache is optional; never create the root directory yourself — only the SessionStart hook's clone does). Slug empty or index unreadable → resolve them manually per protocol §1 (the cwd may not be the analyst repo). - Not listed (cold miss) → proceed to normal discovery; write the spec in the final step.
- Listed → call
get_notebook_fingerprint(notebook_id, spec_path="$WIKI_DOCS_PATH/<project_slug>/notebooks/<id>.md")— the server reads the stored hashes from the spec frontmatter itself and returnsmatchplus an exactdiff; never hand-compare hash maps or re-type them into tool arguments. Then read the spec body (it is the payload, not part of the check):match: true(hit) → trust the spec, skip Step 2 discovery, go to the task.match: false(stale) →diffnames the changed/added/removed paragraph ids; re-learn those and their dependents (cross-unit rule, protocol §5); update the spec in the final step.spec_notein the response → stored hashes unreadable; treat the spec as unverified background and run normal discovery.
Step 1: Identify the notebook
- If the user provides a notebook ID → use
get_notebookdirectly - If the user provides a name or partial name → use
list_notebookswith a name filter - If creating a new notebook → confirm the path follows the folder conventions already visible on the server (e.g.
Users/{username}/{Project}/{Notebook name})- Use
list_notebooksto discover existing structure before creating
- Use
Step 2: Understand context
Read existing notebook paragraphs with get_notebook to understand the structure, data flow, and coding patterns already in use. This is important because paragraphs share interpreter state — variables and imports from earlier paragraphs are available in later ones.
Decide how much exploration is needed:
| Situation | What to explore |
| Adding a paragraph similar to existing ones | Notebook context is sufficient |
| Adding a new kind of query or metric | Check the project's query templates / reference notebooks, if the project keeps any |
| Creating a new notebook from scratch | Read an existing notebook in the same folder/project to learn the interpreter prefix, connection pattern, and coding style |
When the data schema is unknown: discover it live from a scratch paragraph (e.g. inspect the table DDL or list distinct values of a key column with a LIMIT) instead of guessing table or column names.
Step 3: Generate and add content
Markdown paragraphs: separators yes, commentary only on explicit request
Two kinds of %md paragraphs — treat them differently:
- Section separators (a short header line that structures the notebook, e.g.
%md ## Retention) — allowed and encouraged for readability. - Commentary — methodology descriptions, analysis narratives, findings tables, conclusion or recommendation sections — do NOT add these unless the user explicitly asks. Conclusions and methodology belong in the chat response, not in the notebook.
When the user does ask for analysis/conclusion paragraphs: keep them clear and concise — short bullets, key numbers with their source (table, date range), no filler prose or restating what the chart already shows.
Interpreter prefix
Every Zeppelin paragraph starts with an interpreter prefix. Check existing notebooks on the same server to find the correct one — e.g. %python, %sql, %jdbc(...), %md. Do not guess — using a prefix that isn't configured on the server causes HTTP 500 errors.
Code patterns
Follow the connection pattern already used in the notebook. If no pattern exists, a common shape for Python paragraphs querying a database is:
%python
import os
from sqlalchemy import create_engine
import pandas as pd
sql = "QUERY"
df = pd.read_sql(sql, create_engine(os.getenv('YOUR_CONNECTION_STRING_ENV')).connect())(adapt the connection source to whatever the server/team already uses — an env var, a configured interpreter, or a helper module).
- Use
z.show(df)to output DataFrames for Zeppelin's built-in charts - For plotly (only when Zeppelin charts can't handle it — Sankey, heatmaps, violin plots):
print("%html " + fig.to_html(include_plotlyjs='cdn', full_html=False))
Adding paragraphs
Set a descriptive title for each paragraph. For a single paragraph use add_paragraph; for two or more, use batch_add_paragraph — one call, paragraphs created in the given order, returns the new IDs.
Fixing existing code: for targeted changes (a line, a filter, a column, a rename) use edit_paragraph — find-and-replace that sends only the changed snippet instead of re-sending the whole paragraph, which is much faster and cheaper for long paragraphs. Read the code first with get_paragraph_code and copy old_string from that output (raw text — get_notebook/get_paragraph indent code by 2 spaces, so snippets copied from them won't match). old_string must match exactly and be unique: include a neighbouring line if it repeats, or set replace_all for renames. For several edits — in one paragraph or across many — use batch_edit_paragraph (one call; all-or-nothing per paragraph, other paragraphs still proceed). Use update_paragraph / batch_update_paragraph only for whole rewrites or when most of the paragraph changes. The MCP server automatically backs up the original content before applying any of these changes.
Same query, different chart: use clone_paragraph — it copies code, title, and chart config directly below the original, so you only change the chart config afterwards instead of re-sending the code.
Chart configuration
After running a paragraph that outputs table data, use update_paragraph_config to set the chart and the presentation flags from "Finalize paragraph config" below in a single call:
{
"editorHide": true,
"runOnSelectionChange": false,
"graph": {
"mode": "lineChart",
"keys": [{"name": "date_column"}],
"groups": [{"name": "segment_column"}],
"values": [{"name": "metric_column"}]
}
}Supported graph.mode values: table, multiBarChart, stackedAreaChart, lineChart, pieChart, scatterChart.
Set graph.keys, graph.groups, graph.values with name only — omit index and aggr so Zeppelin auto-detects them from the result set.
Important — these cause broken charts if ignored:
- Use
{"name": "col"}only in keys/groups/values — never includeindexoraggrfields. The MCP server auto-fills these from paragraph output headers. - Always verify column names against actual executed output (
get_paragraph) before setting chart config. Column names in code (e.g. SQL aliases) may differ from what Zeppelin outputs. Guessing causes "out of sync" warnings.
Dynamic forms
- Use
get_paragraph_formsto discover available form parameters before running - Pass
paramsdict torun_paragraphto set form values (keys must match field names exactly) - Use
update_paragraph_formsto change values without re-executing
Important — new paragraphs ignore pre-set forms:
update_paragraph_formsbefore a paragraph's first run is silently ignored by Zeppelin — the forms aren't registered yet. Passparamsdirectly torun_paragraphinstead, which registers forms and executes with correct values in one pass.
Running paragraphs
- Several paragraphs in order →
batch_run_paragraph(runs sequentially in the given order; stops on first error by default; each run item is{paragraph_id, params?}so cells can get different form values, with top-levelparamsas the shared default) — use this for the "run each paragraph one-by-one" step of notebook migrations instead of N separate calls - Long-running query →
run_paragraph_asyncto start without waiting, then pollget_paragraph_status - Stuck or runaway execution →
stop_paragraph - Exploratory queries → always add a
LIMITso a scratch query can't scan or return unbounded data
Finalize paragraph config
Every paragraph the assistant adds or edits MUST be finalized with both of the following set via update_paragraph_config before the task is considered complete — these are not optional polish, they are part of "done":
editorHide: true— hides the code editor so readers see the result (chart/table), not the query. Readers who want the code can unhide it with the paragraph menu.runOnSelectionChange: false— disables Zeppelin's default behavior of auto-re-running the paragraph every time a dropdown or form value changes. Heavy queries otherwise fire on every click, which wastes cluster time and can crash the server. Users re-run explicitly with the Run button.
Minimal call (paragraph without a chart — e.g. markdown or a pure table output):
{
"editorHide": true,
"runOnSelectionChange": false
}For paragraphs with charts, fold these keys into the same update_paragraph_config call as graph (see the Chart configuration example above) — one round-trip, not two.
When finalizing several paragraphs, use batch_update_paragraph_config — one call with a config object per paragraph (same shape as above) instead of N update_paragraph_config calls.
Verify before writing: editorHide and runOnSelectionChange are paragraph-config keys in current Zeppelin versions, but names can shift across versions. Fetch the current config via get_paragraph and confirm the key is accepted; if update_paragraph_config returns without the key taking effect, check the paragraph's JSON and adapt (e.g. some versions nest the editor-hide flag under editorSetting).
Step 4: Update the artifact doc cache
After the task succeeds, persist what was learned (protocol: $WIKI_DOCS_PATH/docs/artifact_cache_protocol.md):
- Cold miss → write a new spec to
$WIKI_DOCS_PATH/<project_slug>/notebooks/<notebook_id>.mdusing the spec template (fingerprint + units viaget_notebook_fingerprint; recordvalidated:), and register it:wiki index-add <project> notebooks/<id>.md --name "…" --desc "…". - Stale → update the changed
## Per-unit notes/## Architecturesections (plus dependents per the cross-unit rule), append a## Change logentry (cap at 5 — drop the oldest), refreshvalidated:, and re-fetch the fingerprint into the frontmatter. - Do not run git commands — the plugin Stop hook commits and pushes.
If the hook reports a rebase conflict in
_index.md, take the remote version and re-add this artifact's bullet — never hand-merge prose. (Hook not installed — older plugin — → commit manually per protocol §6.) - If
$WIKI_DOCS_PATHis unset/absent, skip silently — do not fail the task.
Boundaries
What MCP can do: read/search notebooks and paragraphs; add/update/delete/move paragraphs (single or batch_* variants); edit paragraph code in place via find-and-replace (edit_paragraph, batch_edit_paragraph); clone paragraphs and notebooks; create/export/import notebooks; modify paragraph config (charts, single or batch); run paragraphs (sync, batch, or async with status polling) and stop them; update form values; read/update permissions.
What MCP cannot do: modify or delete ~Backups notebooks (protected by the MCP server).
Hard rules — these exist because violations have caused real problems:
- Never make direct HTTP/curl requests to Zeppelin — all interaction goes through MCP tools only
- Never read credential files,
.envfiles, or connection strings from the filesystem - Never modify or delete
~Backupsnotebooks — these are auto-created safety backups and the MCP server blocks mutations on them
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

