Regulomedb Database logo

Regulomedb Database

Community
jaechang-hits
regulomedb-database

Query RegulomeDB v2 GET REST API to score variants for regulatory function and retrieve overlapping evidence (TF binding, histone marks, DNase peaks, footprints, motifs, eQTLs, chromatin state). Scores range 1a (strongest) to 7 (none). Use for GWAS hit prioritization, regulatory variant annotation, cis-regulatory discovery. Use clinvar-database for pathogenicity; gwas-database for trait associations.

Overview

Publisherjaechang-hits
RepositorySciAgent-Skills
Skill nameregulomedb-database
Stars
381
Forks
45
Bundled files
Instructions only
LicenseCC-BY-4.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by jaechang-hits on GitHub. Read the source before you install it.

Installation

Install the Regulomedb Database AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/regulomedb-database
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git /tmp/SciAgent-Skills
mkdir -p .claude/skills
cp -r /tmp/SciAgent-Skills/skills/genomics-bioinformatics/databases/regulomedb-database .claude/skills/regulomedb-database
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Regulomedb Database in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Regulomedb Database on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Regulomedb Database is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

RegulomeDB Database

Overview

RegulomeDB integrates large-scale functional genomics data (ENCODE, Roadmap Epigenomics) to score genetic variants for regulatory potential. Each variant receives a ranking from 1a (highest regulatory confidence: eQTL + TF + DNase + motif + chromatin) to 7 (no known regulatory function). The v2 API is exposed as GET https://regulomedb.org/regulome-search/; the legacy POST /regulome-search/, POST /regulome-summary/, and GET /regulome-datasets/ JSON endpoints are no longer functional (return regulome-notfound stubs or 500). Access is free and requires no authentication.

When to Use

  • Prioritizing GWAS hits for regulatory follow-up — identify which SNPs land in active regulatory elements
  • Annotating a VCF or variant list with regulatory scores to filter to functionally relevant variants
  • Identifying which transcription factors bind near a variant of interest (via the @graph evidence rows)
  • Checking whether a non-coding variant overlaps a QTL and active chromatin simultaneously (features.QTL)
  • Retrieving all annotated rsIDs in a genomic region for cis-regulatory analysis (region query with nearby_snps)
  • Use clinvar-database instead when you need clinical pathogenicity classifications; RegulomeDB scores regulatory function, not germline disease association
  • Use gwas-database instead when you want published GWAS associations with traits

Prerequisites

  • Python packages: requests, pandas, matplotlib
  • Data requirements: rsIDs (e.g., rs4946036), genomic positions (chr1:1000000), or region coordinates (chr1:1000000-2000000)
  • Genome build: GRCh38 (default) or GRCh37; specify in all requests
  • Rate limits: No published rate limits; use time.sleep(0.3) between requests in batch workflows
bash
pip install requests pandas matplotlib

Quick Start

python
import requests

BASE = "https://regulomedb.org"

def regulome_score(variant, genome="GRCh38"):
    """Score a single variant (rsID or chr:pos-pos) via the GET /regulome-search/ endpoint."""
    r = requests.get(
        f"{BASE}/regulome-search/",
        params={"regions": variant, "genome": genome, "format": "json"},
        timeout=30,
    )
    r.raise_for_status()
    d = r.json()
    rs = d.get("regulome_score", {})
    vs = d.get("variants", [])
    return {
        "query": variant,
        "ranking": rs.get("ranking"),           # 1a / 1b / ... / 7
        "probability": float(rs.get("probability", 0)),
        "rsids": vs[0].get("rsids") if vs else [],
        "chrom": vs[0].get("chrom") if vs else None,
        "pos": vs[0].get("start") if vs else None,
    }

print(regulome_score("rs4946036"))
# {'query': 'rs4946036', 'ranking': '7', 'probability': 0.18412,
#  'rsids': ['rs4946036'], 'chrom': 'chr6', 'pos': 114819799}

Core API

Query 1: Score a Single Variant (rsID or position)

The GET /regulome-search/ endpoint accepts an rsID or coordinate as regions=. Returns a regulome_score block (probability, ranking, tissue-specific scores) plus features flags and the per-dataset @graph evidence rows.

python
import requests

BASE = "https://regulomedb.org"

def score_variant(variant, genome="GRCh38"):
    """Return the regulome_score block and resolved coordinates."""
    r = requests.get(
        f"{BASE}/regulome-search/",
        params={"regions": variant, "genome": genome, "format": "json"},
        timeout=30,
    )
    r.raise_for_status()
    d = r.json()
    rs = d.get("regulome_score", {})
    vs = d.get("variants", [])
    feats = d.get("features", {})
    print(f"Variant   : {variant}")
    print(f"Resolved  : {vs[0]['chrom']}:{vs[0]['start']} ({', '.join(vs[0].get('rsids', []))})")
    print(f"Ranking   : {rs.get('ranking')}  prob={rs.get('probability')}")
    print(f"Features  : ChIP={feats['ChIP']} Chromatin_accessibility={feats['Chromatin_accessibility']} "
          f"QTL={feats['QTL']} Footprint={feats['Footprint']} PWM_matched={feats['PWM_matched']}")
    return d

# Strong-regulatory locus example
score_variant("chr11:5226739-5226740")
# Ranking: 1a (HBB beta-globin promoter, multi-evidence)
python
# Score by chromosomal position alone
score_variant("chr17:7670000-7670001")  # TP53 region

Query 2: Region Scan — List Annotated Variants in a Window

A range query returns up to limit resolved variants (variants[]) and all @graph evidence rows in the window, plus nearby_snps (rsIDs adjacent to the resolved hits).

python
import requests, pandas as pd

BASE = "https://regulomedb.org"

def scan_region(chrom, start, end, genome="GRCh38", limit=200):
    """List variants in a region with their resolved positions and overlapping rsIDs."""
    r = requests.get(
        f"{BASE}/regulome-search/",
        params={"regions": f"{chrom}:{start}-{end}", "genome": genome,
                "format": "json", "limit": limit},
        timeout=60,
    )
    r.raise_for_status()
    d = r.json()
    variants = d.get("variants", [])
    print(f"Variants in {chrom}:{start}-{end}: {len(variants)} (total indexed = {d.get('total')})")
    rows = [{"rsids": ", ".join(v.get("rsids", [])),
             "chrom": v.get("chrom"),
             "start": v.get("start"),
             "end": v.get("end")} for v in variants]
    return pd.DataFrame(rows)

df = scan_region("chr11", 5226000, 5227000)
print(df.head(10).to_string(index=False))

Query 3: Full Evidence — Parse the @graph Rows

Each @graph[i] row is one experimental piece of evidence overlapping the query. Fields: method, target_label, biosample_ontology{term_name, organ_slims, classification}, dataset, file, value, chrom, start, end, strand, ancestry, disease_term_name.

python
import requests, pandas as pd

BASE = "https://regulomedb.org"

def evidence_rows(variant, genome="GRCh38"):
    r = requests.get(
        f"{BASE}/regulome-search/",
        params={"regions": variant, "genome": genome, "format": "json"},
        timeout=60,
    )
    r.raise_for_status()
    g = r.json().get("@graph", [])
    rows = []
    for row in g:
        bs = row.get("biosample_ontology") or {}
        rows.append({
            "method": row.get("method"),
            "target_label": row.get("target_label"),
            "biosample": bs.get("term_name"),
            "organ_slims": ", ".join(bs.get("organ_slims") or []),
            "dataset": row.get("dataset", "").split("/")[-2] if row.get("dataset") else None,
            "value": row.get("value"),
        })
    return pd.DataFrame(rows)

df_evidence = evidence_rows("chr11:5226739-5226740")
# Each method is one of: ChIP-seq, Histone ChIP-seq, ATAC-seq, DNase-seq,
# footprints, PWMs, chromatin state, eQTLs
print(df_evidence["method"].value_counts())

Query 4: TF ChIP-seq Hits — Filter Evidence by Method

To list the transcription factors binding near a variant, filter @graph rows where method == "ChIP-seq" and read target_label + biosample_ontology.term_name.

python
import requests, pandas as pd

BASE = "https://regulomedb.org"

def tf_binding(variant, genome="GRCh38"):
    r = requests.get(f"{BASE}/regulome-search/",
                     params={"regions": variant, "genome": genome, "format": "json"},
                     timeout=60)
    r.raise_for_status()
    rows = []
    for g in r.json().get("@graph", []):
        if g.get("method") != "ChIP-seq":
            continue
        bs = g.get("biosample_ontology") or {}
        rows.append({
            "tf": g.get("target_label"),
            "biosample": bs.get("term_name"),
            "classification": bs.get("classification"),
        })
    return pd.DataFrame(rows)

df_tfs = tf_binding("chr11:5226739-5226740")
print(f"TF ChIP-seq peaks overlapping query: {len(df_tfs)}")
print(df_tfs.groupby("tf").size().sort_values(ascending=False).head(10))

Query 5: Tissue-Specific Regulatory Score

regulome_score.tissue_specific_scores maps ~50 tissues to per-tissue regulatory probabilities (0–1). Rank tissues to identify where the variant has the strongest regulatory signal.

python
import requests, pandas as pd

BASE = "https://regulomedb.org"

def tissue_scores(variant, genome="GRCh38", top_n=10):
    r = requests.get(f"{BASE}/regulome-search/",
                     params={"regions": variant, "genome": genome, "format": "json"},
                     timeout=30)
    r.raise_for_status()
    ts = r.json().get("regulome_score", {}).get("tissue_specific_scores", {})
    s = pd.Series({k: float(v) for k, v in ts.items()})
    return s.sort_values(ascending=False).head(top_n)

print("Top tissues by regulatory probability for chr11:5226739-5226740:")
print(tissue_scores("chr11:5226739-5226740"))

Query 6: Nearby SNPs — List rsIDs Adjacent to a Position

nearby_snps carries dbSNP rsIDs near the resolved coordinates, with reference/alt allele frequencies (when GnomAD-indexed).

python
import requests, pandas as pd

BASE = "https://regulomedb.org"

def nearby(variant, genome="GRCh38"):
    r = requests.get(f"{BASE}/regulome-search/",
                     params={"regions": variant, "genome": genome, "format": "json"},
                     timeout=30)
    r.raise_for_status()
    rows = []
    for s in r.json().get("nearby_snps", []):
        rows.append({
            "rsid": s.get("rsid"),
            "chrom": s.get("chrom"),
            "pos": s.get("coordinates", {}).get("gte"),
            "type": s.get("variation_type"),
            "maf": s.get("maf"),
        })
    return pd.DataFrame(rows)

df_nearby = nearby("rs4946036")
print(f"Nearby SNPs to rs4946036: {len(df_nearby)}")
print(df_nearby.head(10).to_string(index=False))

Key Concepts

RegulomeDB Scoring Schema

RegulomeDB ranks encode the strength of evidence overlapping a variant. The regulome_score.ranking string is one of:

RankingEvidenceConfidence
1aeQTL + TF + DNase + motif + matched footprintHighest
1b–1fMulti-evidence (sub-ranks reflect which inputs match)Very high
2aTF binding + DNase + motifHigh
2bTF binding + any DNase (no motif required)High
2cTF binding + DNase (limited)Moderate-high
3aDNase + motif (no TF ChIP-seq)Moderate
3bMotif only (no DNase)Moderate
4Single TF binding evidenceLow-moderate
5DNase peak onlyLow
6Other regulatory evidenceMinimal
7No known regulatory functionNone

regulome_score.probability is the numeric model score (0–1) underlying the discrete ranking.

features Booleans vs @graph Detail

features is a high-level summary — boolean flags indicating presence of ChIP, Chromatin_accessibility, Footprint, PWM, QTL, etc. For per-dataset detail (which exact TF / cell type / experiment), iterate @graph[] and filter by method.

Variant Input Formats

regions= accepts:

python
# rsID — resolved server-side to current-build coordinates
"rs4946036"

# Single-position range
"chr11:5226739-5226740"

# Wider region (returns multiple variants[] entries + larger @graph)
"chr11:5226000-5227000"

Common Workflows

Workflow 1: GWAS Hit Prioritization

Goal: Score a list of GWAS lead SNPs and rank by regulatory confidence.

python
import requests, time, pandas as pd
import matplotlib.pyplot as plt

BASE = "https://regulomedb.org"

gwas_snps = ["rs7903146", "rs10811661", "rs1801282", "rs4946036",
             "rs2268177", "rs10830963", "rs1111875"]

records = []
for snp in gwas_snps:
    r = requests.get(f"{BASE}/regulome-search/",
                     params={"regions": snp, "genome": "GRCh38", "format": "json"},
                     timeout=30)
    r.raise_for_status()
    d = r.json()
    rs = d.get("regulome_score", {})
    feats = d.get("features", {})
    g = d.get("@graph", [])
    tfs = sorted({row["target_label"] for row in g
                  if row.get("method") == "ChIP-seq" and row.get("target_label")})
    records.append({
        "snp": snp,
        "ranking": rs.get("ranking"),
        "probability": float(rs.get("probability", 0)),
        "has_qtl": feats.get("QTL", False),
        "tf_count": len(tfs),
        "num_evidence_rows": len(g),
    })
    time.sleep(0.3)

df = pd.DataFrame(records).sort_values("probability", ascending=False)
print(df.to_string(index=False))
df.to_csv("gwas_regulatory_priority.csv", index=False)

fig, ax = plt.subplots(figsize=(8, 4))
ax.bar(df["snp"], df["probability"], color="steelblue", edgecolor="black")
ax.set_ylabel("Regulatory probability")
ax.set_title("GWAS lead-SNP regulatory probabilities")
plt.xticks(rotation=45, ha="right")
plt.tight_layout()
plt.savefig("gwas_score_distribution.png", dpi=150, bbox_inches="tight")

Workflow 2: Locus Evidence Profile

Goal: Summarize the methods underlying the score at a locus (e.g., HBB promoter).

python
import requests, pandas as pd
import matplotlib.pyplot as plt

BASE = "https://regulomedb.org"

def locus_profile(region, genome="GRCh38"):
    r = requests.get(f"{BASE}/regulome-search/",
                     params={"regions": region, "genome": genome, "format": "json"},
                     timeout=60)
    r.raise_for_status()
    d = r.json()
    rs = d.get("regulome_score", {})
    g = d.get("@graph", [])
    counts = pd.Series([row.get("method") for row in g]).value_counts()
    print(f"\n=== {region} | ranking={rs.get('ranking')} prob={rs.get('probability')} ===")
    print(counts.to_string())
    return counts

counts = locus_profile("chr11:5226739-5226740")  # HBB

fig, ax = plt.subplots(figsize=(8, 4))
counts.plot(kind="barh", color="seagreen", ax=ax)
ax.set_xlabel("Evidence rows in @graph")
ax.set_title("Regulatory evidence by method (HBB promoter)")
plt.tight_layout()
plt.savefig("locus_evidence_profile.png", dpi=150, bbox_inches="tight")

Key Parameters

ParameterEndpointDefaultRange / OptionsEffect
regionsGET /regulome-search/requiredrsID, chrN:start-end, or chrN:pos-posVariant/region to score
genomeGET /regulome-search/"GRCh38""GRCh38", "GRCh37"Reference genome assembly
formatGET /regulome-search/"html""json", "tsv", "html"Use "json" for programmatic access
limitGET /regulome-search/2001–1000Max resolved variants in variants[] for region queries
fromGET /regulome-search/0non-negative intOffset for paging through large @graph lists

Best Practices

  1. Use GET, not POST. The POST /regulome-search/, POST /regulome-summary/, and GET /regulome-datasets/ JSON endpoints return a regulome-notfound stub or HTTP 500. Only GET /regulome-search/?regions=...&genome=...&format=json returns real data.

  2. Read regulome_score.ranking, not regulomedb_score. The field used to be named regulomedb_score in legacy docs; the live API exposes it as regulome_score.ranking (string like "1a", "7").

  3. Add time.sleep(0.3) between calls. RegulomeDB has no published rate limit, but polite spacing prevents intermittent 502s under load.

  4. Score 7 ≠ "no regulation". Score 7 means absence of evidence in RegulomeDB's curated datasets, not biological absence of regulation. Cross-check with ENCODE/Roadmap directly via encode-database for negative results.

  5. For tissue specificity, use tissue_specific_scores. The single ranking is an aggregate; the per-tissue probabilities reveal where the variant has the strongest regulatory signal.

  6. Watch the GRCh37 vs GRCh38 build. rsIDs are auto-resolved to the requested build, but coordinate-based regions=chrN:start-end queries are build-specific — pass the matching genome= value.

Common Recipes

Recipe: Quick Score Lookup

When to use: One-off check before kicking off a larger pipeline.

python
import requests

def quick_score(variant, genome="GRCh38"):
    r = requests.get("https://regulomedb.org/regulome-search/",
                     params={"regions": variant, "genome": genome, "format": "json"},
                     timeout=20)
    r.raise_for_status()
    rs = r.json().get("regulome_score", {})
    print(f"{variant}: ranking={rs.get('ranking')}  prob={rs.get('probability')}")

quick_score("rs4946036")             # ranking=7 prob=0.18412
quick_score("chr11:5226739-5226740") # ranking=1a (HBB promoter)

Recipe: Filter Variants to High-Confidence Regulatory Set

python
import requests, time, pandas as pd

HIGH_CONF = {"1a", "1b", "1c", "1d", "1e", "1f", "2a", "2b"}

def high_conf_only(variants, genome="GRCh38"):
    keep = []
    for v in variants:
        r = requests.get("https://regulomedb.org/regulome-search/",
                         params={"regions": v, "genome": genome, "format": "json"},
                         timeout=30)
        ranking = r.json().get("regulome_score", {}).get("ranking")
        if ranking in HIGH_CONF:
            keep.append({"variant": v, "ranking": ranking})
        time.sleep(0.3)
    return pd.DataFrame(keep)

df = high_conf_only(["rs4946036", "rs7903146", "chr11:5226739-5226740"])
print(df.to_string(index=False))

Recipe: QTL-Linked Variants

When to use: Find variants with features.QTL == True, i.e. those overlapping a curated QTL row in @graph (method "QTLs").

python
import requests, time, pandas as pd

def qtl_overlap(variants, genome="GRCh38"):
    rows = []
    for v in variants:
        r = requests.get("https://regulomedb.org/regulome-search/",
                         params={"regions": v, "genome": genome, "format": "json"},
                         timeout=30)
        d = r.json()
        if not d.get("features", {}).get("QTL"):
            time.sleep(0.3); continue
        for g in d.get("@graph", []):
            if g.get("method") == "QTLs":
                rows.append({
                    "variant": v,
                    "ranking": d.get("regulome_score", {}).get("ranking"),
                    "qtl_target": g.get("target_label"),
                    "value": g.get("value"),
                    "biosample": (g.get("biosample_ontology") or {}).get("term_name"),
                })
        time.sleep(0.3)
    return pd.DataFrame(rows)

print(qtl_overlap(["rs4946036", "chr11:5226739-5226740"]))

Troubleshooting

ProblemCauseSolution
Response body {"@id":"/regulome-notfound","@type":["regulome-help"]...}Using the legacy POST /regulome-search/ with a JSON bodySwitch to GET with regions= query param + format=json
HTTP 500Hitting the deprecated /regulome-summary/ endpointEndpoint is dead; aggregate counts client-side from @graph[].method
KeyError: 'regulomedb_score'Field renamedUse regulome_score.ranking (string) and regulome_score.probability (float-as-string)
peaks / eqtls / assay_type missingOld schemaIterate @graph[] and filter by method (ChIP-seq, DNase-seq, Histone ChIP-seq, ATAC-seq, footprints, PWMs, QTLs, chromatin state)
Empty variants[] for an rsIDrsID not in RegulomeDB index or build mismatchTry the chr:pos form; check genome= matches the coordinates
Region search returns 0 @graph rowsRegion size too small or in an uncharacterized chromosomeWiden the window to ≥ 200 bp; avoid alt contigs (chrUn_*, *_random)
Region query truncates at 200 resultsDefault limit=200Pass limit=1000 or page with from=0,200,400,...

Related Skills

  • gwas-database — NHGRI-EBI GWAS Catalog for published SNP-trait associations; pair with RegulomeDB to prioritize GWAS hits
  • clinvar-database — Clinical pathogenicity classifications; complements RegulomeDB's functional regulatory evidence
  • encode-database — Direct ENCODE REST API access for the TF ChIP-seq / ATAC-seq peak sets that underlie RegulomeDB scores
  • ensembl-database — Variant annotation and gene coordinate lookup; use to map rsIDs to genomic positions before region queries

References

Frequently asked questions

What does the Regulomedb Database AI skill do?

Query RegulomeDB v2 GET REST API to score variants for regulatory function and retrieve overlapping evidence (TF binding, histone marks, DNase peaks, footprints, motifs, eQTLs, chromatin state). Scores range 1a (strongest) to 7 (none). Use for GWAS hit prioritization, regulatory variant annotation, cis-regulatory discovery. Use clinvar-database for pathogenicity; gwas-database for trait associations.

Why use Regulomedb Database on TypingMind?

Because you install it once and use it with any model. Regulomedb Database is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Regulomedb Database in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/regulomedb-database. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Regulomedb Database?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Regulomedb Database?

As many as you like. As long as a model supports skills, you can use Regulomedb Database with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Regulomedb Database AI skill free?

Yes. It is published on GitHub by jaechang-hits under the CC-BY-4.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇