Notebooking
Notebooks are OSO's unit of analysis: a marimo notebook that queries the warehouse and renders charts, tables, and text. You can build one in the OSO app or author it locally and run it on OSO's hosted marimo. Notebooks usually query the marts you've explored and the models you've built.
Build in the app
Open your workspace, create a new notebook, and write cells that query OSO with SQL and render the results. The notebook runs live against your data.
Author locally
Building in the app? You can skip this section — these rules only apply when you author a notebook locally and run it on OSO's hosted marimo.
For a locally authored notebook to run on OSO's hosted marimo (marimo.oso.xyz),
it must follow a few rules that keep it interoperable with the platform.
-
Don't pin a marimo version. The file header must be
__generated_with = "unknown". -
Keep the
setup_pyosocell verbatim. It providesmoand apyoso_db_connevery other cell uses. Never modify its body (you may addhide_code=True):@app.cell(hide_code=True)def setup_pyoso():import pyosoimport marimo as mopyoso_db_conn = pyoso.Client().dbapi_connection()return mo, pyoso_db_conn -
Query with
mo.sql, not a raw client. Run SQL through the shared connection, never by constructingpyoso.Client()inside a cell:@app.cell(hide_code=True)def _(mo, pyoso_db_conn):df_projects = mo.sql("SELECT * FROM oso.projects_v1 LIMIT 5", engine=pyoso_db_conn)return (df_projects,) -
Set
hide_code=Trueon every cell. -
Give each cell's outputs unique names (
df_projects, notdf). Marimo enforces a single-definition rule across the notebook. -
No local file access. Pull all data through
mo.sql, so the notebook runs the same locally and on the platform.
Validate a local notebook before publishing:
uv run marimo check your_notebook.py
Publish
Publishing renders your notebook to a static HTML snapshot others can open without re-running it. Publishing and sharing are separate steps: publishing creates the snapshot; making it visible to others is a permission grant covered in Publishing & sharing.
In the app
Open the notebook and choose Publish. OSO renders the current state to a snapshot. If you have admin access, saving a content change re-publishes automatically, so the snapshot stays current with your edits.
From your agent
Over MCP, the publish loop is:
createNotebookUploadUrlfor a presigned URL, then upload the notebook body. This is the path for larger notebooks; smaller ones can be sent inline viacreateNotebook/updateNotebook.publishNotebookto render and store the snapshot.updateNotebookfor content changes, which re-publishes automatically when the caller has admin.
The snapshot is rendered once, at publish time, under the publisher's identity, so a reader sees the data exactly as the publisher could query it then.
Next
- Make it viewable by others — a public link or org access: Publishing & sharing.
- Let a hosted agent build and publish notebooks for you: Automate with agents.