Cellar

Cellar

An interactive notebook server that enables humans and AI agents to collaboratively edit and run Jupyter notebooks on a shared kernel, with real-time streaming and automatic MCP integration for agent access.

Category
访问服务器

README

Cellar

CI License Latest release

A Python notebook built for you and your AI agent to share.

Cellar runs an interactive notebook in your browser on one shared Jupyter kernel, with a first-class agent interface built in. Open a folder and both you and an AI agent (like Claude Code) work the same live notebook: the agent adds and runs cells, and the results stream into your browser in real time. No copy-paste, no context handoff, no drift.

It saves ordinary .ipynb files that open in vanilla Jupyter, and it keeps them git-clean so your diffs stay meaningful.

Cellar running a live analysis notebook: a markdown heading, Python cells, and an interactive DataFrame grid, with an outline and live variable inspector in the sidebar

<p align="center"><em>One live notebook, one shared kernel - markdown, code, and rich outputs, with an outline and live kernel inspector alongside. (Shown in the dark theme; a light theme ships too.)</em></p>

Why Cellar

  • 🤝 You and your agent, one notebook. An agent's runs and edits appear live in your open tab (streaming output, run badges, structural changes), and your edits flow back the same way. You are never looking at stale state.
  • One command, zero setup. Run cellar in any folder. It resolves (or creates) the project venv with uv, starts the kernel, and opens your browser.
  • 🔌 Zero-config agent connection. Cellar drops a .mcp.json in your workspace, so an agent opened in that folder connects automatically over MCP. Nothing to wire up.
  • 🧹 Git-friendly by design. Clean-on-save strips volatile metadata and normalizes outputs, so re-running a notebook with the same results produces no git diff.
  • 📊 Rich outputs and data tools. Matplotlib, Plotly, HTML, and full-size images render inline; sort and filter DataFrames in an interactive grid, and inspect the live namespace without leaving the page.
  • 🧱 Databricks, natively. Point-and-click connect binds spark and a WorkspaceClient in the kernel and gives you a Unity Catalog browser.

Install

Homebrew (recommended). Trust the formula once, then pick a channel:

brew trust --formula fbereilh/cellar/cellar

Stable - the latest tagged release. Recommended for most people:

brew install fbereilh/cellar/cellar

Latest - tracks main for the newest work, for the adventurous:

brew install --HEAD fbereilh/cellar/cellar

Why trust? Homebrew requires a one-time trust before it will load a third-party tap's formula; --formula trusts just this one (recommended). The install then auto-taps fbereilh/cellar for you, so there's no separate brew tap step.

cellar --update
cellar --version

cellar --update fetches the newest version (install-method aware); cellar --version prints the version, sha, and install method.

<details> <summary>From a git clone (dev)</summary>

git clone https://github.com/fbereilh/cellar.git
cd cellar
make setup

make setup installs deps, builds, and links cellar onto your PATH. make update (or cellar --update) pulls and rebuilds; run make with no target to list all commands.

For the full clone-to-run walkthrough, the kernel/venv resolution order, and every configuration knob, see docs/SETUP.md. </details>

Run with Docker

Prefer to skip installing anything? If you have Docker, you have Cellar. This path needs only Docker on the host - no Node, Python, or uv - and bakes a reproducible, pinned kernel environment into the image so every run is identical. It's meant for single-user, reproducible, zero-prerequisite use: Cellar has one shared kernel and no auth, so it is not for multi-user hosting.

Build the image once, then point it at any project folder:

git clone https://github.com/fbereilh/cellar.git && cd cellar
docker build -t cellar .

# from the project you want to work on:
docker run --rm --init \
  -v "$PWD":/workspace \
  -p 8888:8888 -p 39587:39587 \
  cellar

Open http://localhost:8888 (the container prints it on startup) and you're in. Your folder is mounted at /workspace, so edits, new notebooks, and exports land straight back in it. Ctrl-C (or docker stop) shuts everything down cleanly.

Prefer Compose? It mounts the current directory and publishes both ports for you:

docker compose up --build   # then open http://localhost:8888

Once the image is published to a registry, you can skip the build entirely:

docker run --rm --init -v "$PWD":/workspace -p 8888:8888 -p 39587:39587 ghcr.io/fbereilh/cellar:latest

The reproducible pinned env. The image bakes a uv-managed virtualenv at /opt/cellar-kernel from docker/kernel-requirements.txt - a version-pinned scientific stack (ipykernel, ipywidgets, numpy, pandas, matplotlib, scipy) - and binds the Cellar kernel to it. Every container runs the exact same kernel env, with no network access at start. To make it yours:

  • Rebuild with your own pins (the primary path): edit docker/kernel-requirements.txt, then docker build -t my-cellar .. Swap the base or tool versions with build args, e.g. --build-arg NODE_IMAGE=node:22-bookworm-slim.
  • Ad-hoc extras without a rebuild: mount a requirements file and point CELLAR_REQUIREMENTS at it - -v "$PWD/requirements.txt":/reqs.txt -e CELLAR_REQUIREMENTS=/reqs.txt - and the entrypoint installs them into the kernel venv at startup (needs network).

Connecting an agent. The MCP endpoint is published on http://localhost:39587/mcp (Streamable HTTP). Point an HTTP-capable MCP client at it. (The in-container cellar mcp stdio bridge isn't used from the host, so the image writes no .mcp.json by default; set -e CELLAR_MCP_CONFIG=1 to opt back in for an agent running inside the container.)

Why this image, not a Jupyter base? It's self-contained (Node + uv + Python, multi-stage build) rather than built on a jupyter/docker-stacks conda image. Cellar is uv-first by design - it manages every venv through uv - so a conda base would bolt on a second package manager Cellar never uses, and docker-stacks ships no Node. The container runs isolated (CELLAR_ISOLATED=1, no host registry or reaper), non-root, with fixed published ports and the app/MCP bound to 0.0.0.0.

Good to know (the honest caveats):

  • The kernel environment is the container's baked env, not a host .venv. Point Cellar at a different one by rebuilding, or with -e CELLAR_VENV=/workspace/.venv (it will uv-install ipykernel there at startup if missing).
  • Databricks needs ~/.databrickscfg mounted read-only (-v "$HOME/.databrickscfg":/home/cellar/.databrickscfg:ro, or uncomment the line in docker-compose.yml). A PAT profile works headless; OAuth's browser flow is awkward inside a container.
  • Git blame and diff features need the repo mounted - it is, via /workspace.
  • Linux uid: files are written as uid 1000 by default. If your host user differs, add --user "$(id -u):$(id -g)" so mounted files stay owned by you. (macOS Docker Desktop handles this for you.)
  • Single-user only - don't expose the ports beyond localhost.

Quick start

cd your-project
cellar

Your browser opens to a clean, empty workspace. Click New notebook (or open an existing .ipynb from the sidebar) and start writing and running cells. To bring in an agent, just open one (e.g. Claude Code) in the same folder - it auto-connects through the .mcp.json Cellar wrote, and you can watch it work alongside you.

Ctrl-C stops everything. Run cellar ../other-repo to open a different folder without cd-ing.

Features

Everything you'd expect from a notebook, plus the things that make sharing one with an agent feel natural:

  • Code, Markdown, and SQL cells, with a run queue, live run status, and staleness tracking so you always know what's fresh.
  • Rich outputs: matplotlib, Plotly, rich HTML, and images you can double-click to view at natural size.
  • Interactive DataFrame grid: pandas frames become a sortable, filterable, paginated table instead of a static repr.
  • Run metadata on every cell: when it last ran, how long it took, and who ran it (you or an agent).
  • Checkpoints and undo for agent actions - snapshot before a risky change and roll back.
  • Command palette and Jupyter-style modal keyboard shortcuts for fast navigation.
  • Variable and DataFrame inspection to peek into the live kernel namespace.
  • Git blame and diff gutters right in the editor, and per-cell change bars in the notebook.
  • One shared kernel across notebooks, with a sidebar showing what's actually loaded in memory.

A pandas DataFrame rendered as Cellar's interactive grid, sorted by a column, with dtype headers, a filter box, and pagination

<p align="center"><em>A bare <code>df</code> becomes an interactive grid - click a header to sort, type to filter, page through the rows.</em></p>

A matplotlib line chart rendered inline in a Cellar notebook, showing quarterly revenue by region

<p align="center"><em>Matplotlib, Plotly, and HTML outputs render inline, right where you ran the cell.</em></p>

Working with agents (MCP)

Cellar exposes an in-process MCP server that shares the live document and kernel with the UI. Point any MCP client at the stdio command:

claude mcp add cellar -- cellar mcp

(or just run cellar and let the auto-written .mcp.json do it). On connect, the agent gets a house-style doctrine that frames the work as building one coherent notebook, plus a rich tool set: read the notebook map and live kernel state, add/edit/move cells, and run them (add_and_run is the preferred write-and-execute flow). Because the MCP session is independent of the kernel connection, restarting the kernel never drops the agent's session or your document.

Databricks

Open the sidebar's Databricks section, pick a profile and cluster, and click Connect. Cellar binds spark (a Databricks Connect session) and w (a WorkspaceClient) into the kernel, ready for spark.read.table(...). A lazy Unity Catalog catalog > schema > table browser lets you click a table to drop a real, editable query cell into the notebook. Auth uses the SDK's own ~/.databrickscfg profiles (PAT or OAuth) - no extra CLI required. Agents can see and query the connection too, and can restore a dropped session or connect to a cluster you point them at - but they never start compute or drive the OAuth browser, so a stopped cluster or a browser sign-in stays your call. While a query runs, a live Databricks-style progress bar shows overall task completion across stages and clears when the query finishes (queries faster than a couple of seconds skip the bar, just like Databricks).

A SQL cell holds a raw query that Cellar runs against that spark session and renders as an interactive grid. Its result is bound to _sql_df in the kernel, so a following Python cell can chain off the last SQL result. _sql_df is last-write-wins across the notebook, so with more than one SQL cell, name the binding by opening the cell with a -- >> sales_df line:

-- >> sales_df
SELECT region, sum(amount) AS amount FROM sales GROUP BY region

The result then binds to sales_df (and still to _sql_df), and no later SQL cell clobbers it. The line is a plain SQL comment, so the cell still reads as SQL anywhere else; it must be the first non-blank line, and the name must be a valid Python variable name that isn't already Cellar's (spark, w) - an unusable name fails the cell with a message saying why. Staleness knows about the binding: edit the query and the Python cells using its result go stale.

Requirements

  • Node 18+
  • Python 3.9+
  • uv on your PATH (Cellar uses it for all venv and package management)

Or just Docker - see Run with Docker for a zero-prerequisite, reproducible-env alternative.

Cellar runs with zero configuration - it discovers your home directory, its own install location, and free ports at runtime. For the clone-to-run steps, kernel/venv resolution, and the full environment-variable reference (all optional, with defaults), see docs/SETUP.md.

Testing

Two layers, run with:

npm run test
npm run test:e2e
  • Unit tests (tests/unit/) guard the pure server logic. The crown jewel is clean-on-save: idempotent, git-clean round-trips, the metadata allowlist, memory-address scrubbing, and the notebook model (stable cell IDs, add/move/delete, duplicate-ID re-keying). These are the must-pass gate and run on every PR in CI.
  • E2E (tests/e2e/) drives the real cellar launcher against a scratch workspace in a browser. The smoke spec (smoke.spec.ts) runs 6*7, asserts 42 renders, and confirms the saved .ipynb is valid; the rest cover behavior only the full stack can show (e.g. kernel-watchdog-probe.spec.ts proves a long, silent cell is never aborted for being silent). They need the full kernel runtime (uv + python3 + the cached host-venv), so they're a local, best-effort layer that skips itself when that runtime is absent. CI doesn't provide the kernel runtime, so they run locally, not there - the unit suite is what gates merges. Install the browser once with npx playwright install chromium.

Contributing

Contributions are welcome - see CONTRIBUTING.md for dev setup, the CI gate (npm run build && npm run check && npm run test), and the project's conventions. Please also read the Code of Conduct.

Found a security issue? Please report it privately - see SECURITY.md (Cellar runs an arbitrary-code-execution kernel, so this matters).

See CHANGELOG.md for what changed in each release (it's generated from the git history by git-cliff - never hand-edited; run make changelog to regenerate), or the Releases page.

License

Released under the MIT License. Some editor syntax palettes were ported in from other open-source projects; see THIRD-PARTY.md for their notices.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选