query
Search mu-indexed emails using a flexible query language with field-specific terms, logical operators, date ranges, and flags.
Instructions
Query mu by providing a valid query to be sent in the following way.
Syntax:
mu find $queryHere is the syntax guide for mu queries.
MU FIND(1) General Commands Manual MU FIND(1)
NAME mu-find - find e-mail messages in the mu database.
SYNOPSIS mu [COMMON-OPTIONS] find [OPTIONS] SEARCH_EXPRESSION
DESCRIPTION mu find is the mu command for searching e-mail message that were stored earlier using mu index(1).
SEARCHING MAIL mu find starts a search for messages in the database that match some search pattern. The search patterns are described in detail in mu- query(7).
For example:
$ mu find subject:snow and date:2009..
would find all messages in 2009 with `snow' in the subject field, e.g:
2009-03-05 17:57:33 EET Lucia <lucia@example.com> running in the snow
2009-03-05 18:38:24 EET Marius <marius@foobar.com> Re: running in the snowFIND OPTIONS The find-command has various options that influence the way mu displays the results. If you don't specify anything, the defaults are --fields="d f s", --sortfield=date and --reverse.
-f, --fields fields Specifies a string that determines which fields are shown in the output. This string consists of a number of characters (such as 's' for subject or 'f' for from), which will replace with the actual field in the output. Fields that are not known will be output as-is, allowing for some simple formatting.
For example:
$ mu find subject:snow --fields "d f s"
lists the date, subject and sender of all messages with `snow' in the
their subject.
The table of replacement characters is superset of the list mentions
for search parameters, such as:
t *t*o: recipient
d Sent *d*ate of the message
f Message sender (*f*rom:)
g Message flags (fla*g*s)
l Full path to the message (*l*ocation)
s Message *s*ubject
i Message-*i*d
m *m*aildir
For the complete list, try the command: mu info fields.-s, --sortfield field and -z,--reverse Specify the field to sort the search results by and the direction (i.e., `reverse' means that the sort should be reverted - Z-A). Examples include:
cc,c Cc (carbon-copy) recipient(s)
date,d Message sent date
from,f Message sender
maildir,m Maildir
msgid,i Message id
prio,p Nessage priority
subject,s Message subject
to,t To:-recipient(s)
For the complete list, try the command: mu info fields.
Thus, for example, to sort messages by date, you could specify:
$ mu find fahrrad --fields "d f s" --sortfield=date --reverse-n, --maxnum number If number > 0, display maximally that number of entries. If not specified, all matching entries are displayed.
--summary-len number If number > 0, use that number of lines of the message to provide a summary.
--format plain|links|xml|sexp Output results in the specified format.
— The default is plain, i.e normal output with one line per message.
— links outputs the results as a maildir with symbolic links to the
found messages. This enables easy integration with mail-clients
(see below for more information). This requires --linksdir.
— xml formats the search results as XML.
— sexp formats the search results as an s-expression as used in Lisp
programming environments.--linksdir dir and -c, --clearlinks When using --format=links, output the results as a maildir with symbolic links to the found messages. This enables easy integration with mail-clients (see below for more information). mu will create the maildir if it does not exist yet.
--after timestamp Only show messages whose message files were last modified (mtime) after timestamp. timestamp is a UNIX time_t value, the number of seconds since 1970-01-01 (in UTC).
From the command line, you can use the date command to get this value.
For example, only consider messages modified (or created) in the last 5
minutes, you could specify
--after=`date +%s --date='5 min ago'`-b, --bookmark bookmark Use a bookmarked search query. Using this option, a query from your bookmark file will be prepended to other search queries. See mu- bookmarks(5) for the details of the bookmarks file.
-u, --skip-dups Whenever there are multiple messages with the same message-id field, only show the first one. This is useful if you have copies of the same message, which is a common occurrence when using e.g. Gmail together with offlineimap.
-r, --include-related Include messages being referred to by the matched messages -- i.e.. include messages that are part of the same message thread as some matched messages. This is useful if you want Gmail-style `conversations'.
-t, --threads Show messages in a `threaded' format -- that is, with indentation and arrows showing the conversation threads in the list of matching messages. When using this, sorting is chronological (by date), based on the newest message in a thread.
Messages in the threaded list are indented based on the depth in the
discussion, and are prefix with a kind of arrow with thread-related
information about the message, as in the following table:
| | normal | orphan | duplicate |
|-------------+--------+--------+-----------|
| first child | `-> | `*> | `=> |
| other | |-> | |*> | |=> |MU QUERY(7) Miscellaneous Information Manual MU QUERY(7)NAME mu-query - a language for finding messages in mu databases.
DESCRIPTION The mu query language is the language used by mu find and mu4e to find messages in mu's Xapian database. The language is quite similar to Xapian's default query-parser, but is an independent implementation that is customized for the mu/mu4e use-case.
Here, we give a structured but informal overview of the query language
and provide examples. As a companion to this, we recommend the mu info
fields command to get an up-to-date list of the available fields and
flags.
NOTE: if you use queries on the command-line (say, for mu find), you
need to quote any characters that would otherwise be interpreted by the
shell, such as *--analyze option can be useful.TERMS The basic building blocks of a query are terms; these are just normal words like "banana" or "hello", or words prefixed with a field-name which makes them apply to just that field. See mu info fields for all the available fields.
Some example queries:
vacation
subject:capybara
maildir:/inbox
The language is case-insensitive for terms and attempts to "flatten"
diacritics, so angtrom matches Ångström.
If terms contain whitespace, they need to be quoted.
subject:"hi there"Quoting queries for the shell Remember that you need to escape the quotes for a search query when using this from the command-line; otherwise, the shell (or most shells) process the queries and mu never sees them.
LOGICAL OPERATORS We can combine terms with logical operators -- binary ones: and, or, xor and the unary not, with the conventional rules for precedence and association. The operators are case-insensitive.
You can also group things with ( and ), so you can write:
(subject:beethoven or subject:bach) and not body:elvis
Note that a pure not - e.g. searching for not apples is quite a "heavy"
query.WILDCARDS Wildcards are a Xapian built-in mechanism for matching.
A search term with a rightmost * (and only in that position) matches
any term that starts with the part before the *; they are less powerful
than regular expressions, but also much faster:
An example:
$ mu find "hello*"REGULAR EXPRESSIONS The query language supports matching basic PCRE regular expressions, as per pcre(3), with some limitations.
Regular expressions are enclosed in //. For example:
subject:/h.llo/ # match hallo, hello, ...
Note the difference between "maildir:/foo" and "maildir:/foo/"; the
former matches messages in the "/foo" maildir, while the latter matches
all messages in all maildirs that match "foo", such as "/foo",
"/bar/cuux/foo", "/fooishbar", and so on.Whitespace in regular expression literals To avoid ambiguities in the query parsing, regular express must not contain whitespace, so the search for a message with subject "hello world", you can write mu find 'subject:/hello\040world/'
In many cases, mu find 'subject:/hello.world/'
may be good enough, and easier to type.FIELDS We already saw a number of search fields, such as subject: and body:. For the full table with all details, including single-char shortcuts, try the command: mu info fields.
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| field-name | alias | short | search | value | sexp | example query | description |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| bcc | | h | phrase | yes | yes | bcc:foo@example.com | Blind carbon-copy recipient |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| body | | b | phrase | no | no | body:capybara | Message plain-text body |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| cc | | c | phrase | yes | yes | cc:quinn@example.com | Carbon-copy recipient |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| changed | | k | range | yes | yes | changed:30M.. | Last change time |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| date | | d | range | yes | yes | date:20220101..20220505 | Message date |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| embed | | e | phrase | no | no | embed:war OR embed:peace | Embedded text |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| file | | j | boolean | no | no | file:/image\.*.jpg/ | Attachment file name |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| flags | flag | g | boolean | yes | yes | flag:unread AND flag:personal | Message properties |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| from | | f | phrase | yes | yes | from:jimbo | Message sender |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| language | lang | a | boolean | yes | yes | lang:nl | ISO 639-1 language code for body |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| maildir | | m | boolean | yes | yes | maildir:/private/archive | Maildir path for message |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| list | | v | boolean | yes | yes | list:mu-discuss.example.com | Mailing list (List-Id:) |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| message-id | msgid | i | boolean | yes | yes | msgid:abc@123 | Message-Id |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| mime | mime-type | y | boolean | no | no | mime:image/jpeg | Attachment MIME-type |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| path | | l | boolean | yes | yes | path:/a/b/Maildir/cur/msg:2,S | File system path to message |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| priority | prio | p | boolean | yes | yes | prio:high | Priority |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| references | ref | r | boolean | yes | yes | | References to related messages |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| size | | z | range | yes | yes | size:1M..5M | Message size in bytes |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| subject | | s | phrase | yes | yes | subject:wombat | Message subject |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| tags | tag | x | boolean | yes | yes | tag:projectx | Message tags |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| thread | | w | boolean | yes | no | | Thread a message belongs to |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
| to | | t | phrase | yes | yes | to:flimflam@example.com | Message recipient |
+------------+-----------+-------+---------+-------+------+-------------------------------+----------------------------------+
There are also combination fields which allow you to search for
multiple related fields at once:
# Combination fields
+-------------+-----------------------------------------+
| combi-field | fields |
+-------------+-----------------------------------------+
| recip | to, cc, bcc |
+-------------+-----------------------------------------+
| contact | to, cc, bcc, from |
+-------------+-----------------------------------------+
| related | message-id, references |
+-------------+-----------------------------------------+
| <empty> | to, cc, bcc, from, subject, body, embed |
+-------------+-----------------------------------------+DATE RANGES The date: field takes a date-range, expressed as the lower and upper bound, separated by ... Either lower or upper (but not both) can be omitted to create an open range.
Dates are expressed in local time and using ISO-8601 format (YYYY-MM-DD
HH:MM:SS); you can leave out the right part and mu adds the rest,
depending on whether this is the beginning or end of the range (e.g.,
as a lower bound, "2015" would be interpreted as the start of that
year; as an upper bound as the end of the year).
You can use `/' , `.', `-', `:' and "T" to make dates more human-
readable.
Some examples:
date:20170505..20170602
date:2017-05-05..2017-06-02
date:..2017-10-01T12:00
date:2015-06-01..
date:2016..2016
You can also use the special "dates" now and today:
date:20170505..now
date:today..
Finally, you can use relative "ago" times which express some time
before now and consist of a number followed by a unit, with units s for
seconds, M for minutes, h for hours, d for days, w for week, m for
months and y for years. Some examples:
date:3m..
date:2017.01.01..5wSIZE RANGES The size or z field allows you to match size ranges -- that is, match messages that have a byte-size within a certain range. Units (b (for bytes), K (for 1000 bytes) and M (for 1000 * 1000 bytes) are supported). Some examples:
size:10k..2m
size:10m..FLAG FIELD The flag/g field allows you to match message flags. The following fields are available: +-----------+----------+----------+-----------------------------+ | flag | shortcut | category | description | +-----------+----------+----------+-----------------------------+ | draft | D | file | Draft (in progress) | +-----------+----------+----------+-----------------------------+ | flagged | F | file | User-flagged | +-----------+----------+----------+-----------------------------+ | passed | P | file | Forwarded message | +-----------+----------+----------+-----------------------------+ | replied | R | file | Replied-to | +-----------+----------+----------+-----------------------------+ | seen | S | file | Viewed at least once | +-----------+----------+----------+-----------------------------+ | trashed | T | file | Marked for deletion | +-----------+----------+----------+-----------------------------+ | new | N | maildir | New message | +-----------+----------+----------+-----------------------------+ | signed | z | content | Cryptographically signed | +-----------+----------+----------+-----------------------------+ | encrypted | x | content | Encrypted | +-----------+----------+----------+-----------------------------+ | attach | a | content | Has at least one attachment | +-----------+----------+----------+-----------------------------+ | unread | u | pseudo | New or not seen message | +-----------+----------+----------+-----------------------------+ | list | l | content | Mailing list message | +-----------+----------+----------+-----------------------------+ | personal | q | content | Personal message | +-----------+----------+----------+-----------------------------+ | calendar | c | content | Calendar invitation | +-----------+----------+----------+-----------------------------+
Some examples:
flag:attach
flag:replied
g:xPRIORITY FIELD The message priority field (prio:) has three possible values: low, normal or high. For instance, to match high-priority messages: prio:high
MAILDIR The Maildir field describes the directory path starting after the Maildir root directory, and before the /cur/ or /new/ part. So, for example, if there's a message with the file name ~/Maildir/lists/running/cur/1234.213:2,, you could find it (and all the other messages in that same maildir) with: maildir:/lists/running
Note the starting `/'. If you want to match mails in the "root"
maildir, you can do with a single `/':
maildir:/MORE EXAMPLES
Find all messages with both "bee" and "bird" (in any field)
bee AND bird
Find all messages with either Frodo or Sam:
Frodo OR Sam
Find all messages with the "wombat" as subject, and "capybara"
anywhere:
subject:wombat and capybara
Find all messages in the "Archive" folder from Fred:
from:fred and maildir:/Archive
Find all unread messages with attachments:
flag:attach and flag:unread
Find all messages with PDF-attachments:
mime:application/pdf
Find all messages with attached images:
mime:image/*Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- mu_mcp/mu_mcp.py:19-38 (handler)The 'query' function executes the tool logic: it takes a query string, runs 'mu find' via subprocess, and returns the result or an error message.
def query(query: str) -> str: """Query `mu` by providing a valid query to be sent in the following way. Syntax: ``` mu find $query ``` Here is the syntax guide for mu queries. """ import subprocess try: result = subprocess.run( ["mu", "find"] + query.split(), capture_output=True, text=True, check=True ) return result.stdout.strip() except subprocess.CalledProcessError as e: return f"Error: {e.stderr.strip()}" - mu_mcp/mu_mcp.py:44-44 (registration)The tool named 'query' is registered with the MCP server using mcp.tool('query')(query).
mcp.tool("query")(query) - mu_mcp/mu_mcp.py:19-38 (schema)No formal schema/type definition exists beyond the function signature 'def query(query: str) -> str', which defines the input as a string and output as a string.
def query(query: str) -> str: """Query `mu` by providing a valid query to be sent in the following way. Syntax: ``` mu find $query ``` Here is the syntax guide for mu queries. """ import subprocess try: result = subprocess.run( ["mu", "find"] + query.split(), capture_output=True, text=True, check=True ) return result.stdout.strip() except subprocess.CalledProcessError as e: return f"Error: {e.stderr.strip()}" - mu_mcp/mu_mcp.py:7-8 (helper)Supporting data: 'mu_query_man' and 'mu_find_man' are loaded from text files and appended to the docstring of the query function for context.
mu_query_man = open("mu_mcp/mu-query.txt", "r").read().strip() mu_find_man = open("mu_mcp/mu-find.txt", "r").read().strip()