How to Integrate Hister with qutebrowser: Complete CDP Setup Guide
You can integrate Hister with qutebrowser by launching the browser with QTWEBENGINE_REMOTE_DEBUGGING=127.0.0.1:9222 and running hister companion qutebrowser, which connects via the Chrome DevTools Protocol to automatically index rendered page content.
Hister provides a native companion tool that captures qutebrowser tabs in real-time using the Chrome DevTools Protocol (CDP). This integration extracts the fully rendered DOM—including dynamic JavaScript content—and submits it to your Hister server for full-text search and vector-based retrieval. The setup requires only a single environment variable and CLI command, leveraging qutebrowser's built-in Qt WebEngine remote debugging capabilities as implemented in the asciimoo/hister repository.
Enable the DevTools Endpoint in qutebrowser
Before running the companion, you must expose qutebrowser's internal DevTools interface. Start qutebrowser with the QTWEBENGINE_REMOTE_DEBUGGING environment variable set to a local address and port.
QTWEBENGINE_REMOTE_DEBUGGING=127.0.0.1:9222 qutebrowser
This launches a Chrome-DevTools-compatible HTTP and WebSocket endpoint at http://127.0.0.1:9222. The Hister companion connects to this interface to discover open pages, inject monitoring scripts, and extract content without requiring a browser extension.
Run the Hister qutebrowser Companion
With qutebrowser running and the DevTools port exposed, execute the companion command to begin indexing:
hister companion qutebrowser
This command, registered in cmd/companion.go, initializes a CDP client that performs the following actions:
- Connects to the DevTools endpoint at
http://127.0.0.1:9222by default. - Discovers all open pages and attaches to them.
- Injects a lightweight mutation observer script that detects DOM changes.
- Extracts the page title, visible text, raw HTML, and favicon URL.
- Submits the document to Hister via the
DocumentSubmitterinterface defined in the Go client library.
Configuration Options and CLI Flags
The companion accepts several flags to customize connection parameters and indexing behavior. These options are defined and validated in cmd/companion/qutebrowser/options.go.
hister companion qutebrowser \
--devtools-url http://127.0.0.1:9222 \
--label "my-qute-tabs" \
--initial-delay 2s \
--debounce 10s \
--retry-delay 30s
--devtools-url– Specifies the HTTP endpoint of the qutebrowser DevTools server.--label– Attaches a custom string label to each submitted document for filtering in Hister queries.--initial-delay– Sets the wait time before the first extraction after a page loads, allowing dynamic content to settle.--debounce– Configures the quiet period after a DOM mutation before triggering a re-extraction, preventing excessive updates during rapid changes.--retry-delay– Defines the backoff duration for resubmission attempts if the Hister server is temporarily unreachable.
Technical Implementation and Source Code
The integration relies on three core components within the Hister codebase.
cmd/companion/qutebrowser/companion.go implements the main event loop. It maintains a persistent WebSocket connection to the DevTools protocol, handles page lifecycle events (load, navigate, close), and orchestrates the extraction pipeline. When the mutation observer detects changes, this file's logic triggers the extraction routine and serializes the data for transmission.
cmd/companion/qutebrowser/options.go contains the Options struct and validation logic for all configurable parameters, including network timeouts and retry policies.
cmd/companion.go wires the companion into the Cobra command tree, exposing the hister companion qutebrowser subcommand and binding the CLI flags to the options struct.
According to the source code in cmd/companion/qutebrowser/companion.go, the companion uses a CDP Runtime domain to evaluate JavaScript injection scripts and the DOM domain to retrieve the full document tree. Extracted data is normalized and sent to the Hister server configured via --hister-url (defaulting to http://localhost:4433/).
Programmatic Integration in Go
You can embed the qutebrowser companion directly into your own Go applications by importing the companion package and providing a custom DocumentSubmitter client.
import (
"context"
qutebrowser "github.com/asciimoo/hister/cmd/companion/qutebrowser"
"github.com/asciimoo/hister/client"
)
func main() {
ctx := context.Background()
opts := qutebrowser.DefaultOptions()
// Customize connection parameters
opts.DevToolsURL = "http://127.0.0.1:9222"
opts.HisterURL = "http://localhost:4433/"
// Initialize the Hister API client
c := client.NewClient(opts.HisterURL, "my-token", nil)
// Start the monitoring loop
if err := qutebrowser.Run(ctx, opts, c); err != nil {
panic(err)
}
}
This approach reuses the same extraction pipeline as the CLI tool while allowing you to implement custom authentication, logging, or document preprocessing logic before submission.
Summary
- Launch qutebrowser with
QTWEBENGINE_REMOTE_DEBUGGING=127.0.0.1:9222to expose the DevTools endpoint required for CDP communication. - Execute
hister companion qutebrowserto start the indexing service, which monitors tabs via WebSocket and extracts title, text, HTML, and favicon data. - Customize behavior using flags like
--debounce,--initial-delay, and--labelto control when and how documents are submitted. - The companion is implemented in
cmd/companion/qutebrowser/companion.goand submits data through theDocumentSubmitterinterface to your Hister server.
Frequently Asked Questions
What specific data does the Hister companion extract from qutebrowser tabs?
The companion extracts the page title, visible text content, raw HTML, and favicon URL from each tab. According to the implementation in cmd/companion/qutebrowser/companion.go, this data is captured via CDP Runtime and DOM domain calls whenever the mutation observer detects a page load or significant DOM change.
Can I run the Hister companion on a different machine than qutebrowser?
Yes, but you must bind qutebrowser's DevTools interface to a network-accessible address rather than localhost. Use QTWEBENGINE_REMOTE_DEBUGGING=0.0.0.0:9222 when starting qutebrowser, then specify the remote URL via the --devtools-url flag when running the companion. Note that the DevTools protocol transmits unencrypted data, so use this only on trusted networks or through SSH tunnels.
How do I prevent the companion from indexing specific qutebrowser tabs?
While the companion does not support URL filtering at the browser level, you can apply sensitivity rules and skip patterns on the Hister server side. Additionally, you can use the --label flag to tag all qutebrowser submissions with a specific identifier, then configure your Hister instance to exclude or quarantine documents with that label based on your content policies.
Does this integration require installing a browser extension in qutebrowser?
No browser extension is required. The integration operates entirely through the Chrome DevTools Protocol via the remote debugging port. The companion injects JavaScript monitoring code directly through the CDP Runtime.evaluate method, eliminating the need for user-side extension installation or browser UI modifications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →