Skip to main content
Glama

query

Find specific emails in your local mu index using structured search expressions with support for date ranges, message flags, and logical operators.

Instructions

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.

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 snow



   Note, this the default, plain-text output, which is the default, so you
   don't have to use --format=plain. For other types of output (such as
   symlinks, XML or s-expressions), see the discussion in the
   OPTIONS-section below about --format.


   The search pattern is taken as a command-line parameter. If the search
   parameter consists of multiple parts (as in the example) they are
   treated as if there were a logical and between them.


   For details on the possible queries, see mu-query(7).

FIND OPTIONS Note, some of the important options are described in the mu(1) manual page and not here, as they apply to multiple mu commands.

   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.


   The message flags are described in mu-query(7). As an example, a
   message which is `seen', has an attachment and is signed would have
   `asz' as its corresponding output string, while an encrypted new
   message would have `nx'.

-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



   Note, if you specify a sortfield, by default, messages are sorted in
   reverse (descending) order (e.g., from lowest to highest). This is
   usually a good choice, but for dates it may be more useful to sort in
   the opposite direction.

-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.

   If you specify --clearlinks, existing symlinks will be cleared from the
   target directories; this allows for re-use of the same maildir.
   However, this option will delete any symlink it finds, so be careful.

      $ mu find grolsch --format=links --linksdir=~/Maildir/search --clearlinks



   stores links to found messages in ~/Maildir/search. If the directory
   does not exist yet, it will be created. Note: when mu creates a Maildir
   for these links, it automatically inserts a .noindex file, to exclude
   the directory from mu index.

--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'`


   This is assuming the GNU date command.

--exec command The --exec coption causes command to be executed on each matched message; for example, to see the raw text of all messages matching `milkshake', you could use: $ mu find milkshake --exec='less'

   which is roughly equivalent to:
      $ mu find milkshake --fields="l" | xargs less

-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	    | |->    | |*>    | |=>	  |



   Here, an `orphan' is a message without a parent message (in the list of
   matches), and a duplicate is a message whose message-id was already
   seen before; not this may not really be the same message, if the
   message-id was copied.


   The algorithm used for determining the threads is based on Jamie
   Zawinksi's description: http://www.jwz.org/doc/threading.html

-a,--analyze Instead of executing the query, analyze it by show the parse-tree s- expression and a stringified version of the Xapian query. This can help users to determine how mu interprets some query.

   The output of this command are differ between versions, but should be
   helpful nevertheless.

--muhome Use a non-default directory to store and read the database, write the logs, etc. By default, mu uses the XDG Base Directory Specification (e.g. on GNU/Linux this defaults to ~/.cache/mu and ~/.config/mu). Earlier versions of mu defaulted to ~/.mu, which now requires --muhome=~/.mu.

   The environment variable MUHOME can be used as an alternative to
   --muhome. The latter has precedence.

COMMON OPTIONS -d, --debug Makes mu generate extra debug information, useful for debugging the program itself. Debug information goes to the standard logging location; see mu(1).

-q, --quiet Causes mu not to output informational messages and progress information to standard output, but only to the log file. Error messages will still be sent to standard error. Note that mu index is much faster with --quiet, so it is recommended you use this option when using mu from scripts etc.

--log-stderr Causes mu to not output log messages to standard error, in addition to sending them to the standard logging location.

--nocolor Do not use ANSI colors. The environment variable NO_COLOR can be used as an alternative to --nocolor.

-V, --version Prints mu version and copyright information.

-h, --help Lists the various command line options.

INTEGRATION It is possible to integrate mu find with some mail clients

mutt For mutt you can use the following in your muttrc; pressing the F8 key will start a search, and F9 will take you to the results.

      # mutt macros for mu
      macro index <F8> "<shell-escape>mu find --clearlinks --format=links --linksdir=~/Maildir/search " \\
			       "mu find"
      macro index <F9> "<change-folder-readonly>~/Maildir/search" \\
			       "mu find results"

Wanderlust Sam B suggested the following on the mu-mailing list. First add the following to your Wanderlust configuration file:

      (require 'elmo-search)
      (elmo-search-register-engine
	  'mu 'local-file
	  :prog "/usr/local/bin/mu" ;; or wherever you've installed it
	  :args '("find" pattern "--fields" "l") :charset 'utf-8)

      (setq elmo-search-default-engine 'mu)
      ;; for when you type "g" in folder or summary.
      (setq wl-default-spec "[")



   Now, you can search using the g key binding; you can also create
   permanent virtual folders when the messages matching some expression by
   adding something like the following to your folders file.

      VFolders {
	[date:today..now]!mu  "Today"
	[size:1m..100m]!mu    "Big"
	[flag:unread]!mu      "Unread"
      }



   After restarting Wanderlust, the virtual folders should appear.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.


   Furthermore, mu find provides the --analyze option, which shows how mu
   interprets your query; similarly, mu4e has a command. mu4e-analyze-
   last-query.  See the ANALYZING QUERIES section for further details.


   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



   Terms without an explicit field-prefix, (like "vacation" above) are
   interpreted as:

      to:vacation or subject:vacation or body:vacation or ...



   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"



   This is a so-called phrase query, which means that we match against
   subjects that contain the literal phrase "hi there". Phrase queries
   only work for certain fields; they have the word phrase in their mu
   info fields search column.

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.

   In this case, that means the difference between search for a subject
   "hi there" versus and subject "hi" and some word "there" that can
   appear in any of the combination fields for <empty> (combination fields
   are discussed below).


   We can use the mentioned --analyze option to show the difference:


   #+begin_example mu find subject:"hi there" --analyze

query: subject:hi there

parsed query: (and (subject "hi") (_ "there"))

parsed query (expanded): (and (subject "hi") (or (to "there") (cc "there") (bcc "there") (from "there") (subject "there") (body "there") (embed "there")))

Xapian query: Query((Shi AND (Tthere OR Cthere OR Hthere OR Fthere OR Sthere OR Bthere OR Ethere))) #+end_example

   And with quotes escaped:


   #+begin_example mu find subject:$

query: subject:"hi there"

parsed query: (or (subject "hi there") (subject (phrase "hi there")))

Xapian query: Query((Shi there OR (Shi PHRASE 2 Sthere))) #+end_example

   We won't dwell on the details of the --analyze output here, but
   hopefully this illustrates the difference between quoted and unquoted
   queries.

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



   If you do not explicitly specify an operator between terms, and is
   implied, so the queries
      subject:chip subject:dale

      subject:chip AND subject:dale


   are equivalent. For readability, we recommend the second version.


   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*"



   Quoting the "hello*" is recommended; some shells (but not all) would
   otherwise expand the '*' to all files in the current directory.

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.


   Regular expressions are more powerful than wildcards, but are also much
   slower.	Moreover, their behavior in mu can be a bit confusing, due to
   some implementation details. See below for some of the caveats.

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/'

   (with the $ 40 specifying a space in the regular expression, and and
   extra '$´ to escape it). In many cases,
      mu find 'subject:/hello.world/'


   may be good enough, and easier to type.

Anchors in regular expressions Since the underlying Xapian database does not support regular expressions (it does support wildcards), mu implements the regular- expression search by matching the user's regular expression against all "terms" (words or phrases) that in the database for a given field.

   That implementation detail explain why "anchored" regular expressions
   (with ^ and $ to mark begin/end, respectively) can get unexpected
   results.


   Suppose you want to match all messages that start with "pie", and you
   search with subject:/^pie/. This also matches messages with subject
   "apple pie", since both those words are indexed as terms separately (as
   well as phrases), and thus "^pie" matches as well for a message with
   subject "apple pie".

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 |
      +-------------+-----------------------------------------+



   Hence, for instance,
      contact:fnorb@example.com


   is equivalent to
      (from:fnorb@example.com or to:fnorb@example.com or
	    cc:from:fnorb@example.com or bcc:fnorb@example.com)

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..5w

SIZE 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:x



   Encrypted messages may be signed as well, but this is only visible
   after decrypting and thus invisible to mu.

PRIORITY 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:/



   If you have maildirs (or any fields) that include spaces, you need to
   quote them, i.e.,
      maildir:"/Sent Items"



   And once again, note that when using the command-line, such queries
   must be quoted:
      mu find 'maildir:"/Sent Items"'



   Also note that you should not end the maildir with a /, or it can be
   misinterpreted as a regular expression term; see aforementioned.

MORE EXAMPLES Here are some simple examples of mu queries; you can make many more complicated queries using various logical operators, parentheses and so on, but in the author's experience, it's usually faster to find a message with a simple query just searching for some words.

   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/*


   (and beware that on the command-line, you need to put this in quotes or
   it would expand the *.


   Find a messages with the given message-id:
      msgid:CAE56pjGU2oNxN-wWku69@mail.gmail.com



   Find all messages written in Dutch or German with the word "hallo":
      hallo and (lang:nl or lang:de)



   This is only available if your mu has support for this; see mu info and
   check for "cld2-support*.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The query tool handler function that executes mu find commands by running a subprocess with the provided query string and returning stdout or error messages
    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)
    Registration of the query tool with the MCP server using mcp.tool() decorator pattern
    mcp.tool("query")(query)
  • Input/output type schema defined by function signature: takes a string query parameter and returns a string result
    def query(query: str) -> str:
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. While 'query' implies read-only, the description never explicitly states safety guarantees, idempotency, error behavior, or performance characteristics (e.g., 'heavy' queries mentioned in the docs). It focuses entirely on syntax rather than operational behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely verbose—essentially a full man page dump for mu-find and mu-query. Critical selection context is buried under thousands of words of reference material. Every sentence does not earn its place; most content belongs in external documentation, not a tool description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the existence of an output schema, the description appropriately omits return value details. The query syntax is comprehensively documented (albeit inefficiently), covering all possible query constructs. However, it lacks tool-level context like authentication needs or rate limits that would be expected for a search interface.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates by providing exhaustive documentation of query syntax (fields, flags, date ranges, wildcards). However, this information is not explicitly tied to the 'query' parameter—it reads as general reference material rather than parameter guidance. Baseline 3 is appropriate as the schema is simple but undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states the tool queries 'mu' using the syntax 'mu find $query', which identifies the verb (query/find) and resource (mu database). However, it fails to distinguish from siblings like 'view' or 'get_attachment'—it doesn't clarify that this searches across messages while others retrieve specific content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides extensive query syntax documentation (fields, operators, ranges) but offers zero guidance on when to select this tool versus alternatives. It does not state prerequisites (e.g., indexed maildir) or when to use 'view' instead for reading specific messages.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/danielfleischer/mu-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server