Frog plugins: add features of your own, built with your AI agent

A plugin adds a feature of your own to Frog: a page in the sidebar, commands in the command bar, or both. Ask an AI agent with the Frog skill to build one, or write it yourself. Plugins run in a sandbox and do only what you approve. They arrived in Frog 1.0.40.

What a plugin is

A plugin is a folder with a plugin.json manifest and web files: HTML, CSS, JavaScript and images. Frog shows the plugin’s page in a sandboxed web view inside its window. The page talks to Frog through a frog object in JavaScript, and every call is checked against the permissions you approved.

Plugins run only on your Mac, and sharing one is up to you. The manifest names the plugin and says what it needs:

  • id: lowercase letters, digits, dots and hyphens, 3 to 64 characters, such as com.example.word-counter. It never changes between versions.
  • name, up to 40 characters, is shown in the sidebar. description is one sentence of up to 200 characters.
  • version is major.minor.patch, such as 1.2.0. frog is the oldest Frog version the plugin works with.
  • symbol is an SF Symbol name for the sidebar, puzzlepiece.extension unless you choose another. entry is the page Frog opens: index.html unless you name another, or null for a plugin with commands only.
  • permissions, hosts and scripts say what the plugin may do, as described under Permissions.
  • commands are command bar rows. Choosing one sends its id to the page; "show": false runs it without opening the page.
  • A plugin has at most 400 files and 20 MB in all, and no symbolic links. Hidden files and folders, such as .git and .DS_Store, are left out when it is installed or packed.
{
  "id": "com.example.word-counter",
  "name": "Word counter",
  "version": "1.0.0",
  "description": "Counts the words on the clipboard.",
  "author": "Jane Appleseed",
  "homepage": "https://github.com/jane/frog-word-counter",
  "symbol": "textformat.123",
  "entry": "index.html",
  "frog": "1.0.40",
  "permissions": ["clipboard-read", "notifications"],
  "hosts": [],
  "scripts": {},
  "commands": [
    { "id": "count", "title": "Count words on the clipboard", "keywords": "words length" }
  ]
}

Build one with your AI agent

With agent access on and the Frog skill installed, your AI agent can build a plugin for you, check it and install it for your review. It uses the frog plugins commands below, which you can run yourself too.

  1. Turn on agent access in Settings → Agents and install the skill for your agent, such as Claude Code or Codex.
  2. Ask for the feature you want, such as “build me a Frog plugin that shows my open GitHub pull requests”.
  3. The agent starts the plugin from a template, checks it and installs it. Your first install of a plugin waits for you in Frog → Plugins, where you read what it asks for and approve it.
  4. Ask for changes. After you approve a plugin, the agent’s updates apply directly while they ask for nothing new.
frog plugins guide                        the reference for plugin authors
frog plugins new <folder> --name "Name"   start a plugin from a template
frog plugins check <folder>               check the manifest and files
frog plugins install <folder>             install or update it for your review
frog plugins logs <id>                    the page's console and errors
frog plugins snapshot <id>                a picture of the page, to check its layout
frog plugins pack <id> [--output file]    a .frogplugin file to share, with its SHA-256
frog plugins list                         installed plugins and their state
frog plugins remove <id>                  move a plugin to the Trash

Install and approve a plugin

A newly installed plugin waits in Frog → Plugins until you approve it. The review shows the permissions it asks for, the hosts it may reach and the scripts it may run. Only you can approve or turn on a plugin: the frog command can install one for review, but not approve it.

Frog records what you approved. An update that asks for a new permission, adds a host or changes a script waits for you to review it again; any other update applies directly. A plugin with scripts waits for review after any change, since its scripts can run any of its files. A plugin with the same id from somewhere else, such as a file or another author’s link, is reviewed as a new install. There are three ways to install one:

  • From the plugin directory on this website: Install in Frog opens Frog’s review.
  • From a link someone shared: Frog → Plugins → Install from link, or a frog://plugins/install link, which opens the same review.
  • From a folder: frog plugins install and the plugin’s folder, which is how your agent installs what it builds. frog plugins remove moves a plugin to the Trash.

Permissions

A plugin without permissions can show its page, keep its own storage and receive its commands. Everything else needs a permission that you approve when you install it:

  • clipboard-read: read the text on the clipboard. Text that password managers mark as concealed is never given.
  • clipboard-write: put text on the clipboard.
  • notifications: show a notification.
  • links: open web links in your browser.
  • network: send requests with frog.fetch to the hosts in hosts, and only those.
  • ai: send text to the AI model your Writing rules use by default. A cloud model’s provider bills you for it.
  • scripts: run the shell scripts listed in scripts, with your user’s full access to this Mac and the permissions you gave Frog, such as Accessibility. Install a plugin with scripts only when you trust its author and have read the scripts.

What the sandbox enforces

  • The page loads only from its own folder, at frog-plugin://<id>/. Every other address is blocked, including links, frames, forms, fetch, WebSockets and WebRTC. Network requests go through frog.fetch, which Frog checks against the plugin’s hosts.
  • WebRTC, WebTransport, DNS prefetching, the browser’s clipboard API, web notifications, geolocation and sharing are off in every frame. Plugins use frog.fetch, frog.clipboard and frog.notify instead.
  • The page has no cookies or shared website data, and cannot leave its folder or navigate elsewhere.
  • alert, confirm and prompt show as a sheet on the plugin’s page, naming the plugin, and only while the page is shown. You can turn a plugin’s dialogs off.
  • A page in the background cannot bring itself forward or write the clipboard. It can do that only right after one of its commands.
  • Plugins cannot read Frog’s settings, notes, history, keys or other plugins’ storage.
  • Scripts run with /bin/zsh from the plugin’s data folder. They stop after 60 seconds, and their output is cut at 1 MB. A script runs only while every file of the plugin is the one you approved.

The frog JavaScript API

The page calls Frog through window.frog. Every function returns a promise, and a call without the permission it needs fails with an error that names the permission.

Scripts receive args as $1, $2 and so on, and find input in the FROG_INPUT environment variable. console.log, errors and rejected promises go to the plugin’s log, which frog plugins logs prints.

await frog.storage.get("key")            // the stored value, or null
await frog.storage.set("key", value)     // any JSON value; 5 MB per plugin in all
await frog.storage.remove("key")
await frog.storage.keys()

await frog.clipboard.readText()          // clipboard-read
await frog.clipboard.writeText("text")   // clipboard-write

await frog.notify("Title", "Body")       // notifications
await frog.openURL("https://…")          // links

const response = await frog.fetch("https://api.github.com/…", {
  method: "GET", headers: {}, body: "", as: "text"   // as: "text", "json" or "base64"
})                                       // network: { status, headers, body }

await frog.ai("Summarize in one sentence:", text)    // ai: the model's answer as text

const result = await frog.run("stats", { args: ["--short"], input: "text" })
                                         // scripts: { output, status, truncated }

frog.on("command", (id) => { … })        // a command bar row was chosen
frog.on("show", () => { … })             // the page came into view
frog.show()                              // bring the plugin's page forward
frog.close()                             // after a command with "show": false
frog.info                                // { id, name, version, permissions, frog }

Make it look like Frog

Frog sets CSS variables on the page for the light or dark appearance and the theme you chose: --frog-ink, --frog-muted, --frog-canvas, --frog-surface, --frog-border, --frog-accent, --frog-critical and --frog-font. A plugin that uses them matches Frog in every theme.

Link /_frog/frog.css for Frog’s buttons, inputs, cards and type. frog plugins snapshot takes a picture of the page, so an agent can check its layout.

<link rel="stylesheet" href="/_frog/frog.css">

Share a plugin

frog plugins pack makes a .frogplugin file, a zip of the plugin’s folder, and prints its SHA-256. Publish the file where people can download it over https, such as a GitHub release.

Anyone can then install it from Frog → Plugins → Install from link, or with a link of this form, which opens Frog’s review. The URL is percent-encoded, and the SHA-256 names the exact file the link is for.

frog://plugins/install?url=<https URL of the .frogplugin>&sha256=<hex>

The plugin directory

The plugin directory on this website lists plugins people shared, each with its permissions and an Install in Frog button. To have yours listed, open an issue on Frog’s GitHub with the link to its source and its .frogplugin file.

Listed plugins are read before they are added, and their files are pinned by SHA-256, but they remain their authors’ work: review the permissions before you install one.

Source documentation