SkillAgentSearch skills...

Gmailctl

Declarative configuration for Gmail filters

Install / Use

/learn @mbrt/Gmailctl
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

gmailctl

Go Report Card Go

This utility helps you generate and maintain Gmail filters in a declarative way. It has a Jsonnet configuration file that aims to be simpler to write and maintain than using the Gmail web interface, to categorize, label, archive and manage your inbox automatically.

Table of contents

Motivation

If you use Gmail and have to maintain (like me) a lot of filters (to apply labels, get rid of spam or categorize your emails), then you probably have (like me) a very long list of messy filters. At a certain point one of your messages got mislabled and you try to understand why. You scroll through that horrible mess of filters, you wish you could find-and-replace stuff, test the changes on your filters before applying them, refactor some filters together... in a way treat them like you treat your code!

Gmail allows one to import and export filters in XML format. This can be used to maintain them in some better way... but dear Lord, no! Not by hand! That's what most other tools do: providing some kind of DSL that generate XML filters that can be imported in your settings... by hand [this is the approach of the popular antifuchs/gmail-britta for example].

Gmail happens to have also a neat API that we can use to automate the import step as well, so to eliminate all manual, slow tasks to be done with the Gmail settings.

This project then exists to provide to your Gmail filters:

  1. Maintainability;
  2. An easy to understand, declarative, composable language;
  3. A builtin query simplifier, to keep the size of your filters down (Gmail has a limit of 1500 chars per filter);
  4. Ability to review your changes before applying them;
  5. Automatic update of the settings (no manual import) in seconds.

Install

gmailctl is written in Go and requires a recent version (see go.mod). Make sure to setup your $GOPATH correctly and include its bin subdirectory in your $PATH.

go install github.com/mbrt/gmailctl/cmd/gmailctl@latest

Alternatively, if you're on macOS, you can install easily via Homebrew or Macports:

# Install with Homebrew
brew install gmailctl
# Install with Macports
sudo port install gmailctl

On Fedora Linux, you can install from the official repositories:

sudo dnf install gmailctl

You can also choose to install the snap:

sudo snap install gmailctl

If so, make sure to configure xdg-mime to open the config file with your favorite editor. For example, if you'd like to use vim:

xdg-mime default vim.desktop text/x-csrc

If you are on windows, you can configure an editor (like VS Code) like this:

//cmd
set "EDITOR=code --wait"
//powershell
setx EDITOR "code --wait"

Once installed, run the init process:

gmailctl init

This will guide you through setting up the Gmail APIs and update your settings without leaving your command line.

Usage

asciicast

The easiest way to use gmailctl is to run gmailctl edit. This will open the local .gmailctl/config.jsonnet file in your editor. After you exit the editor the configuration is applied to Gmail. See Configuration for the configuration file format. This is the preferred way if you want to start your filters from scratch.

NOTE: It's recommended to backup your current configuration before you apply the generated one for the first time. Your current filters will be wiped and replaced with the ones specified in the config file. The diff you'll get during the first run will probably be pretty big, but from that point on, all changes should generate a small and simple to review diff.

Migrate from another solution

If you want to preserve your current filters and migrate to a more sane configuration gradually, you can try to use the download command. This will look up at your currently configured filters in Gmail and try to create a configuration file matching the current state.

NOTE: This functionality is experimental. It's recommended to download the filters and check that they correspond to the remote ones before making any changes, to avoid surprises. Also note that the configuration file will be quite ugly, as expressions won't be reconstructed properly, but it should serve as a starting point if you are migrating from other systems.

Example of usage:

# download the filters to the default configuration file
gmailctl download > ~/.gmailctl/config.jsonnet
# check that the diff is empty and no errors are present
gmailctl diff
# happy editing!
gmailctl edit

Often you'll see imported filters with the isEscaped: true marker. This tells gmailctl to not escape or quote the expression, as it might contain operators that have to be interpreted as-is by Gmail. This happens when the download command was unable to map the filter to native gmailctl expressions. It's recommended to manually port the filter to regular gmailctl operators before doing any changes, to avoid unexpected results. Example of such conversion:

{
  from: "{foo bar baz}",
  isEscaped: true,
}

Can be translated into:

{
  or: [
    {from: "foo"},
    {from: "bar"},
    {from: "baz"},
  ],
}

Other commands

All the available commands (you can also check with gmailctl help):

  apply       Apply a configuration file to Gmail settings
  debug       Shows an annotated version of the configuration
  diff        Shows a diff between the local configuration and Gmail settings
  download    Download filters from Gmail to a local config file
  edit        Edit the configuration and apply it to Gmail
  export      Export filters into the Gmail XML format
  help        Help about any command
  init        Initialize the Gmail configuration
  test        Execute config tests

Configuration

NOTE: Despite the name, the configuration format is stable at v1alpha3. If you are looking for the deprecated versions v1alpha1, or v1alpha2, please refer to docs/v1alpha1.md and docs/v1alpha2.md.

The configuration file is written in Jsonnet, that is a very powerful configuration language, derived from JSON. It adds functionality such as comments, variables, references, arithmetic and logic operations, functions, conditionals, importing other files, parameterizations and so on. For more details on the language, please refer to the official tutorial.

Simple example:

// Local variables help reuse config fragments
local me = {
  or: [
    { to: 'pippo@gmail.com' },
    { to: 'pippo@hotmail.com' },
  ],
};

// The exported configuration starts here
{
  version: 'v1alpha3',
  // Optional author information (used in exports).
  author: {
    name: 'Pippo Pluto',
    email: 'pippo@gmail.com'
  },
  rules: [
    {
      filter: {
        and: [
          { list: 'geeks@newsletter.com' },
          { not: me },  // Reference to the local variable 'me'
        ],
      },
      actions: {
        archive: true,
        labels: ['news'],
      },
    },
  ],
}

The Jsonnet configuration file contains mandatory version information, optional author metadata and a list of rules. Rules specify a filter expression and a set of actions that will be applied if the filter matches.

Filter operators are prefix of the operands they apply to. In the example above, the filter applies to emails that come from the mail list 'geeks@newsletter.com' AND the recipient is not 'me' (which can be 'pippo@gmail.com' OR 'pippo@hotmail.com').

We will see all the features of the configuration file in the following sections.

Search operators

Search operators are the same as the ones you find in the Gmail filter interface:

  • from: the mail comes from the given address
  • to: the mail is delivered to the given address
  • subject: the subject contains the given words
  • has: the mail contains the given words

In addition to those visible in the Gmail interface, you can specify natively the following common operators:

  • list: the mail is directed to the given mail list
  • cc: the mail has the given address as CC destination
  • bcc: the mail has the given address as BCC destination
  • replyto: the mail has the given address as Reply-To destination

One more special function is given if you need to use less common operators<sup id="a1">1</sup>, or want to compose your query manually:

  • query: passes the given contents verbatim to the Gmail filt
View on GitHub
GitHub Stars2.1k
CategoryDevelopment
Updated16h ago
Forks80

Languages

Go

Security Score

100/100

Audited on Apr 3, 2026

No findings