Skip to content

Integrations

Ng Guoyou edited this page Jul 10, 2026 · 11 revisions

How other extensions, scripts, and AI agents drive Save in. It listens on browser.runtime.onMessageExternal (any extension) and onMessage (same extension), and — experimentally — registers WebMCP tools.

Extension ID: {72d92df5-2aa0-4b06-b807-aa21767545cd} (Firefox gecko.id; the Web Store ID on Chrome).

Not officially supported beyond what's documented here. Use at your own risk.


Download API (v1)

Push a URL into the routing/rename pipeline. PING first to negotiate the version.

const ID = "{72d92df5-2aa0-4b06-b807-aa21767545cd}";

// Discover the version and capabilities
await browser.runtime.sendMessage(ID, { type: "PING" });
// -> { type: "PONG", body: { version: 1, capabilities: [...] } }

// Save a URL
await browser.runtime.sendMessage(ID, {
  type: "DOWNLOAD",
  body: {
    url: "https://example.com/pic.jpg",  // required
    comment: "foo",                       // optional; matched by `comment:` rules
    info: {                               // all optional
      pageUrl: "https://example.com/",
      srcUrl: "https://example.com/pic.jpg",
      selectionText: "…"
    }
  }
});
// -> { status: "OK", version, url }
//  | { status: "ERROR", error, message, version }
  • error is BAD_REQUEST, INVALID_URL, or UNKNOWN_TYPE.
  • Only http(s), ftp, data, and blob URLs are accepted.
  • The download runs through the same routing rules, :variables:, Referer feature, auto-retry, history, and notifications as a context-menu save. status: "OK" means accepted, not finished.

Foxy Gestures

  1. Foxy Gestures → options → User Scripts → new gesture.

  2. Use this script (the ID is Save in's Mozilla Addons ID):

    const source = data.element.mediaInfo && data.element.mediaInfo.source;
    
    if (source) {
      browser.runtime.sendMessage("{72d92df5-2aa0-4b06-b807-aa21767545cd}", {
        type: "DOWNLOAD",
        body: { url: source, info: { pageUrl: `${window.location}`, srcUrl: source }, comment: "foo" }
      });
    }
  3. Assign a gesture to the script.

comment is targetable in routing rules:

comment: foo
into: ./from-foxy/:filename:

Config API

Read the schema, validate paths/rules, and apply config — the basis for scripted and AI-assisted setup.

  • GET_SCHEMA{ version, options: [{ name, type, default, description }] }. Read-only.
  • VALIDATE { paths?, filenamePatterns? }{ pathErrors, ruleErrors, menuPreview }. Dry-run, read-only.
  • GET_KEYWORDS{ variables, matchers } — the :variables: (paths/filenames) and clause matchers (fileext, into, capture, … for Dynamic Downloads rules).
  • APPLY_CONFIG { config: { name: value } }{ applied, rejected }. Validated against the schema (unknown keys and type mismatches rejected). Same-extension only — not reachable via onMessageExternal.

AI agents (WebMCP, experimental)

In a WebMCP-capable Chrome, the options page registers five tools an in-browser agent can call: save_in_get_schema, save_in_list_vocabulary, save_in_validate_config, save_in_apply_config, save_in_download. They change any setting, build directory menus, and write routing rules.

Ask in plain language — e.g. "sort my downloads into folders by website and date, number each file, and notify me only on failures." The agent reads the schema and vocabulary, then validates and applies. You never type :variable: codes.

Connect: open the options page in a WebMCP-enabled Chrome (origin trial or chrome://flags), keep the tab open, point your agent at it. See More Options → AI agent tools. The API is subject to change.


Trust model

  • onMessageExternal accepts from any installed extension and triggers downloads. The URL scheme is validated but senders aren't allowlisted — treat "can install an extension" as the trust boundary.
  • APPLY_CONFIG is deliberately internal-only.
  • No externally_connectable block, so web pages can't message Save in directly — only extensions can.

Clone this wiki locally