Add tools
The Pixie skill library has ten ways to create a new tool. Pick the one whose source artefact matches what you have.
Quick chooser
| You have… | Use this skill |
|---|---|
| A natural-language description, no code | add-tool-from-description |
| A Git URL | add-tool-from-repo |
A local .py file | wrap-local-script |
A Jupyter .ipynb | add-tool-from-notebook |
A CLI binary (ffmpeg, yt-dlp, …) | add-tool-from-cli-command |
| An OpenAPI / Swagger spec | add-tool-from-openapi-spec |
A Streamlit .py app | convert-streamlit-app |
A Gradio .py app | convert-gradio-app |
An Excel .xlsx model | add-tool-from-excel-model |
| A research paper PDF or arXiv link | add-tool-from-paper |
A .zip someone packaged via share-tool | import-tool |
| A detailed model spec (architecture etc.) | implement-model-from-spec |
Every skill ends with uv run pixie validate <tool_id> and refuses to
claim success on a fail.
add-tool-from-description
non-destructive
Trigger: “Add a Pixie tool that …”, “Make me a tool that …”, “Generate a tool to …” — with no artefact attached.
Steps:
- Ask up to 3 clarifying questions (inputs? outputs? stateful or functional? needs external APIs?).
- Pick template — pure function / stateful / LLM-wrapping (see patterns).
- Pick a kebab-case
idand human-readable name. - Write
tools/<id>/tool.json,pyproject.toml,main.py,README.md. uv syncinside the tool folder.uv run pixie validate <id> --json.- Surface the full report.
Refuses to: scaffold tools that require a GPU, Docker, a database server, or system packages outside the allowlist (currently empty — Python-only).
Example trigger:
Add a Pixie tool that converts between metric and imperial unitsadd-tool-from-repo
non-destructive
Trigger: a Git URL (github.com/…, gitlab.com/…, *.git,
git@…). “Add github.com/x/y as a Pixie tool”, “Wrap this repo”.
Steps:
- Parse URL. Refuse non-Git inputs (route to alternates).
git clone --depth=1to a temp dir.- Read README, main code files,
pyproject.toml/requirements.txtto understand the entrypoint and dependencies. - Decide whether the repo can be cleanly wrapped. Refuse if it needs a GPU not present, a database server, Docker, system packages outside allowlist, or it’s a full SPA rather than a tool.
- Create
tools/<id>/with kebab-case id derived from repo name. - Write
tool.json(inputs/outputs inferred),pyproject.toml(declared deps + fastapi/uvicorn/python-dotenv),main.py(FastAPI wrapper around the repo’s entrypoint). uv sync.uv run pixie validate <id>. Surface report verbatim.
Hard rules:
- Never invent dependencies. Use only what the repo declares or imports.
- Never modify cloned source. Wrap from outside.
- Pin Python 3.12 unless the repo’s metadata says otherwise.
- If the entrypoint is ambiguous, ask before writing.
Example trigger:
Add github.com/foo/bar as a Pixie toolwrap-local-script
non-destructive
Trigger: a local .py file path. “Wrap ./scripts/foo.py as a
Pixie tool”.
Refuses .py files that import streamlit or gradio (routes to
convert-streamlit-app / convert-gradio-app).
add-tool-from-notebook
non-destructive
Trigger: an .ipynb path. “Convert this notebook to a Pixie tool”.
Extracts the meaningful “input cells” and “output cells” by inspecting
the notebook, generates tool.json and main.py that re-runs the
relevant pipeline, then validates.
add-tool-from-cli-command
non-destructive
Trigger: a CLI binary name (ffmpeg, pandoc, yt-dlp,
imagemagick, curl). “Wrap ffmpeg as a Pixie tool”.
Generates tool.json from the binary’s flags (via --help parsing) and
a subprocess-based main.py. Refuses Python scripts (use
wrap-local-script) and full repos (use add-tool-from-repo).
add-tool-from-openapi-spec
non-destructive
Trigger: mentions of “OpenAPI”, “Swagger”, openapi.yaml,
openapi.json. “Wrap this API spec”.
Reads the spec, picks one endpoint (asks if multiple), generates inputs
from the endpoint’s parameters and outputs from the response schema,
writes an httpx-based main.py.
convert-streamlit-app
non-destructive
Trigger: mentions of Streamlit, streamlit run, or a .py that
imports streamlit. “Port this Streamlit app to Pixie”.
Maps st.* widgets to tool.json inputs and st.* outputs to partials.
Single-form apps only — refuses multi-page or stateful apps.
convert-gradio-app
non-destructive
Trigger: mentions of Gradio, gr.Interface, gr.Blocks, or a .py
importing gradio.
Same idea as Streamlit conversion but for gr.Interface / gr.Blocks
mappings.
add-tool-from-excel-model
non-destructive
Trigger: a .xlsx workbook. “Wrap this Excel model”.
Parses the formula DAG with openpyxl, generates Python that
reproduces every cell. Refuses .xlsm/.xlsb/.xls (different
binary formats) and .csv (route to fetch-dataset-from-url or
import-dataset-from-local).
add-tool-from-paper
non-destructive
Trigger: a paper PDF, arXiv link, or DOI. “Implement this paper as a Pixie tool”.
Reads the paper, implements the method as a new tool, and generates reference fixtures from the paper’s reported numbers — so check 12 is useful from day one.
Refuses to cite without creating (cite-source does that). Refuses code
(use add-tool-from-repo).
implement-model-from-spec
non-destructive
Trigger: a detailed ML model spec (architecture, training setup, hyperparameters, expected metric). “Build a tool that implements this model”.
For when you have a spec but no code, no paper, and no repo — i.e. you know what you want, you just need it built.
import-tool
non-destructive
Trigger: a .zip someone packaged via share-tool. “Install this
zipped tool”.
Refuses zips that contain:
.venv/(platform-specific bloat)..env(secrets must be set out-of-band viaset-secret).- Native binaries.
../in any path (traversal).- Multiple top-level directories.
Routes elsewhere if:
- The zip is a
.gitarchive →add-tool-from-repo. - The zip is a notebook →
add-tool-from-notebook. - The zip is a single
.py→wrap-local-script.
Steps:
- Extract to a temp dir; validate security constraints.
- Refuse if a tool with this id already exists (offer
remove-toolorrename-tool). - Move to
tools/<id>/. uv sync.uv run pixie validate <id> --json. Surface report.
After it lands
Every “add” skill leaves you with:
- A new folder under
tools/<id>/. - An installed
.venv/. - A
validation_reportsrow inpixie.db.
Refresh the dashboard and the tool appears in the sidebar.
If validation failed, the skill says so and offers
debug-tool. Run it. The first
attempt usually fixes obvious issues (missing dep, wrong output shape).