- Brand
- Unknown
- Category
- Pending
- Primary Subcategory
- Pending
Integration details
Description
Turn your idea into a plix: a self-contained deck holding data, code and visualization. Python cells run in the browser or on cloud GPUs, and your AI assistant builds the deck through its connector. With Plixlab in ChatGPT you can create presentations, add and edit slides, text, equations and diagrams, add data (tables, values, images, molecules from the Protein Data Bank), write the Python cells that compute the charts, run them, and share the result as a link. Plixlab only accesses the presentations, data and settings of the Plixlab account you connect.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Category
- Pending
- Primary Subcategory
- Pending
- Secondary Subcategories
- None listed
- Brand
- Unknown
- Access
- Account required
- First tracked
- 2026-10-15
- Tool count
- 75
- Geography
- US
The broad Category that contains the Primary Subcategory.
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Plixlab
Get updates when Plixlab’s Discoverability Score or category rank changes.
Competitive lineup
75 tools agents can invoke
Fetch a structure from the RCSB Protein Data Bank by its 4-character PDB code into the plix as a `pdb` row (named pdb_<CODE>: the .pdb file exactly as RCSB serves it — a Biopython Structure at a cell port) and place it on a slide as an interactive 3D molecule. Use search_pdb first if you only know the name. A structure you have as a file or text (a .pdb or an .xyz you wrote or were given): upload_asset (the file as it is → a pdb / xyz row), then add_dataset.
fetch_pdb_molecule
Adds CELLS to the plix's pipeline (each: `label`, its `code` body, its `inputs` / `outputs` ports). The plix's PIPELINE is its cells, drawn as ONE column in dependency order (a cell below what feeds it; ties in the pipeline's own order: a new cell lands last, reorder_cells sets it) — there are no positions. Every cell write takes expectedRev, the pipeline's rev (returned by get_current_state, get_pipeline, get_cell, create_plix and every write or run): when the pipeline changed since that rev, nothing is written and the reply carries the pipeline as it is now. One call takes a list of items, applied together. An edit to code, ports or an environment reaches the slides only through a run: with run: true the plix runs right after the edit, in the same call, and the reply carries the run's report and the pipeline after it (rev, every port's row with its shape and value — what get_pipeline and read_dataset_content would return). In that pipeline, an input row with no data and no upstream writer stops the run, and a cell that feeds nothing stays until delete_cell removes it. Changes appear live in the open editor. A cell's RUNNER and PACKAGES are its ENVIRONMENT's (the account's, the same list in every plix — list_environments: Browser / Cloud-CPU / Cloud-GPU / a paired machine + packages) — add_cell / update_cell {environment: name}; a new cell without one takes the plix's default environment (Browser unless the owner made another the default in the rail); "Browser", "Cloud-CPU" and "Cloud-GPU" are every account's built-in environments (that runner alone). The plix pins no runner. PORT GRANULARITY: one port per value usable on its own; parts meaningless alone travel as ONE dict on one port (a spectrum = {wavelength, intensity}, a fit = {params, residual}) — split only when each part is read by itself. A cell's declared input ports arrive in its code as variables named after each port; after the cell runs, declared output ports are read from variables of the same name — declare ports for everything the code consumes or produces. PORTS ARE ROWS: a port IS the plix row of its name — its name is the row's name (the code identifier), its kind the row's. A WIRE = two cells naming the same row. FEED an input = declare it under an existing row's name (list_assets; create_dataset / upload_asset make one; an upstream cell's output is a row: its port name) — the row's kind must fit; a name no row has is REFUSED — make the row first (a run refuses a cell whose input row holds no data, naming cell and input). An OUTPUT under a new name mints its EMPTY row; each run rewrites it — read_dataset_content reads it, add_dataset places it (a data row draws as a box / table; a media row: a plotly Figure is a LIVE chart; image / video / gltf / fem / glyphs / ifc / pdb / xyz draw as themselves). One writer per row. RENAME a port = rename_row (every cell naming the row follows, code identifiers included). A row outlives its port: a port dropped from a cell leaves its row; a row goes only by delete_row (off every cell naming it). CELL NAMES: a cell's name (`label`) is REQUIRED — a Python function name no other cell of the plix has; a taken name (also on a rename) is refused, never renumbered. WHAT A CELL COMPUTES is said in its CODE: open it with a short # comment (what it computes, which output is THE result vs a diagnostic, units, caveats such as 'testing design, 5 iterations') — read it (get_cell) before composing with its outputs. CELLS ARE THE PLIX'S: a cell's name is unique in the plix; its code, ports and environment are its own — editing it changes nothing elsewhere. To reuse one in another plix the user pastes a COPY in the rail (a new cell there).
add_cell
Add TEXTS and SHAPES to a slide — ONE call per slide: pass every element the slide needs in `elements`, they land in ONE atomic write (one rev). EVERY ELEMENT IS A ROW of the plix made and placed by this call: a text a `markdown` row from its `content` (markdown: paragraphs, **bold**, lists, inline math $…$; role / align / fontSize / color on its element; update_element content rewrites it), a shape a `shape` row of its form and colours (placed UNDER everything: a card or band behind text, in any order; update_element fill / stroke change it; a diagram is a mermaid ROW and an equation a latex ROW — create_dataset format mermaid / latex, then add_dataset). Position/size are percentages of the slide (0-100), x/y anchor the TOP-LEFT corner; fontSize is px on the 1920x1080 raster. Layout rules: 5% margins; title band y=5 h=10 (role title); content from y=18; body (role body) left-aligned; columns x=5/52 width 43; center = x:50-width/2; elements must NEVER overlap. Every text names a ROLE (hero / title / heading / body / caption) — its size and colour are the plix style's; no fontSize / color. Returns the new elements' IDs (in order) and the slide's new rev. For a row use add_dataset (any kind: a data row, a picture, a movie, a chart, a model), never this.
add_element
An entry is a pip requirement ('scipy>=1.12', 'pkg[extra]==1.0'), a PUBLIC GitHub repository that IS a Python package ('owner/repo[@ref]' / github.com URL — pyproject.toml or setup.py at its root), or an environment VARIABLE 'NAME=value' (MKL_NUM_THREADS=16 …; set in os.environ at the top of every cell before any import, on every backend; whoever a plix using it is shared with sees them, so never a secret). Adds entries to an environment. The change is saved in one step: validate → resolve the packages ON THE ENVIRONMENT'S RUNNER (Cloud: its image; a paired runner: its own Python and installed packages; Browser: micropip in the plix's open tab) into ONE reproducible lock (exact versions + hashes, refs → commit SHAs) → persist. What the runner already has never changes; a conflict names those packages — relax or change the package. If any step fails the environment is UNCHANGED and the error says why. The runner installs only what it lacks before the next run. A Browser environment saved from here resolves as soon as the plix's tab is open; GitHub packages need Cloud or a runner. Any change gives the environment a new identity, so the cells using it are not replayed from cache — Run again.
add_environment_entries
Put a ROW on a slide — THE placement (the rail's "+ Current slide", a drag): the element binds the row and draws it WHOLE, by its kind. A yaml → A BOX of its keys and values (nested keys as dotted paths; a one-row box for a scalar), a csv → A TABLE (its columns, a longer one scrolls), a markdown → THE TEXT (prose at its role's size; `role` / `align` / `fontSize` / `color` on the element style it — add_element {type: text} makes and places one in one call), a mermaid → THE DIAGRAM, a latex → THE EQUATION, a shape → the shape; a picture (image, svg), a movie (video), a LIVE chart (plotly — redrawn on every run: never re-create it to refresh), a 3D model (gltf / fem / glyphs / ifc), a structure (pdb / xyz → 3Dmol) → drawn as what it is; an h5 → THE DATASET: a read-only line per array (path, shape, dtype, first values) — never a chart: a cell plots it. EITHER a row (`dataset`: its name or id — list_assets; a cell's output is a row: its port's name, or under a sweep one sample's "<port>/<sample>") OR a cell's output port (`cell` + `port`: the port's row — it draws once the cell has run and follows every later run; `port` defaults to the cell's only drawing output). A slide element pins a row, always: two combinations can sit side by side. ONE CALL: `datasets` is a LIST — put every row to place (any slides) in this single call (done in order; the first failure stops the list, the ones before it stay done).
add_dataset
Add slides to a plix — each a WHOLE SLIDE: its title and its `elements` (add_element's specs: text, shape; a diagram is a mermaid ROW and an equation a latex ROW: create_dataset + add_dataset). Returns each slide's ID, its rev (expectedRev of your next write on it) and its elements' IDs. Plix rows go on them afterwards with add_dataset. Layout rules: 5% margins; title band y=5 h=10 (role title); content from y=18; body (role body) left-aligned; columns x=5/52 width 43; center = x:50-width/2; elements must NEVER overlap. Every text names a ROLE (hero / title / heading / body / caption) — its size and colour are the plix style's; no fontSize / color. ONE CALL: `slides` is a LIST — put every slide to add, each with its title and elements — a whole plix in one call in this single call (done in order; the first failure stops the list, the ones before it stay done).
add_slide
Bring an element to the front or send it to the back of a slide's stacking order.
change_layer
Drops CELLS' CACHED RESULTS (each by `nodeId`): its outputs and its run-cache entries, so the next Run recomputes it (definition, ports and rows untouched: the next run replaces the rows' content) — for results that are stale or were never justified by the graph. The plix's PIPELINE is its cells, drawn as ONE column in dependency order (a cell below what feeds it; ties in the pipeline's own order: a new cell lands last, reorder_cells sets it) — there are no positions. Every cell write takes expectedRev, the pipeline's rev (returned by get_current_state, get_pipeline, get_cell, create_plix and every write or run): when the pipeline changed since that rev, nothing is written and the reply carries the pipeline as it is now. One call takes a list of items, applied together. An edit to code, ports or an environment reaches the slides only through a run: with run: true the plix runs right after the edit, in the same call, and the reply carries the run's report and the pipeline after it (rev, every port's row with its shape and value — what get_pipeline and read_dataset_content would return). In that pipeline, an input row with no data and no upstream writer stops the run, and a cell that feeds nothing stays until delete_cell removes it. Changes appear live in the open editor.
clear_cell_outputs
Delete EVERY element on a slide, leaving it blank. The slide itself stays.
clear_slide
COPY an asset or a cell into a plix — the rail's ⋮ Copy then Paste, in one call: `asset` (an input's name; every sample comes along, the same files, no upload) or `cell` (a cell's name or id: its code, its ports by name and kind, its environment — the workspace's of that name, else the plix's default) of plix `from` (default: the plix itself — a duplicate beside the original), pasted into `plixId` as its own. A taken asset, cell or output name gets `_2` (the code's identifier follows); a pasted cell's input with no asset of its name stays unbound until one exists; its outputs are empty rows until it runs. An OUTPUT has no copy: copy its cell.
copy
Create a data row from TEXT — the text IS the row's file, stored as you write it. `format` names it: `yaml` (the default) holds a value — one number (a scalar input: `0.5`), a string, a list, a dict of them (JSON is YAML: `{"n": 3, "label": "run A", "R": [1.5, 2.0]}`); an integer literal is an int, any other number a float; `csv` holds a table — a header row, then the rows, every column one length (numbers, or text). A cell reads a yaml row as the document (number lists as numpy arrays) and a csv row as {column: float64 array | list of str}. Arrays that matter (large, N-D, a dtype) are an `h5` row: a FILE — upload_asset. The row belongs to the plix, its bytes on `storage` (the plix's default storage when absent). `mermaid` holds A DIAGRAM — the bare mermaid source (`flowchart LR …`, no markdown fence), drawn to fill its box on a slide; `latex` holds AN EQUATION — bare LaTeX math (`E = mc^2`, no $ and no size command), typeset by KaTeX at the text size (neither is ever a cell's input or output: a port holds data or media). Bind a yaml / csv to a cell input with update_cell; place a row on a slide with add_dataset (a csv draws as a table, a yaml as a box, a mermaid as the diagram, a latex as the equation). ONE CALL: `datasets` is a LIST — put every row to create in this single call (done in order; the first failure stops the list, the ones before it stay done).
create_dataset
An ENVIRONMENT is the ACCOUNT's — stored once, the SAME list in every plix (an edit is live: the cells of every plix using it go stale and rerun) — naming its RUNNER (Browser / Cloud-CPU / Cloud-GPU / one of the user's paired machines; the plix pins none) plus packages + variables on top of it. EVERY CELL NAMES ONE environment (get_pipeline shows `environment` per cell; update_cell {environment: name}; every account has 'Browser', 'Cloud-CPU' and 'Cloud-GPU' — one per built-in runner, that runner alone, listed first, never renamed / deleted / moved — and a new cell is on Browser; a Browser cell and a Cloud cell can live in one plix), so a cell runs with no setup wherever it goes. The user sees the same rows in the rail (Compute) and picks a cell's from its rail row (Environment). Creates a new EMPTY environment (`name`: default env_N; `runner`: a name from list_runners or its engineUrl, default Browser) — then add_environment_entries fills it and update_cell {environment: name} assigns it. This is how a cell gets a package its runner lacks (an ImportError): the environment holds it, not a pip install inside the cell.
create_environment
Create a new PLIX — a presentation whose slides are computed by its own Python cells (the user may ask for a presentation, a deck or slides: this is it). Every plix is born with one slide AND its ONE pipeline (the graph of its cells; there is no other), empty — add_cell authors it. Build the SLIDES in this same call — `slides`: each its title (every slide has a real title) and its `elements` (add_element's specs); the first fills the slide the plix is born with. The reply carries the plix's `appUrl` and every rev: open that link for the user right away (or give it to them) — never leave a new plix unlinked; no open_plix call is needed for a plix you just created. Layout rules: 5% margins; title band y=5 h=10 (role title); content from y=18; body (role body) left-aligned; columns x=5/52 width 43; center = x:50-width/2; elements must NEVER overlap. Every text names a ROLE (hero / title / heading / body / caption) — its size and colour are the plix style's; no fontSize / color.
create_plix
Deletes CELLS of the pipeline (each by `nodeId`: its id or name): a cell leaves the plix; its rows stay in the plix (delete_row removes a row). The plix's PIPELINE is its cells, drawn as ONE column in dependency order (a cell below what feeds it; ties in the pipeline's own order: a new cell lands last, reorder_cells sets it) — there are no positions. Every cell write takes expectedRev, the pipeline's rev (returned by get_current_state, get_pipeline, get_cell, create_plix and every write or run): when the pipeline changed since that rev, nothing is written and the reply carries the pipeline as it is now. One call takes a list of items, applied together. An edit to code, ports or an environment reaches the slides only through a run: with run: true the plix runs right after the edit, in the same call, and the reply carries the run's report and the pipeline after it (rev, every port's row with its shape and value — what get_pipeline and read_dataset_content would return). In that pipeline, an input row with no data and no upstream writer stops the run, and a cell that feeds nothing stays until delete_cell removes it. Changes appear live in the open editor.
delete_cell
Delete elements from a slide by ID — every one to remove in ONE call (`elementIds`). Other elements are untouched.
delete_element
Deletes an environment — refused while a cell of any plix runs under it (the refusal names them); the built-ins never delete.
delete_environment
Delete a plix and everything in it — every slide, its pipeline, and the resources only it used. This cannot be undone. Only its creator, or an admin of the team, can (list_plixes `canManage`).
delete_plix
Deletes by name: the whole ASSET (every row of it; every cell port naming it goes with it: the output off its writer, the input off its readers), its slide elements go; by "<name>/<sample>": that one row. A CELL is deleted with delete_cell. ONE CALL: `rows` is a LIST — put every row to delete row in this single call (done in order; the first failure stops the list, the ones before it stay done).
delete_row
Delete slides — every one to remove in ONE call (`slideIds`). Its elements go with it; the rows those elements viewed are left in place.
delete_slide
Stop sharing a plix. Everyone it was shared with loses access at once; sharing again makes a new link. Only its creator, or an admin of the team, can (list_plixes `canManage`).
disable_sharing
A URL to DOWNLOAD a row's file — the counterpart of upload: fetch it from your execution environment with any HTTP client (`curl -sS -o <filename> '<url>'`); the bytes must NOT pass through your context. ANY row on ANY storage, as it is stored: an image row its PNG, a video its mp4, a gltf its GLB, a plotly row its figure JSON, an svg its markup, a data row its .yaml / .csv / .h5 (read_dataset_content gives a yaml or a csv as text), a fem / glyphs row its .h5, a pdb / xyz row its structure file. NOT a public link — nothing is minted or published (the row's ⋮ Link in the app is the link for Overleaf or a README — no tool makes one): the URL serves the content the row holds NOW (after a re-run, call again); one on a storage the user paired is signed, expires within two days and is reached only from that storage's network. ONE CALL: `rows` is a LIST — put every row to download in this single call (done in order; the first failure stops the list, the ones before it stay done).
download
Duplicate an element on a slide, slightly offset from the original.
duplicate_element
Duplicate a plix as a fully independent copy — slides, its pipeline, and the rows they reference all come along, each on its storage. A plix shared with you whose environments run on its owner's machine can't be imported (they are not yours).
duplicate_plix
Share a plix read-only and return its link. Whoever opens the link signs in (or signs up) and the plix joins their list, read-only; knowing the plix id alone grants nothing. Disabling sharing or regenerating the link (in the app) revokes everyone. Refused while any row is on one of the user's own storages (a viewer could never read it): move_row it to Plixlab Storage first — a row moved onto one later stops the plix serving its viewers. Environments on the user's machines are fine: viewers see the rows, they just can't import the plix.
enable_sharing
A SAMPLE sits out of every Run and every collected dict (the rail's Exclude); include_row brings it back. ONE CALL: `rows` is a LIST — put every row to exclude a sample in this single call (done in order; the first failure stops the list, the ones before it stay done).
exclude_row
Deletes recorded facts the conversation contradicted, or the user asks to forget (each by `id`, from help / get_current_state / a memory tool's read-back). Memory is injected at the start of every session (help / get_current_state), so write what a future session must not rediscover: stated preferences (accent colour, chart style, which engine runs what), corrections the user made to your work, standing context about a plix (what it is for, what its data is). One short sentence per fact; no secrets, nothing the user would not expect kept. scope 'global' = every plix; 'plix' + plixId = that plix only. Budget 30 global + 20 per plix, oldest-touched evicted. The reply reads every fact back.
forget
REQUIRED READING — returns the complete PlixLab skill: design rules, proven layouts, geometry, type scale, compute/pipeline authoring, engine selection, chart/equation/mermaid rules, and this surface's execution semantics. Call this ONCE at the start of any conversation in which you will create or edit slides, elements, charts, datasets, or pipelines — BEFORE the first write tool — and follow all of it. Read-only, no arguments.
help
Read code cells of a pipeline — EVERY cell you need in ONE call (`cells`): full source code (its leading comment says what it computes), declared input/output ports, environment (runner + packages), and `draft` when the user is typing in its editor (uncommitted — not what runs). Read a cell only when you do not hold it, or the pipeline's rev moved (get_current_state gives the pipeline's rev and cell names; a write's reply carries the new rev). `rev` = the pipeline rev, the cell tools' expectedRev.
get_cell
ONE environment by name: its runner, every entry (a GitHub entry with the commit it is pinned to, a pip one with its resolved version), whether its packages are resolved on its runner, its envId and the cells of this plix using it.
get_environment
THE SYNC — call it ONCE at the start of every turn on a plix (each new user message), before you think about the edit: the user may have changed the plix by hand since your last call. Returns where the USER is right now (their open tab's current slide, selected element, active view), the content of that slide, and the plix's OUTLINE: every slide, and the pipeline, with its `rev` (the pipeline with its cell names). COMPARE each rev with the one you hold: equal = that slide / pipeline is exactly as you last saw it — work from what you hold, read nothing; moved = re-read only the ones you are about to touch (get_slide {slideIds} / get_cell {cells}, each ONE call). OMIT plixId to get the plix the user is looking at (their tab's latest report) — use it whenever the user says "this plix" / "the one I'm on". After it, no list_slides / get_plix is needed.
get_current_state
Get a summary of the plix's pipeline: its code cells (each with its `environment`: runner + packages) with their ports — each port with its row: `datasetId` (an input without one is unwired), `row` = the row's name, `storage` = where its bytes live (Plixlab Storage | the name of its machine; a Cloud cell can't read or write a private row), `empty` = never written, else — for a row holding one value — that `value`. Use this to learn the cells' ids and the rows their ports name.
get_pipeline
Get a plix's raw structure (slide IDs, metadata — `defaultEnvironment` / `defaultStorage`: where a new cell runs and a new row lives; `autoRun`: whether a change runs the plix by itself; update_plix sets them) as JSON — for reasoning about or editing it. To SHOW/OPEN a plix for the user to look at, use `open_plix` instead.
get_plix
Check a pipeline run request (every engine). A run still going is WAITED FOR — up to 30 s — before the reply: call it once and read the answer, never in a quick loop (each call is one status per half minute of run). Statuses: waiting (Browser cells queued for the plix's tab and no tab has the plix open — `waiting` reads "waiting for the plix's tab — open <appUrl>" and names the cells: open that link; once a tab claims them it reads running), running (`cells` carries per-cell state so far — ONE entry per cell × combination (`comboKey`; '' without a sweep), each as waiting/starting/running/done/cached/error/skipped with logs; `live` carries the stdout/stderr so far of every RUNNING cell, the same lines the log panel shows live), done (`cells` is the per-cell report; outputs are persisted in the plix), or error
get_run_status
Get slides with all their elements — EVERY slide you need in ONE call (`slideIds`). Read a slide only when you do not hold it, or its rev moved (get_current_state lists every slide's rev; a write's reply carries the new one): a slide whose rev you hold unchanged is exactly what you last saw. Each `rev` is the expectedRev of your next write on that slide.
get_slide
Jump every live view of a plix to a specific slide (1-based number)
goto_slide
A SAMPLE excluded before is back in every Run and every collected dict (the rail's Include). ONE CALL: `rows` is a LIST — put every row to include a sample in this single call (done in order; the first failure stops the list, the ones before it stay done).
include_row
List the rows (assets) of a plix. A ROW IS ONE FILE, stored as written; its `kind` is the format of that file: yaml (application/yaml: numbers, strings, lists, dicts), csv (text/csv: a table), mermaid (text/vnd.mermaid: the source of a diagram, drawn), latex (application/x-tex: an equation, typeset), h5 (application/x-hdf5: a numpy array, or numpy arrays in dicts and groups), image (a PNG), svg, video (an mp4), plotly (a figure's JSON), gltf (a GLB), ifc (a STEP file), fem / glyphs (a mesh, an HDF5 file), pdb (a PDB structure file: a Biopython Structure at the port), xyz (an extended XYZ: an ase.Atoms at the port). A yaml / csv / mermaid / latex row is TEXT: read_dataset_content returns it, rewrite_row rewrites it. Any other row moves as a file: `download` (a signed URL), upload_asset (the user edits a yaml / csv / h5 row in its card too). Each row lists which cells use it. EVERY ROW IS THE PLIX'S OWN and is `name/sample` (its `address`): an asset with no samples is one row labelled `root` (addressed by its name alone); a SAMPLED asset is one row per sample, each labelled (`sample`; `excluded`: sitting out of the Run — the cell reading the asset runs once per included sample); a cell's OUTPUT is one row per combination it was computed under, labelled with the chosen samples joined by "/" ("scene/fourier", "scene/fourier/C2_tanh"). A name is one asset of the plix. `usedBy` lists every cell node of this plix with a port of the row's name — empty = no port names it yet. Its KIND says how it draws on a slide: a yaml as A BOX of its keys and values (nested keys as dotted paths), a csv as A TABLE — an h5 NEVER draws (a cell plots it, or writes a csv / yaml of the values to show); a media row is drawn by its kind — add_dataset places any. What goes on a slide is its own row, drawn WHOLE: a flat yaml of the few values to show, a csv for a table — configs stay in rows you do not place. `storage` is where its bytes live: "Plixlab Storage" or the name of the machine holding it (move_row moves it). A row's `_id` addresses it too.
list_assets
An ENVIRONMENT is the ACCOUNT's — stored once, the SAME list in every plix (an edit is live: the cells of every plix using it go stale and rerun) — naming its RUNNER (Browser / Cloud-CPU / Cloud-GPU / one of the user's paired machines; the plix pins none) plus packages + variables on top of it. EVERY CELL NAMES ONE environment (get_pipeline shows `environment` per cell; update_cell {environment: name}; every account has 'Browser', 'Cloud-CPU' and 'Cloud-GPU' — one per built-in runner, that runner alone, listed first, never renamed / deleted / moved — and a new cell is on Browser; a Browser cell and a Cloud cell can live in one plix), so a cell runs with no setup wherever it goes. The user sees the same rows in the rail (Compute) and picks a cell's from its rail row (Environment). Lists every environment: its runner, entries, envId, whether its packages are resolved and the cells of THIS plix using it.
list_environments
The LOCAL PACKAGES of a runner are the ones it was started with (`--include <path>`: packages under development, installed editable in the runner's venv) — and nothing else on that machine. READ-ONLY: the runner never writes a package (the owner edits it on their machine; the tree hash shows the edit). `runner` = the runner's name (list_runners, kind 'hosted'; default: the only online one). Docs (runners, --include): https://docs.plixlab.com/#runners Lists the runner's local packages (name, path, git HEAD, working-tree hash, dirty) — or, with `package`, that package's files (path, size).
list_local_packages
List all the user's PLIXES — a plix is a presentation (a slide deck) whose slides are computed by its own Python cells — in their Plixlab workspace. `canManage`: whether YOU may rename or delete it — only its creator, or an admin of the team, can (in a team the others' creators are named: `createdBy`).
list_plixes
A RUNNER is where a cell computes — the runner menu of an environment's card. Three built-ins (Browser = Pyodide in the user's tab; Cloud-CPU = PlixLab Cloud base image; Cloud-GPU = the same packages with CUDA torch and jax on ONE NVIDIA L4 — a second there uses 15.4 compute seconds of the plan, Cloud-CPU's 1) plus the user's paired runner MACHINES. A cloud run is charged the time its machine is up for it: startup, the run, and the time it stays ready after the last run (1 min); a cloud cell is stopped at 10 minutes. An ENVIRONMENT picks one (set_environment_runner) — the plix pins none; packages / variables are the environment's, never the runner's. A cell whose environment is on a runner runs server-side there (run, no tab) as soon as the runner process is online. A runner only computes: where rows are kept is a storage (list_storages), which any runner reads and writes. Lists every runner option with the exact engine / engineUrl values, each paired runner's `online` state, and the startCommand. ADDING a runner is AUTH-BASED and happens on the machine + in the browser, not through a tool: the startCommand (`uv run <app>/pair.py runner` — a self-contained script the app serves) runs on the target machine in the directory that becomes the runner's root (the runner builds its OWN venv there: `--python 3.12` is required, `-r requirements.txt` seeds the base packages, `--include <path>` adds a local package editable and reports its git state) and prints a link `<app>/pair/<code>`; the USER opens it signed in and confirms — the runner comes online with a key it keeps in that directory, so later starts need no pairing. If you have shell access on that machine, start it yourself in the background, read the link from its output and give it to the user to open. The runner pulls its jobs over an outbound connection: nothing to expose, no URL. ONE directory = ONE runner: pairing under an existing runner's name re-keys that runner instead of adding another. Runners persist per user across sessions and devices. Docs (runners, pairing): https://docs.plixlab.com/#runners
list_runners
List a plix's slides in plix order: id, title, rev, element count and `excluded` (skipped when presenting; get_slide reads one whole).
list_slides
A STORAGE is where rows keep their bytes — the rail's Storage section. Plixlab Storage ('cloud') is always there; the user can PAIR their own — a directory of one of their machines served as an S3-compatible storage, reached by their tab and by any of their runners on its network through signed URLs (never by a Cloud cell). A row's storage is chosen per row (create_dataset / upload_asset `storage`, move_row; update_plix defaultStorage = where a plix's new rows start), apart from where its cells compute. Lists Plixlab Storage and each paired storage with its `online` state, endpoint, machine and directory, how much the account keeps on it, and the startCommand. ADDING a storage is AUTH-BASED and happens on the machine + in the browser, not through a tool: the startCommand (`uv run <app>/pair.py storage`) runs on the target machine in the directory whose `.plixlab/blobs` becomes the store (`--port` picks the port it listens on) and prints a link `<app>/pair/<code>`; the USER opens it signed in and confirms — the storage comes up with a key it keeps in that directory, so later starts need no pairing. The process must keep running for its rows to be read.
list_storages
Moves a row's bytes — the row card's storage menu: `storage` = 'cloud' (Plixlab Storage — every cell, viewer and link reaches it) or one of the user's OWN STORAGES (list_storages — reached by the user's tab and their runners on its network, never by a Cloud cell); the row keeps its identity and nothing recomputes; waited for up to 90 s. ONE CALL: `rows` is a LIST — put every row to move row to a storage in this single call (done in order; the first failure stops the list, the ones before it stay done).
move_row
Advance every live view of a plix to the next slide
next_slide
SHOW / OPEN / DISPLAY / VIEW / PRESENT a plix (a presentation, a slide deck, whose slides its own Python cells compute). Use this whenever the user asks to see, open, show, view, present, or 'pull up' a specific plix. Returns a private, ready-to-open link to the LIVE plix — if you can run shell commands, open it in the user's default browser yourself; otherwise give the user the link. It is not rendered inline in this conversation. The plix stays live once open: subsequent update_slide / goto_slide / run calls are reflected in it instantly, and the user can edit in it directly. Works for the user's own private plixes (no sharing needed). Do NOT use get_plix for showing a plix (that returns raw JSON, not a view).
open_plix
Go back to the previous slide in every live view of a plix
prev_slide
The LOCAL PACKAGES of a runner are the ones it was started with (`--include <path>`: packages under development, installed editable in the runner's venv) — and nothing else on that machine. READ-ONLY: the runner never writes a package (the owner edits it on their machine; the tree hash shows the edit). `runner` = the runner's name (list_runners, kind 'hosted'; default: the only online one). Docs (runners, --include): https://docs.plixlab.com/#runners Reads ONE file of a local package (`path` inside the package): its text.
read_local_package_file
Read a row — by its id or its name (list_assets). A cell's OUTPUT is a row: read it by its port's name (its LAST-RUN value: run first if the cell never ran); under a SWEEP a cell writes one row per sample, named as its port — read one as "<port>/<sample>". A yaml / csv / mermaid / latex / markdown row comes back as the TEXT its file is (a csv cut to its first maxRows rows, any text to 100,000 characters); every other row is a FILE (an h5, an image, a video, a gltf…), described by its kind and size: `download` gives the file itself. ONE CALL: `datasets` is a LIST — put every row to read in this single call (done in order; the first failure stops the list, the ones before it stay done).
read_dataset_content
Records durable FACTS about THIS USER in the connector's memory (each: `content`, its `type`, its `scope`). Memory is injected at the start of every session (help / get_current_state), so write what a future session must not rediscover: stated preferences (accent colour, chart style, which engine runs what), corrections the user made to your work, standing context about a plix (what it is for, what its data is). One short sentence per fact; no secrets, nothing the user would not expect kept. scope 'global' = every plix; 'plix' + plixId = that plix only. Budget 30 global + 20 per plix, oldest-touched evicted. The reply reads every fact back.
remember
Plixlab ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Plixlab's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.