Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 2 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Kerf is a cross-platform desktop editor with an **embedded MCP server**, so an L
**same engine the GUI uses, on the same live project** — and it can actually *see* the
frames it's editing. Nothing is re-encoded until you export.

**[kerf website](https://orellbuehler.github.io/kerf/)** · [download](https://orellbuehler.github.io/kerf/#get) · [FAQ](https://orellbuehler.github.io/kerf/#faq)

[![CI](https://github.com/OrellBuehler/kerf/actions/workflows/ci.yml/badge.svg)](https://github.com/OrellBuehler/kerf/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/OrellBuehler/kerf?color=e29d2e&label=release)](https://github.com/OrellBuehler/kerf/releases)
[![License](https://img.shields.io/badge/license-PolyForm%20Noncommercial-22b4c4.svg)](./LICENSE.md)
Expand All @@ -20,13 +22,6 @@ frames it's editing. Nothing is re-encoded until you export.

</div>

<div align="center">

<!-- Drop a screenshot of the full editor here. See docs/img/README.md for the shot list. -->
<img src="docs/img/screenshot-editor.png" alt="Kerf editor — multi-track timeline, preview, and agent panel" width="880" />

</div>

> A _kerf_ is the slit a saw leaves behind — the cut itself. Kerf edits
> non-destructively: your timeline is an edit list over the original media, and
> nothing is re-encoded until you hit export.
Expand Down Expand Up @@ -80,14 +75,6 @@ agent isn't scripting a black box; it drives the identical engine — and its ed
| **Agent workflow** | 78 MCP tools, **staged edits with a reviewable diff**, a persisted task queue, and a fully revertible edit history attributed to user / agent / system. |
| **Auto-update** | The app updates itself from its own GitHub releases; a bundle only installs if its **minisign signature** verifies against the embedded public key. |

<div align="center">

<!-- Agent panel + inspector screenshots. See docs/img/README.md. -->
<img src="docs/img/screenshot-agent.png" alt="Kerf agent panel — task queue and edit history" width="430" />
<img src="docs/img/screenshot-inspector.png" alt="Kerf inspector — effects, keyframes, and overlays" width="430" />

</div>

---

## Quickstart
Expand Down
20 changes: 11 additions & 9 deletions docs/img/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,25 @@ Capture these from the running desktop app (dark theme, a real project loaded) a
them here with the **exact filenames** below. PNG, retina if you can. Aim for a populated
timeline — a few clips across two or three tracks, a waveform, a scene marker or two.

| Filename | What to capture | Used by |
| Filename | What to capture | Wire into |
| ---------------------------- | ------------------------------------------------------------------------------- | ------------------------ |
| `screenshot-editor.png` | The **full editor** window — title bar, media bin, preview, multi-track timeline. Hero shot. | README |
| `screenshot-agent.png` | The **agent panel** — task queue (a `ready` task with Apply/Dismiss) + history. | README |
| `screenshot-inspector.png` | The **inspector** — an effects chain, the Transform/keyframe panel, or overlays. | README |
| `screenshot-editor.png` | The **full editor** window — title bar, media bin, preview, multi-track timeline. Hero shot. | README, under the badges |
| `screenshot-agent.png` | The **agent panel** — task queue (a `ready` task with Apply/Dismiss) + history. | README, after Features |
| `screenshot-inspector.png` | The **inspector** — an effects chain, the Transform/keyframe panel, or overlays. | README, after Features |

Only those three are referenced today. `screenshot-timeline.png` (a tight crop of the
timeline — clips, waveforms, beat ticks, playhead) is a nice-to-have you can add and wire
into the features section later.
**Nothing references these yet.** The README used to carry `<img>` tags for all three and
rendered three broken-image placeholders on the repo page instead, so the tags were
removed — add one back next to the file you drop in, not before. `screenshot-timeline.png`
(a tight crop of the timeline — clips, waveforms, beat ticks, playhead) is a nice-to-have
for the features section.

Tips:
- Hide any OS chrome; capture just the app window.
- A 16:10-ish crop reads best in the README hero (≈ 880 px wide as displayed).
- Keep the amber playhead visible — it's the brand's signature.

Until these exist, the `README` shows broken-image placeholders where they go. The
landing site no longer embeds them — it renders animated CSS/SVG mockups instead.
The landing site does not embed them either — it renders animated CSS/SVG mockups
instead — so a shot dropped here is a README-only change until you wire it in there too.

## `og.png` — the social-card image

Expand Down
31 changes: 31 additions & 0 deletions site/assets/css/kerf.css
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,37 @@ code {
line-height: 1.7;
}

/* ---------------- FAQ ---------------- */
.faq-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px 28px;
}
@media (max-width: 760px) {
.faq-grid {
grid-template-columns: 1fr;
}
}
.faq-item {
min-width: 0;
border-top: 1px solid var(--border-subtle);
padding-top: 18px;
}
.faq-item h3 {
font-family: var(--font-display);
font-weight: 600;
font-size: 17px;
line-height: 1.3;
margin: 0 0 8px;
color: var(--text-primary);
}
.faq-item p {
margin: 0;
color: var(--text-secondary);
font-size: 15px;
line-height: 1.65;
}

/* ---------------- Footer ---------------- */
.footer {
border-top: 1px solid var(--border-subtle);
Expand Down
2 changes: 1 addition & 1 deletion site/content/_index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
title: "Kerf — the video editor your AI can drive"
title: "Kerf — the AI video editor your agent can drive"
---
52 changes: 52 additions & 0 deletions site/data/faq.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# One source of truth for the FAQ: layouts/partials/faq.html renders these as
# visible page copy, and partials/schema.html emits the same pairs as FAQPage
# JSON-LD. Google requires the answer it shows to be present on the page, so
# these must never drift apart — hence one file, two consumers.
- q: What is Kerf?
a: >-
Kerf is a free, cross-platform desktop video editor for non-destructive video and
audio editing. What makes it different is the embedded MCP server: an AI assistant
can analyze your footage, look at real frames, and assemble the cut through the same
engine the GUI uses — on the same live project you have open.
- q: How is Kerf different from an AI video editor with a chat sidebar?
a: >-
Most tools bolt a chatbot onto an editor and let it script a black box. Kerf inverts
that: the editor is an API, exposed twice over one shared project — as the GUI you
click, and as 78 Model Context Protocol tools an agent calls. There is no import or
export round-trip and no second copy of the truth.
- q: Which AI assistants can drive Kerf?
a: >-
Any MCP client. The desktop app hosts a streamable-HTTP MCP server on
127.0.0.1:7777/mcp, so Claude Code, Claude Desktop or any HTTP-capable Model Context
Protocol client connects with a single command and starts editing.
- q: Does the AI change my timeline without asking?
a: >-
No. Agent edits build a staged proposal, not your cut. The review card shows a real
diff — added, cut, moved, retrimmed — and you can watch the proposed timeline play
before you apply it as one revertible revision, or discard it.
- q: Is Kerf free?
a: >-
Yes, free to download and free for noncommercial use under the PolyForm Noncommercial
1.0.0 license. The full source is on GitHub, and installers for macOS, Windows and
Linux come straight from the latest release — no account needed.
- q: Which platforms does Kerf run on?
a: >-
macOS 10.15 or later (Apple silicon and Intel .dmg), Windows 10/11 x64 (.exe
installer or .msi) and Linux x86_64 (AppImage, .deb, .rpm). The app keeps itself up
to date over a signature-verified update feed.
- q: Do I need FFmpeg installed?
a: >-
On Windows, no — FFmpeg is bundled. On macOS and Linux, Kerf uses a system ffmpeg on
your PATH (brew install ffmpeg, or your distribution's package). The engine drives
the ffmpeg and ffprobe binaries, so the development libraries are never required.
- q: What does non-destructive editing mean in Kerf?
a: >-
Your timeline is an edit list over the original media: a clip is just a source range
at a timeline position. Cuts, effects, colour and keyframes edit that data, never the
files. Sources are read once, at export — nothing is re-encoded before then.
- q: Can Kerf edit 360 and Insta360 footage?
a: >-
Yes. Spherical footage is detected on import and clips cut from it are reframed to an
ordinary flat shot: aim a virtual camera with yaw, pitch, roll and field of view, and
keyframe the pan. An Insta360 lens pair imports as one asset — Kerf stitches the two
fisheyes into an equirectangular sphere and caches it.
25 changes: 21 additions & 4 deletions site/hugo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
baseURL = "https://orellbuehler.github.io/kerf/"
languageCode = "en-us"
title = "Kerf — the video editor your AI can drive"
title = "Kerf — the AI video editor your agent can drive"
enableRobotsTXT = true

# Single landing page; no taxonomies/RSS clutter.
disableKinds = ["taxonomy", "term", "RSS", "sitemap"]
# Single landing page; no taxonomies/RSS clutter. The sitemap stays on — it is
# what robots.txt points crawlers at, and a project page on a shared
# github.io host is not discovered from a domain root.
disableKinds = ["taxonomy", "term", "RSS"]

[sitemap]
changefreq = "weekly"
priority = 1.0

[params]
description = "Kerf is a non-destructive, FFmpeg-backed desktop video editor with an embedded MCP server, so an LLM can analyze your footage and assemble the cut through the same engine the GUI uses — and can see the frames it edits. Free download for macOS, Windows and Linux."
# Kept under ~155 chars: past that a search snippet is truncated mid-sentence.
# The longer pitch lives in `about`, which feeds the JSON-LD description where
# there is no such budget.
description = "Kerf is a free, non-destructive AI video editor for macOS, Windows and Linux. An embedded MCP server lets Claude — or any LLM — cut your footage with you."
about = "Kerf is a cross-platform desktop video editor for AI-assisted, non-destructive video and audio editing. An embedded Model Context Protocol (MCP) server exposes the same editing engine the GUI uses, so an LLM can analyze footage, see real frames, and assemble a cut on the live project — staged for your review. FFmpeg-backed; nothing is re-encoded until export."
author = "Orell Bühler"
# Proves ownership of the Search Console property. Public by design —
# it is only meaningful on a site Google already fetches from this URL.
# Removing it un-verifies the property, so leave it after verification.
googleSiteVerification = "aYnZ5m8jHpn8cqpi1FN2kkozCTdLCTb17VorcQm69JA"
authorUrl = "https://orellbuehler.ch"
license = "https://github.com/OrellBuehler/kerf/blob/main/LICENSE.md"
tagline = "The non-destructive video editor your AI can drive."
github = "https://github.com/OrellBuehler/kerf"
# owner/name — download.js resolves release assets through the GitHub API,
Expand Down
23 changes: 23 additions & 0 deletions site/layouts/_default/baseof.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,46 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{{ .Title }}</title>
<meta name="description" content="{{ .Site.Params.description }}" />
<meta name="author" content="{{ .Site.Params.author }}" />
{{ with .Site.Params.googleSiteVerification }}
<meta name="google-site-verification" content="{{ . }}" />
{{ end }}

{{/* max-image-preview:large is what lets a result carry the big thumbnail
rather than a 100px one; the -1s lift Google's snippet limits. */}}
<meta
name="robots"
content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"
/>

<link rel="canonical" href="{{ .Permalink }}" />
<link rel="sitemap" type="application/xml" href="{{ "sitemap.xml" | absURL }}" />

<meta property="og:type" content="website" />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="Kerf" />
<meta property="og:title" content="{{ .Title }}" />
<meta property="og:description" content="{{ .Site.Params.description }}" />
{{/* docs/img is mounted at static/img, so this is the same file the repo
README can use — see docs/img/README.md for how it is regenerated. */}}
<meta property="og:image" content="{{ "img/og.png" | absURL }}" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Kerf — the video editor your AI can drive" />
<meta property="og:url" content="{{ .Permalink }}" />

{{/* Twitter falls back to the og:* tags, but only for the ones it knows —
so state the card's own set rather than relying on the overlap. */}}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{{ .Title }}" />
<meta name="twitter:description" content="{{ .Site.Params.description }}" />
<meta name="twitter:image" content="{{ "img/og.png" | absURL }}" />
<meta name="twitter:image:alt" content="Kerf — the video editor your AI can drive" />
<meta name="theme-color" content="#0f1318" />

{{ partial "schema.html" . }}

<link rel="icon" href="{{ "favicon.svg" | relURL }}" type="image/svg+xml" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
Expand Down
13 changes: 9 additions & 4 deletions site/layouts/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<a href="#features">Features</a>
<a href="#agent">The&nbsp;agent</a>
<a href="#mcp">MCP</a>
<a href="#faq">FAQ</a>
<a class="ghost-link" href="{{ $gh }}" target="_blank" rel="noopener">GitHub&nbsp;↗</a>
<a class="nav-dl" href="#get">Download</a>
</nav>
Expand All @@ -32,7 +33,7 @@
<span class="eyebrow"><span class="dot"></span> Non-destructive · MCP-native · FFmpeg-backed</span>
<h1>The video editor<br />your <span class="amber">AI can drive</span>.</h1>
<p class="lede">
Kerf is a cross-platform desktop editor with an <b>embedded MCP server</b>, so an
Kerf is a cross-platform desktop <b>video editor</b> with an <b>embedded MCP server</b>, so an
LLM can analyze your footage and assemble the cut through the <b>same engine the
GUI uses, on the same live project</b> — and it can actually <i>see</i> the frames
it edits. Nothing is re-encoded until you export.
Expand Down Expand Up @@ -194,9 +195,9 @@ <h2>Connect any MCP client<br />and start editing.</h2>
<div class="section-head reveal">
<span class="kicker">Get it</span>
<h2>Download Kerf.</h2>
<p class="sub">Installers for every platform, straight from the latest GitHub release —
no account needed. Once installed, Kerf keeps itself up to date over a
signature-verified update feed.</p>
<p class="sub">Free download for macOS, Windows and Linux — installers straight from the
latest GitHub release, no account needed. Once installed, Kerf keeps itself up to
date over a signature-verified update feed.</p>
<div class="get-cta">
{{ partial "download-button.html" (dict "Site" .Site "id" "get") }}
<span class="dl-meta" data-dl-meta hidden></span>
Expand Down Expand Up @@ -225,6 +226,9 @@ <h3>Then point an agent at it</h3>
</div>
</div>
</section>

<!-- ============ FAQ ============ -->
{{ partial "faq.html" . }}
</main>

<footer class="footer">
Expand All @@ -236,6 +240,7 @@ <h3>Then point an agent at it</h3>
</div>
<nav class="foot-links">
<a href="#get">Download</a>
<a href="#faq">FAQ</a>
<a href="{{ $gh }}" target="_blank" rel="noopener">GitHub</a>
<a href="{{ $rel }}" target="_blank" rel="noopener">Releases</a>
<a href="{{ $gh }}/blob/main/LICENSE.md" target="_blank" rel="noopener">License</a>
Expand Down
20 changes: 20 additions & 0 deletions site/layouts/partials/faq.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{- /* Visible FAQ. Renders data/faq.yaml, which partials/schema.html also emits
as FAQPage JSON-LD — same words in both, which is what Google requires of
a marked-up answer. */ -}}
<section id="faq" class="band">
<div class="wrap">
<div class="section-head reveal">
<span class="kicker">Questions</span>
<h2>Kerf, answered.</h2>
<p class="sub">What the AI video editor is, what it costs, and what it needs to run.</p>
</div>
<div class="faq-grid reveal stagger">
{{- range $.Site.Data.faq }}
<article class="faq-item">
<h3>{{ .q }}</h3>
<p>{{ .a }}</p>
</article>
{{- end }}
</div>
</div>
</section>
Loading
Loading