Emacs' browser-gt: claude's eyes and hands on the Web

browser-gt was formely known as browsel.
Agents, like Claude, require eyes and hands to be able to help me accomplish work. While MCP servers can provide some of those capabilities, I find them too restrictive for this purpose. Instead, what about giving an agent the ability to read the DOM and execute JavaScript directly in the current browser's tab?
At the same time, I want these actions to be scriptable, so I can ask the agent to help me write commands that I can later execute myself whenever I need them.
Emacs can already be controlled programmatically through emacsclient. So why not
give myself—and the agent—the ability to control the browser as well?
This was the motivation to create browser-gt. It creates a two-way bridge between Emacs and the browser: Emacs can query and control the browser, and the browser can ask Emacs to perform actions.
For example:
Extract all the
h2headings from the current Chrome tab and insert them into the current Emacs buffer.
But the interaction can go in the other direction too. From the browser, I can
trigger Emacs commands to capture a selection in Org, save a page, save a ChatGPT
conversation, or retrieve a YouTube transcript. browser-gt currently supports
Chrome and Firefox.
It can also serve as a management tool. Its tab manager gives me an Emacs interface for seeing the many tabs I have open and quickly visiting, bookmarking, filtering, or closing them.
More generally, the goal is to make the browser scriptable from Emacs. Because the interface is programmable, the same operations can be used interactively by me, composed into Emacs Lisp commands, or invoked by an agent.
This is how to answer my question above, and the result of evaluating it while visiting
the tab where this post is being displayed. Note it is an evaluation of javascript using
browser-gt-js inside an emacs buffer using babel:
#+begin_src browser-gt-js :results raw
Array.from(document.querySelectorAll('h2'))
.map(h => h.textContent.trim())
.filter(t => t)
.join('\n')
#+end_src
#+RESULTS:
Emacs' browser-gt: claude's eyes and hands on the WebIts repository is https://github.com/dmgerman/browser-gt. Available via MELPA.
The summary is below:
