Skip to main content

FigOps

PyPI Python License CI

From messy analysis folders to traceable, publication-oriented figures.

FigOps is a small research-ops toolkit for figure work: it reads a project config, checks the declared data contract, runs analysis and plotting scripts, applies journal/presentation styling, and records enough provenance to make the figure auditable later.

It is intentionally boring in the best way: one config, one command, clear inputs, repeatable outputs.

python -m pip install figops
figops --help
figops-mcp --smoke

If those commands work, the CLI is installed and the MCP surface is alive.


Why FigOps exists

Research figures often start as a few scripts and a folder of exported data. That works until the figure changes, a collaborator asks where a value came from, or a manuscript revision needs the same plot in a different journal style.

FigOps keeps that workflow lightweight while making the important parts explicit:

  • Data is the API — inputs are declared, checked, and traceable.
  • Figures are rebuildable — analysis, plotting, diagrams, and assembly live behind the same project contract.
  • Style is reusable — journal and presentation targets are selected through config instead of one-off plotting edits.
  • Agents can inspect safely — the MCP server exposes read, render, and smoke surfaces for tool-assisted figure workflows.

Current State

Item Status
Source checkout 0.20.0 release-candidate metadata (pyproject.toml); not yet published
Published package figops==0.19.0 is the latest published PyPI release
TestPyPI figops==0.19.0 is the latest available build; rerun install smoke before 0.20.0 promotion
Python 3.12+
License Apache-2.0 for public package distribution
Commands figops, figops-mcp
Compatibility aliases graphhub, graphhub-mcp
GitHub Release v0.19.0 is the latest published release asset

The source checkout is a 0.20.0 release candidate. The latest published PyPI package, TestPyPI dry run, and GitHub Release asset remain at 0.19.0 until a separate release promotion is approved and run.

Install

For normal use:

python -m pip install figops

For a pinned, reproducible install:

python -m pip install figops==0.19.0

If you need the exact GitHub Release asset:

gh release download v0.19.0 --repo Moonweave-Research/figops --pattern "*.whl" --dir dist-release
python -m pip install dist-release/figops-0.19.0-py3-none-any.whl
figops-mcp --smoke

Quick start

For an installed package, verify the published CLI surface first:

figops --help
figops-mcp --smoke
figops-mcp doctor

For a source checkout, use hub_uv.py instead of bare uv run so the managed environment stays outside the repository:

python hub_uv.py sync
python hub_uv.py --print-env
python hub_uv.py run python figops_mcp_server.py --hub-path . --research-root . --runtime-root .omo/evidence/task-6-runtime doctor --json
python hub_uv.py run python figops_mcp_server.py doctor
python hub_uv.py run python -m pytest tests/test_doctor.py -q

If uv is not installed, the source-checkout path cannot bootstrap itself. Use an already prepared Python 3.12+ environment with the FigOps runtime/dev dependencies, or install uv outside the repository and rerun the wrapper commands. The JSON doctor output reports the active Python, uv on PATH, the resolved runtime root, and the planned external uv environment/cache paths. R is only required for projects that declare lang: R.

Create a new figure project:

figops --init --project my_figure_project
cd my_figure_project

That creates a scaffold with:

my_figure_project/
├── project_config.yaml
├── raw/
│   ├── example.csv
│   └── .raw_manifest.json
├── hub_scripts/
│   ├── analysis/analyze.R
│   ├── figures/
│   │   ├── plot.py
│   │   └── device_cross_section.py
│   └── shared/project_context.py
└── results/
    ├── data/{intermediate,source}/
    ├── tables/
    ├── figures/
    ├── evidence/
    └── publication/

The scaffold manifest records these durable role roots and explicitly marks runtime state as external and disposable. Scaffolding never creates runtime, cache, log, preview, or temporary directories inside the project.

Run the project:

figops --project . --step all

For a first sanity check, list the available CLI options:

figops --help

What FigOps does

A FigOps run coordinates the work around a research figure:

  1. read project_config.yaml,
  2. resolve declared input files,
  3. validate data contracts and research-ops rules,
  4. run analysis scripts when needed,
  5. render figures, diagrams, or assembled panels,
  6. apply the selected style profile,
  7. write provenance and runtime metadata for auditability.

A minimal config looks like this:

project:
  name: "Example Study"

visual_style:
  target_format: nature
  font_scale: 1.0
  profile: baseline

pipeline:
  analysis:
    - script: "hub_scripts/analyze.R"
      lang: R
      cache: true

figures:
  - id: Fig1
    script: "hub_scripts/plot.py"
    output: "results/figures/Fig1.png"
    cache: true

R is only required when your configured analysis scripts use R. Python plotting and package/MCP smoke checks run from the Python package install.

Everyday commands

# Choose a configured project interactively
figops

# List configured projects
figops --list-projects

# Run the full pipeline for one project
figops --project "ProjectName" --step all

# Re-render figures only
figops --project "ProjectName" --step plot

# Re-render diagrams only
figops --project "ProjectName" --step diagrams

# Force a clean rerun and bypass cache
figops --project "ProjectName" --step all --force

From a source checkout, use the repo-local runtime wrapper:

python hub_uv.py sync
python hub_uv.py run python orchestrator.py --list-projects
python hub_uv.py run python -m pytest tests/test_runtime_paths.py -q

hub_uv.py keeps the Python runtime outside the repository so the working tree does not get polluted with local virtualenv state.

MCP for agents

FigOps includes a Model Context Protocol server entry point:

figops-mcp --smoke

A healthy smoke response looks like:

{"status": "ok", "health_status": "ok", "tool_surface": "figops_mcp"}

Use this before wiring FigOps into Claude, Codex, or another MCP-capable client. For compatibility with earlier local setups, graphhub-mcp remains available as an alias.

Migrating MCP discovery in 0.20.0

The launcher now returns the compact AI-native v2 profile from tools/list by default. Existing tool handlers and payload schemas were not removed. Clients that depend on the full pre-v2 list—including the frozen canonical tools and graphhub.* aliases—must explicitly select the compatibility surface profile. This opt-in preserves existing calls while keeping new-agent discovery small and evidence-first. Set GRAPH_HUB_MCP_SURFACE_PROFILE=compatibility in launcher configuration, or pass surface_profile="compatibility" when embedding FigOpsMCPServer. See docs/tools-v2.md and docs/tools-compatibility.md.

Projects outside the primary PROJECT_ROOT may be admitted explicitly with GRAPH_HUB_MCP_ALLOWED_PROJECT_ROOTS (a path-separated list), or by repeating --allowed-project-root on the MCP launcher. This includes NAS-backed research roots; the disposable MCP runtime root is intentionally never a project root.

Troubleshooting

Symptom What to try
project_config.yaml not found Run figops --init --project "<project>" or move into a configured project.
Project directory not found Run figops --list-projects and copy the exact configured name.
Strict lockfile errors --strict-lock is for reproducibility checks. For quick local rendering, rerun without strict mode.
Google Drive files feel stuck Let Drive finish syncing, then rerun. The prefetch layer can help with declared inputs, but it cannot repair a broken Drive login/session.
Source-checkout tests fail with No module named pytest Run python hub_uv.py sync --group dev, then rerun tests through python hub_uv.py run python -m pytest ....
Doctor reports missing pandas, matplotlib, or yaml Run python hub_uv.py sync from the checkout, or use a Python 3.12+ environment with FigOps runtime dependencies installed.
R script fails immediately Confirm Rscript is available if your project config uses lang: R.

For maintainers

Release candidates are checked with the packaging and test gates below:

uv build
python scripts/package_metadata_smoke.py
python scripts/public_package_surface.py
python scripts/consumer_install_smoke.py
uv run --with twine python -m twine check dist/*
python hub_uv.py run python -m pytest -q
python hub_uv.py run ruff check .

After release assets are uploaded, verify both the GitHub artifact and the public install path:

python scripts/github_release_asset_smoke.py
python -m pip install figops==0.19.0
figops-mcp --smoke

Publishing uses the manual Trusted Publishing workflow in .github/workflows/publish.yml: TestPyPI first, install smoke, then PyPI. See docs/packaging/trusted-publishing.md for the exact runbook.

Repository map

Path Purpose
orchestrator.py CLI entry point and top-level pipeline coordinator
hub_core/ Config loading, validation, cache, provenance, process execution, MCP logic
hub_core/mcp/ MCP server, schemas, transport, resources, prompts, and tool handlers
plotting/ Reusable plotting helpers and figure assembly utilities
themes/ Journal and presentation style presets
examples/ Small synthetic projects and package-facing examples
scripts/ Release, packaging, and distribution checks
tests/ Regression and contract tests
docs/packaging/ PyPI readiness, clearance checklist, and Trusted Publishing runbook

Next release checklist

For the next release, keep the same conservative path:

  1. bump the version,
  2. rebuild wheel/sdist from a clean tree,
  3. confirm package artifacts exclude private docs/tests/research markers,
  4. publish to TestPyPI through .github/workflows/publish.yml,
  5. install-check from TestPyPI,
  6. promote the same version to PyPI,
  7. install-check from public PyPI.

License

FigOps is distributed under the Apache-2.0 license. See LICENSE and NOTICE.

Metadata

Release files for figops 0.20.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for figops 0.20.3
File Size Uploaded
figops-0.20.3.tar.gz 597.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for figops 0.20.3
File Interpreter ABI Platform
figops-0.20.3-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / figops-0.20.3.tar.gz

Download URL figops-0.20.3.tar.gz
Size 597.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e748e80b71fe489cb1612dcf3f5f206a73781203d29b3f9fa07adf0ca54f6784
BLAKE2b-256 checksum
How to use checksums
9163989f56cdd602ab6a0824616885755afacdc5654dec1ea6abc08e4cfc1d77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.

Transparency log

Release files / figops-0.20.3-py3-none-any.whl

Download URL figops-0.20.3-py3-none-any.whl
Size 720.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9dd0dfb26a7d01839a4ed69d6efd99f46faec0eb9d0b9ff6bb8484b2ddaf2a0a
BLAKE2b-256 checksum
How to use checksums
c0f6b7d415a080a65455f51dbab326b2c2c06c3d8c4ff771ef34adb80ff72825
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.

Transparency log

Release history Release notifications | RSS feed

0.20.5

2 release files

0.20.4

2 release files

This release

0.20.3 This release

2 release files

0.20.0

2 release files

0.19.0

2 release files

0.18.0

2 release files

0.17.9

2 release files

0.17.8

2 release files

0.17.7

2 release files

0.17.6

2 release files

0.17.5

2 release files

0.17.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page