Use mf (metafunctor) to manage papers, projects, series, and content for the metafunctor.com Hugo site. Also covers site architecture, taxonomies, front matter conventions. For cross-posting, use the crier plugin. Invoke from ANY repo — mf works globally.
From mfnpx claudepluginhub queelius/claude-anvil --plugin mfThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
A CLI toolkit + site architecture guide for metafunctor.com. Works from any directory.
Division of labor:
Install location: ~/github/repos/mf (editable install: pip install -e ".[dev]")
Site root: ~/github/repos/metafunctor
Site URL: https://metafunctor.com (also https://queelius.github.io/metafunctor)
Engine: Hugo with Ananke theme
Deployment: docs/ committed to master, served by GitHub Pages
| Directory | Type | Notes |
|---|---|---|
content/post/ | Blog posts | Date-prefixed dirs: 2024-01-slug/index.md |
content/papers/ | Research papers | Generated from paper_db via mf papers generate |
content/publications/ | Peer-reviewed subset | Generated from paper_db via mf pubs generate |
content/projects/ | Software projects | Generated from projects_db via mf projects generate |
content/series/ | Multi-part series | Landing pages with _index.md |
content/writing/ | Fiction/creative | writing_type: "novel", "essay", "short-story" |
content/medical/ | Medical records | Custom sidebar layout, Chart.js for labs |
content/research/ | Research overviews | |
content/probsets/ | Problem sets | Organized by course |
content/media/ | Book/resource reviews |
Content type separation is strict: fiction goes in /writing, not /papers.
| Taxonomy | URL | Purpose |
|---|---|---|
tags | /tags/ | Technical keywords (kebab-case) |
categories | /categories/ | Broad content categories |
genres | /genres/ | Document types (paper, novel, etc.) |
series | /series/ | Multi-part content grouping |
linked_project | /linked-projects/ | Links content to projects |
Critical: Use linked_project (NOT projects) — URL must not conflict with content/projects/.
Use slugs, not paths:
# Correct
linked_project: ["likelihood.model"]
# Wrong — causes Hugo panic
linked_project: ["/projects/likelihood.model/"]
Posts:
title: "Post Title"
date: 2026-02-13
description: "Card preview text"
categories: ["Computer Science"]
tags: ["algorithms", "data-structures"]
series: ["series-slug"]
series_weight: 5
featured: true
toc: true
Papers: stars (1-5), pdf_file (filename in static/latex/), html_path, authors, abstract
Projects: featured, project: { status, type, year_started }, tech: { languages, topics }, sources: { github }, packages: { pypi, crates }
Series membership (in posts): series: ["slug"], series_weight: N
index.md): Most content. Self-contained page._index.md): Rich projects, series landing pages. Can have child pages.Rich projects use _index.md. Regular projects use index.md.
make serve # Dev server with drafts (localhost:1313)
make build # Build to public/ (testing)
make deploy # Build to docs/ for production
make push # Build + git push to GitHub Pages
relativeURLs=true — one build works on both domains.
| Content | Ground Truth | mf Role | Has Database? |
|---|---|---|---|
| Projects | GitHub repos | DB + overrides + generate | Yes (projects_db.json) |
| Papers | LaTeX sources | DB + sync + generate | Yes (paper_db.json) |
| Series | mf series_db | DB + sync + landing pages | Yes (series_db.json) |
| Posts | The .md file | mf posts (list, create, set, tag, feature) | No |
| Writing | The .md file | None | No |
| Medical | The .md file | None | No |
Key principle: Databases exist only for content whose ground truth lives elsewhere.
When users describe what they want, map to the right mf workflow:
| User says... | Workflow |
|---|---|
| "new paper", "add a paper" | Paper workflow (below) |
| "new project", "add repo" | Project workflow (below) |
| "new post", "write about X" | Post workflow (below) |
| "health check", "audit site" | Health pass (below) |
| "deploy", "push to prod" | Pre-deploy (below) |
| "feature X", "star this paper" | mf {type} feature <slug> |
| "tag X with Y" | mf {type} tag <slug> --add Y |
| "sync papers/projects" | mf papers sync / mf projects sync |
| "cross-post", "share on socials" | Use /crier skill instead |
| "what content do I have" | mf analytics summary |
| "find broken links" | mf health links |
| "clean up tags" | mf taxonomy audit then mf taxonomy normalize |
mf papers process path/to/paper.texmf papers set <slug> stars 5 (and any other metadata)mf papers generate --slug <slug>mf pubs generate (updates publications if peer-reviewed)make deploy/crier.mf/projects_db.json (or mf projects import)mf projects synchugo --gc --minify (verify)make deploymf posts create --title "Title" --tag x --category Ycontent/post/YYYY-MM-DD-slug/index.md — write contentmf posts set <slug> draft false (when ready)make deploy/criermf health links — broken internal linksmf health descriptions — missing descriptionsmf health images — missing featured imagesmf health stale — content diverged from DBmf integrity check — database consistencymf content audit --extended — pluggable content checksmf taxonomy audit — near-duplicate termsmf integrity check — database ok?hugo --gc --minify — Hugo build errors?mf health links — no broken links?make deploy — build to docs/make push — push to GitHub Pages| Group | Key verbs | Notes |
|---|---|---|
papers | process, sync, generate, set, feature, tag | LaTeX → DB → Hugo |
projects | import, sync, generate, refresh, set, feature, hide, bundle | GitHub → DB → Hugo |
series | create, sync, add, set, feature, tag, delete | DB → landing pages |
packages | sync, generate, set, feature, tag | PyPI/CRAN → DB → Hugo |
posts | create, list, set, unset, tag, feature | Direct front matter edits (no DB) |
pubs | generate, list | Subset of papers (peer-reviewed) |
content | match-projects, about, list-projects, audit | Cross-content linking |
taxonomy | audit, orphans, stats, normalize | Tag/category hygiene |
health | links, descriptions, images, drafts, stale | Content quality checks |
analytics | summary, gaps, tags, timeline, suggestions | Content insights |
integrity | check, fix, orphans | Database consistency |
backup | list, restore | Backup management |
config | show | Configuration display |
generate first — it's read-only on the databasesync before generate if you want fresh datagenerate (or sync) before make deploymf pubs generate after any paper change (publications derive from papers)set commands accept --regenerate to auto-rebuild Hugo pages after the editmf --help and mf <group> --help at runtime for exact flags--dry-run for preview--json output available on most list and health commandsThe mf CLI resolves the site root in this order:
MF_SITE_ROOT environment variable (highest priority).mf/ directory~/.config/mf/config.yaml# One-time setup (from any directory):
mkdir -p ~/.config/mf
echo "site_root: ~/github/repos/metafunctor" > ~/.config/mf/config.yaml
# Now all commands work from any directory:
cd ~/github/repos/likelihood.model
mf posts create --title "New release" # Creates in metafunctor/content/post/
mf posts list --tag python # Lists metafunctor posts
Content flows: mf (create/update) → Hugo (render) → crier (distribute)
After creating or updating content with mf, suggest cross-posting:
# 1. Create/update content
mf papers generate --slug new-paper
# 2. Build site
make deploy
# 3. Cross-post (see /crier skill for full workflow)
crier audit content/papers/new-paper/index.md
crier publish content/papers/new-paper/index.md --to devto
For short-form platforms (Bluesky, Mastodon), Claude writes the rewrite and passes it via --rewrite. See the /crier skill for detailed guidance.
docs/ is committed to git (GitHub Pages). Don't gitignore it._index.md (branch bundle) vs regular use index.md.linked_project taxonomy, NOT projects — URL collision with content section._index.md.soprano → soprano-tts).queelius.r-universe.dev/PACKAGE (author subdomain, not package).content/post (singular), not content/posts.