Repository navigation
Releases: commonpost/thunderbird-mcp
Release list
v0.17.3
In short
- Fixed: a reply or forward made by an assistant without a compose window (a draft, or a direct send) could let
the end of a quoted message run into the text and signature after it. With Thunderbird's default settings the quote
was already cleaned up before this point; it mattered mostly with an advanced setting changed by hand. Messages
written in a compose window were not affected. - The bridge does not change in this release: nothing to update in your MCP clients if their bridge is 0.17.1.
- No call that worked stops working. Updating is recommended, not urgent.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.17.3.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release ships the same bridge as v0.17.1: a bridge of version 0.17.1 needs no update.
- Claude Desktop: download
commonpost-mcp-v0.17.1.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Claude Code with the plugin:
/plugin marketplace update commonpost(or turn on auto-update for the marketplace in/plugin), then/reload-plugins. The plugin always carries the bridge of the release. - Other clients (Claude Code without the plugin, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date", "Newer version available" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Fixed
- A reply or forward built without a compose window (a draft, or a direct send) could let the end of a quoted message
run into what follows it: a tag, attribute value, comment or<textarea>left open at the very end of the quote
took in the caller's text or the signature after it, so markup the quote checks never saw could come out as an
element. The quote is now replaced by Thunderbird's parsed reading of it, which ends where the quote ends, whenever
markup put after it would not be read as markup of its own. With Thunderbird's default settings the quote of a
reply or forward is already parsed before it gets here; messages composed in a window were not affected.
Changed
- The Claude Code plugin manifest lists a terms of service link (the MIT license), for the Claude plugin directory.
v0.17.2
In short
- Fixed: with an identity that writes in HTML, an apostrophe reached the recipient as
'("j'ai" for
"j'ai") in a draft, a direct send, or a reply or forward made by an assistant without a compose window. Non-breaking
spaces and other special characters of an HTML body, an HTML signature or a quoted message showed the same way.
Messages written in a compose window were not affected. - The bridge does not change in this release: nothing to update in your MCP clients if their bridge is 0.17.1.
- No call that worked stops working. Updating is recommended, not urgent.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.17.2.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release ships the same bridge as v0.17.1: a bridge of version 0.17.1 needs no update.
- Claude Desktop: download
commonpost-mcp-v0.17.1.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Claude Code with the plugin:
/plugin marketplace update commonpost(or turn on auto-update for the marketplace in/plugin), then/reload-plugins. The plugin always carries the bridge of the release. - Other clients (Claude Code without the plugin, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date", "Newer version available" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Fixed
- An apostrophe reached the recipient as
'(j'aifor "j'ai") in an HTML message built without a compose
window:saveDraft, a directsendMail, and the text of a reply or forward sent directly or saved as a draft, when
the identity composes in HTML. The same happened to any character reference in an HTML body (', ,
é...), and in an HTML signature or quoted message that has one. Thunderbird's send path escapes the&of
every reference but<,>,&and", which are the only ones its editor writes; these bodies
now reach it with the other references decoded, as the editor would have written them. A body in which this would
change more than the text (an HTML body with a>inside a quoted attribute value) goes as before. Messages composed
in a window were not affected.
v0.17.1
In short
Security release: update both the add-on and the bridge. Files of a Thunderbird profile, or of an account's local
mail folder, kept outside the default locations could be attached to a message; they are now refused. A bridge
older than 0.17.1 does not apply this check: the add-on now recommends updating it (Claude Code plugin: update the
plugin; Claude Desktop: install the new .mcpb; elsewhere: replace mcp-bridge.cjs). No call that worked stops
working, except attaching files from those folders.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.17.1.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release changes the bridge: update it in every MCP client that uses it.
- Claude Desktop: download
commonpost-mcp-v0.17.1.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Claude Code with the plugin:
/plugin marketplace update commonpost(or turn on auto-update for the marketplace in/plugin), then/reload-plugins. The plugin always carries the bridge of the release. - Other clients (Claude Code without the plugin, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date", "Newer version available" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Security
- Attachments: the add-on lists the folders of the running Thunderbird profile, of every other profile Thunderbird
knows and of every account's local mail folder, wherever they are, in the connection file; the bridge refuses a
path attachment under any of them (by the path given, its real path, and the folder's identity, so a link or a
second mount of the same folder is refused too). The bridge now finds Thunderbird before it accepts a path
attachment, and checks again if a request ends up going to another Thunderbird than the one it was checked
against. The add-on applies a similar check, by path and real path, to path attachments it receives directly. Not covered: the account
folders of profiles other than the running one, a mail store at the root of a drive, and a folder the bridge
sees under another path (a bridge under WSL or in a container). See "Attachments refused" in the README.
Changed
- Bridge 0.17.1. The add-on recommends it (
MIN_BRIDGE_VERSION0.17.1); older bridges keep working. - The connection file is written in ASCII (non-ASCII characters escaped), so a path with accents reads back the same.
v0.17.0
In short
- New: a Claude Code plugin. Add this repository as a plugin marketplace (
claude plugin marketplace add commonpost/thunderbird-mcp, or "Add marketplace" in Customize > Plugins of your Claude account) and install
commonpost-mcp: the plugin carries the bridge of the release, so there is nomcp-bridge.cjsto download or to
replace by hand, and updating the plugin updates the bridge. It works in Claude Code and Cowork; the chat of
Claude Desktop still needs the.mcpbbundle. - The bridge does not change in this release: nothing to update in your MCP clients if their bridge is 0.14.0. A
bridge 0.13 keeps working; updating it is optional. - No call that worked stops working. Updating is not urgent.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.17.0.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release ships the same bridge as v0.14.0: a bridge of version 0.14.0 needs no update.
- Claude Desktop: download
commonpost-mcp-v0.14.0.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Claude Code with the plugin:
/plugin marketplace update commonpost(or turn on auto-update for the marketplace in/plugin), then/reload-plugins. The plugin always carries the bridge of the release. - Other clients (Claude Code without the plugin, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date", "Newer version available" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Added
- A Claude Code plugin: this repository is a plugin marketplace (
claude plugin marketplace add commonpost/thunderbird-mcp, thenclaude plugin install commonpost-mcp@commonpost). The plugin
(plugins/claude-code/) declares thecommonpost-mailserver and carries the bridge of the release, so Claude Code
users have nomcp-bridge.cjsto download or to replace by hand: updating the plugin updates the bridge. Its version
is the product's and its bridge a byte-for-byte copy of the repository's (the version check requires both), so every
release reaches plugin users.
The plugin folder carries its own README, LICENSE and listing icon, as Anthropic's plugin directory requires.
v0.16.0
In short
- Fixed:
listEventslists a whole day when it is asked for one date (2026-10-15to2026-10-15): it returned
nothing, with no error, so an assistant answered that the day was free. A date without a time is now a day in
local time. - Fixed: a folder address written with a trailing slash is accepted;
createFolderanswered "Folder not found". - Changed: three answers now tell an assistant what it needs to go on: an empty search of several words says
why it found nothing, a draft whose recipient has no e-mail address carries a warning, andrenameFolderreturns
the new address of the folder. - The bridge does not change in this release: nothing to update in your MCP clients if their bridge is 0.14.0. A
bridge 0.13 keeps working; updating it is optional. - No call that worked stops working. Updating is not urgent.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.16.0.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release ships the same bridge as v0.14.0: a bridge of version 0.14.0 needs no update.
- Claude Desktop: download
commonpost-mcp-v0.14.0.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Other clients (Claude Code, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date", "Newer version available" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Changed
searchMessagesadds ahintto an empty result of a search of several words: every word must match as written,
and a single leading operator (from:Carol training budget) sends every word to that field. Results that found
something are unchanged.sendMail,saveDraft,replyToMessageandforwardMessageadd awarningwhen a recipient has no e-mail address
(to: "Frank Osei"): the draft was saved and reported as a success, addressed to nobody. The call still succeeds,
because the name of a Thunderbird mailing list is such a recipient too. A direct send that fails names it as the
likely cause.renameFolderreturns the new URI of the folder aspath, next tooldPath, and says so in its message: a caller
that went on with the old URI got "Folder not found".
Fixed
listEventslists a whole day whenstartDateandendDateare the same date without a time (2026-10-15): it
returned an empty list, with no error, and an assistant answered that the day was free. A date without a time is now
a calendar day in local time: asstartDatethe start of that day, asendDatethe end of it. A date with a time
is read as before.- A folder URI written with a trailing slash (
mailbox://nobody@Local%20Folders/) is accepted wherever a tool takes
a folder:createFolderanswered "Folder not found" for it.moveFolderstill says "already under this parent"
when that parent is written this way. - Release pages name the
.mcpbfile as it is published. The bundle carries the version of the bridge, so a release
that does not change the bridge ships the bundle of an earlier version: the page of 0.15.0 said
commonpost-mcp-v0.15.0.mcpbfor the filecommonpost-mcp-v0.14.0.mcpb(corrected by hand on that page).
v0.15.0
In short
- New: saved searches (virtual folders): create one with
createFolder, list them withlistFolders, delete one
withdeleteFolder. A saved search is a live view: nothing is moved, copied or deleted. - New: Thunderbird shows a notification when an MCP client connects with a bridge that should be updated, and
the options page (section Bridge) now says "Newer version available" for a bridge that works but is not the latest. - Changed: release pages say whether updating the bridge is needed or optional.
- The bridge does not change in this release: nothing to update in your MCP clients if their bridge is 0.14.0. A
bridge 0.13 keeps working; updating it is optional. - No call that worked stops working.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.15.0.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release ships the same bridge as v0.14.0: a bridge of version 0.14.0 needs no update.
- Claude Desktop: download
commonpost-mcp-v0.14.0.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Other clients (Claude Code, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date", "Newer version available" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Added
- A system notification when a bridge that the add-on recommends updating, or refuses, connects: once per bridge and
per Thunderbird session. The hidden preferenceextensions.commonpost-mcp.bridgeUpdateAlert(false) turns it off.
It uses the notifications of the system; on a Linux desktop without a notification service nothing is shown. - The options page (section Bridge) shows "Newer version available" for a bridge that works but is not the one
published with the add-on, and names that version. - Saved searches (virtual folders), through
createFolder(savedSearch),listFolders(savedSearches) and
deleteFolder(a saved search is deleted as a view, never as mail). By Sven Scharmentke (@svnscha), from
TKasperczyk/thunderbird-mcp#198. Conditions are the same ascreateFilter's (same typed values and address-book
restrictions), at most 50 folders and 50 conditions; a searched folder of an excluded account is counted in
hiddenSearchFolders, never named.
Changed
- The release page calls the bridge update optional when the oldest recommended bridge does not change.
v0.14.0
In short
- Security: with 0.13.0, a reply or a forward saved as a draft (
mode: "draft") could carry an image or a link
of the original message that Thunderbird fetches and attaches when the draft is opened and sent. Fixed here; update
if you use drafts of replies or forwards. Direct sends and replies made in Thunderbird's window were not affected. - New:
replyToMessagecan answer the newest message of a conversation (latestInThread), in a window or as a
draft. - Fixed: a signature with images read from files, and the bridge now waits long enough for a slow send or save.
- Changes you may notice:
moz-do-not-send="false"in an HTML body passed to the compose tools is no longer
kept. No call that worked stops working. - This release changes the bridge: update it in every MCP client (steps below). A bridge 0.13 keeps working.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.14.0.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release changes the bridge: update it in every MCP client that uses it.
- Claude Desktop: download
commonpost-mcp-v0.14.0.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Other clients (Claude Code, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Added
replyToMessagelatestInThread: truereplies to the newest message of the conversation (Sent included; Drafts,
Templates and the Outbox left out), found assearchMessagesthreadOffinds it. When that is another message
than the one passed, the result names it inrepliedTo(messageId,folderPath,date, and
linkedBy: "subject"when it has no References to the conversation). The server instructions gain a line on
replies and one on editing drafts withsaveDraftdraftId. Thanks to Konstantin (@mazixs), last piece of #18.- Only for a window or a draft, which you review: with
mode: "send"(orskipReview) it is refused, because
anyone can join a conversation with a message and the newest one would be quoted and answered unseen. It also
needs thesearchMessagestool enabled. threadIncomplete: truein the result means the mailbox holds more messages than the conversation search reads
(10,000 headers): a newer message may exist.
- Only for a window or a draft, which you review: with
Security
- A reply or a forward saved as a draft (
mode: "draft") could keep an image or a link of the original message
without themoz-do-not-send="true"mark that Thunderbird's own reply sets, and with the sender's own
moz-do-not-send="false". The mark was set on the tags found in the text of the quote, and a tag that the text
and Thunderbird's parser read differently (a quote character in an attribute name is enough) was missed. Opened in
the compose window and sent, such a draft makes Thunderbird fetch the URL and attach what it gets, as it does for
an object marked"false". The elements Thunderbird's parser finds in the quote are now checked after the text,
and nomoz-do-not-sendwritten by the message is kept. A direct send was not affected (it embeds nothing), nor
a reply made in Thunderbird's window. - The
<html>,<head>and<body>tags of a quoted message are removed from its text; a<body>tag could be
left when the removal itself put one together (<bo<body x>dy background=...>), and it then gave its attributes,
a background image for one, to the body of the draft. What is left of such a tag is now text. moz-do-not-send="false"in the HTML body given by the caller (sendMail,saveDraft,replyToMessage,
forwardMessage) is no longer kept either, for the same reason: text an assistant wrote after reading a message
must not make Thunderbird fetch and attach a URL.moz-do-not-send="true"is kept.
Fixed
- A signature with
file://images: the URL that was replaced by its data was looked for in a lower-cased copy of the
signature, made again for every URL, and a character whose lower case is longer (U+0130) before a URL moved the
place that was replaced. The signature is now read once, as it is. mcp-bridge.cjswaits up to 180 s, instead of 150 s, for a direct send or a saved draft. Before the 120 s of the
send or the save, the add-on can wait for a folder summary (20 s), the original message (20 s) and its quote
(15 s): 175 s in all, so a bridge that gave up at 150 s could report a failure for a message that still went out. A
test now keeps the wait of the bridge above the sum of the waits of the add-on. A bridge 0.13 keeps working.
v0.13.0
In short
- New:
saveDraftcan edit an existing draft (draftId) instead of creating another one. A reply or a forward
saved as a draft or sent directly, and a new draft, now have the body Thunderbird itself would write: the quote with
its formatting, the forward header, your signature. - Fixed: the bridge waits long enough for
saveDraft: a slow save could be reported as failed and end in a second
draft. The notice about a bridge to update no longer skips a session that starts shortly after another one, and
says where the bridge is. - Changes you may notice: drafts and direct sends now carry your signature when you have one, and the subject of
a forward made without a window always gets theFwd:prefix. No call that worked stops working. - This release changes the bridge: update it in every MCP client (steps below). A bridge 0.12 keeps working, and
the add-on reminds you until it is replaced. - Release pages start with this summary and the steps to update, from now on.
How to update
- Thunderbird add-on: it updates itself. To get this version now: Add-ons and Themes, gear menu, Check for Updates, then restart Thunderbird. For a first installation, see the README (
commonpost-mcp-v0.13.0.xpibelow). - MCP bridge: it is installed in your MCP client and is never updated automatically. This release changes the bridge: update it in every MCP client that uses it.
- Claude Desktop: download
commonpost-mcp-v0.13.0.mcpbbelow and open it with Claude Desktop; if the file does not open there (Windows), use Settings > Extensions > Advanced settings > Install Extension. - Other clients (Claude Code, Cursor, VS Code, ...): download
mcp-bridge.cjsbelow and put it in place of your copy, then restart the client or reconnect the server (/mcpin Claude Code). The path of your copy is in the MCP configuration of the client (Claude Code:claude mcp get <server name>). - Not sure which bridges you have? The options page of the add-on (section Bridge) lists the bridges that connected, each with its version and "Up to date" or "Update recommended". Claude Desktop and another client on the same computer are two bridges, updated separately.
- Claude Desktop: download
The .sigstore.json files are provenance attestations, not something to install.
All changes
Added
- Every release page now starts with a summary in plain words ("In short": what is new, what is fixed, what breaks),
then the steps to update the add-on and the bridge, with a line that says whether the release changes the bridge,
then the list of changes as before.scripts/release-notes.cjswrites it fromCHANGELOG.mdandBRIDGE_VERSION;
from 0.13.0 on, a release whose CHANGELOG section has no summary is refused by the Version sync check. saveDrafttakesdraftId(and optionally itsfolderPath) to edit an existing draft instead of deleting and
recreating it, as Thunderbird does when a draft is reopened and saved. Passed fields replace, the others are kept:
recipients, subject, body, attachments, Reply-To, priority, References, Content-Language, the return receipt / DSN /
delivery format flags and the reply or forward state. The draft keeps the format of its body;isHtmlchanges it only
when the whole body is replaced. The old version is removed once the new one is stored. The result has the new
messageId(Thunderbird gives every saved draft a new one) andreplacedDraftId. With a newbody,keepQuote
(default true) replaces only the typed text and keeps the cite line, quote, forwarded message and signature;
keepAttachments: falsedrops the draft's attachments. By @mazixs in #30.
A refused attachment fails the whole call, as for a new draft, and an encrypted draft is not rewritten while
encrypted content is not allowed: in both cases the draft stays as it is.
Changed
- The add-on recommends bridge 0.13.0 or newer (
MIN_BRIDGE_VERSION), the first that waits 150 s forsaveDraft:
an older bridge still works, and gets the notice to update in a tool result and "Update recommended" in the
options page.mode: "send"and"draft"keep their own minimum, 0.12.0. - The notice for a bridge to update, in a tool result and in the options page (section Bridge), says where the copy
to replace is (the MCP configuration of the client;claude mcp get <server name>in Claude Code) and how to
install the.mcpbbundle when the file does not open in Claude Desktop (Settings > Extensions > Advanced settingsInstall Extension). The options page and the README say that each MCP client has its own bridge.
- A reply without a window (
mode: "draft"or"send"),saveDraftandsendMailwithskipReviewget the body
Thunderbird's compose window would save with the same text typed at its caret: the localized cite line
(mailnews.reply_header_type), the quote from Thunderbird's own quoting (nsIMsgQuote) with the original's HTML
formatting, the identity's signature (text, HTML, file or image) placed by its reply position and signature
settings, HTML in UTF-8, plain text asformat=flowedwrapped atmailnews.wraplength. Before, a reply quoted the
plain-text body by hand under an English "On ..., ... wrote:" line without a signature, a new message got no
signature, a plain body went out labeledformat=flowedwithout being flowed, and an HTML body (isHtml: true)
had every non-ASCII character written as a&#...;reference, which made a Cyrillic body several times larger. By
@mazixs in #28.
While encrypted content is not allowed, Thunderbird's own quote, which decrypts, is taken only for a message that
was read and holds no encrypted part: a reply to a message that could not be read in time quotes nothing, as before. - A forward without a window (
mode: "draft"or"send") gets the body Thunderbird's forward window would save with
the same text typed at its caret: the localized forward header (mail.show_headers), the forwarded body with the
original's HTML formatting, and the identity's signature placed by its forward and position settings. Before, a
forward quoted the plain-text body by hand under an English "Forwarded Message" header without a signature. By
@mazixs in #29.- A plain-text forward keeps the signature below the forwarded message, as Thunderbird 140 and 158+ do.
Thunderbird 150-157 drop it (bug 2063939, a regression from Gecko bug 2019689); the tool does not copy that bug.
- A plain-text forward keeps the signature below the forwarded message, as Thunderbird 140 and 158+ do.
- The subject of a forward without a window is
mail.forward_subject_prefix(defaultFwd) and the original's
subject as the message database keeps it, as Thunderbird's forward makes it: a forward of "Re: x" is "Fwd: x", and
of "Fwd: x" is "Fwd: Fwd: x". Before, the prefix was alwaysFwdand was not added to a subject that had it. By
@mazixs in #29.
Fixed
mcp-bridge.cjs: asaveDraftcall waits up to 150 s for Thunderbird, likereplyToMessageandforwardMessage
withmode: "draft", instead of 30 s. Thunderbird can take up to 120 s to save a draft, so the bridge used to
report a timeout for a draft that was still being saved, and a client that retried would create two. After that
wait the error says the draft may still appear in the Drafts folder later.- The notice for a bridge to update reached only one of several clients that share an entry, as every bridge 0.11
or older does (it sends no version): a session that listed its tools within 10 minutes of that notice never got
one. Its notice now waits and goes out with its first tool call after those 10 minutes.
v0.12.0
Breaking
replyToMessagewithskipReviewnow needs explicittoandfrom, andforwardMessagewithskipReviewan
explicitfrom. A direct send no longer takes any address from the original message, which anyone can write: it
goes only to the caller'sto/cc/bccplus the sending identity's own automatic Cc / Bcc, with that
identity's Reply-To (a direct reply-all no longer adds the original's To / Cc). The result of a direct send lists
thefrom,to,cc,bccandreplyToit went out with. By @mazixs in #26.- The error that
replyToMessageandforwardMessagereturn when direct sending is blocked has new text, and it now
coversmode: "send"as well asskipReview: it was "User preference blocks skipReview. Retry with skipReview:
false (or omitted) to open the review window instead.", it is now "User preference blocks direct sending (mode
"send" or skipReview). Use mode "draft" to save a draft, or "window" (the default) to open a review
window." A client that matches the old string exactly must be updated (sendMail,createEventandcreateTask
keep theirs). By @mazixs in #27.
Added
replyToMessageandforwardMessagetakemode:window(the default, the review window as before),draftor
send.mode: "send"is a direct send, the same asskipReview: true, with the same rules: explicittoand
from, subject to BlockskipReview, and the bridge waits up to 150 s for it.mode: "draft"saves the
reply or forward to the identity's Drafts folder without opening a window and returns itsmessageIdand
folderPath. It sends nothing, so BlockskipReviewdoes not block it. By @mazixs in #27.
mode: "draft"needs thesaveDrafttool to be enabled: a tool the user disabled is not reachable through
another tool, and the call returns an error saying so.- A reply draft gets the recipients Thunderbird's Reply / Reply All computes (
nsMsgCompose.cpp, ported to a
pure function): Reply-To and Mail-Reply-To, Mail-Followup-To for Reply All, the author instead of a mailing list
that rewrites Reply-To, the recipients of your own message from the identity that sent it, your own addresses
dropped, and the identity's automatic Cc / Bcc and Reply-To. Atoorccfrom the caller replaces the
computed one. - The draft stores the state Thunderbird's own reply or forward draft stores (
origURIs,queuedDisposition), so
the original is marked as replied or forwarded when the draft is sent, not when it is saved. - The body is quoted by the tool, as for a direct send.
- A reply draft gets the recipients Thunderbird's Reply / Reply All computes (
- The bridge tells the user, once per connection, when the add-on is older than the version it needs
(MIN_EXTENSION_VERSION, 0.12.0). After the firsttools/listortools/callthat Thunderbird answers, it sends
the add-on aninitializeon the same validated connection (1.5 s at most, answer capped at 64 KB) and, if the
add-on is older, appends one text item to the result of the nexttools/call(Check for Updates, then restart
Thunderbird; the release page) and writes one line to stderr. Never for a direct send (skipReviewor
mode: "send"); silent when a version is missing,0.0.0or malformed, or when the server is notcommonpost-mcp; only
digits from the add-on reach the text. When the add-on is newer, the add-on judges the bridge (below). - A
.mcpbbundle for Claude Desktop (macOS and Windows), attached to each release from the next one on:commonpost-mcp-v<version>.mcpb, with a provenance attestation. It contains only the stdio bridge (mcp-bridge.cjs,LICENSE,THIRD-PARTY.md, an icon and amanifest.jsoninmcpb/, manifest_version 0.3), needs Node.js 22 or later and the add-on of the same release or newer, has no settings and is not signed. It is built byscripts/build-mcpb-reproducible.cjslike the XPI (committed files only, sorted stored entries, fixed date: the same bytes on any Node version), and the release job rebuilds it from the tag and refuses any difference. The zip writer moved toscripts/zip-stored.cjs(the XPI is byte for byte unchanged). The Version sync check and the tag check now covermcpb/manifest.jsontoo. - The bridge ignores
COMMONPOST_MCP_CONNECTION_FILEwhen its value is exactly an unexpanded${user_config.…}placeholder (a client passing an empty optional field through as text) and runs the automatic discovery, instead of pinning itself to a path that cannot exist. - The bridge answers
server/discoveritself, at once, with the JSON-RPC error -32601 "Method not found", without
contacting Thunderbird. Clients that speak both protocol eras (MCP 2026-07-28 and earlier, such as Claude Desktop)
probe with it first and fall back toinitialize; the probe used to reach Thunderbird and, with Thunderbird closed,
came back after about 5 s with a discovery error that named local paths. - The bridge announces itself on every request to the add-on, in the
X-Commonpost-Bridgeheader: its version, how it
was installed (packaging=mcpbwhen the.mcpbbundle setsCOMMONPOST_MCP_PACKAGING=mcpb, otherwisefile) and,
whenCOMMONPOST_MCP_PROFILEholds a valid name (a-z, 0-9 and -, 32 at most),profile=<name>, reserved for
per-client tool sets (nothing uses it yet). The header is self-declared: it is not a security boundary, the token
is. - The add-on judges bridges older than itself: once per client session (at most every 10 minutes) it adds a notice to
a tool result when the bridge is older than 0.12.0 or reports no version (0.11 or older), with the release page and
what to do (.mcpbor file); never on a direct send. It refusesreplyToMessage/forwardMessagewith
mode: "send"or"draft"(withoutskipReview) from such a bridge before doing anything, because an old bridge stops
waiting after 30 s and can report a failure for a message that is still being sent;mode: "window"and every other
call keep working. A program that calls the HTTP API directly can declare itself with the header (README,
Development). - A local security floor in the add-on (
BRIDGE_SECURITY_FLOOR), shipped disarmed (0.0.0): if a future release arms
it, every tool call from an older bridge, or from a client without the header, is refused before anything acts, with
the reason and the release page;tools/listkeeps answering. No remote switch, no setting to bypass it. - Options page, section "Bridge": the bridges that connected since Thunderbird started (version, installation,
profile, last seen, status) and the release page to update one. Kept in memory only.
Changed
- Without
from,replyToMessageandforwardMessageuse the identity Thunderbird's own Reply / Forward picks
(MailUtils.getIdentityForHeader, asComposeMessageinmailCommands.jscalls it) instead of the account's
default identity: the identity the message was addressed to (To / Cc, then Delivered-To), the identity that sent
it for a reply to your own message, and for a catch-all identity the address the message was sent to. Identities
of accounts the MCP may not access are never picked. By @mazixs in #26.
An identity shared by an accessible and a restricted account counts as accessible, whatever the order of the
accounts, asfindIdentityalready did. Fetching the original message for that choice gives up after 20 s: a
compose window or a draft then opens without it, and a direct send returns an error instead of hanging. Encrypted
messages stay withheld from a direct reply or forward while the "read encrypted messages" option is off. saveDraftsaves throughnsIMsgCompose, as Thunderbird's compose window does, and returns the new draft's
messageIdandfolderPath. IfnsIMsgComposecannot be used, it falls back to the previousnsIMsgSendpath.
By @mazixs in #27.forwardMessageno longer requiresto, except withmode: "send"(orskipReview). By @mazixs in #27.- A reply's References header is the original's References plus its Message-ID, as Thunderbird's reply builds it
(it used to be the original's Message-ID only); Thunderbird trims a chain longer than the header limit when it
writes the message, as for its own reply. A reply to a message without Message-ID gets no References. In-Reply-To
is no longer set by the tool: Thunderbird derives it from the last References entry. By @mazixs in #27. mcp-bridge.cjs: areplyToMessageorforwardMessagecall withmode: "send"is a direct send like
skipReview: true, so it waits up to 150 s and gets the same "outcome unknown" error on a timeout. By @mazixs in
#27. On top, from the maintainers: the mode is compared trimmed and lower-cased to decide that (so"SEND", which
the extension refuses, still counts as a send: no version notice, the long wait), without changing what is sent to
the extension; andmode: "draft"waits 150 s too, since Thunderbird can take up to 120 s to save a draft and a
client that retries after 30 s would create two. After that wait the error says the draft may still appear in the
Drafts folder later.- README: a "Quick install" section at the top, in five steps, with the Claude Code command (Windows example included) and a bold reminder that the bridge is not updated with the extension. It also corrects the old advice to replace the bridge's
package.jsontoo: the release ships onlymcp-bridge.cjs, which needs nothing else. - README: a new "Other MCP clients" section with the configuration file, location and format of Claude Desktop, VS Code, Cursor, OpenAI Codex CLI and Gemini CLI, checked against each client's documentation, and when and how to set
COMMONPOST_MCP_CONNECTION_FILE(only if the bridge cannot find the connection file). The bridge is not tied to any client, andmcpServersis not the key every client uses. - RELEASING: the verification step now says that a rebase merge rewrites the commit date, so the ...
v0.11.0
The MCP protocol changes below come from #16 by Konstantin (mazixs), rebased on 0.10.1. Its own removal of
invisible characters was replaced by 0.10.0's handling of untrusted content, which covers the same ground; the
escaping of what is left, the table and dupLocations handling and the disabled-tool wording were added on top.
The search and reading changes come from #17 by Konstantin (mazixs), rebased on top of #16. On top of it, the
maintainers keep encrypted messages withheld in its new outputs, apply the account restriction to its new paths,
treat its new identifiers and the decoded rawSource like the rest of 0.10.0's untrusted-content handling, find
addresses in headers in linear time (two of its regular expressions backtracked quadratically on a long header a
sender can write), and applied the review of #17.
Breaking
-
getFilterConfirmationis removed, which brings the server back to 40 tools, the limit Cursor accepts per MCP
server. CalllistFilterswithconfirmation: trueinstead: it returns the same read-only view (the pending
request and the recent ones, with the limits) and ignoresaccountId; addingconfirmationIdreads one
request, as before (an unknown id is the same error).confirmationIdis ignored withoutconfirmation: true.
Withoutconfirmation,listFiltersis unchanged. A disabled-tools preference that still namesgetFilterConfirmationis harmless. Disabling
listFiltersnow also disables the confirmation view. -
Tool failures are tool results with
isError: trueand{ "error": "..." }instead of JSON-RPC errors, as the
MCP spec asks for errors the model can act on: invalid arguments, a disabled tool, a handler that throws or
returns{ error }(including a message-tool result too large to check for untrusted content, which is still
refused as a whole), an attachment path the bridge refuses, Thunderbird not reachable, a timeout (with a note
that the operation may still complete, except for a direct send, whose error already says that the outcome is
unknown). JSON-RPC errors remain for protocol problems only, with new codes: unknown tool or missing name
-32602, internal errors-32603(the extension used-32000), unparsable input-32700(the bridge used
-32700for every failure). -
Values outside their bounds are rejected with an error that names the bound:
priority0-9 (createTask,
updateTask),percentComplete0-100 (updateTaskclamped 150 to 100 before). Only limits are clamped:
maxResultsoflistEvents/listTasksis an integer from 1 to 500, a larger value becomes 500 and a fraction
is floored, while 0 is an error (it meant the default of 100 before). -
createEvent.statusis an enum (tentative,confirmed,cancelled, in any case); an empty string, which
meant the default, is rejected, so omit the parameter instead.updateEvent.statusstays a free string on
purpose: an empty string there removes the event's status, and any other value is still checked against the
same three values, in any case. -
searchMessagesandgetRecentMessagesreturn a new envelope and compact rows, for every client (#17).
format: "legacy"returns the old envelope and rows: it is deprecated and will be removed in a later release,
keeps the new folder default (passincludeTrash: truefor the old one) and the decodedccList, and cannot be
combined withgroupBy.0.10.x now Result a plain array; { messages, totalMatches, offset, limit, hasMore }only whenoffsetis passedalways { messages, totalMatches, offset, limit, hasMore }, plusincomplete: truewhen the scan stopped at 10,000 matchesDefault rows 50 (max 200) 20 (max 200); format: "legacy"keeps 50Folders every folder, Trash and Junk included Trash and Junk skipped unless includeTrash: trueor an explicitfolderPaththreadId,folderpresent omitted ( threadIdis folder-local;folderPathidentifies the folder)Empty fields, flagged: falsepresent ( "",[],false)omitted previewthe whole stored preview the first 120 characters, then ...subjectof a replywithout Re:, as stored in the databasewith Re:, as Thunderbird displays itccListas stored (may hold MIME encoded-words) decoded -
getMessage/getMessagescut long bodies by default: 20,000 characters forgetMessageand 4,000 per message
forgetMessages(maxBodyChars, up to 200,000). A longer body setsbodyTruncated,nextBodyOffsetand
bodyTotalChars;getMessagereads the rest withbodyOffset. The same cap applies torawSource(#17). -
rawSourceis decoded text instead of a Latin-1 byte string (see Added), and hidden characters are removed from
it and counted, as in a body.rawEncoding: "base64"returns the exact bytes (#17). -
getMessage: thesubjectof a reply keepsRe:as Thunderbird displays it (the database stores it without),
andccListis decoded, also in the result of an encrypted message. The subject of an encrypted message and of
rawSourcestays the wire-level one, as in 0.10.0;displayMessageis unchanged (#17). -
Search parameters are checked like the others (#17):
offsetmust be a whole number from 0,daysBacka whole
number from 1 (0 meant the default of 7, and fractions were floored),bodyOffseta whole number from 0, and
sortOrderascordesc; other values are errors.maxResultsofsearchMessages,getRecentMessagesand
searchContactsis an integer from 1 to 200 andmaxBodyCharsone from 1 to 200,000: a larger value becomes the
maximum and a fraction is floored, while 0 is an error (formaxResultsit meant the default before). -
searchContactsleaves empty fields out of each contact and also matches the organization (#17).
Added
initializereturns short serverinstructions(IDs, untrusted mail content, search, review windows, stale
IMAP folders), identical in the bridge and the extension. The three lines on search (counts, tables, body
paging, company mail, conversations) come with #17.tools/listentries carrytitleand all four annotations (readOnlyHint,destructiveHint,idempotentHint,
openWorldHint) set explicitly, since the spec defaults assume a destructive open-world tool. They err on the
cautious side:sendMail,replyToMessage,forwardMessage,createFilter,updateFilterandapplyFilters
are destructive and open-world (a sent message can't be taken back, and filter rules can forward or reply), and
getMessage/getMessages(saveAttachmentswrites files) anddisplayMessage(a displayed message is marked
read) are not read-only.searchMessages:participant:matches From, To, Cc or Bcc;participant:@example.commatches the domain of each
address exactly, as Gloda'sLIKE '%@domain'does (@example.comno longer matchesexample.community), and
commas list alternatives for companies with several domains. Operators and quoted phrases combine:
participant:@example.com subject:"invoice 42"(#17).searchMessagesthreadOf: { messageId, folderPath }: the whole conversation across folders (Sent included),
oldest first. Headers are read first and then joined by References (union-find), so the result does not depend
on folder order. ARe:message without threading headers joins by subject only the earlier message whose
author (or, for own mail, a recipient) it involves (linkedBy: "subject"), so the same mail sent separately to
several companies and repeated notifications stay apart. It reads at most 10,000 headers (the search limit) and
setsincomplete: truewhen it stops there. Seedocs/thunderbird-internals.md(#17).searchMessagesgroupBy: "sender" | "thread": one row per sender or conversation, withcount,unread, the
first and last date, andlatestId/latestFolderPath, the newest message that is not a draft (#17).format: "table"({ columns, rows }) forsearchMessages,getRecentMessages,searchContacts,listEvents
andlistTasks: fewer tokens on long lists (#17).searchMessagestagaccepts a tag's label (Important) as well as its key ($label1) (#17).searchBodyreports the terms Gloda leaves out (under 3 characters) inwarning, and errors instead of running
an empty full-text query; its description says that only English words are stemmed (#17).getMessage/getMessages:maxBodyCharsandbodyOffsetpage long bodies and raw sources (#17).rawSourcenames its charset inrawCharset: strict UTF-8, else the charset of the top-levelContent-Type,
then those of the parts, else Thunderbird's charset detector. Encodings that cannot decode a whole message are
refused, declared or detected: the "replacement" labels (iso-2022-kr,hz-gb-2312, ...), UTF-16 and
x-user-defined.warningsays when parts declare different charsets (listed inrawMixedCharsets) or when
invalid UTF-8 was replaced with U+FFFD.rawEncoding: "base64"returns the exact bytes instead, for 8bit/binary
parts; its pages are multiples of 4 characters, so each one decodes on its own. Before, 8-bit sources came back
as Latin-1 mojibake (#17).
Changed
- Tool results are compact JSON (no indentation). Hidden characters left in them are written as
\uXXXXescapes: in
what the untrusted-content handling only counts (id,folderPath,filePath,dupLocations, andlatestId/
latestFolderPath, see below) and in the results of the tools it does not clean (folder, account or filter names,
...). The value is the same once parsed, so an id passed back unchanged still finds the same message or folder,
but the character is visible in the text. The bridge passes compact results through unchanged. An older bridge
(0.10.1 or earlier) paired with this extension undoes the escaping: it parses...