Skip to main content

JupyterLab extension that opens an OpenAI Codex chat in the left sidebar.

Project description

jupyterlab-codex

A JupyterLab 4 extension that adds an OpenAI Codex chat panel to the left sidebar. The OpenAI mark serves as the sidebar tab icon.

Scope: notebook copilot, not project agent

This is a deliberately small tool. The agent can only:

  • list variables in your notebook kernel
  • describe a pandas DataFrame
  • run short Python snippets in the kernel
  • read the source / outputs of a selected cell or a cell by execution count
  • insert (and optionally run) a new code cell below the active one

That's the complete tool surface. No filesystem read/write. No shell. No MCP. No project-wide context. The agent sees what's in your kernel and your active notebook — nothing else.

This is a feature, not a limitation. Claude Code, Cursor, and the Codex CLI itself are excellent project agents — they edit files, run tests, manage git. Use them for that. jupyterlab-codex is for the inner loop inside a notebook: explain this cell, evaluate this model, describe this DataFrame, write the next cell. It runs where your exploratory work already lives, with zero context-switch and a live view of kernel state.

If you find yourself wishing it could grep your repo, that's a sign you want a different tool — and you almost certainly already have one open in another window.

Authentication uses the user's ChatGPT subscription via OAuth (the same flow the Codex CLI uses). Tokens live in localStorage and are forwarded to a small proxy that talks to the Codex Responses API.

Tested in JupyterLab 4 and JupyterLite. Notebook 7 should work — file an issue if it doesn't.

Two deployment modes

The extension needs a proxy because both chatgpt.com/backend-api/codex/responses and auth.openai.com reject browser fetches from arbitrary origins. Where the proxy lives depends on how you're running JupyterLab.

Classic JupyterLab — bundled, no external infra

pip install jupyter-codex ships a Tornado server extension that proxies to OpenAI from same-origin. The browser fetches /codex and /codex/device/... on whichever host the Jupyter server is exposed on — no CORS, no third-party services.

pip install jupyter-codex        # (or pip install -e . for dev)
jupyter lab

Open the OpenAI mark in the left sidebar and click Sign in with ChatGPT. That's it.

Setting Default Notes
codexProxyUrl codex Resolved against the Jupyter base URL → <base>/codex
codexModel gpt-5.3-codex Must be a model your ChatGPT account is entitled to

The bundled handlers live under the Jupyter base_url:

POST  <base>/codex                  → forwards Responses API call upstream
POST  <base>/codex/device/start     → request a device code
POST  <base>/codex/device/poll      → poll for completion + token exchange
POST  <base>/codex/refresh          → rotate the refresh_token

JupyterLite — external proxy required

In JupyterLite there is no Python server (the kernel runs in Pyodide, the page is static). The Python package isn't installed, so the bundled proxy can't run. Host a proxy out-of-band and override codexProxyUrl to point at it.

The bundled jupyter_codex/handlers.py is itself a reference implementation — port it to whichever runtime you prefer (Netlify Function, Cloudflare Worker, AWS Lambda, a small FastAPI service). Any proxy works as long as it exposes the same four routes:

POST  <proxy>                       → forwards Responses API call upstream
POST  <proxy>/device/start
POST  <proxy>/device/poll
POST  <proxy>/refresh

Then in Settings → jupyterlab-codex set codexProxyUrl to the proxy URL (e.g. /.netlify/functions/codex if the proxy is co-hosted on the lite site, or https://my-proxy.example.com/codex if it's elsewhere).

URL resolution

codexProxyUrl is interpreted as follows:

Value Resolved to
"codex" (default) <jupyter-base-url>/codex
"/foo/bar" /foo/bar (absolute path on current origin)
"https://x.com/y" used as-is
"" <jupyter-base-url>/codex

This lets the same default work in classic Lab (hits the bundled server extension), single-user JupyterHub (<base> becomes /user/<name>/), and JupyterLite (user picks an absolute path or a full URL).

Install for development

pip install -e ".[dev]"
jupyter labextension develop . --overwrite
jlpm build

jlpm watch rebuilds the labextension on change; refresh Lab to pick up TypeScript changes.

Project layout

src/
  index.ts              # plugin entry point — registers the sidebar
  widget.ts             # Lumino widget — chat UI + sign-in flow
  icon.ts               # OpenAI mark for the sidebar tab
  kernelRpc.ts          # run-Python + sentinel-parsing primitive
  agent/
    client.ts           # tool-use loop driver
    codexAuth.ts        # localStorage auth + device-code login
    codexProvider.ts    # Codex Responses API client (Anthropic-shape adapter)
    proxyUrl.ts         # codexProxyUrl resolution helper
    tools.ts            # kernel-side tool schemas + Python prelude
    toolRunner.ts       # injects prelude, parses sentinel-wrapped JSON
    frontendTools.ts    # browser-side tools (insert_cell, get_cell_context, …)
    transcriptStore.ts  # persists chat to .jupyterlab-codex-chat.json
    markdown.ts         # tiny markdown → HTML renderer
schema/plugin.json      # ISettingRegistry schema
style/                  # sidebar + chat CSS, OpenAI SVG mark
jupyter_codex/         # Python distribution name on PyPI: jupyter-codex
  __init__.py           # labextension paths + server-extension entry points
  handlers.py           # Tornado proxy: /codex, /codex/device/*, /codex/refresh
jupyter-config/         # auto-enables the server extension on install

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jupyter_codex-0.1.1.tar.gz (113.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jupyter_codex-0.1.1-py3-none-any.whl (35.4 kB view details)

Uploaded Python 3

File details

Details for the file jupyter_codex-0.1.1.tar.gz.

File metadata

  • Download URL: jupyter_codex-0.1.1.tar.gz
  • Upload date:
  • Size: 113.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.7

File hashes

Hashes for jupyter_codex-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8156b0771f471bf2bc715d010a9f5d336109e7c8662c8f095b9d68c368fd2666
MD5 76ec625b89b6c2df3e95daa8078b2b31
BLAKE2b-256 f2a33fb5f4d1f160faab1322b6e1166134a62cecc8fb99f7b552c1bf1465b4f0

See more details on using hashes here.

File details

Details for the file jupyter_codex-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for jupyter_codex-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 461130b822e85b72b99b888bc15577548e99d3487089a42dbb87c2bdea9e633c
MD5 87f7a9afd239f3c9e7b4764a3ff80d4d
BLAKE2b-256 84a162924a5b09ccba2c81b306b0f9c24f00cafa87a1148069fb9ea4135b4932

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page