Pappus

A local-first notebook that teaches

It hints.
You run
the code.

Pappus is a notebook where the AI is a thinking partner, not a ghostwriter. It follows Answer.AI's SolveIt method: small steps, one cell at a time. The AI never runs your cells, and by default it can't write files. Running the code is your job.

Who runs cells
cells run by you
AI file writes
AI file writes off
Compute
laptop ↔ H100
App front end
0 CDNs in the app
The AI suggested one line. You wrote it and pressed Run.

The permission design

An AI that won't do your homework

A coding agent left alone does what agents do: it writes the whole solution to a scratch file and runs it off-screen. That takes the seat you're supposed to hold. So Pappus keeps the AI's hands off the Run button on every model, and off your files by default.

What it does

  • Sees every cell above your questionOn every model. Notes, code, outputs and earlier answers go in as context, so "why is this slow?" just works.
  • Answers in small stepsIn learning mode, a guiding question or a hint, not the finished solution.
  • Edits a cell you can see, when you ask"Fix cell 3" rewrites it in the notebook in front of you. Codex and Claude CLI models only, and never on its own initiative.

What it doesn't do

  • Run a cell, on any modelIts notebook tools can list, read, edit and insert cells. None of them runs one. Even a cell it edited waits for you to press Run.
  • Write files, by defaultNothing off-screen. Each kind of model is held back in its own way, below.

How each model is held back

Codex CLIthe default model

Runs in Codex's read-only sandbox, so it can't write files. Pappus gives it no web search, only the notebook-cell tools. It is told not to run commands; that part is an instruction, not a lock.

Claude CLIwith a Claude Max plan

Web search and page fetch are allowed, so answers can rest on current facts. Write, Edit and Bash are denied. The rules sit in one JSON file you can read and change; "deny": [] opens it up completely.

~/.config/pappus/tools.json
json{
  "allow": ["WebSearch", "WebFetch"],
  "deny":  ["Write", "Edit", "Bash"]
}
API keyClaude, GLM

No tools at all. It reads the notebook context and answers in text.

How a session goes

Small steps, and you take every one

  1. 1note

    Put the idea on the page

    Write a note, or pull a passage in from a paper you're reading. Headings fold into sections, so a long dialog stays navigable.

  2. 2ask ai

    Ask, and get a nudge

    In learning mode, the default, the AI asks a guiding question or gives a hint and leaves room for you to try. Stuck? It shows the smallest piece that unblocks you, and the idea behind it.

  3. 3code

    Write it, run it, check it

    You write the cell and press Run. The kernel keeps your variables between cells, and the AI sees the output, so "is my version equivalent?" gets a real answer.

What it looks like

A calm page, not a chat window

Every message is a live cell: notes render as markdown, code as highlighted Python, prompts as your question with the AI's answer beneath. Click any cell to edit it.

Pappus in light mode, dialog fourier/square-wave. A code cell plots partial sums of a square wave with 1, 3 and 9 odd terms in matplotlib, the plot renders inline, and the learner asks: It overshoots at the edges, even with 9 terms. Bug? The AI, labelled Claude · Opus high, names the Gibbs phenomenon.
The learner plotted the partial sums. The AI explains the overshoot they found: the Gibbs phenomenon.
Pappus in dark mode, lesson Why only odd harmonics? The learner asks why a square wave has only odd harmonics and adds: Don't give me the answer, help me see it. The AI gives two nudges and no proof. Below, the learner's numpy FFT code prints the magnitude of harmonics 1 to 7: the even ones are near zero.
"Don't give me the answer, help me see it." Two nudges, then the learner's own FFT.
The Wikipedia article Fourier series open as clean text in the reading panel on the left, with the lesson Why only odd harmonics? on the right.
A web article in the reading panel, the lesson beside it.

Features

A notebook first, with a tutor in the margin

Cells that link

Every cell has a stable id. Type #_<id> to link to it, or prefix a dialog path to link across notebooks. The AI can cite cells the same way.

Completion from the live kernel

After import numpy as np, typing np.ar offers arange. Suggestions come from what you've actually run, via jedi.

Live values in prompts

Write $`df.shape` in a question and the AI gets the real number, evaluated fresh each time you ask.

Context you can see

Each cell shows its token count and a meter reads out the total. Mute a cell to drop it from context; pin one to keep it.

Three modes

learning favours your understanding, concise keeps it short, standard answers in full when you want it to.

Rich output

Matplotlib figures render inline, and so does anything with _repr_html_ or _repr_png_, like a DataFrame.

Jupyter keys

Command and edit modes, j/k to move, a/b to insert, dd to delete, z to undo it.

Export anywhere

Download any dialog as a Jupyter .ipynb or as markdown.

Cells into a library

Tag cells from any dialog into a Python package and build it with nbdev. Each function links back to the cell you wrote it in.

Read papers with it

Pull in the part that matters, then build it yourself

  • pdf

    Open a PDF or paste a URL. An arXiv link imports the paper, not the abstract page. It's converted to structured text with marker: sections, tables, equations as LaTeX, figures. A blog post is cut down to its main content.

  • sel

    Highlight a passage. → Notebook brings it in as a note with an empty code cell below, focused, so you reimplement the idea. Ask AI drops it into your next question.

  • ▸

    Or step through it. Next section brings the paper in one section at a time, each followed by a cell for your version.

Yours, wherever it runs

Local by default, a GPU when you need one

Your notebooks stay on your machine

Notebooks, papers, libraries: everything you create lives under ~/.config/pappus, out of git. Every save keeps the previous version, and a timestamped snapshot is taken every 15 minutes while you work.

just backup packs it all into one archive, leaving your API keys out unless you ask. Keys themselves sit in a chmod 600 file.

The front end needs no internet

Every script, editor and font is vendored and served locally. Markdown and code highlighting are rendered on the server. The app's own front end loads nothing from a CDN. The network is used when you ask for it: a call to the AI model, a web search, a URL you paste. An imported web page may still show its images from the original site.

Laptop or H100, same notebook

A dropdown in the top bar switches targets. The remote box's port is tunnelled over SSH to your localhost, so it never touches the public internet.

kernellocalhost:5055 · laptop, bundled locallocalhost:5001 · a SolveIt server h100localhost:5101 ⇢ ssh ⇢ H100:5001

SolveIt, or its own kernel

Point it at a SolveIt server, or run the small SolveIt-compatible kernel server that ships with it. That one executes real Python with a persistent namespace per dialog, and refuses to listen beyond loopback without a token.

Install

Up and running in four steps

The one prerequisite is uv. It manages Python 3.10+ and every dependency, so you never touch pip or a venv by hand.

1

Install uv and just

shellcurl -LsSf https://astral.sh/uv/install.sh | sh
brew install just
2

Get the code and everything it needs

This pulls in the kernel's numpy/torch stack, marker for PDFs, and trafilatura for web pages. torch is large, so let it finish once.

shellgit clone https://github.com/slegroux/pappus && cd pappus
uv sync --extra kernel --extra paper --extra web
3

Start it

Kernel on :5055, the notebook on localhost:8000. A green light in the top-right means you're live; amber means it fell back to the mock, usually because the kernel isn't up yet.

shelljust dev      # foreground, Ctrl+C stops both
just start    # or in the background; just stop to end
just app      # optional: a double-click launcher for macOS
4

Pick a model

The default model runs through your installed codex command and needs no key. For Claude or GLM, paste a key under ⚙ Settings; with a Claude Max plan, the claude CLI works too.

Where it comes from

Standing on a good method

Pappus follows the method behind Answer.AI's SolveIt: work in small steps, keep the human in the driver's seat, and let the AI be a thinking partner. It can connect to a SolveIt server or run on its own. It is an independent project, not affiliated with or endorsed by Answer.AI.

The name has two halves. In Pólya's How to Solve It, "Pappus" is the entry on working backwards from the unknown. And a pappus is the little parachute on a dandelion seed, the thing that carries it forward.

Made by Sylvain Le Groux at Sisyphe.