Flowfile Debugging Playbook
Edwardvaneechoud/Flowfile
Symptom-to-cause triage playbook for Flowfile (core/worker/kernel/frontend/AI) — covers "no such table" DB cascades (two distinct causes), import-time Alembic migration corruption, silent…
A skill your agent uses when running Python or GPU workloads serverlessly on Modal — modal.App, inline container Images, gpu= on @app.function, Volumes for weight caching, Cron schedules, ASGI…
$ npx skills add ericrisco/rsc-harness --skill modal -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ericrisco/rsc-harness modal --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/modal .claude/skills/modal && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "modal" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/modal into .claude/skills/modal/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "modal", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/ericrisco/rsc-harness/tree/main/skills/modalType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add ericrisco/rsc-harness --skill modal -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ericrisco/rsc-harness modal --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/modal .agents/skills/modal && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "modal" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/modal into .agents/skills/modal/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "modal", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ericrisco/rsc-harness --skill modal -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ericrisco/rsc-harness modal --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/modal .cursor/skills/modal && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "modal" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/modal into .cursor/skills/modal/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "modal", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/ericrisco/rsc-harness.git --path skills/modal--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add ericrisco/rsc-harness --skill modal -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ericrisco/rsc-harness modal --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/modal .gemini/skills/modal && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "modal" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/modal into .gemini/skills/modal/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "modal", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install ericrisco/rsc-harness modalInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add ericrisco/rsc-harness --skill modal -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/modal .github/skills/modal && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "modal" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/modal into .github/skills/modal/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "modal", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ericrisco/rsc-harness --skill modal -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ericrisco/rsc-harness modal --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/modal .opencode/skills/modal && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "modal" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/modal into .opencode/skills/modal/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "modal", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
modalA skill your agent uses when running Python or GPU workloads serverlessly on Modal — modal.App, inline container Images, gpu= on @app.function, Volumes for weight caching, Cron schedules, ASGI…
Modal is an agent skill from ericrisco/rsc-harness. Use when running Python or GPU workloads serverlessly on Modal — modal.App, inline container Images, gpu= on @app.function, Volumes for weight caching, Cron schedules, ASGI endpoints, modal run vs serve vs deploy. NOT managed prediction APIs with no container of your own (that is replicate); NOT SSH-able GPU boxes rented by the hour (that is runpod).
Its SKILL.md is about 3.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/images-gpu-cookbook.md`).
It sits in Backend & APIs, covering Containers, Scheduled and recurring tasks and Caching. It works with Python, Docker and FastAPI. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 92fde8f. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/ (Shell), which the agent can run.
Shell commands in SKILL.md call:
modalpippythonFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
modal.coma.comb.comc.comslow.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
HF_TOKENFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Modal loads about 3.5k tokens when it runs, and up to ~5.9k if it reads all its reference files. Until then it costs about 90 tokens; SKILL.md has 1,332 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from ericrisco/rsc-harness at commit 92fde8f, republished under its MIT licence (© ericrisco). 1,332 words, ~3,467 tokens.
.claude/skills/modal/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.Modal runs your Python on remote containers without you ever writing a Dockerfile or a YAML
file. The mental model: infrastructure is declared inline as Python decorators. A
modal.App is the deployable unit; each @app.function runs in its own container built from
a modal.Image you describe in code; you attach a GPU, a Volume, or a Secret as keyword
arguments and the platform provisions, scales to zero, and tears down for you. There is no
control plane to babysit — the source file is the infra.
Pinned stack: modal 1.4.3 (released 2026-05-18), Python 3.10–3.14 (>=3.10,<3.15).
Install with pip install modal then modal setup to authenticate. Everything below uses
the Modal 1.0+ API; several pre-1.0 forms were removed and are called out as Bad→Good.
Modal owns the serverless-container-as-decorators surface and its CLI lifecycle; the contents of your function belong elsewhere.
| The job | Goes to |
|---|---|
| Calling a managed prediction API with no container of your own | replicate / together-fireworks / fal |
| Renting a persistent, SSH-able GPU box by the hour/week | runpod |
| FastAPI design (routing, Pydantic, deps) independent of host | fastapi |
| Writing a Dockerfile for a registry / k8s / Compose | docker |
| General Python language/runtime questions | python |
| RAG / LLM pipeline orchestration logic itself | llm-pipeline |
| You want… | Use | Persists after exit? |
|---|---|---|
| Run a function once and exit (script, batch) | modal run app.py + @app.local_entrypoint() | No (ephemeral) |
| Hot-reload dev loop for a web endpoint | modal serve app.py | No (dies on Ctrl-C) |
| A persistent named deployment (prod, schedules, endpoints) | modal deploy app.py | Yes |
| Fan out work across many containers | .map() / .starmap() / .spawn() inside an entrypoint | n/a |
Rule: schedules and live web endpoints require modal deploy. modal run exits when the
entrypoint returns, so a Cron defined under modal run never fires. modal serve is for the
dev loop only — it watches your files and redeploys on save, but the app vanishes when you
stop it.
import modal
app = modal.App("hello-modal")
# The image is the container spec. Build it once, reuse across functions.
image = modal.Image.debian_slim(python_version="3.12").uv_pip_install("requests")
@app.function(image=image)
def fetch(url: str) -> int:
import requests # imported INSIDE the function: it lives in the remote image, not locally
return len(requests.get(url).content)
@app.local_entrypoint()
def main() -> None:
# Runs on your laptop; .remote() ships the call to a Modal container.
print(fetch.remote("https://modal.com"))Run it: modal run app.py. Bad = wiring infra with argparse + a bash launcher + a
hand-rolled Dockerfile. Good = the decorators above; the app, image, and scaling are all
declared in the one file. Note the in-function import: dependencies you uv_pip_install exist
in the remote image, so import them inside the function (or guard top-level imports), not at
module top where your laptop would need them too.
Build images by chaining methods on modal.Image. Rules, each with its why:
.uv_pip_install(...) over .pip_install(...) — it resolves and installs with
uv, materially faster image builds..uv_pip_install("torch==2.5.1", "transformers==4.46.0"). Unpinned
deps make builds non-reproducible and silently drift on rebuild..add_local_dir(...) / .add_local_python_source(...), not by
pip-installing your repo. These are applied last so editing your source doesn't rebuild torch..from_registry("...") when you need a specific base image; .apt_install("ffmpeg")
for system binaries; .run_commands(...) for arbitrary build steps.image = (
modal.Image.debian_slim(python_version="3.12")
.apt_install("ffmpeg") # stable: rarely changes
.uv_pip_install("torch==2.5.1", "transformers==4.46.0") # heavy wheels, pinned
.add_local_python_source("my_pkg") # volatile: your code, applied last
)→ references/images-gpu-cookbook.md for vLLM / torch+CUDA
/ diffusers recipes and the download-once weight-cache pattern.
In Modal 1.0+ the GPU is a string on the decorator. The old modal.gpu.H100() objects
were removed.
gpu="H100".gpu="A100:2" (two A100s in one container).gpu="A100-80GB" (also A100-40GB).gpu=["H100", "A100", "any"].T4, L4, A10, L40S, A100(-40GB/-80GB), RTX-PRO-6000, H100, H200, B200.# Bad — removed API, raises at import.
# @app.function(gpu=modal.gpu.A100())
# Good — string form.
@app.function(image=image, gpu="A100-80GB", timeout=600)
def embed(texts: list[str]) -> list[list[float]]: ...Pick the smallest GPU that fits: T4/L4 for cheap inference and small models, A10/L40S
mid-range, A100/H100 for training and large-model serving, H200/B200 for frontier-scale.
GPU time is billed per second a container is alive — never attach a GPU to a CPU-only job, and
keep scaledown_window tight so idle GPU containers don't burn money.
Tune these keyword args on @app.function, each with its why:
| Param | Effect | Why |
|---|---|---|
min_containers=N | Keep N warm instances always running | Kills cold starts for latency-sensitive endpoints (costs idle compute) |
buffer_containers=N | Pre-warm N extra beyond current load | Smooths bursty traffic |
scaledown_window=300 | Seconds an idle container lingers before shutdown | Reuse hot containers across nearby calls; lower = cheaper, higher = warmer |
timeout=600 | Max seconds a single call may run | Caps runaway jobs |
retries=3 | Auto-retry failed inputs | Survives transient failures in .map() fan-outs |
Migration note: keep_warm → min_containers and container_idle_timeout →
scaledown_window in the 1.0 migration. The old names are gone.
Concurrency within a container is now its own decorator: @modal.concurrent(max_inputs=N)
stacked under @app.function (it replaces the old allow_concurrent_inputs= argument). Use it
so one container handles N simultaneous requests instead of one-per-container.
A Volume is a distributed filesystem you mount into containers to persist data across runs —
the canonical use is caching downloaded model weights so cold starts skip the re-download.
weights = modal.Volume.from_name("hf-cache", create_if_missing=True)
@app.function(image=image, gpu="H100", volumes={"/cache": weights})
def serve_model():
# Reader: refresh the view so you see writes from other containers.
weights.reload()
# ... load model from /cache ...
@app.function(image=image, volumes={"/cache": weights})
def download_weights():
# ... write files into /cache ...
weights.commit() # WITHOUT this, writes are NOT durable across containersGotcha: writers must call vol.commit() to persist; readers call vol.reload() to see
another container's committed writes. Forgetting commit() is the #1 "my cache is empty"
bug — the files existed in that container and vanished with it.
Secrets land as environment variables in the container:
@app.function(image=image, secrets=[modal.Secret.from_name("hf-token")])
def pull():
import os
token = os.environ["HF_TOKEN"] # value injected from the named Modal SecretNever bake a token into the image (.run_commands("export TOKEN=...")) — it's recorded in
layer history. Use a Secret. The cookbook above also carries the HF/OpenAI secret patterns.
Stack a web decorator under @app.function. Pick by surface:
| Decorator | Use for | Needs |
|---|---|---|
@modal.fastapi_endpoint() | A single GET/POST function-as-URL | fastapi[standard] in image |
@modal.asgi_app() | A full FastAPI/Starlette app you return | fastapi[standard] |
@modal.wsgi_app() | A Flask/Django WSGI app | the framework |
@modal.web_server(port=8000) | Your own server process (e.g. vLLM) on a port | the server |
Decorator stack order matters: @app.function is outermost (top), then optional
@modal.concurrent, then the web decorator innermost (bottom, closest to def).
@app.function(image=image, gpu="H100", min_containers=1, scaledown_window=300)
@modal.concurrent(max_inputs=10) # middle
@modal.asgi_app() # innermost
def web():
from fastapi import FastAPI
api = FastAPI()
@api.get("/health")
def health():
return {"ok": True}
return apiDevelop with modal serve app.py (hot-reload); ship with modal deploy app.py (stable URL).
For custom domains, proxy-auth tokens, batching (@modal.batched), and concurrency tuning →
references/web-and-scaling.md. For the FastAPI app's own
design (routes, Pydantic, deps), that's fastapi — this skill only mounts it.
# Fixed wall-clock time, with timezone — survives redeploys at the same clock time.
@app.function(schedule=modal.Cron("0 6 * * *", timezone="America/New_York"))
def nightly_report(): ...
# Interval relative to deploy time.
@app.function(schedule=modal.Period(hours=5))
def every_five_hours(): ...Gotcha: Period is measured from deploy time and resets on every redeploy — redeploy
at 4:59 and your "every 5 hours" clock restarts. Cron is wall-clock stable; prefer it for
"run at 6am" semantics. Either way you must modal deploy (not modal run) for the
schedule to live on the platform.
Fan a function out across containers without managing a pool:
@app.local_entrypoint()
def main():
urls = ["https://a.com", "https://b.com", "https://c.com"]
# .map: one arg per call, results in input order.
sizes = list(fetch.map(urls))
# .starmap: each item is an argument tuple. .spawn: fire-and-forget -> handle.get() later.
handle = fetch.spawn("https://slow.com")
print(sizes, handle.get()).map(iterable) returns results in order by default; pass order_outputs=False to yield as
they complete (faster when latencies vary). Combine with retries= on the function so a
single bad input doesn't sink the batch.
| Anti-pattern | Do instead |
|---|---|
"I'll use gpu=modal.gpu.A100() like the old docs" | Removed in 1.0. Use the string gpu="A100-80GB". |
| "Attach a GPU, it might speed up this CPU job" | GPU is billed per second alive. CPU-only job → no gpu=. |
| "My files are written, the Volume will keep them" | Not without vol.commit() (writer) / vol.reload() (reader). |
"Pin later — uv_pip_install('torch') is fine for now" | Unpinned deps drift; builds aren't reproducible. Pin every version. |
"modal run it, the endpoint/schedule will stay up" | run is ephemeral; it exits. Use modal deploy for anything persistent. |
| "Order the decorators however — Modal figures it out" | @app.function outermost, web decorator innermost. Wrong order errors. |
"Bake the HF token into the image with run_commands" | Leaks into layer history. Use modal.Secret.from_name(...). |
| "Just call the model via a managed API through Modal" | If you write no container, that's a managed-API job → replicate. |
| "I need a box to SSH into for a week" | That's a persistent rental → runpod, not Modal's scale-to-zero. |
"Set min_containers high so it's always fast" | Idle warm containers cost money 24/7. Tune scaledown_window first. |
scripts/verify.sh [TARGET] statically lints the nearest emitted Modal
*.py: it requires a modal.App(, fails if the removed modal.gpu. object form appears,
checks that any web decorator sits under an @app.function, and that any Volume uses
from_name(..., create_if_missing=...). It runs python -c "import modal" only if modal is
installed (skip-pass otherwise), needs no Modal credentials, and exits 0 on an empty target.
In a project with a 02-DOCS/ layer (the harness wiki), read
02-DOCS/wiki/stack/modal.md first, then record this app's real Modal choices there — GPU types,
image base, Volume names, schedule, endpoint shape — and index it in 02-DOCS/wiki/index.md. No
02-DOCS/? Skip silently.
© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 5 other files (scripts, references) in skills/modal of ericrisco/rsc-harness.
Open the folder on GitHubat commit 92fde8f
Modal next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Modal this skillericrisco/rsc-harness | 156 | — | ~3.5k | Automated safety check: Pass | MIT | |
| Flowfile Debugging PlaybookEdwardvaneechoud/Flowfile | 370 | — | ~6.3k | Automated safety check: Pass | MIT | |
| Verifylkmeta/txtify | 135 | — | ~583 | Automated safety check: Pass | Apache-2.0 | |
| Make Python Recipe Deployablegoogle/adk-recipes | 10k | — | ~6.9k | Automated safety check: Notes | Apache-2.0 | |
| Vercel Functionsvercel/vercel-plugin | 301 | — | ~12k | Automated safety check: Notes | Custom licence | |
| Model Deploymentmajiayu000/claude-skill-registry | 666 | 1 repos | ~2.1k | Automated safety check: Pass | MIT |
Edwardvaneechoud/Flowfile
Symptom-to-cause triage playbook for Flowfile (core/worker/kernel/frontend/AI) — covers "no such table" DB cascades (two distinct causes), import-time Alembic migration corruption, silent…
lkmeta/txtify
Verify a Txtify change end-to-end. An agent skill from lkmeta/txtify.
google/adk-recipes
Makes an existing Python recipe deployable: generates the serving files a container needs (Dockerfile, .dockerignore, fastapiapp.py, apputils/a2a.py, apputils/services.py…
vercel/vercel-plugin
Vercel Functions expert guidance — Node.js/Bun/Python runtimes, Fluid Compute, long-duration (30 min) functions, large functions (5 GB bundles), Docker/OCI container images, plan limits, streaming…
majiayu000/claude-skill-registry
Deploy trained machine learning models as production-ready services using REST APIs, containers, serverless functions, and orchestration platforms.
hashgraph-online/awesome-codex-plugins
Python stdlib scripts for the YApi OpenAPI (no Java/Docker/MCP) — search interfaces, query details, and sync/upsert one interface's docs from a YApi-native payload (often converted from OpenAPI).
ericrisco/rsc-harness
A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…
ericrisco/rsc-harness
A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…
ericrisco/rsc-harness
A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…
ericrisco/rsc-harness
A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…
ericrisco/rsc-harness
A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…
ericrisco/rsc-harness
A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.
Categories
A skill your agent uses when running Python or GPU workloads serverlessly on Modal — modal.App, inline container Images, gpu= on @app.function, Volumes for weight caching, Cron schedules, ASGI…. Modal is an agent skill from ericrisco/rsc-harness.function, Volumes for weight caching, Cron schedules, ASGI endpoints, modal run vs serve vs deploy.
Modal fits situations like: GPU workloads serverlessly on Modal — modal.App; inline container Images; gpu= on @app.function; volumes for weight caching.
Run `npx skills add ericrisco/rsc-harness --skill modal -a claude-code`. Or copy the skill folder (skills/modal in ericrisco/rsc-harness) into .claude/skills/modal in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ericrisco/rsc-harness --skill modal -a codex`. Or copy the skill folder (skills/modal in ericrisco/rsc-harness) into .agents/skills/modal in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill modal -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/modal, .gemini/skills/modal, .github/skills/modal and .opencode/skills/modal in your project.
Going by SKILL.md and its folder, Modal needs a shell for the scripts in its folder, the command-line tools its instructions call (modal, pip and python) and credentials named HF_TOKEN. Our summary lists: Python 3; A Bash shell; Docker.
SKILL.md names 5 domains. In commands or code: modal.com, a.com, b.com, c.com and slow.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Modal is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.5k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Modal: Flowfile Debugging Playbook (Edwardvaneechoud/Flowfile, 370 stars), Verify (lkmeta/txtify, 135 stars), Make Python Recipe Deployable (google/adk-recipes, 10k stars) and Vercel Functions (vercel/vercel-plugin, 301 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 156 GitHub stars. The repository holds 229 skills in this directory. The repository was last updated on October 6, 2026.
Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.