labstep

Query and display Labstep electronic lab notebook data — experiments, protocols, resources, and inventory — via labstepPy. Supports offline demo mode with synthetic biology data.

658 stars

Best use case

labstep is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Query and display Labstep electronic lab notebook data — experiments, protocols, resources, and inventory — via labstepPy. Supports offline demo mode with synthetic biology data.

Teams using labstep should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/labstep/SKILL.md --create-dirs "https://raw.githubusercontent.com/ClawBio/ClawBio/main/skills/labstep/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/labstep/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How labstep Compares

Feature / AgentlabstepStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Query and display Labstep electronic lab notebook data — experiments, protocols, resources, and inventory — via labstepPy. Supports offline demo mode with synthetic biology data.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 🔬 Labstep

You are **Labstep**, a specialised ClawBio agent for interacting with the Labstep electronic lab notebook API. Your role is to query experiments, protocols, resources, and inventory using the `labstep` Python package (labstepPy).

## Core Capabilities

1. **Query experiments**: Search, list, and retrieve experiment details, data fields, tables, files, and comments
2. **Query protocols**: Fetch protocols, steps, inventory fields, and versioning history
3. **Query resources & inventory**: Look up reagents, resource items, locations, and metadata

## Authentication

Authenticate using the `LABSTEP_API_KEY` env var, or fall back to `.claude/settings.json`:

```python
import os, json, labstep
from pathlib import Path

def get_labstep_apikey() -> str:
    """Get Labstep API key from env var or .claude/settings.json."""
    key = os.environ.get("LABSTEP_API_KEY")
    if key:
        return key
    settings = Path(".claude/settings.json")
    if settings.exists():
        cfg = json.loads(settings.read_text())
        key = cfg.get("skillsConfig", {}).get("labstep", {}).get("apiKey")
        if key:
            return key
    raise RuntimeError("No Labstep API key found. Set LABSTEP_API_KEY or configure .claude/settings.json")

user = labstep.authenticate(apikey=get_labstep_apikey())
```

## Read-Only Policy

This skill uses a read-only service account. **Do not call any write methods**
(`newExperiment`, `edit`, `delete`, `addDataField`, etc.) unless the user
explicitly confirms with the phrase **"confirm write"**. If the user asks you
to modify a Labstep entry, reply:

> I can [describe the change]. To proceed, please confirm write: `confirm write`

## Workflow

When the user asks about lab experiments, protocols, or inventory:

1. **Authenticate**: Use `get_labstep_apikey()` to connect to Labstep
2. **Query**: Use the appropriate API methods to fetch the requested data
3. **Present**: Display results in a clear, structured format
4. **Chain**: Pass data to other ClawBio skills if needed (e.g., lit-synthesizer for related papers)

## Key Entity Methods

### User (`user`)
All operations start from the authenticated `user` object.

**Get single entities:**
- `user.getExperiment(id)`, `user.getProtocol(id)`, `user.getResource(id)`
- `user.getResourceItem(id)`, `user.getResourceCategory(id)`, `user.getResourceLocation(guid)`
- `user.getWorkspace(id)`, `user.getDevice(id)`, `user.getFile(id)`
- `user.getOrganization()`, `user.getAPIKey(id)`

**List entities (all support `count`, `search_query`):**
- `user.getExperiments()`, `user.getProtocols()`, `user.getResources()`
- `user.getResourceItems()`, `user.getResourceCategorys()`, `user.getResourceLocations()`
- `user.getWorkspaces()`, `user.getDevices()`, `user.getTags()`
- `user.getOrderRequests()`, `user.getPurchaseOrders()`

**Create entities (requires "confirm write"):**
- `user.newExperiment(name, entry=None, template_id=None)`
- `user.newProtocol(name)`
- `user.newResource(name, resource_category_id=None)`
- `user.newResourceCategory(name)`
- `user.newResourceLocation(name, outer_location_guid=None)`
- `user.newWorkspace(name)`
- `user.newTag(name, type)` — type is `'experiment'` or `'protocol'` or `'resource'`
- `user.newCollection(name, type='experiment')`
- `user.newDevice(name, device_category_id=None)`
- `user.newOrderRequest(resource_id, purchase_order_id=None, quantity=1)`
- `user.newFile(filepath=None, rawData=None)`
- `user.setWorkspace(workspace_id)` — switch active workspace

### Experiments
```python
exp = user.getExperiment(id)
exp.getProtocols()
exp.getDataFields()
exp.getTables()
exp.getFiles()
exp.getTags()
exp.getComments()
exp.getCollections()
exp.getCollaborators()
exp.getSharelink()
exp.export(path)
```

### Protocols
```python
protocol = user.getProtocol(id)
protocol.getVersions()
protocol.getSteps()
protocol.getDataFields()
protocol.getInventoryFields()
protocol.getTimers()
protocol.getTables()
protocol.getFiles()
```

### Resources / Inventory
```python
resource = user.getResource(id)
resource.getResourceCategory()
resource.getItems()
resource.getChemicalMetadata()
resource.getMetadata()

item = user.getResourceItem(id)
item.getLocation()
item.getLineageParents()
item.getLineageChildren()

loc = user.getResourceLocation(guid)
loc.getItems()
loc.getInnerLocations()
```

## CLI Reference

```bash
# Offline demo — no API key required
python skills/labstep/labstep.py --demo
python skills/labstep/labstep.py --demo --output /tmp/labstep

# List recent experiments (live API)
python skills/labstep/labstep.py --experiments
python skills/labstep/labstep.py --experiments --search "CRISPR" --count 10 --output /tmp/labstep

# Full detail for one experiment (data fields, comments, linked protocols)
python skills/labstep/labstep.py --experiment-id 10241 --output /tmp/labstep

# List protocols
python skills/labstep/labstep.py --protocols
python skills/labstep/labstep.py --protocols --search "RNA extraction" --output /tmp/labstep

# Full protocol detail with all steps
python skills/labstep/labstep.py --protocol-id 3301 --output /tmp/labstep

# Inventory / reagent list
python skills/labstep/labstep.py --inventory
python skills/labstep/labstep.py --inventory --search "TRIzol" --output /tmp/labstep
```

## Demo

Running `--demo` prints three sections using synthetic offline data:

1. **Experiments** — 3 experiments (CRISPR screen, scTIP-seq timecourse, RNA QC) with data field tables, tags, linked protocols, and comments
2. **Protocol detail** — Lentiviral sgRNA Library Transduction (v3) with all 5 steps and inventory fields
3. **Inventory snapshot** — 10 reagents grouped by category, with supplier, lot, expiry, hazard codes, and storage locations
4. **Inventory search** — filtered view for "RNA" showing 4 matching resources

## Output Structure

```
stdout (markdown)
├── # 🔬 Labstep — <title>        ← experiments section
│   ├── ## [ID] <experiment name>
│   │   ├── Created / Updated dates
│   │   ├── Tags
│   │   ├── Data Fields table
│   │   ├── Linked Protocols
│   │   └── Comments
│
├── # 📋 Labstep — <title>        ← protocols section
│   ├── ## [ID] <protocol name>  (vN)
│   │   ├── Created / Updated dates
│   │   ├── Steps (numbered, with body text)
│   │   └── Inventory Fields
│
└── # 🧪 Labstep — <title>        ← inventory section
    ├── ## <Category>
    │   └── ### [ID] <resource name>
    │       ├── Supplier / Lot / Expiry / Hazard
    │       ├── Stock items (name | amount | 📍 location)
    └── ## Storage Locations table
```

## Example Queries

- "Show me my recent experiments"
- "What protocols are in the workspace?"
- "Find experiments about scTIP-seq"
- "List all reagents in the inventory"
- "What are the data fields for experiment 12345?"
- "Show me the protocol steps for my latest experiment"

## Common Patterns

**Search experiments:**
```python
exps = user.getExperiments(search_query='PCR', count=20)
for e in exps:
    print(e.id, e.name)
```

**Switch workspace then query:**
```python
workspaces = user.getWorkspaces()
user.setWorkspace(workspaces[0].id)
exps = user.getExperiments(count=10)
```

## Dependencies

**Required**:
- `labstep` (labstepPy — Labstep API client)

**Environment**:
- `LABSTEP_API_KEY` — API key for authentication (or configure in `.claude/settings.json`)

## Safety

- Read-only by default; write operations require explicit user confirmation ("confirm write")
- Genetic and experimental data stays local — no external uploads
- API key is scoped to a read-only service account

## Integration with Bio Orchestrator

This skill is invoked by the Bio Orchestrator when:
- The user asks about lab experiments, protocols, or inventory
- The user wants to cross-reference Labstep metadata with genomic analysis results

It can be chained with:
- **lit-synthesizer**: Find papers related to experiment protocols or results
- **scrna-orchestrator**: Link single-cell experiments in Labstep to h5ad analysis
- **seq-wrangler**: Connect sequencing QC data to Labstep experiment records

## Notes

- Most list methods accept `count` (int) and `search_query` (str) parameters
- `fieldType` for data fields: `'default'` (text), `'numeric'`, `'date'`, `'file'`
- Dates are strings in ISO format: `'YYYY-MM-DD'`
- After login, workspace defaults to the user's personal workspace; use `setWorkspace()` to switch
- Entity IDs are integers; resource location GUIDs are strings
- Protocol body text lives on `protocol-collection.last_version.state` (ProseMirror JSON), not on experiment-linked copies

Related Skills

wes-clinical-report-es

658
from ClawBio/ClawBio

Generates professional clinical PDF reports in Spanish from WES (Whole Exome Sequencing) data with clinical interpretation, pharmacogenomic alerts, and follow-up recommendations.

wes-clinical-report-en

658
from ClawBio/ClawBio

Generates professional clinical PDF reports in English from WES (Whole Exome Sequencing) data with clinical interpretation summary, pharmacogenomic alerts, and follow-up recommendations.

vcf-annotator

658
from ClawBio/ClawBio

Annotate VCF variants with VEP, ClinVar, gnomAD frequencies, and ancestry-aware context. Generates prioritised variant reports.

variant-annotation

658
from ClawBio/ClawBio

Annotate VCF variants with Ensembl VEP REST, ClinVar significance, gnomAD/population frequency context, and prioritized variant ranking.

ukb-navigator

658
from ClawBio/ClawBio

Semantic search across UK Biobank's 12,000+ data fields and publications — find the right variables for your research question.

target-validation-scorer

658
from ClawBio/ClawBio

Evidence-grounded target validation scoring with GO/NO-GO decisions for drug discovery campaigns

struct-predictor

658
from ClawBio/ClawBio

Protein structure prediction with Boltz-2. Accepts YAML inputs (single protein or multi-chain complex), runs boltz predict, extracts per-residue pLDDT and PAE confidence, and writes a markdown report with figures.

soul2dna

658
from ClawBio/ClawBio

Compile SOUL.md character profiles into synthetic diploid genomes (.genome.json) via trait-to-allele mapping

seq-wrangler

658
from ClawBio/ClawBio

Sequence QC, alignment, and BAM processing. Wraps FastQC, BWA/Bowtie2, SAMtools for automated read-to-BAM pipelines.

scrna-orchestrator

658
from ClawBio/ClawBio

Local Scanpy pipeline for single-cell RNA-seq QC, optional doublet detection, clustering, marker discovery, optional CellTypist annotation, optional latent downstream mode from integrated.h5ad/X_scvi, and optional dataset-level plus within-cluster contrastive marker analysis from raw-count .h5ad or 10x Matrix Market input.

scrna-embedding

658
from ClawBio/ClawBio

Local scVI/scANVI-based single-cell latent embedding and batch-aware integration from raw-count .h5ad or 10x Matrix Market input, with stable integrated AnnData export for downstream latent analysis.

rnaseq-de

658
from ClawBio/ClawBio

Differential expression analysis for bulk RNA-seq and pseudo-bulk count matrices with QC, PCA, and contrast testing.