From MozillaZine Knowledge Base
Message filters are useful if you routinely want to perform certain actions on messages. For instance, you can have incoming mail automatically sorted into different folders and certain messages tagged, marked as Junk, forwarded or even deleted. Filters can be applied automatically to incoming mail, or you can run them manually when desired. There is a section on message filters in the FLOSS tutorial for Thunderbird.
Creating and editing filters
This tutorial has step-by-step instructions (with screenshots) for how to set up message filters in Thunderbird. You can also create a new filter from any message by right-clicking on the email address of the sender in a message's headers, and choosing "Create Filter From Message...."
Filters are account specific, there is no support for global filters. The closest thing to a global filter would be to configure several POP accounts to use a Global Inbox. In that case, you could create filters for the Local Folders pseudo account that would be applied automatically to incoming mail for those accounts.
The file that stores your filter settings is called "msgFilterRules.dat". Each account will have its own "msgFilterRules.dat" file, stored in the "Local Directory" for the account in your profile. The Local Directory is specified at the bottom of Tools -> Account Settings -> Server Settings, right by the Browse button. The filters for Local Folders are stored in the Mail\Local Folders directory in the profile.
If you want to duplicate an accounts filters in another account you don't need to create them again. Exit Thunderbird and copy the "msgFilterRules.dat" file instead. If the account is in another profile and it uses custom headers you will also need to copy the mailnews.customHeaders setting from prefs.js.
There is no support for sorting rules in the message filter window. If you have problems finding a filter try using the Filter Of Filters add-on. However, if you have hundreds of rules it is usually easier to edit them by editing the "msgFilterRules.dat" file with a text editor (not a word processor).
Enabled filters are run automatically, in the order they are listed in the "Message Filters" dialog ("Tools -> Message Filters..."). If a filter moves a message to another folder subsequent filters will not be automatically applied to that message once it has been moved from the Inbox. There is no built-in support for automatically running filters on outgoing mail. Install the Send Filter add-on if you want to do that.
To run filters manually on the currently opened folder, select "Tools -> Run Filters on Folder". To manually run only some of your filters rather than all of them, go to "Tools -> Message Filters...", select the filters you want to run, and click the "Run Now" button.
When you create a filter "Apply filter where" defaults to "Checking Mail or Manually Run". That means the filter will be run automatically when Thunderbird checks for new mail in the inbox for that account, and if you manually run the filter using Tools -> Run Filters on Folder or Tools -> Run Filters on Message. The list box can be used to fine tune exactly when the filter is run. For example, "Checking Mail (after classification)".
Filtering the message body
You can filter based on the contents of the message body if you select "Body". If you have a message with both a plain text and a HTML version of the message body it searches both copies. This works for both local and remote (IMAP) folders. You used to be able to search the entire message (including all headers and the attachments) if you selected "Body" though in some releases you had to add it as a custom header (see Custom Headers section below) to use it with an IMAP account. Nowadays Body is only predefined for POP accounts, and it only searches the message body.
If you want to filter the message body of a IMAP account you need to add a Body custom header (see Custom Headers section below). You usually also need a local copy of the message/folder (due to "Tools -> Account Settings -> Account_name -> Synchronization & Storage -> Keep messages in all folders for this account on this computer" creating a local file that contains the message).  However, with some IMAP servers if there is no offline folder and the message is a plain text message, Thunderbird will search the body using IMAP commands.  . Whether the search succeeds also appears to depend upon the health of the folders *.msf file. You might need to rebuild it by right clicking on the folder in the folder pane, selecting Properties and then pressing the "Repair Folder" button.
The official reason Body is not supported by default for remote folders is that Thunderbird only downloads the message headers before applying filters, and adding support for filtering the message body in an IMAP account would require adding support for reading the offline folders (offline message store) in the IMAP filter code.  However, that appears to be what the workaround is doing. Bottom line is searching the contents of a message body in a IMAP account is reluctantly supported and you may need to experiment to figure out why it might fail.
Message filters don't know about every type of message header. For example, any header beginning with a X such as X-Spam-score:. If you want to use a unknown header select "Customize" at the bottom of the leftmost list box (while editing the filter rule). Then either select a custom header from the list box or add one by entering its name in "New message header:". Omit the ':'. For example, if you have a Message-ID: <email@example.com> header and want to test Message-ID: headers you would enter Message-ID (omit the trailing ':').
This creates a custom header that is stored using the mailnews.customHeaders setting. You can use it with other filters. It will show up in the normal list of headers, you don't need to use Customize again.
There is no header called Body, but if you add a custom header with that name (omit the ':') using "Customize" at the bottom of the leftmost list box (while editing the filter rule) that will let a IMAP account filter the message body. It will also add it to mailnews.customHeaders .
While you can create message filters to test for Spam thats re-inventing the wheel. Its more efficient to use the junk mail controls . This article explains how to tweak the the junk mail controls to make them learn faster. You could also run other tools such as SpamAssassin or SpamPal that add headers to describe its analysis of the message and some sort of spam score that you can test. For example, SpamPal adds a X-SpamPal: PASS header if the message isn't spam. You could test that yourself, or configure the junk mail controls to trust SpamAssassin or SpamPal and have it test it instead.
When you check for new mail message filters are run before the junk mail controls. There is no way to change that order.
Testing whether a message is marked as junk
The message filters don't support testing whether a message is marked as junk. The information seems to be stored in the index file, not one of the two MozillaStatus headers. However, if you configured the junk mail controls to trust either SpamAssasson or SpamPal you could look in the SpamAssassin.sfd or SpamPal.sfd file in the isp directory in your Thunderbird program directory and figure out what it tested in order to mark the message as junk, and test the same thing. For example, the following line in SpamAssassin.sfd
condition="OR (\"X-Spam-Status\",begins with,Yes) OR (\"X-Spam-Flag\",begins with,YES) OR (subject,begins with,***SPAM***)"
means that SpamAssassin normally tests whether the X-Spam-Status or X-Spam-Flag header begins with Yes or the subject begins with ***SPAM***.
Usually you can do some simple testing by sending yourself a message from some other account. It helps if you enable the filter log beforehand . Go to Tools -> Message Filters , and click on "Filter Log". If "Enable the filter log" is not checked, check it. Otherwise press "Clear log".
Rather than testing the filters over a couple of days as you get new mail from other people edit an existing message using the HeaderToolsLite add-on. It lets you edit the raw message source. Edit the message, save it, and then right click on the message, and select either Tag (if you want to add/delete a tag) or Mark (if you want to set it unread etc.) as appropriate before running the message filter. This should save you a lot of time.
However, sometimes you can get by using multiple rules instead. For example, to test for From: addresses that look like firstname.lastname@example.org, email@example.com, and firstname.lastname@example.org you could create a single filter with two rules, and check "Match all of the following". The first rule would be "From" "begins with" "no-reply" and the second rule "From" "ends with " "workingin-australia.com".
Account specific filters
Each account has its own set of message filters, but the filters have no concept of accounts. You can create account specific message filters by checking the value of the X-Account-Key header.
Use View -> Message Source and find the header, noting what its set to. For example, X-Account-Key: account10. Then create a message filter and scroll the leftmost list box (it defaults to Subject) down to Customize. Enter X-Account-key as the new message header, and press OK. Select X-Account-Key in that list box and test whether "X-Account-Key" "is" "account10" (replace account10 with the value your account uses) and select in "Perform these actions" what it should do.
If the filter doesn't work see if Thunderbird changed the header it tests to Subject behind your back. Sometimes you run into a temporary glitch after adding a customized header. If that happens, exit Thunderbird, restart it , and edit the message filter to use X-Account-Key.
Messages filters work when run manually but will not run automatically
There are some long standing issues where you can successfully run filters manually, but they will not run automatically. This appears to be a configuration specific bug that never got fixed, not a regression bug. Despite its age it's only recently that a few bug reports have been written about it. 
If you have never written a message filter before and can't figure out what is wrong, try starting smaller and working your way up. For example, you might have written a filter to move certain new messages to a different folder and it doesn't seem to do anything. Modify the message filter to make it add a star to all new messages. That is something harmless you can see and easily undo manually. If that works then modify it to add the star only for those messages that you want to move to a folder. If that works then modify it to move the messages instead of adding a star. The reason for doing this is by starting small its easier to catch and debug common errors, or identify if there is something wrong with that account that prevents any message filter from working etc.
You could create a message filter that adds a star to all messages by testing whether the "Subject" "isn't" "~!@#$%^&*()_+i" (or some other extremely unlikely string) and selecting "Add Star" in the actions list box. Test it using "Tools -> Run Filters on Folder". If no matter what you do it doesn't work, try replacing the contents of the "msgFilterRules.dat" file for your account in the profile as follows. If that doesn't work you probably choose the wrong directory.
version="8" logging="yes" name="Apply a star to all messages" enabled="yes" type="1" action="Mark flagged" condition="OR (subject,isn't,\"~!@#$%^&*()_+i\")"
If you have a IMAP account your email provider may support server side filters. That is a combination of message filters and junk mail filters that are run automatically by the server whenever it receives a message for your mailbox. Some may also provide the option to create custom scripts using the Sieve mail filtering language. There is a Sieve extension that lets you manage the Sieve scripts without having to use a browser. Unfortunately server side filters aren't available in free IMAP accounts provided by Gmail, GMX, or AIM.
Some alternatives to the junk mail controls provide powerful filtering capabilities but they typically don't support the commands needed to manage messages.
The message filters for each account are stored in a "msgFilterRules.dat" file in the accounts "local directory". The local directory is specified near the bottom of each accounts server settings by the browse button. You could copy that file over the corresponding file in another account. You could also copy and paste filters from one file to another using a text editor. Its a ASCII text file whose format is not hard to figure out.
There is a Message Filter Import/Export but several comments on that add-ons web page claim it doesn't work anymore.
Thunderbird 3 or later only
Note: SeaMonkey and Thunderbird share the core mail/news code.