Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
kuri — Browser-Automatisierung, Web-Crawling und iOS- + Android-Gerätesteuerung für KI-Agenten. Zig-native, token-effiziente CDP-Snapshots, HAR-Aufzeichnung, nativer adb-Wire-Protocol-Client und ein eigenständiger Fetcher. | Kitploit
Tools/GitHubGitHub/justrach/kuri
InformationsbeschaffungWebsicherheitPenetrationstestsMobile SicherheitCrawler
GitHubjustrach/kuri

kuri

Browser-Automatisierung, Web-Crawling und iOS- + Android-Gerätesteuerung für KI-Agenten. Zig-native, token-effiziente CDP-Snapshots, HAR-Aufzeichnung, nativer adb-Wire-Protocol-Client und ein eigenständiger Fetcher.

Repository anzeigen
3501844vor 11 TagenVon Kitploit geprüft
Webseite

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
<p align="center">
  <img src="https://assets.kitploit.com/production/public/readmes/13639/7915bba5fb25229c11f59482cfcd4a0eaf2945ee066dbf5cec395df880b53268.png" alt="Kuri" width="200" />
</p>

<h1 align="center">Kuri 🌰</h1>

<p align="center">
  <a href="https://kuri.trilok.ai/download/latest.json"><img src="https://img.shields.io/badge/stable-v0.6.1-brightgreen?style=flat-square" alt="Stable release"></a>
  <a href="https://github.com/justrach/kuri/blob/main/LICENSE"><img src="https://img.shields.io/github/license/justrach/kuri?style=flat-square" alt="License"></a>
  <img src="https://img.shields.io/badge/zig-0.16.0-f7a41d?style=flat-square" alt="Zig">
  <img src="https://img.shields.io/badge/node__modules-0_files-brightgreen?style=flat-square" alt="node_modules">
  <img src="https://img.shields.io/badge/status-stable-brightgreen?style=flat-square" alt="status">
</p>

## Installation

```sh
curl -fsSL https://kuri.trilok.ai/download | sh
```

macOS arm64/x86_64 und Linux x86_64/arm64. Einzelne Binärdatei, keine Laufzeitabhängigkeiten.

Direkte Downloads: [macOS arm64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-aarch64-macos.tar.gz) · [macOS x86_64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-x86_64-macos.tar.gz) · [Linux x86_64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-x86_64-linux.tar.gz) · [Linux arm64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-aarch64-linux.tar.gz)

---

**Browser-Automatisierung & Web-Crawling für KI-Agenten. Geschrieben in Zig. Null Node.js.**

CDP-Automatisierung · A11y-Snapshots · HAR-Aufzeichnung · Standalone-Fetcher · Interaktiver Terminal-Browser · Agentic CLI · Sicherheitstests · iOS- + Android-Gerätesteuerung

[Schnellstart](#-quick-start) · [Benchmarks](#-benchmarks) · [kuri-agent](#-kuri-agent) · [Sicherheitstests](#-security-testing) · [API](#-http-api) · [Skills](#-skills) · [Changelog](https://github.com/justrach/kuri/blob/main/CHANGELOG.md)

> **Warum Teams zu Kuri wechseln:** Aktuelle Apple-Silicon-`ReleaseFast`-Builds bleiben unter 2 MB pro Binärdatei, und ein frischer Google-Flights-Durchlauf am 2026-04-23 maß **3.392 Tokens** für eine vollständige `kuri-agent`-Schleife (`go→snap→click→snap→eval`). Tool-übergreifende Deltas sollten in derselben Umgebung erneut ausgeführt werden, bevor ein Prozentsatz zitiert wird.

---

## Warum Kuri für Agenten gewinnt

Die meisten Browser-Tools wurden für QA-Ingenieure entwickelt. Kuri ist für Agenten-Schleifen gebaut: die Seite lesen, Token-Kosten niedrig halten, auf stabile Refs reagieren und weitermachen.

- **135 HTTP-Endpunkte** — vollständige Parität mit agent-browser und browser-use, von React-Inspektion bis Core Web Vitals.
- **7-12 % weniger Tokens** als agent-browser auf echten Seiten dank `@eN`-Ref-Format und Zero-Prefix-Rendering.
- **44x leichtere Beobachtungen** mit `/page/state` (48 Tokens) vs. vollständigem Snapshot (2.124 Tokens) für dieselbe Google-Flights-Seite.
- **Batch-Ausführung** — `POST /batch` sendet N Befehle in einem HTTP-Aufruf und eliminiert N-1 Round-Trips und N-1 LLM-Turns.
- **React-kompatibel** — vertrauenswürdige CDP-Mausereignisse und Zeichen-für-Zeichen-Tastenereignisse lösen React 18/19 `onClick` und `onChange` aus.

### Snapshot-Tokens: Google Flights `SIN → TPE`

Frischer Durchlauf am 2026-05-24 in diesem Workspace, gemessen mit `wc -c` und `chars/4`-Approximation.

| Tool / Modus | Zeichen | ~Tokens | Hinweis |
|---|---:|---:|---|
| `kuri snap` (vollständig) | 8.499 | **2.124** | Alle Knoten + interaktive Refs |
| `kuri snap` (nur interaktiv) | ~3.000 | **~750** | Am besten für Agenten-Schleifen |
| `kuri /page/state` | 190 | **48** | Leichtgewichtige Beobachtung (url, title, scroll%, counts) |
| agent-browser snap (geschätzt) | ~9.183 | **~2.295** | `[ref=e0]`-Format-Overhead |

### Token-Effizienz: kuri vs agent-browser

| Seite | kuri-Tokens | agent-browser-Tokens | Ersparnis |
|---|---:|---:|---|
| example.com | 40 | 35 | -13 % (triviale Seite, agent-browser überspringt Root) |
| Hacker News | 386 | ~440 | **12 % weniger** |
| Google Flights SIN→TPE | 2.124 | ~2.295 | **7 % weniger** |

Die Ersparnis kommt von kuris kompaktem Format:
- `@e0`-Refs (3 Zeichen) vs. `[ref=e0]` (9 Zeichen)
- Kein `- `-Präfix pro Zeile (spart 2 Zeichen × Zeilenanzahl)
- Gleiche Einrückung, gleiche Knotenfilterung

### Vollständige Workflow-Kosten: `go → snap → click → snap → eval`

| Tool | Tokens pro Zyklus |
|---|---:|
| **kuri-agent** | **~3.400** |
| Mit `/page/state` statt zweitem Snap | **~1.700** |
| Mit `POST /batch` (alles in einem Aufruf) | **~1.700** (gleiche Tokens, 1 HTTP-Aufruf statt 5) |

### kuri vs libretto

[libretto](https://github.com/saffron-health/libretto) (Playwright + Node) ist der engste Konkurrent bei den Token-Kosten pro Schritt. Direktvergleich am 2026-07-04 gemessen — gleicher Chrome, gleicher Tab, echte `tiktoken`-`o200k_base`-Zählungen (vollständige Methodik und Reproduktion: **[benchmarks/libretto_comparison.md](https://github.com/justrach/kuri/blob/main/benchmarks/libretto_comparison.md)**). Die ehrliche Aufteilung:

| Achse | Gewinner | Detail |
|---|---|---|
| Latenz pro Aufruf | **kuri** | 4–117 ms vs. 1.344–1.500 ms (**13–376× schneller** — persistenter Server vs. Node-pro-Befehl) |
| Snapshot-Tokens, typische Seite | **kuri** | einfach 61 vs. 151 (2,5×), Artikel 265 vs. 363 (1,37×) — straffere Grammatik |
| Snapshot-Tokens, große Liste | geteilt | kuri-Standard 4.424 vs. 813 — kuri gibt alle 259 Refs aus, libretto kürzt standardmäßig. Mit `limit=5` rendert kuri 555 Tokens (**1,46× unter libretto**), 34 Refs + `… +45 more`-Marker |
| Trajektorie (Feed, 9 Klicks) | **kuri**, knapp | 898 vs. 939 Tokens (`limit=5`-Basis + Diff-Schleife vs. Exec-Schleife) — Parität bis leichter Vorteil; der 5,1×-Verlust am Morgen war die ungekürzte Basis |
| Wiederholte Durchläufe | **libretto** | kompiliert Trajektorien zu einem Playwright-Skript → 0-Token-Wiederholungen; kuri zahlt die Schleife bei jedem Durchlauf erneut |

**Was kuri aus dem Studium von libretto gewonnen hat** (alles in diesem Release ausgeliefert): eine Diff-First-Schleife (`take_snapshot_diff`, ~38 Tokens/Schritt); ein adaptiver Diff, der bei Navigation auf einen vollständigen Snapshot mit `! page replaced`-Header zurückfällt; reine Identitäts-Entfernungszeilen; Screenshots auf die Festplatte geschrieben (Pfad zurückgegeben, Bytes gelangen nie in den Kontext); `get_page_state` über MCP; und — nach dem Umschreiben von `parseA11yNodes` als echten DFS-Baumdurchlauf — **Opt-in-Listenkürzung** (`/snapshot?limit=N`, eine `… +K more`-Zeile pro gekapptem Durchlauf), **bereichsbezogene Neuerfassung** (`scope=@ref`) und **Hierarchie-Einrückung**, ebenfalls als `uid`/`limit` bei MCP `take_snapshot` verfügbar. Die 9-Klick-Feed-Trajektorie, die mit naiven vollständigen Re-Snapshots 44.285 Tokens kostete, kostet mit gekürzter Basis + Diffs **898** — 49× günstiger und über librettos 939.

> Die älteren Tabellen oben verwenden eine `chars/4`-Token-Approximation; der libretto-Vergleich verwendet echte `tiktoken`-Zählungen. Führen Sie tool-übergreifende Zahlen in Ihrer eigenen Umgebung erneut aus, bevor Sie einen Prozentsatz zitieren.

### Binärgröße und Speicher

Gemessen auf Apple M4 Pro, macOS 26.4.1. Aktuelle Binärdateien wurden mit `-Doptimize=ReleaseFast` gebaut.

| Binärdatei | Aktuelle Größe |
|---|---:|
| `kuri` | 1.093.840 B (1,04 MiB) |
| `kuri-agent` | 629.904 B (615 KiB) |
| `kuri-browse` | 1.089.120 B (1,04 MiB) |
| `kuri-fetch` | 2.063.488 B (1,97 MiB) |

### RSS blieb während der Zig-0.16-Migration flach

Gemessen gegen den aktuellen `v0.4.3`-`ReleaseFast`-Build mit `/usr/bin/time -l`.

| Befehl | `v0.4.3` mittleres max. RSS |
|---|---:|
| `kuri-fetch --version` | ~2,45 MiB |
| `kuri-browse --version` | ~2,45 MiB |
| `kuri-fetch --quiet --dump markdown http://example.com/` | ~9,17 MiB |

## Das Problem

Jedes Browser-Automatisierungstool schleppt Playwright (~300 MB), eine Node.js-Laufzeit und eine Kaskade von npm-Abhängigkeiten mit. Ihr KI-Agent möchte nur eine Seite lesen, auf eine Schaltfläche klicken und weitermachen.
**Kuri ist eine einzelne Zig-Binärdatei.** Vier Modi, null Laufzeit:

```
kuri           →  CDP server (Chrome automation, a11y snapshots, HAR)
kuri-fetch     →  standalone fetcher (no Chrome, QuickJS for JS, ~2 MB)
kuri-browse    →  interactive terminal browser (navigate, follow links, search)
kuri-agent     →  agentic CLI (scriptable Chrome automation + security testing)
```

---
## 📦 Installation

### Einzeilige Installation (macOS / Linux)

```sh
curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh
```

Erkennt deine Plattform, lädt die passende Binärdatei herunter, installiert nach `~/.local/bin`.
Downloads stammen aus Kuris selbstverwaltetem `release-channel`-Branch. macOS-Binärdateien sind lokal mit einem Developer ID-Zertifikat signiert. GitHub-Release-Assets spiegeln dieselben Tarballs.

### bun / npm

```sh
bun install -g kuri-agent
# or: npm install -g kuri-agent
```

Lädt bei der Installation die korrekte native Binärdatei für deine Plattform herunter.

### Release-Kanal

Kuris stabile Binärdateien liegen im Branch `release-channel` und werden direkt über GitHub-Raw-URLs bereitgestellt.

- Stabiler Installer: `https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh`
- Stabiles Manifest: `https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/latest.json`
- Branch-Ansicht: `https://github.com/justrach/kuri/tree/release-channel/stable`
- Direktes Download-Muster: `https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/<version>/kuri-<version>-<target>.tar.gz`

### Manuell

Lade das Tarball für deine Plattform aus dem [stabilen Release-Manifest](https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/latest.json) oder von der [GitHub-Releases-Seite](https://github.com/justrach/kuri/releases) herunter und entpacke es in deinen `$PATH`.

Stabile Installations-URL:

```sh
curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh
```

Das Manifest enthält exakte Asset-URLs sowie SHA-256-Prüfsummen für `aarch64-linux`, `x86_64-linux`, `aarch64-macos` und `x86_64-macos`.

### Plattformunterstützung

| Plattform | Status |
|---|---|
| macOS (`aarch64`, `x86_64`) | Vorkompilierte Binärdateien, signiert + notarisiert |
| Linux (`aarch64`, `x86_64`) | Vorkompilierte Binärdateien |
| Windows (`x86_64`) | **Experimentell — nur Cross-Compile.** `zig build -Dtarget=x86_64-windows-gnu` ist CI-verifiziert, aber Chrome-Automatisierung, Daemonisierung, signalbasiertes Herunterfahren, HAR-Aufzeichnung und der dateibasierte Auth-Speicher sind zur Laufzeit alle mit `error.UnsupportedOnWindows` als Stub implementiert. Verwende **WSL2**, wenn du den echten Funktionsumfang benötigst. Verfolgt unter [#153](https://github.com/justrach/kuri/issues/153). |

Kuri stützt sich an mehreren Stellen auf POSIX-Primitive (`fork`, `clock_gettime`, Raw-Sockets), daher ist ein vollständiger nativer Windows-Port echte Arbeit. Die obige Baseline auf Compile-Ebene lässt die `--version`/`--help`-Pfade und reine In-Memory-Operationen laufen; die kniffligen Teile (Chrome, Sockets, Daemonize) benötigen echte Win32-Implementierungen, bevor sie von der Stub-Liste gestrichen werden können. Wenn du dich eines davon annehmen möchtest, gib +1 auf [#153](https://github.com/justrach/kuri/issues/153) oder öffne einen PR.

### Aus dem Quellcode bauen

Erfordert [Zig ≥ 0.16.0](https://ziglang.org/download/).

```bash
git clone https://github.com/justrach/kuri.git
cd kuri
zig build -Doptimize=ReleaseFast
# Binaries in zig-out/bin/: kuri  kuri-agent  kuri-fetch  kuri-browse
```

---

## ⚡ Schnellstart

**Voraussetzungen:** [Zig ≥ 0.16.0](https://ziglang.org/download/) · Chrome/Chromium (für den CDP-Modus)

```bash
git clone https://github.com/justrach/kuri.git
cd kuri

zig build              # build everything
zig build test         # run 252+ tests

# CDP mode — launches Chrome automatically
./zig-out/bin/kuri

# Standalone mode — no Chrome needed
./zig-out/bin/kuri-fetch https://example.com

# Interactive browser — browse from your terminal
./zig-out/bin/kuri-browse https://example.com

# Experimental standalone browser runtime — separate build, not production
(cd kuri-browser && zig build run -- render https://example.com)
(cd kuri-browser && zig build run -- bench --offline)
```

### Erster Durchlauf, kürzester Pfad

```bash
# start the server; if CDP_URL is unset, kuri launches managed Chrome for you
./zig-out/bin/kuri

# discover tabs from that managed browser
curl -s http://127.0.0.1:8080/discover

# inspect the discovered tab list
curl -s http://127.0.0.1:8080/tabs
```

### Sitzungsorientierte Agent-Schleife

Für die HTTP-Nutzung im Agent-Stil sollten Sie einen Sitzungs-Header zusammen mit `/tab/new`, `/page/info` und `/snapshot` bevorzugen, anstatt `tab_id` bei jedem Aufruf zu wiederholen.

```bash
SESSION=hn-demo
BASE=http://127.0.0.1:8080

curl -s -H "X-Kuri-Session: $SESSION" \
  "$BASE/tab/new?url=https%3A%2F%2Fnews.ycombinator.com"

curl -s -H "X-Kuri-Session: $SESSION" "$BASE/page/info"
SNAP=$(curl -s -H "X-Kuri-Session: $SESSION" "$BASE/snapshot?filter=interactive&format=compact")
MORE_REF=$(printf '%s' "$SNAP" | python3 -c 'import re,sys; print(re.search(r"\"More\" @(e\\d+)", sys.stdin.read()).group(1))')
curl -s -H "X-Kuri-Session: $SESSION" "$BASE/action?action=click&ref=$MORE_REF"
curl -s -H "X-Kuri-Session: $SESSION" "$BASE/page/info"
```

Es gibt auch einen dünnen experimentellen Wrapper unter `tools/kuri_harness.py`, wenn du Python-Helfer auf derselben HTTP-Oberfläche möchtest.

Wenn Chrome bereits mit Remote-Debugging läuft, setze `CDP_URL` entweder auf den WebSocket- oder den HTTP-Endpunkt:

```bash
CDP_URL=ws://127.0.0.1:9222/devtools/browser/... ./zig-out/bin/kuri
# or
CDP_URL=http://127.0.0.1:9222 ./zig-out/bin/kuri
```

### vercel.com in 4 Befehlen durchsuchen

```bash
# 1. Discover Chrome tabs
curl -s http://localhost:8080/discover
# → {"discovered":1,"total_tabs":1}

# 2. Get tab ID
curl -s http://localhost:8080/tabs
# → [{"id":"ABC123","url":"chrome://newtab/","title":"New Tab"}]

# 3. Navigate
curl -s "http://localhost:8080/navigate?tab_id=ABC123&url=https://vercel.com"

# 4. Get accessibility snapshot (token-optimized for LLMs)
curl -s "http://localhost:8080/snapshot?tab_id=ABC123&filter=interactive"
# → [{"ref":"e0","role":"link","name":"VercelLogotype"},
#    {"ref":"e1","role":"button","name":"Ask AI"}, ...]
```

---

## 🌐 HTTP-API

Alle Endpunkte liefern JSON zurück. Optionale Authentifizierung über die Umgebungsvariable `KURI_SECRET`. **135 Endpunkte** — vollständige Parität mit agent-browser und browser-use.

### Kern

| Pfad | Beschreibung |
|------|-------------|
| `GET /health` | Serverstatus, Tab-Anzahl, Version |
| `GET /tabs` | Alle registrierten Tabs auflisten |
| `GET /discover` | Chrome-Tabs automatisch über CDP erkennen |
| `GET /tab/current` | Aktuellen Tab für eine `X-Kuri-Session` abrufen oder setzen |
| `GET /page/info` | Live-URL/Titel/Ready-State/Viewport/Scroll für den aktiven Tab |
| `GET /page/state` | Kompakte Seitenbeobachtung: URL, Titel, Scroll-%, Viewport, Anzahl von Formularen/Links/Bildern/Inputs |
| `POST /batch` | Mehrere Befehle in einem HTTP-Aufruf ausführen — liefert ein Array von Ergebnissen zurück |
| `GET /browdie` | 🌰 (Easter Egg) |

### Browser-Steuerung

| Pfad | Parameter | Beschreibung |
|------|--------|-------------|
| `GET /navigate` | `tab_id`, `url` | Tab zur URL navigieren |
| `GET /tab/new` | `url`, `activate`, `wait` | Neuen Tab erstellen und optional hydratisieren/als aktuellen Tab setzen |
| `GET /tab/close` | `tab_id` | Tab schließen |
| `GET /window/new` | `url`, `activate`, `wait` | Neues Fenster-/Tab-Ziel erstellen |
| `GET /snapshot` | `tab_id`, `filter`, `format` | A11y-Baum-Snapshot mit `eN`-Referenzen. Verwende `filter=interactive&format=compact` für token-effiziente Agent-Schleifen. |
| `GET /text` | `tab_id` | Seitentext extrahieren |
| `GET /screenshot` | `tab_id`, `format`, `quality`, `save` | Screenshot aufnehmen (base64); `save=true` schreibt das PNG nach `STATE_DIR/screenshots` und liefert stattdessen `{path,bytes}` zurück |
| `GET /screenshot/annotated` | `tab_id` | Screenshot mit nummerierten Elementbeschriftungen |
| `GET /screenshot/diff` | `tab_id`, `baseline` | Visueller Diff zwischen aktuellem und Baseline-Screenshot |
| `GET /action` | `tab_id`, `ref`, `action`, `value` | Klicken/Tippen/Ausfüllen/Auswählen/Scrollen/Hovern/Doppelklicken/Anhaken/Abhaken/Blur per Ref |
| `GET /evaluate` | `tab_id`, `expression` | JavaScript ausführen |
| `GET /evalhandle` | `tab_id`, `expression` | JS ausführen, objectId-Handle zurückgeben (nicht den Wert) |
| `GET /close` | `tab_id` | Tab schließen + aufräumen |
| `GET /bringtofront` | `tab_id` | Tab in den Vordergrund bringen |

### Aktionen

| Pfad | Parameter | Beschreibung |
|------|--------|-------------|
| `GET /clear` | `ref` | Wert des Eingabefelds leeren |
| `GET /selectall` | `ref` | Gesamten Text in Input/contenteditable auswählen |
| `GET /setvalue` | `ref`, `value` | Eingabewert direkt setzen (umgeht Tastenereignisse) |
| `GET /dispatch` | `ref`, `type` | Benutzerdefiniertes DOM-Ereignis auf Element auslösen |
| `GET /boundingbox` | `ref` | Begrenzungsrechteck des Elements abrufen (x, y, width, height, centerX, centerY) |
| `GET /getattribute` | `ref`, `name` | Element-Attribut nach Namen abrufen |
| `GET /inputvalue` | `ref` | Aktuellen Wert des Eingabeelements abrufen |
| `GET /element/state` | `ref`, `check` | Schneller Boolescher Wert: `exists`, `visible`, `enabled`, `checked` |
| `GET /find-element` | `text`/`role`/`label`/`placeholder`/`testid` | Semantischer Locator — Element ohne Snap finden |
| `GET /highlight` | `ref` oder `selector` | Element mit Overlay hervorheben |

### Maus & Touch

| Pfad | Parameter | Beschreibung |
|------|--------|-------------|
| `GET /mouse/move` | `x`, `y` | Maus zu Koordinaten bewegen |
| `GET /mouse/down` | `x`, `y`, `button` | Maustaste drücken |
| `GET /mouse/up` | `x`, `y`, `button` | Maustaste loslassen |
| `GET /mouse/wheel` | `x`, `y`, `deltaX`, `deltaY` | Mausrad-Scrollen |
| `GET /tap` | `x`, `y` | Touch-Tap (touchStart + touchEnd) |
| `GET /swipe` | `startX`, `startY`, `endX`, `endY` | Touch-Wischgeste |
| `GET /drag` | `src_ref`, `tgt_ref` | Element zum Ziel ziehen |

### Tastatur

| Pfad | Parameter | Beschreibung |
|------|--------|-------------|
| `GET /keyboard/type` | `tab_id`, `text` | Text über Tastenereignisse eingeben |
| `GET /keyboard/inserttext` | `tab_id`, `text` | Text direkt einfügen |
| `GET /keydown` | `tab_id`, `key` | Key-Down-Ereignis |
| `GET /keyup` | `tab_id`, `key` | Key-Up-Ereignis |

### Inhaltsextraktion

| Pfad | Beschreibung |
|------|-------------|
| `GET /markdown` | Seite in Markdown konvertieren |
| `GET /links` | Alle Links extrahieren |
| `GET /dom/query` | CSS-Selektor-Abfrage |
| `GET /dom/html` | Element-HTML abrufen |
| `GET /dom/attributes` | Element-Attribute abrufen |
| `GET /pdf` | Seite als PDF drucken |
| `GET /find` | Textsuche innerhalb der Seite |

### Warten

| Pfad | Parameter | Beschreibung |
|------|--------|-------------|
| `GET /wait` | `selector`, `text`, `url`, `state`, `visible`, `timeout` | Auf Selektor/Text/URL-Muster/networkidle/Ladezustand warten |
| `GET /wait/function` | `expression`, `timeout` | Auf beliebigen JS-Ausdruck warten, bis er truthy ist |
| `GET /wait/download` | `timeout` | Auf Abschluss eines Dateidownloads warten |

### Dialog-Behandlung

| Pfad | Beschreibung |
|------|-------------|
| `GET /dialog/auto` | Alle JS-Dialoge automatisch behandeln (akzeptieren oder verwerfen) |
| `GET /dialog/accept` | Aktuellen Dialog akzeptieren (mit optionalem Prompt-Text) |
| `GET /dialog/dismiss` | Aktuellen Dialog verwerfen |

### Netzwerk & HAR

| Pfad | Beschreibung |
|------|-------------|
| `GET /har/start` | Netzwerkverkehr aufzeichnen starten |
| `GET /har/stop` | Aufzeichnung stoppen + HAR 1.2 JSON zurückgeben |
| `GET /har/status` | Aufzeichnungszustand + Anzahl der Einträge |
| `GET /har/replay` | API-Map mit curl/fetch/python-Code-Snippets |
| `GET /cookies` | Cookies abrufen |
| `GET /cookies/set` | Cookies setzen |
| `GET /cookies/delete` | Cookies löschen |
| `GET /cookies/clear` | Alle Cookies löschen |
| `GET /headers` | Benutzerdefinierte Request-Header setzen |
| `GET /intercept/start` | Request-Interception starten |
| `GET /intercept/stop` | Request-Interception stoppen |
| `GET /intercept/requests` | Abgefangene Requests auflisten |
| `GET /request/detail` | Response-Body für eine Request-ID abrufen |
| `GET /response/body` | URL abrufen und Response-Body zurückgeben |
| `GET /network` | Netzwerkverkehrsstatistiken |
| `GET /download` | Dateidownload auslösen |

### Navigation & Zustand

| Pfad | Beschreibung |
|------|-------------|
| `GET /back` | Browser zurück |
| `GET /forward` | Browser vorwärts |
| `GET /reload` | Seite neu laden |
| `GET /stop` | Seitenladen stoppen |
| `GET /pushstate` | SPA-Navigation über history.pushState |
| `GET /storage/local` | localStorage abrufen/setzen |
| `GET /storage/session` | sessionStorage abrufen/setzen |
| `GET /storage/local/clear` | localStorage leeren |
| `GET /storage/session/clear` | sessionStorage leeren |
| `GET /session/save` | Browser-Sitzung speichern |
| `GET /session/load` | Browser-Sitzung wiederherstellen |
| `GET /session/list` | Gespeicherte Sitzungen auflisten |
| `GET /setcontent` | Seiten-HTML direkt setzen (POST) |

### Auth-Profile

| Pfad | Beschreibung |
|------|-------------|
| `GET /auth/profile/save` | Cookies + Storage als benanntes Auth-Profil speichern |
| `GET /auth/profile/load` | Benanntes Auth-Profil in einen Tab wiederherstellen |
| `GET /auth/profile/list` | Gespeicherte Auth-Profile auflisten |
| `GET /auth/profile/delete` | Gespeichertes Auth-Profil löschen |
| `GET /auth/extract` | Auth-Tokens extrahieren (JWT, Cookies, Header) |
| `GET /set/credentials` | HTTP-Basic-Auth-Anmeldedaten setzen |

Unter macOS werden Auth-Profil-Geheimnisse im Benutzer-Schlüsselbund gespeichert.

### Emulation

| Pfad | Parameter | Beschreibung |
|------|--------|-------------|
| `GET /emulate` | Gerätetyp, Bildschirmgröße | Geräteemulation |
| `GET /set/viewport` | `width`, `height` | Viewport-Größe setzen |
| `GET /set/useragent` | `ua` | User-Agent setzen |
| `GET /set/media` | `media` | Medientyp emulieren |
| `GET /set/offline` | `offline` | Offline-Modus umschalten |
| `GET /geolocation` | `lat`, `lng` | Geolokalisierung überschreiben |
| `GET /timezone` | `timezone` | Zeitzone überschreiben (z. B. `America/New_York`) |
| `GET /locale` | `locale` | Locale überschreiben (z. B. `en-US`) |
| `GET /permissions` | `name`, `state` | Berechtigungen erteilen/verweigern (Geolokalisierung, Benachrichtigungen, Zwischenablage) |

### Skripte & Injection

| Pfad | Beschreibung |
|------|-------------|
| `GET /script/inject` | JavaScript in die Seite injizieren (bleibt über Navigation hinweg erhalten) |
| `GET /initscript/remove` | Ein zuvor injiziertes Init-Skript entfernen |
| `GET /addstyle` | CSS-Stylesheet injizieren |
| `GET /expose` | Eine benannte Funktion im JS-Kontext der Seite verfügbar machen |

### React-Inspektion

| Pfad | Beschreibung |
|------|-------------|
| `GET /react/tree` | React-Komponentenbaum über DevTools-Hook |
| `GET /react/inspect` | React-Komponenten-Props und -State |
| `GET /react/renders` | React-Render-Tracking (Start/Stop) |
| `GET /react/suspense` | Status der React-Suspense-Grenze |

### Aufzeichnung & Performance

| Pfad | Beschreibung |
|------|-------------|
| `GET /recording/start` | Benutzeraktionen aufzeichnen (Klick, Eingabe, Navigation) |
| `GET /recording/stop` | Aufzeichnung stoppen + Aktionsprotokoll zurückgeben |
| `GET /vitals` | Core Web Vitals (LCP, CLS, FID, TTFB, FCP, domInteractive) |
| `GET /perf/lcp` | Largest Contentful Paint Timing |
| `GET /trace/start` | Performance-Trace starten |
| `GET /trace/stop` | Trace stoppen |
| `GET /profiler/start` | JS-Profiler starten |
| `GET /profiler/stop` | Profiler stoppen |

### Debugging

| Pfad | Beschreibung |
|------|-------------|
| `GET /debug/enable` | In-Page-Debug-HUD und optionalen Freeze-Modus aktivieren |
| `GET /debug/disable` | In-Page-Debug-HUD deaktivieren |
| `GET /inspect` | Element-Inspektion |
| `GET /errors` | JS-Fehler sammeln |
| `GET /console` | Konsolen-Logs lesen |
| `GET /frames` | Seiten-Frames auflisten |
| `GET /frame` | Zum iframe-Kontext per Name oder URL wechseln |
| `GET /mainframe` | Zurück zum Haupt-Frame wechseln |
| `GET /diff/snapshot` | Kompakter `+`/`~`/`-`-Diff gegenüber dem vorherigen Aufruf für diesen Tab — die token-effiziente Aktionsschleife (Alias von `/snapshot/changes`). Fällt bei massiven Änderungen auf einen vollständigen Snapshot mit `! page replaced`-Header zurück. |
| `GET /diff/url` | Zwei URLs nebeneinander vergleichen (navigieren, Snapshot, Diff) |

### Streaming

| Pfad | Beschreibung |
|------|-------------|
| `GET /screencast/start` | Bildschirmaufzeichnung starten |
| `GET /screencast/stop` | Bildschirmaufzeichnung stoppen |
| `GET /video/start` | Videoaufzeichnung starten |
| `GET /video/stop` | Videoaufzeichnung stoppen |
| `GET /ws/start` | WebSocket-Tunnel starten |
| `GET /ws/stop` | WebSocket-Tunnel stoppen |

### Agent-freundliche Schleife

Die reibungsärmste Server-Schleife ist:

1. `GET /tab/new?url=...`
2. `GET /page/state` (leichtgewichtig) oder `GET /snapshot?filter=interactive&format=compact` (vollständig)
3. `GET /action?action=click&ref=eN`
4. Wiederholen — oder `POST /batch` für mehrstufige Operationen in einem Aufruf verwenden

Die Query-Parameter `url` und `expression` werden prozent-dekodiert. Sende `X-Kuri-Session: my-agent`, um den Tab-Kontext serverseitig zu persistieren.
---

## 🧠 Skills

Das Repository enthält einen benutzererweiterbaren Skill-Bereich:

- `skills/kuri-skill.md` ist der Basis-Kuri-HTTP-Agent-Skill
- `skills/custom/` ist für deine eigenen projektspezifischen Skills reserviert
- `skills/custom/hackernews-page-2.md` ist ein konkretes Beispiel für einen benutzerdefinierten Skill
- `.claude/skills/kuri-server/SKILL.md` bleibt für Claude-artige Repo-Skills synchron

Der Basis-Skill erklärt nun auch, welcher Browser-Pfad verwendet werden sollte:

- `kuri` HTTP-API: Produktions-Chrome/CDP-Automatisierung mit Sitzungen, Snapshots, Aktionen, HAR, Cookies und Screenshots
- `kuri-fetch`: eigenständige Fetch-/Textextraktion ohne Chrome
- `kuri-browse`: interaktives Terminal-Browsing
- `kuri-agent`: skriptbare CLI-Automatisierung gegen den Kuri-Server
- `kuri-browser/`: experimentelle separate Zig-native Browser-Runtime für Paritätsarbeit

Für die experimentelle Browser-CLI:

```bash
cd kuri-browser
zig build run -- render https://news.ycombinator.com --selector ".titleline a" --dump text
zig build run -- render https://todomvc.com/examples/react/dist/ --js --wait-eval "document.querySelectorAll('.todo-list li').length >= 1"
zig build run -- parity --offline
zig build run -- bench --offline
zig build run -- serve-cdp --port 9333
```

`kuri-browser serve-cdp` stellt eine Chrome-artige HTTP-Discovery sowie einen minimalen WebSocket-JSON-RPC-Router für Protokoll-Smoke-Tests bereit. Runtime-Eval gibt V8-förmige CDP-Remote-Objekte zurück, die von QuickJS unterstützt werden; dies fügt keine V8-Abhängigkeit hinzu und ist noch keine vollständige Playwright/Puppeteer-Kompatibilität.

Screenshots in `kuri-browser` delegieren derzeit an den Haupt-Kuri/CDP-Renderer. Starten Sie zuerst `./zig-out/bin/kuri`, dann:

```bash
cd kuri-browser
zig build run -- screenshot https://example.com --out example.jpg --compress --kuri-base http://127.0.0.1:8080
```

`--compress` erfasst eine PNG-Basislinie und einen JPEG-Kandidaten, schreibt die kleinere Datei und meldet die Byte-Einsparung. Aktuelle lokale Messung auf `https://example.com`: `20,523` Bytes PNG auf `18,183` Bytes JPEG Qualität 50, Einsparung von `2,340` Bytes oder `11%`.

### Erweitert

| Pfad | Beschreibung |
|------|-------------|
| `GET /diff/snapshot` | Kompaktes `+`/`~`/`-` Delta gegenüber dem vorherigen Snapshot (Agent-Aktionsschleife) |
| `GET /emulate` | Geräteemulation |
| `GET /geolocation` | Geolokalisierung festlegen |
| `POST /upload` | Datei-Upload |
| `GET /script/inject` | JavaScript injizieren |
| `GET /intercept/start` | Anfragen-Interception starten |
| `GET /intercept/stop` | Interception stoppen |
| `GET /screenshot/annotated` | Screenshot mit Element-Annotationen |
| `GET /screenshot/diff` | Visueller Diff zwischen Screenshots |
| `GET /screencast/start` | Screencast starten |
| `GET /screencast/stop` | Screencast stoppen |
| `GET /video/start` | Videoaufzeichnung starten |
| `GET /video/stop` | Videoaufzeichnung stoppen |
| `GET /console` | Konsolen-Nachrichten abrufen |
| `GET /stop` | Seitenladen stoppen |
| `GET /get` | Direkter HTTP-Abruf (serverseitig) |
| `GET /scrollintoview` | Ein referenziertes Element in den sichtbaren Bereich scrollen |
| `GET /drag` | Von einer Referenz zu einer anderen ziehen |
| `GET /keyboard/type` | Text mit Tastenereignissen eingeben |
| `GET /keyboard/inserttext` | Text direkt einfügen |
| `GET /keydown` | Ein keydown-Ereignis auslösen |
| `GET /keyup` | Ein keyup-Ereignis auslösen |
| `GET /wait` | Auf Ready-State oder Element-Bedingungen warten |
| `GET /tab/close` | Einen Tab schließen |
| `GET /highlight` | Ein Element per Referenz oder Selektor hervorheben |
| `GET /errors` | Seiten-/Laufzeitfehler abrufen |
| `GET /set/offline` | Offline-Netzwerkemulation umschalten |
| `GET /set/media` | Emulierte Media-Features festlegen |
| `GET /set/credentials` | HTTP-Basic-Auth-Anmeldedaten festlegen |
| `GET /find` | Textübereinstimmungen auf der aktuellen Seite finden |
| `GET /trace/start` | Chrome-Tracing starten |
| `GET /trace/stop` | Tracing stoppen und Trace-Daten zurückgeben |
| `GET /profiler/start` | JS-Profiler starten |
| `GET /profiler/stop` | JS-Profiler stoppen |
| `GET /inspect` | Ein Element oder den Seitenzustand inspizieren |
| `GET /set/viewport` | Viewport-Größe festlegen |
| `GET /set/useragent` | User Agent überschreiben |
| `GET /dom/attributes` | Element-Attribute abrufen |
| `GET /frames` | Frame-Baum auflisten |
| `GET /network` | Netzwerkzustand/-anfragen inspizieren |

---

## 🛡️ Stealth & Bot-Umgehung

Kuri wendet Anti-Detection-Patches beim Start automatisch an — keine manuelle Konfiguration erforderlich.

### Was angewendet wird

- **`Page.addScriptToEvaluateOnNewDocument`** — Stealth-Patches laufen vor jedem Seiten-JS
- **navigator.webdriver = false** — verbirgt das Automatisierungs-Flag auf Chromium-Ebene (`--disable-blink-features=AutomationControlled`)
- **WebGL/Canvas/AudioContext-Spoofing** — besiegt fingerprint-basierte Erkennung
- **UA-Rotation** — 5 realistische Chrome/Safari/Firefox User Agents
- **chrome.csi/chrome.loadTimes** — Stubs für Akamai-spezifische Prüfungen

### Bot-Block-Erkennung

Navigate erkennt Blocks automatisch und gibt einen strukturierten Fallback zurück:

```bash
curl -s "http://localhost:8080/navigate?tab_id=ABC&url=https://protected-site.com"
# If blocked:
# {"blocked":true,"blocker":"akamai","ref_code":"0.7d...",
#  "fallback":{"suggestions":["Open URL directly in browser","Use KURI_PROXY"]}}
# If ok: normal CDP response
```

Erkennt: **Akamai**, **Cloudflare**, **PerimeterX**, **DataDome**, generisches Captcha.

### Proxy-Unterstützung

```bash
KURI_PROXY=socks5://user:pass@residential-proxy:1080 ./zig-out/bin/kuri
KURI_PROXY=http://proxy:8080 ./zig-out/bin/kuri
```

### Getestete Seiten

| Seite | Schutz | Ergebnis |
|------|-----------|--------|
| Singapore Airlines | Akamai WAF | ✅ Umgangen (war vor v0.4.0 blockiert) |
| Shopee SG | Benutzerdefinierte Betrugsabwehr | ✅ Seite lädt, leitet zur Anmeldung weiter |
| Google Flights | Keine | ✅ Vollständige Interaktion |
| Booking.com | PerimeterX | ⚠️ Benötigt Proxy |

---

## 🔧 kuri-fetch

Eigenständiger HTTP-Fetcher — kein Chrome, kein Playwright, kein npm. Wird als ~2 MB große Binärdatei mit integriertem QuickJS für die JS-Ausführung ausgeliefert.

```bash
zig build fetch    # build + run

# Default: convert to Markdown
kuri-fetch https://example.com
```

---

[Read more](https://github.com/justrach/kuri)
Tool herunterladen