Wasm Compatibility
ericmjl/llamabot
Check if a marimo notebook is compatible with WebAssembly (WASM) and report any issues.
Work inside a running marimo notebook's kernel — execute code, create cells, and build a notebook as an artifact.
$ npx skills add cosanlab/nltools --skill marimo-pair -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install cosanlab/nltools marimo-pair --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/cosanlab/nltools.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/marimo-pair .claude/skills/marimo-pair && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "marimo-pair" agent skill from https://github.com/cosanlab/nltools/tree/master/.claude/skills/marimo-pair into .claude/skills/marimo-pair/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "marimo-pair", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/cosanlab/nltools/tree/master/.claude/skills/marimo-pairType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add cosanlab/nltools --skill marimo-pair -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install cosanlab/nltools marimo-pair --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cosanlab/nltools.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/marimo-pair .agents/skills/marimo-pair && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "marimo-pair" agent skill from https://github.com/cosanlab/nltools/tree/master/.claude/skills/marimo-pair into .agents/skills/marimo-pair/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "marimo-pair", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add cosanlab/nltools --skill marimo-pair -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install cosanlab/nltools marimo-pair --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cosanlab/nltools.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/marimo-pair .cursor/skills/marimo-pair && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "marimo-pair" agent skill from https://github.com/cosanlab/nltools/tree/master/.claude/skills/marimo-pair into .cursor/skills/marimo-pair/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "marimo-pair", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/cosanlab/nltools.git --path .claude/skills/marimo-pair--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add cosanlab/nltools --skill marimo-pair -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install cosanlab/nltools marimo-pair --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cosanlab/nltools.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/marimo-pair .gemini/skills/marimo-pair && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "marimo-pair" agent skill from https://github.com/cosanlab/nltools/tree/master/.claude/skills/marimo-pair into .gemini/skills/marimo-pair/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "marimo-pair", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install cosanlab/nltools marimo-pairInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add cosanlab/nltools --skill marimo-pair -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/cosanlab/nltools.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/marimo-pair .github/skills/marimo-pair && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "marimo-pair" agent skill from https://github.com/cosanlab/nltools/tree/master/.claude/skills/marimo-pair into .github/skills/marimo-pair/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "marimo-pair", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add cosanlab/nltools --skill marimo-pair -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install cosanlab/nltools marimo-pair --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cosanlab/nltools.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/marimo-pair .opencode/skills/marimo-pair && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "marimo-pair" agent skill from https://github.com/cosanlab/nltools/tree/master/.claude/skills/marimo-pair into .opencode/skills/marimo-pair/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "marimo-pair", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
marimo-pairWork inside a running marimo notebook's kernel — execute code, create cells, and build a notebook as an artifact.
Marimo Pair is an agent skill from cosanlab/nltools. Work inside a running marimo notebook's kernel — execute code, create cells, and build a notebook as an artifact. Use when the user wants to start a marimo notebook or work in an active marimo session.
Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts (for example `reference/finding-marimo.md`, `reference/gotchas.md` and `reference/notebook-improvements.md`).
It sits in Data & Analytics, covering Jupyter notebooks. It works with marimo and Python. The repository describes itself as: Python toolbox for analyzing imaging data. The licence is MIT.
Read from SKILL.md and the folder at commit cf366c2. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
Bash(bash **/scripts/discover-servers.sh *)Bash(bash **/scripts/execute-code.sh *)ReadFrom allowed-tools in the SKILL.md frontmatter.
Ships 2 files in scripts/ (Shell), which the agent can run.
Shell commands in SKILL.md call:
bashuvFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use uv, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
MARIMO_TOKENFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Marimo Pair loads about 3k tokens when it runs. Until then it costs about 53 tokens; SKILL.md has 1,469 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from cosanlab/nltools at commit cf366c2, republished under its MIT licence (© cosanlab). 1,469 words, ~2,953 tokens.
.claude/skills/marimo-pair/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.This skill gives you full access to a running marimo notebook. You can read cell code, create and edit cells, install packages, run cells, and inspect the reactive graph — all programmatically. The user sees results live in their browser while you work through bundled scripts or MCP.
marimo notebooks are a dataflow graph — cells are the fundamental unit of computation, connected by the variables they define and reference. When a cell runs, marimo automatically re-executes downstream cells. You have full access to the running notebook.
pyproject.toml, existing cells,
and dir(ctx) before reaching for external tools.Only servers started with --no-token register in the local server registry
and are auto-discoverable — starting without a token makes discovery easier.
If a server has a token, set the MARIMO_TOKEN environment variable before
calling the execute script (avoids leaking the token in process listings). The
right way to invoke marimo depends on context (project
tooling, global install, sandbox mode). See
finding-marimo.md for the full decision tree.
Do NOT use --headless unless the user asks for it. Omitting it lets
marimo auto-open the browser, which is the expected pairing experience. If the
user explicitly requests headless, offer to open http://localhost:<port>
in their browser (open on macOS, xdg-open on Linux, start on Windows).
SyntaxError or ImportError from execute-code.shCode runs inside the running marimo kernel — execute-code.sh POSTs it
over HTTP and never invokes a local Python. So errors here are not caused by
the local Python version, missing venv, or uv vs pip — they're problems
with the code being sent. Fix the code (use a heredoc for anything
multiline; don't try to one-line compound statements with ;).
The skill declares allowed-tools in its frontmatter, but Claude Code may
still prompt for each Bash call. To fix this, the user should add the absolute
paths to the scripts to their .claude/settings.json (project-level) or
~/.claude/settings.json (global):
{
"permissions": {
"allow": [
"Bash(bash /absolute/path/to/skills/marimo-pair/scripts/discover-servers.sh *)",
"Bash(bash /absolute/path/to/skills/marimo-pair/scripts/execute-code.sh *)"
]
}
}Two operations: discover servers and execute code.
| Operation | Script | MCP |
|---|---|---|
| Discover servers | bash scripts/discover-servers.sh | list_sessions() tool |
| Execute code | bash scripts/execute-code.sh -c "code" | execute_code(code=..., session_id=...) tool |
| Execute code (multiline) | bash scripts/execute-code.sh <<'EOF' | same |
| Execute code (by URL) | bash scripts/execute-code.sh --url http://localhost:2718 -c "code" | same (with url param) |
Scripts auto-discover sessions from the local server registry. Use
--port to target a specific server when multiple are running,
--session to target a specific session when multiple notebooks are
open on the same server, or --url to skip discovery and connect to a
server by URL (e.g. --url http://localhost:2718). On Windows, prefer
direct --url when registry discovery is empty — see the next section
for why. Set the MARIMO_TOKEN env var to authenticate when the server
has token auth enabled (--token flag also works but exposes the token
in process listings). If the server was started with --mcp, you'll
have MCP tools available as an alternative.
Only --no-token servers are in the registry. If discovery comes up empty,
the server likely has token auth — ask the user for the token and set it as
the MARIMO_TOKEN environment variable.
On Windows (Git Bash / MSYS2), discovery can also come up empty even for
a running --no-token server. If the user confirms marimo is reachable
locally, fall back to --url http://127.0.0.1:<port> (ask for the port).
Always discover before starting. Background task "completed" notifications do not mean the server died — check the output or run discover first.
If no servers are found, read the user's intent — if they want a notebook,
start one. Always start marimo as a background task (using
run_in_background on the Bash tool) so the server automatically gets cleaned
up when the session ends and doesn't block the conversation. See
finding-marimo.md.
If there's no .py file yet, pick a descriptive filename based on context
(e.g., exploration.py, analysis.py, dashboard.py). Don't ask — just
pick something reasonable.
Avoid shell escaping issues. -c works for simple one-liners, but for
multiline code or code with quotes/backticks/${}, use a heredoc or a file:
# heredoc (single-quoted delimiter prevents shell interpolation)
bash scripts/execute-code.sh <<'EOF'
import marimo._code_mode as cm
async with cm.get_context() as ctx:
ctx.create_cell("x = 1")
EOF
# file
bash scripts/execute-code.sh /tmp/code.py
# target a specific port (skips auto-selection when multiple servers run)
bash scripts/execute-code.sh --port 2718 -c "1 + 1"Every execute-code call runs inside the notebook's kernel. All cell variables
are in scope — print(df.head()) just works. Nothing you define persists
between calls (variables, imports, side-effects all reset), but you can freely
introspect the notebook: inspect variables, test code snippets, check types
and shapes. Use this to explore, prototype, and validate before committing
anything to the notebook — then create cells to persist state and make results
visible to the user.
To mutate the notebook's dataflow graph — create, edit, and delete cells,
install packages, and run cells — use marimo._code_mode:
import marimo._code_mode as cm
async with cm.get_context() as ctx:
cid = ctx.create_cell("x = 1")
ctx.packages.add("pandas")
ctx.run_cell(cid)You must use async with — without it, operations silently do nothing.
All ctx.* methods are synchronous — they queue operations and the
context manager flushes them on exit. Do not await them.
The kernel supports top-level await, so use async with directly. Do
not wrap calls in async def main(): ... + asyncio.run(main()) — it's
unnecessary and easy to get wrong (compound statements like async with
can't follow def name(): on the same line, so cramming it into a -c
one-liner produces a SyntaxError).
Cells are not auto-executed. create_cell and edit_cell are structural
changes only — use run_cell to queue execution.
code_mode is a tested, safe API for notebook mutations — prefer it for all
structural changes. You also have access to marimo internals from the kernel,
but treat that as a last resort and only with high confidence after exploration.
Edit cells through code_mode, never the file system. Direct file writes
are silently lost. It is tempting to reach for Edit/Write for a small
tweak since edit_cell requires the full new cell body. Don't — without
--watch (off by default) the kernel never sees those edits and overwrites
them on its next save, so the user sees nothing. (Read on the .py is
okay, but content may lag the live kernel; prefer ctx.cells[target].code.)
UI state lives outside the reactive graph. Anywidget traitlets can be read
or set directly (e.g., slider.value = 5). For mo.ui.* elements, use
ctx.set_ui_value(element, new_value) inside code_mode.
The code_mode API can change between marimo versions. Explore it at the
start of each session — dig deeper into anything you're unsure about.
import marimo._code_mode as cm
help(cm)Skip these and the UI breaks:
ctx.packages.add(), not uv add or pip.
The code API handles kernel restarts and dependency resolution correctly.
Only fall back to external CLIs if the API is unavailable or fails.mo.ui is fine for simple forms and controls.
See rich-representations.md.Edit, Write, or NotebookEdit the notebook .py file while a
session is running. Direct writes are silently destroyed and never reach the
user. marimo only watches the file with --watch, which is off by
default. Without it, the kernel doesn't pick up file edits — and on its
next save, the kernel writes its own state and clobbers yours. The user sees
no change, you think the work landed, and the bug is invisible. Always use
ctx.edit_cell(target, code=...) with the full new cell body — even for a
one-character change. (Read is allowed, but disk content may lag the live
kernel; for the current truth prefer ctx.cells[target].code.)pathlib.Path("/tmp/...") in cell code is a bug.edit_cell into existing empty cells rather
than creating new ones. Clean up any cells that end up empty after edits.Anywidget state (traitlets) lives outside marimo's reactive graph. To hook a widget trait into the graph, pick one strategy per widget — never mix them:
mo.state + .observe() — you pick specific traits to bridge. Default choice.mo.ui.anywidget() — wraps all synced traits into one reactive .value. Convenient but coarser.Read rich-representations.md before wiring either.
ctx.packages.add() adds
real dependencies — confirm when it's not obvious from context.© cosanlab, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 6 other files (scripts) in .claude/skills/marimo-pair of cosanlab/nltools.
Open the folder on GitHubat commit cf366c2
We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in cosanlab/nltools, which our catalogue first saw on October 7, 2026.
Marimo Pair next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Marimo Pair this skillcosanlab/nltools | 131 | 1 repos | ~3k | Automated safety check: Pass | MIT | |
| Wasm Compatibilityericmjl/llamabot | 182 | 2 repos | ~1.6k | Automated safety check: Pass | None | |
| Marimo PairPhySpace/SimpleCADAPI | 140 | — | ~3k | Automated safety check: Pass | Apache-2.0 | |
| Marimo Pair Vscodemarimo-team/marimo-lsp | 130 | — | ~2.7k | Automated safety check: Pass | Apache-2.0 | |
| Marimobrycewang-stanford/Auto-Empirical-Research-Skills | 4.5k | — | ~2.8k | Automated safety check: Pass | Custom licence | |
| Marimo Notebookminicoohei/ai-agent-camp | 347 | — | ~1.5k | Automated safety check: Pass | None |
ericmjl/llamabot
Check if a marimo notebook is compatible with WebAssembly (WASM) and report any issues.
PhySpace/SimpleCADAPI
Drive a live marimo notebook as a workspace: run Python in the same kernel the user does, inspect live notebook state, and commit durable notebook changes.
marimo-team/marimo-lsp
Drive a live marimo notebook in VS Code as a workspace: run Python in the same kernel the user does, inspect and explore live notebook state and data, prototype and debug code, and commit durable…
brycewang-stanford/Auto-Empirical-Research-Skills
Reactive Python notebook system. An agent skill from brycewang-stanford/Auto-Empirical-Research-Skills.
minicoohei/ai-agent-camp
marimo ノートブックを正しいフォーマットでPythonファイルに作成するスキル. An agent skill from minicoohei/ai-agent-camp.
aiskillstore/marketplace
Expert guidance for creating and working with marimo notebooks - reactive Python notebooks that can be executed as scripts and deployed as apps.
cosanlab/nltools
Write a marimo notebook in a Python file in the right format.
cosanlab/nltools
Comprehensive nilearn (neuroimaging) API reference and best practices.
Categories
Work inside a running marimo notebook's kernel — execute code, create cells, and build a notebook as an artifact. Marimo Pair is an agent skill from cosanlab/nltools. Work inside a running marimo notebook's kernel — execute code, create cells, and build a notebook as an artifact.
Marimo Pair fits situations like: the user wants to start a marimo notebook; work in an active marimo session.
Run `npx skills add cosanlab/nltools --skill marimo-pair -a claude-code`. Or copy the skill folder (.claude/skills/marimo-pair in cosanlab/nltools) into .claude/skills/marimo-pair in your project. Claude Code loads it when a task matches its description.
Run `npx skills add cosanlab/nltools --skill marimo-pair -a codex`. Or copy the skill folder (.claude/skills/marimo-pair in cosanlab/nltools) into .agents/skills/marimo-pair in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add cosanlab/nltools --skill marimo-pair -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/marimo-pair, .gemini/skills/marimo-pair, .github/skills/marimo-pair and .opencode/skills/marimo-pair in your project.
Going by SKILL.md and its folder, Marimo Pair needs a shell for the scripts in its folder, the command-line tools its instructions call (bash and uv) and credentials named MARIMO_TOKEN. Our summary lists: Python 3; A Bash shell; A credential in MARIMO_TOKEN. Its frontmatter pre-approves these tools: Bash(bash **/scripts/discover-servers.sh *), Bash(bash **/scripts/execute-code.sh *), Read.
SKILL.md contains no URLs. Its commands use uv, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Marimo Pair is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Marimo Pair: Wasm Compatibility (ericmjl/llamabot, 182 stars), Marimo Pair (PhySpace/SimpleCADAPI, 140 stars), Marimo Pair Vscode (marimo-team/marimo-lsp, 130 stars) and Marimo (brycewang-stanford/Auto-Empirical-Research-Skills, 4.5k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
cosanlab (a GitHub organization) maintains it in cosanlab/nltools, which has 131 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 1, 2026.
Source: cosanlab/nltools on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.