daedalus
Daedalus
Fernsteuerung des Browsers über eine Chrome-Erweiterung. Eval-Brücke + dauerhafte Hotfixes + Steuerung pro Tab + Screenshots, CDP, Cookies und Netzwerkaufnahme auf Seiten, auf denen Chrome die Erweiterung ausführt.
Installation
Bevor du installierst, solltest du das wissen: normales Eval verwendet eine bannerfreie MAIN-World-Injektion. Wenn eine quellfreie CSP-Probe nicht feststellen kann, dass dynamische Kompilierung verfügbar ist, versucht Daedalus den CDP-Fallback; bei einem erfolgreichen Anhängen zeigt Chrome das Banner „Daedalus started debugging this browser„, solange dieser Fallback läuft. Eine offen gehaltene CDP-Session oder ein Netzwerk-Capture kann den Anhang länger aufrechterhalten. Das Banner kennzeichnet einen Debugger-Anhang, nicht eine Garantie für die Integrität von Werten.
Lade die entpackte Erweiterung (extension/) in Chrome:
Besuche
chrome://extensionsAktiviere Entwicklermodus
Klicke auf Entpackte Erweiterung laden und wähle
extension/
Bei der ersten Installation bekomme die Erweiterung automatisch einen eindeutigen Token dieser in chrome.storage.local gespeichert. Auf der Optionsseite der Erweiterung kannst du ihn anzeigen oder ändern (Puzzle-Symbol → Daedalus → Optionen).
Für paralleles Scraping über mehrere Tabs deaktiviere die Drosselung von Hintergrund-Tabs in Chrome:
chrome --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-renderer-backgroundingSo funktioniert es
Token: Wird einmalig bei der Installation über
crypto.randomUUID()generiert und inchrome.storage.localgespeichertTab-IDs: Die native
tabs-API von Chrome – jede Seite wird über ihre Chrome-tabIdidentifiziert und bei „create/update“ mit einem Heartbeat überchrome.alarms(30 s) registriertEin einziger update:
background.jsöffnet eine dauerhaftefetch-Verbindung mitSSE(tab=extension) und verteilt eingehende Befehle an den richtigen TabSeiten-Brücke:
content.js(ISOLATED world) leitetwindow.GMNachrichten zwischen Background undpage.js(MAIN world) weiter. Zuerst verwendet Eval die MAIN-World-Injektion überchrome.scripting. Eine Probe ohne Seiten-CSP pruft, ob eine dynamische Kompilierung möglich ist; wenn blockiert, erfolgt der Weg über CDP – deren Seite-Relay kommt, falls dort kein Kontakt möglich ist. Auf jedem Kanal wird dieMAIN-World-Semantik der Seite verwendet.Hotfixes: gespeichert im Erweiterungsbereich
chrome.storage.localunter dem Schlüsseldaedalus-hotfixes– nicht pro Token –, beim Laden jeder passenden Top-Level-Seite erneut abgespielt und für nicht-permanente Fixes versionsgebunden. Das Rotieren des Tokens trennt diesen Store nicht und leert ihn auch nicht.
Befehle senden
Daedalus stellt seine Erweiterungsbefehlsfläche als MCP-Server unter <your-bridge>/mcp bereit (Transport „streamable-http“). Vor der Zusendung ist erforderlich, dass der Bearer-Wert exakt dem Bridge-Token entspricht, das über den bestehenden Konfigurationspfad der CLI aufgelöst wird: TOKEN hat Vorrang vor DAEDALUS_TOKEN, einschließlich eines optionalen _settings-Providers. Ohne konfigurierten Token schließt die MCP-Oberfläche mit 401 ab (fail closed). Die kannst du zu Claude Code (oder einem beliebigen MCP-Client) wie folgt hinzufügen:
{
"mcpServers": {
"daedalus": {
"url": "https://daedalus.example.com/mcp",
"headers": { "Authorization": "Bearer <your-bridge-token>" }
}
}
}Das Bridge-Token ist das von der Erweiterung bei der Installation generierte Token – sichtbar auf der Erweiterungsoptionen-Seite (Puzzle-Symbol → Schweinwurf → Options).
In diesem Beispiel steht der MCP-Server hinter einer öffentlichen Domain, doch die standardmäßig erlaubten Host-Transporte sind auf die Schleife beschränkt (127.0.0.1:*,localhost), *])* – nenne den öffentlichen Host in DAEDALUS_MCP_ALLOWED_HOSTS, sonst werden die angeforderten Anfragen abgelehnt. Alle drei Einstellungen für MCP unter „Server“.
40 Werkzeuge in 7 Gruppen – Achtk und Haken etc.: Tabs, eval/debug, Media, Cookies, Blocking & CSS, Hotfixes, Netz/CDP. Die vollständige Liste findest du im <mcp>-Abschnitt der Datei CLAUDE.md oder via tools/list am MCP-Endpunkt.
Ein Script zur manuellen Verarbeitung (kein MCP-Client erforderlich):
TOKEN=<tok> python3 scripts/mcp_probe.py list
TOKEN=<tok> python3 scripts/mcp_probe.py call title '{"tab_id":"<tabId>"}'
TOKEN=<tok> python3 scripts/mcp_probe.py call screenshot '{"include_image":true}'CLI
Die Shell-CLI wird in diesem Repository ( daedalus_cli/) als daedalus-Wheel ausgeliefert und als Befehl daedalus installiert. Sie liest DAEDALUS_URL und DAEDALUS_TOKEN aus den Umgebungsvariablen, TOKEN ist dose Einmal-Override, ID=<tabId> gezielteauswahl oder Tab (weglassen = senden an alle):
DAEDALUS_TOKEN=<tok> daedalus tabs
DAEDALUS_TOKEN=<tok> ID=<tabId> daedalus title
DAEDALUS_TOKEN=<tok> daedalus exec myid 'document.title'daedalus --help listet alle Unterbefehle auf, und jeder hat sein eigenes --help. Der exec-Code, den du ihmCode sendest, ist eine Expression oder ein Funktionsrumpf, dessen Rückgabe als Ergebnis übernommen wird – siehe Vertrag in „Befehle senden“ weiter oben.
Zusätzlich gibt es diese optionale Importbreite: Ist ein Modul _settings auf sys.path verfügbar, verwendet die CLI deren Funktionen setting(name, default) und required(name) z für DAEDALUS_URL und DAEDALUS_TOKEN statt dem eingebauten Env-Fallback. Die TOKEN-Variable in der Umgebung bleibt die einmalige Token-Anderung und hat die höchste Priorität. Fehlt _settings, benutzt DAEDALUS_URL seinen Standardwert und DAEDALUS_TOKEN wird zwingend; ID bleibt als Variable zur gezielten Tab-Steuerung.
Oder atomisches Veröffentlichen einer Roh-Befehl (kein MCP, kein CLI). Ein direktes Umlenken auf die endgültige .json-Datei wird nicht unterstützt, da der Stream die Datei sehen könnte, bevor der Writer die Datei abgeschlossen hat. Schreibe einen Nachbarnamen auf .tmp um und benenne ihn im selben Verzeichnis um:
# Broadcast to all tabs
commands_dir="$DAEDALUS_DIR/commands"
final="$commands_dir/<token>.json"
tmp="$(mktemp "$commands_dir/.<token>.XXXXXX.tmp")"
printf '%s\n' '{"id":"test1","code":"document.title"}' > "$tmp" &&
mv "$tmp" "$final"
# Target a specific tab
final="$commands_dir/<token>_<tabId>.json"
tmp="$(mktemp "$commands_dir/.<token>_<tabId>.XXXXXX.tmp")"
printf '%s\n' '{"id":"test1","code":"document.title"}' > "$tmp" &&
mv "$tmp" "$final"Der Reader ignoriert zugehörige .tmp-Namen. Wenn ein älterer Writer die .json korrupt anzeigt, wird sie vom Leser unangetastet zu lassen und ein neuer Vererd erzeugt, statt eines unterbchenen statts zu löschen. Nach dem atomaren Umbenennen liefert der SSE-Stream den Befehl und verbraucht ihn. Ausgabe unter $DAEDALUS_DIR/results/<token>_<tabId>.json (pro Tab) und zusätzliche $DAEDALUS_DIR/results/<token>.json (letzter Schreiber gewinnt). page-main-Injektionen und Page-Relay-Evalz-Abschlüsse können ein exec_ms-Feld enthalten – die Ausführzeitms im Seitenkontext. Die Seite kann dieses Feldd Waehler verfälschen oder weglassen. CDP-Abschlüsse bringen kein exec_ms mit. Ergebnisse, die über eine verzögerte Zustellung liefen, enthalten außerdem roundtrip_ms – die Dauer des gesamten, serverbeobachteten Umlaufs ab Einrangieren (PUT /command) bis der Ú ergebnisRenderer (POST /result). Dazu gehört Warteschlange + SSE-Zustellung + Client-Relay + Ausführzeit + Rückweg; wenn beide Felder vorhanden sind, nähert roundtrip_ms − exec_ms den Transport-/Warteschlangen-Overhead an. Zwei Uhren – exec_ms basiert auf performance.now() der Seite, eine roundtrip_ms-Uhr auf Serverintegrität; deren Umfang daher eine Approximation, keine exakte Differenz. Ein Alterthumsrahmen ohne _did hat kein roundtrip_ms.
Synth Unterstützung
Die eigentlichen page-main-Kanal schickt Ausdrücke in eval der Seite, Ausdrücke in der Functionder Seite; ein async Wrapper liefert dasawaitA auf Top-Level. Wenn der Background die Quelle macht, wird nur eine constFunction-Probe eingefügt. Bei Rückgabe truewird die Quellinjektion einmal versucht und jede Folge ist Folge: ein Wert, eine Exception oder Transport- Injektionsfehler wird sofortigen CDP gemeldet, ohne dass die Quelle neuen Weg zum CDP gelegt wird. Da die Seite über dieFunction` die Wahl hat, ist der Umweg eine Kannali-Option – sie bewirkt aber keine Doppelwirkung der Seiteneffekte.
Die Probe wird nicht messbar zurück, meist Verhindert eine CSP die dynamic Kompilierung –, so versucht es eine CDP Die Anhängung zeigt das Debugger-Banner von Chrome; Runtime.evaluate benutzt REPL Mode für await; return-Code wird als Körper der function betrachtet, wenn der Parser der Probe nicht verhindertkann, dass er ist. Dies ist keine Ausführungs-Stellschraube: Handler-gesteuerten Quellen können prophylaxen. Nach der wurde die CDP-B-Sand box verwendet..." Auch terminal. Nur wenn das CDP-ö die Form schon beim Inject nicht passt. Damit stellt die Seite am Weiterleitung, CDP-Promise liegt bei maximal 10s. Das Protokoll fatigue verreicht und Objekt-Handles zur Exception werden nicht, und wenn eine offen gehaltene Sitzunges auf Verifikation.
JavaScript in einerfremden Seite (der du nicht gesetzt hast) kann daher jeden Wert näherbringen, unabhängig der Ausführkanaken. Das world-Feld protokolliert nur welchen Kanal Code (CMD) gelaufen ist; es ist eine Metainformation Wir*Diagnose zur UFSP und Begeschwerb, kein Vertrauenswert. Seine Eval-Werte sind page-main für die übliche Injektion, cdp für den Inspector-Fallback und page:<hostname> für den Relay. hostname ist dabei die location.hostname des Content-Scripts. Der Background setzt den Prefix page: herum, so dass ein Relay-Fallback nicht über cdp oder page-main liegen kann; diese simple Provider-Funktion macht makaber nichtsle noteworthy: Das CLI stellt das Feld als channel=... dar, wie auch Das Dashboard; die MCP-Tools exec, put, result und ping liefern den nativen world-Wert. Durch kein Werk wird eine Vertrauensklasse festgelegt.
Der übliche injektionsog der Advanced, sowie. Ausnahmen / Die CDP-Fallback rettet das klassische Script Verhalten der früheren Sloppy-Fälle: with wird, Oktales, deklariertes Assign wird zum globalen Delarator. CDP REPL-Modus erlaubt auch wiederholte let/const-Bindungen. CLI und MCP warten standardmäßig 15 Sekunden auf Ergebnis; einTimeout des Callers brdelete die Code nicht „laufend (already ongoing) auf der Seite. Der Blob-Relay e.» - Onlygilt - nach dem parsec-
Örtlich der über bringen Embeddett nichts ... „10 seconds await, sonst 3 Sekden, bevor as zum Fallback (timeout) führt.
Relayed-Korration bleibt `; der absoluter Tab muss übereinstimmen; Eine einmal angenommene Nachricht setzt die random ID über. Keine ID wird registriert, bis die zwei Bedingungen erfüllt sind: Die Probequelle wird nicht910 und CDP abschlieender nicht behebt. So vielfälftige Abschlüsse/Doppelte werden verhindert, ist aber keine Werthaltigkeit.
Maximal 1000 Relayige ReandVorher im Zeitzustand. Bei Erreichen der Oberkapazität erhält der neue Eintrag nur einmal eine FehlerMeldung „Terminal Capacity" ohne dass neue Arbeit gelöscht wird. Jeder weitere Eintrag at nach 300000 ms ab und bekommt nur einmalig den Timeout-Fehler gemeldet, falls er nicht vorher durch früheren Eintrag senden im selben Tab oder vorherigen Fehler entfernt wurde.
Dashboard
Eine webbasierte Steuerfläche zum blind- und Flussab Combs ohne CLI bei <your-bridge>/dashboard öffnen – die live TabListe, eine eval-REPL, Screenshots, Cookies, Hotfixes, Blockierte-Regwerke und net-Capture, net CDP, CSS, fetch-Timings, etc.
Öffne dafür eine URL & gehe in eine Tab, die die Erweiterung sich erkannt um
Deminement in §12 Geben Sie dort (Einstellungen) das Tokengegenständlich aus der Erweiterungsoptionen Seite ein (Puzzle-Symbol → Daedalus → Options) & speichert / Den Status-SSE aufder Zeile oben wird cyan.
Wenn der Dashboard recht vorher geschnittenen Server aktualisiert.
Accounts werden regiert durch serverantwort zu ...
**server.py (Repo)und den/dd Direktes); *For das/stream-Gerät
Sign. events durch schreibt z.B.
commands/<token>_dashboard/<ts>_<uuid>.json, wenn/registerein bestehendes gleiche erstellt. Durch das/sync-tabsErfolg und das/unregistersowie/result– Trigger. Bei/unregisterEmmission auch, wenn kein tab nicht da ist. Dashboard liest die Stream und Frames von Typ `kind:'event'.
Wichtig: Die Content- & Page-Scripts (Belg.) Reggen sind anstrengend, da sie sich alle an deckende Pages haben, auch der Dashboard-Tab. So läuft Hindcast-AvchBefehl (exec -b) auch im Dashboard – benutze das Zielbund- oder schließe das Dashboard, wenn du unterricht dev eingeschalteter "in das Wasser fährst".
Self-Patch
Hotfix-Patches
Langfristige kleine Patches, dass beim Laden jeder komponierten Top-Level-Seite per RDP erhalten ... MCP-Werkzeuge: store_hotfix, list_hotfixes, clear_hotfix, clear_hotfixes, set_permanent. Beispiel (via Skript):
TOKEN=<tok> python3 scripts/mcp_probe.py call store_hotfix '{"fix_id":"my-fix","code":"console.log(\"patched\")"}'
TOKEN=<tok> python3 scripts/mcp_probe.py call store_hotfix '{"fix_id":"always-on","code":"console.log(\"baseline\")","permanent":true}'
TOKEN=<tok> python3 scripts/mcp_probe.py call set_permanent '{"fix_id":"my-fix","permanent":true}'
TOKEN=<tok> python3 scripts/mcp_probe.py call list_hotfixes
TOKEN=<tok> python3 scripts/mcp_probe.py call clear_hotfix '{"fix_id":"my-fix"}'
TOKEN=<tok> python3 scripts/mcp_probe.py call clear_hotfixes
TOKEN=<tok> python3 scripts/mcp_probe.py call clear_hotfixes '{"include_permanent":true}'Hotfixes sind in der Regel "versioned" (Version gebunden). Nach einem Versionsänderung der Extension werden die Common ImportantPatches gebunden/ beinhalten das Fix, das die neue Revision mitbringt. Ein nur Schein hat das; sie ist ein. Als dauerhaft markierte Fix (via uptime-Param. permanent: true in store_hotfix oder set_permanent_check) werden über mehrere Versionen hinweg neu abgespielt. clear_hotfixesentfernt Standard nicht-permanente Fixes und erhält Welche permanenten;include_permanent: true` & leert komplett.
Erweiterungsbefehle
Der Background Service Worker akzeptiert Befehle (Empfehlungen über MCP-Tools oder JSON mit "type": "..." schreben in ein /commands/abhängig von $DAEDALUS_DIR/commands/):
Command | Purpose |
| Sichtbaren Tab als PNG erfassen |
| Rohe Aufrufe des Chrome DevTools Protocol ausführen |
| Vollständige Anfrage-/Antwort-Interception über CDP |
| Zugriff auf den Cookie-Speicher |
| Tab-Steuerung |
| CSS-Injektion pro Tab |
| Blockierung über declarativeNetRequest |
| Hotfix-Verwaltung (permanente Fixes überstehen Versionssprünge) |
| Die Erweiterung selbst von der Festplatte neu laden |
| Diagnose-Ringpuffer für Fetch-Relays |
GM Bridge
window.GM (in page.js, MAIN-Welt) bietet diese Tampermonkey-ähnliche Teilmenge:
Methode | Beschreibung |
| Liest einen nicht reservierten String-Schlüssel aus dem erweiterungsweiten |
| Schreibt einen nicht reservierten String-Schlüssel in den erweiterungsweiten Speicher |
| Löscht einen nicht reservierten String-Schlüssel aus dem erweiterungsweiten Speicher |
| Listet nicht reservierte Speicherschlüssel auf |
| Über den Hintergrund vermittelte HTTP-Anfrage (CSP-immun) |
| CSS injizieren |
| In die Zwischenablage schreiben |
| Desktop-Benachrichtigung |
| Neuen Tab öffnen |
| Download auslösen |
| Skript-Metadaten |
Cookie-Zugriff ist eine Fähigkeit des Betreibers, nicht der Seite. Er läuft über die token-authentifizierten cookies / set-cookie / remove-cookie / clear-cookies-Befehle oben und ist bewusst nicht im Seitenkontext verfügbar. page.js läuft auf jeder passenden Top-Level-Seite, die andernfalls Cookies lesen könnte, die ihr eigenes document.cookie nicht sehen kann.
Architektur
Browser (matching tab) Server (your bridge host)
┌────────────────────────────────────────────┐ ┌──────────────────────┐
│ MAIN world │ │ bridge (server.py) │
│ ├─ page-main: default injection channel │ │ /stream?token │
│ └─ page.js: GM + relay channel │ │ watches commands/ │
│ ▲ │ │ │
│ │ window.postMessage │ │ /result writes │
│ content.js (ISOLATED) │ │ results/ │
│ ▲ │ │ │
│ │ chrome.runtime │ │ │
│ background.js (service worker) │ │ │
│ ├─ CDP: CSP fallback channel │ │ │
│ ├─ single SSE stream ◄────────────────────┼───┤ │
│ └─ POST result, fetch ────────────────────┼──►│ │
└────────────────────────────────────────────┘ └──────────────────────┘Ein SSE-Stream: Der Hintergrund öffnet eine einzelne
fetch-SSE-Verbindung (tab=extension) und leitet Befehle überchrome.tabs.sendMessagean den Ziel-Tab weiter. Ein 30-Sekunden-Watchdog erzwingt bei veralteten Streams eine Wiederverbindung.Pro-Tab-Routing: Befehle adressieren eine konkrete Chrome-
tabIdoder werden an alle Tabs gesendet.CSP-Verhalten:
GM.xmlhttpRequestsendet die HTTP-Arbeit an denfetchdes Hintergrund-Service-Workers.Evalverwendet normalerweise bannerfreie Injektion in die MAIN-Welt. Wenn die quellfreie Sonde meldet, dass dynamische Kompilierung nicht verfügbar ist, liefert CDP den CSP-Fallback und zeigt Chromes Debugger-Banner, falls es sich verbindet. Ein Verbindungsfehler erreicht das Seiten-/Blob-Relay. Der resultierendeworld-Wert beschreibt diesen Kanal und stellt keinen Integritätsanspruch.
Server
Starten Sie die Bridge mit ihren drei Pflicht-Einstellungen. Ohne DAEDALUS_DIR oder DAEDALUS_PORT beendet sie sich beim Start, und jede Bridge-Controllroute verweigert ohne konfiguriertes Token den Zugriff:
DAEDALUS_DIR=<data-dir> DAEDALUS_PORT=<port> DAEDALUS_TOKEN=<bridge-token> python3 server.pyserver.py läuft unter jedem Supervisor, den Sie verwenden (hier eine systemd-Unit). Setzen Sie einen TLS-terminienden Reverse-Proxy davor, wenn Sie es über lokalehost hinaus verfügbar machen. Die Bridge selbst spricht einfaches HTTP. Bridge-Control- und Speicher-Routen vergleichen ihr Token mit einem konfigurierten Secret, das über den CLI-Konfigurationspfad aufgelöst wird: TOKEN ist die einmalige Überschreiber-Anzeige; andernfalls wird DAEDALUS_TOKEN benötigt (und ein eingebettetes _settings-Modul kann es bereitstellen). Fehlende Konfiguration und Abweichungen führen zu verweigertem Zugriff. Nur die seitenbezogenen Routen POST /segment und GET /segment-status verwenden stattdessen eine Job-geskopte Capability.
Das in-process MCP-Frontend nimmt drei optionale Einstellungen entgegen, die hier zusammen dokumentiert sind, weil sie einen Listener beschreiben: DAEDALUS_MCP_PORT (Standard 8086) ist der Loopback-Port, an den es sich bindet. Seine Tool-Handler verwenden die tatsächlichgebundene Loopback-URL der Bridge, auch wenn DAEDALUS_PORT=0 ist. DAEDALUS_LOCAL_URL überschreibt diese URL ausdrücklich für eine eigenständige MCP-Bereitstellung, die eine Bridge bedient, die woanders läuft. DAEDALUS_MCP_ALLOWED_HOSTS (Standard 127.0.0.1:*,localhost:*) ist die kommagetrennte Host-Allowlist, die die DNS-Rebinding-Schutz akzeptiert; wer also /mcp mit einem öffentlichen Hostnamen betreibt, der muss diesen Namen dort eintragen.
Endpunkte: GET /stream, GET /tabs, GET /health, GET /dashboard[/<asset>], POST /register, POST /sync-tabs, POST /unregister, POST /poll, POST /result, PUT /command, GET /result, POST/GET/DELETE /upload, GET /screenshot, POST /segment-job, POST /segment + GET /segment-status. POST /segment-job erfordert den konfigurierten Bridge-Token; nur POST /segment und GET /segment-status verwenden die Job-geskopte sig. Hinweise zu Payloads und Endpunkten finden Sie in CLAUDE.md.
POST /poll konsumiert und löscht die alte Befehlsdatei für Broadcast-Befehle, falls eine vorhanden ist.
PUT /command stellt Befehle in eine FIFO-Verzeichniswarteschlange pro Ziel ein (unmittelbar aufeinanderfolgende Befehle an einen Tab überschreiben sich nicht mehr), versieht jeden Befehl mit einer Zustell-ID (_did), damit die Erweiterung ein erneut zugestelltes Frame erkennen kann, und verwirft per TTL Befehle, die nach DAEDALUS_CMD_TTL Sekunden (Standard 90) nicht abgeholt wurden. Ein Hintergrund-Sammler wendet diese TTL an und entfernt leere Warteschlangenverzeichnisse, auch wenn sich nie ein SSE-Konsument verbindet. GET /health meldet die Lebendigkeit von Stream/Registry/letzter Zustellung, um eine stillgestorbene Bridge zu erkennen.
Die Bridge lehnt wiederholte Autoritätsträger ab, statt einen Wert auszuwählen: das gilt für token in Query-Strings oder JSON-Bodies sowie job / sig auf den Segment-Capability-Routen, auch wenn die wiederholten Werte. Identisch oder leer sind. Der MCP-Transport lehnt gleichermaßen wiederholte Authorization-, Mcp-Session-Id-, Host- und Origin-Header ab, zusätzlich zu wiederholten job-Argumenten für die Segment-Tools.
Wenn die Erweiterung ein Ergebnis postet, legt der Server die _did des Befehls als deliveryId offen und vergibt eine neue resultGeneration. CLI- und MCP-Warter schauen zunächst in den gemeinsamen Ergebnis-Slot, prüfen Befehls-ID und deliveryId und konsumieren diese Generation dann bedingt mit GET /result?...&consume=1&expected=<resultGeneration>. Falls between those Requests ein anderes Ergebnis den Slot ersetzt, lässt der bedingte Konsum das neue Ergebnis unangetastet und meldet, dass es nicht konsumiert wurde. Ein bloßes consume=1 ohne expected bleibt ein destruktiver Kompatibilitäts-Lesevorgang des aktuellen Slots.
GET /stream hält die SSE-Verbindung unbegrenzt offen und zeigt die Lebendigkeit mit einem Keepalive-Kommentar alle DAEDALUS_STREAM_KEEPALIVE Sekunden (Standard 15), statt die Verbindung zeigesteuert neu aufzubauen; DAEDALUS_STREAM_MAX_AGE (Standard 3600) ist nur eine äußerste Obergrenze. Der Schließpfad ist von tests/test_stream_lifecycle.py festgelegt.
DAEDALUS_MAX_BODY_SIZE (Standard 64 * 1024 * 1024 Bytes, 64 MiB) begrenzt die Request-Bodies, die von den POST-, PUT- und DELETE-Handlern gelesen werden; ein deklarierter Body größer als das Limit erhält 413. Erhöhen Sie den Wert beim Relay größerer Segmente oder anderer Payloads.
Dateisystemgestützte Aufrufer-Werte folgen einer einheitlichen Pfadkomponenten-Regel: Sie lehnt .., C0/C1-Steuerzeichen und Surrogate, unter Windows ungültige Pfadzeichen und Gerätenamen ab. nachgestellte Punkte oder Leerzeichen sowie UTF-8-Kodierungen länger als 240 Bytes. Bridge-Token sind strenger und lehnen zusätzlich Punkte und Unterstriche ab. Andere UTF-8-Auftragsnamen werden akzeptiert; Clients müssen sie in Query-Strings URL-encodieren.
POST /segment-job kopiert drei feste Quoten in jeden neuen Auftragsdatensatz: DAEDALUS_MAX_SEGMENT_INDEX (Standard 99999), DAEDALUS_MAX_SEGMENTS_PER_JOB (Standard 10000) und DAEDALUS_MAX_SEGMENT_JOB_SIZE (Standard 4 * 1024 * 1024 * 1024 Byte, 4 GiB). Das Ändern dieser Einstellungen betrifft später erstellte Aufträge; ein Auftrag mit gespeicherten Quoten verwendet weiterhin ihre aufgezeichneten Werte. DAEDALUS_MAX_BODY_SIZE begrenzt außerdem jede einzelne Segmentanfrage.
Sicherheit
Lesen Sie dies, bevor Sie die Erweiterung installieren.
Es injizert einen window.GM-Shim in jede passende Top-Level-Seite (<all_urls>, MAIN-Welt), wodurch ein Skript, das mit put gesendet wird, Cross-Origin-Anfragen stellen kann. Die Konsequenz ist der Teil, über den man sich bewusst werden muss: Jede passende Website, die Sie besuchen, kann diesen Shim aufrufen. Sie können also über die Berechtigungen derErweiterung Cross-Origin-Anfragen auslösen, genau wie ein Userscript-Manager mit einem Wildcard-@match. Wenn das für Ihr Surfverhalten nicht akzeptabel named, schränken Sie die matches in extension/manifest.json auf die Hosts ein, die Sie tatsächlich bedienen, und nehmen Sie in Kauf, dass die Bridge dann auf anderen Seiten nichts tut.
Bridge-Token und Server-URL sind über die GM-Speichermethoden der Seite nicht erreichbar. Sie liegen in chrome.storage.local unter dem Präfix daedalus-, und das Relay verweigert das Lesen, Schreiben oder Aufzählen dieses Namespace für Seitenskripte. Ohne diese Regel jeder besuchten Site Ihren-Bridge-Token mit GM.getValue('daedalus-token') auslesen oder die Bridge mit GM.setValue('daedalus-server', ...) stillschweigend umhängen. tests/test_repo_contract.py legt diese Regel fest.
Hotfix-Quellcode ist bewusst seitenzugestellter Zustand und kein vertraulicher Erweiterungszustand. content.js liest den Datensatz daedalus-hotfixes, wählt permanente Fixes sowie nicht permanente Fixes aus, das sind der Erweiterungsversion entsprechen, und sendet die ausgewöhnlichen vollständigen Objekte an jede berechtigte Seite. page.js in der MAIN-Zone wertet dann code jedes Objekts aus, sodass die Seite diesen seitenzugestellten Quellcode sehen kann.
Ein MCP-Inhaber kann keine Datei des Server-Hosts angeben, die der MCP-Prozess lesen könnte. Die MCP-Tools put, CSS-Injektion/-Entfernung und Hotfix-Speicherung akzeptieren nur Inline-Quellcode. Das lokale CLI behält seine Dateipfad-Komfortfunktion, aber der CLI-Prozess liest diese vom Betreiber ausgewählte Datei und überträgt ihren Inhalt als Inline-Quellcode. Das Halten des Bridge-Tokens gewährt daher die dokumentierte Browser- und Erweiterungs-Steuerungsbefugnis, einschließlich Lesen gespeicherter Hotfix-Quellen, fügt aber keinen beliebigen Lesezugriff auf das Host-Dateisystem über diese Tools hinzu.
Bridge-Control- und Speicherrouten erfordern das konfigurierte Bridge-Token; /segment und /segment-status sind die einzige Capability-Ausnahme. Der Server vergleicht die Request-Tokens mit dem aus TOKEN oder DAEDALUS_TOKEN aufgelösten Secret und lehnt Anfragen ab, wenn kein Secret konfiguriert ist. POST /segment-job erfordert das Bridge-Token, weil damit die auftragsbezogene Capability erzeugt wird; nicht vertrauenswürdiges Seiten-JavaScript verwendet die Capability ausschließlich, um diesen Auftrag zu posten und abzufragen. Jeder, der das Bridge-Token besitzt, kann Ihren Browser steuern. Setzen Sie den Bridge-Port nicht über Loopback ohne einen Reverse-Proxy, der TLS terminiert, und behandeln Sie das Token als Zugangsdaten.
Eval-Ergebnisse bringen keinerlei Garantie für die Wertintegrität. JavaScript, das in einer Seite ausgeführt wird, die Sie nicht kontrollieren, liefert einen Wert zurück, den die Seite wählen kann, unabhängig davon, über welchen Kanal es ausgeführt wurde. Das world-Feld gibt an, wie der übermittelte Quellcode lief – nicht, ob seinem Wert vertraut werden kann. page-main ist eine gewöhnliche MAIN-World-Injektion, cdp ist der Inspector-CSP-Fallback und page:<hostname> ist das Relay. Das zwingende page:-Präfix wird außerhalb des Seitenkontexts hinzugefügt, sodass kein Hostname cdp oder page-main erzeugen kann; diese Kollisionsfestigkeit ist nur deskriptiv. Bei page-main können die der Seite gehörenden eval- und Function-Bindings den übermittelten Quell lesen und auch den von ihnen zurückgegebenen Wert beeinflussen.
Die CDP-Kompilierung vermeidet das Auflösen der eval- und Function-Bindings der Seite, und die Implementierung holt direkte Handles per Referenz, bevor sie diese serialisiert. Diese Transportdetails ändern die Vertrauensgrenze nicht: Der übermittelte Quellcode liest weiterhin seitenkontrollierten Zustand und kann jeden Wert, auch einen primitiven, durch die Promise-Maschinen der Seite leiten, bevor CDP ihn empfängt. Immer wenn der Quellcode diese seitenkontrollierten Pfade verwendet, kann die Seite auch bei cdp den zurückgegebenen Wert wählen.
Das Relay akzeptiert nur den gespeicherten Aufruf, der zu dieser zufälligen ID gehört, verlangt die gespeicherte Tab-Zuordnung des Absenders und konsumiert den Eintrag genau einmal. Das Downgrade gibt weder das Bridge-Token, eine Server-URL noch die Delivery-ID oder einen Ergebnisweg preis, verleiht keine zusätzlichen Erweiterungs- oder Browserautorisierung und kann keinen Aufruf in einem anderen Tab beeinflussen. Diese Eigenschaften schützen Routing und Browser-Autorität; sie erzeugen kein Vertrauenssignal aus dem Relay-Marker oder seinem zurückgegebenen JavaScript-Wert.
Bereitstellung
Die Bridge spricht einfaches HTTP über Loopback. Bridge-Steuer- und Storage-Routen erfordern das konfigurierte Token und bleiben bei Fehlen niedrigverschlossen; nur /segment und /segment-status verwenden die auftragsbezogene Capability. Zwei Dinge tut sie bewusst NICHT, denn sie gehören zu dem, was davor liegt:
TLS und CORS.
server.pysendet keine CORS-Header. Wenn die Bridge cross-origin ist, müssen die pageseitigenfetch-Aufrufe des Beispiel-HLS-Relays Zugriff aufGET /segment-statusundPOST /segmenthaben; der von der Proxy muss die Seiten-Origin für beide Routen erlauben und die Methoden/Header für den POST-Flight (Preflight) unterstützen. Ist der Status-GET blockiert, nicht verfügbar, non-2xx oder ungültig, behandelt das Beispiel den Auftrag als frisch und übermittelt jedes Segment erneut per POST. Diese Schreibvorgänge ersetzen wieder die gleichen ses per-Index–dateien, aber die Ausführung verliert ihre Sparzungen beim Wiederaufsetzen/Überspringen. Führen Sie beide Requests stattdessen über die GM-Bridge der Erweiterung, wenn die Installation keine entsprechende CORS-Policy bieten kann.Angebot gespeicherter Uploads. Ein Wechsel des Dashboards verlinkt Downloads unter
/uploads/<pfad>, aber die Bridge has keine solche Route. Stellen Sie vom Aufrufer gelieferte Upload-Namen und -Bytes nicht direkt auf der Dashboard-Origin bereit, wo ausführbarer Inhalt same-origin zu dem tokenführenden Storage des Dashboards wäre. Lassen Sie diese Links entweder unverfügbar oder sorgen Sie dafür, dass/uploads/den Weiterleitung auf eine separate, nur-Download-Origin macht, dieContent-Disposition: attachmenterzwingt,application/octet-streamnutzt undX-Content-Type-Options: nosniffausliefert.GET /upload(Auflistung) undGET /screenshotwerden von der Bridge selbst bedient und brauchen keinen Proxy.
Wenn Sie direkt mit einem konfigurierten Token betreiben, sind beide Dinge einfach – alles andere funktioniert.
Dateien
Datei | Beschreibung |
| MV3-Manifest |
| Service Worker – SSE, Befehl-Verteilung, Fetch-Relay, Screenshots, CDP, Cookies, Downloads |
| Nachrichten-Relay zwischen Seite und Hintergrundservice |
| MAIN-World-Bridge – |
| UI für Token-/Server-Einstellungen |
| DebugServer (beherbergt zusätzlich den MCP-Daemon-Thread at 127.) |
| MCP-Server – stell Bridge zwischen der Befehls-Oberfläche der Erweiterung und |
| Minimale MCP-Client-Hilfe für manuelle Verifikation |
| Versionskonsistenz-Prüfung / Änderung über alle Versions-Orte |
| pre-commit- und pre-push-Versionskonsistenz-Gates |
| Shell-CLI, veröffentlicht als |
| Browser-Kontrolloberfläche, die |
| Skripte, die per |
| Suiten; |
Beispiele
examples/ enthält Skripte, die per put innerhalb einer Seite ausgeführt werden sollen. Fünf der sechs zeigen eine Teil des Bridges statt eine bestimmte Website; das Diskord-Kondor ist bewusst website-spezifisch, weil das Zurückscrollen durch eine virtualisierte Liste eine Technik ist, die Sie virtuell keine echte Liste demonstrieren can:
Beispiel | Shows |
| Ein permanenter MAIN-World-Hotfix bei |
| Das |
| Eine Player-Instanz finden und zerstören, die nicht aufhört, es erneut Betwi. |
| Eingabe eines React-gesteuerten Felds füllen, damit Reacts eigener Zustand tatsächlich ändert |
| Durch eine virtualisierte Nachrichtenliste zurückscrollen und sie extrahieren |
| Der kleinmögliche |
Ihre Konfiguration erhalten sie über __PLACEHOLDER__-Ersetzung, bevor sie gesendet werden, denn put liefert ein Skript aus, ruft keine Funktion auf und kann keine Argumente übergeben.
Jedes davon ist der BODY einer async function, kein eigenständiges Skript: die Bridge umschließt, was Sie senden. Das ist der Grund, warum die meisten mit einem asynchronen (top-level return) enden, und eines – scrape-discord-messages.js – zusätzlich ein async-Anfangs-await- top-level verwendet. Jedoch sind beide gültig, wo sie auch wirklich laufen. node --check parst jede Datei im CommonJS-Wrapper, der den Top-Level-return erlaubt, verwirft aber den Top-Level-await bzw. genau diese Datei fällt durchdie Syntax-Prüfung.
Entwicklung
Der Versionsstring begegnet an Orten in der Erweiterung, im Dashboard und im CLI-Paket. python3 scripts/check_versions.py ist die Liste – es nennt jeden Versionsort und meldet, wie viele haben gefunden; deswegen nennt dieser Absatz keine Zahl mehr, die beim nächsten Hinzufügen furzt werden. Ändern Sie sie zusammen, nie von Hand:
python3 scripts/check_versions.py --set 0.18.0 # rewrite every site
python3 scripts/check_versions.py # verify the working tree.githooks/pre-commit prüft den Index und .githooks/pre-push prüft jeden gepushten Commit, damit ein halb-commit nicht landen kann. Jedes Klon muss einmalig opt-in – andernfalls wird Git trotz getracktem Verzeichnis keine Hooks ausführen:
git config core.hooksPath .githooksWird die Erweiterung des Browsers geladen aus einem anderen Checkout als dem bearbeiteten, die Hook-Installation dort ebenfalls vornehmen – und zurüger innopt1n, dass das Laden der Erweiterung die Dateien neu liest bzw. im Browser, nicht im lokalen.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Access Kernel's cloud-based browsers and app actions via MCP (remote HTTP + OAuth).
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Nitjsefnie-Harness-Commons/daedalus'
If you have feedback or need assistance with the MCP directory API, please join our Discord server