protonmail-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.13", "3.14"]
18
+ steps:
19
+ - uses: actions/checkout@v7.0.1
20
+ - uses: astral-sh/setup-uv@v10.2.0
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+ - run: uv sync --locked
24
+ - run: uv run ruff check .
25
+ - run: uv run pytest
26
+ - run: uv build
@@ -0,0 +1,20 @@
1
+ name: Publish
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ pypi:
12
+ runs-on: ubuntu-latest
13
+ environment: pypi
14
+ permissions:
15
+ id-token: write
16
+ steps:
17
+ - uses: actions/checkout@v7.0.1
18
+ - uses: astral-sh/setup-uv@v10.2.0
19
+ - run: uv build
20
+ - uses: pypa/gh-action-pypi-publish@v1.14.2
@@ -0,0 +1,24 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[codz]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ wheels/
9
+
10
+ # Virtual environments
11
+ .venv/
12
+ venv/
13
+
14
+ # Tooling caches
15
+ .pytest_cache/
16
+ .ruff_cache/
17
+ .mypy_cache/
18
+ .coverage
19
+ htmlcov/
20
+
21
+ # Secrets and local config
22
+ .env
23
+ .env.local
24
+ *.pem
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Manoah BERNIER
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,195 @@
1
+ Metadata-Version: 2.5
2
+ Name: protonmail-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for Proton Mail via Proton Bridge (IMAP/SMTP)
5
+ Project-URL: Homepage, https://github.com/mhbxyz/protonmail-mcp
6
+ Project-URL: Repository, https://github.com/mhbxyz/protonmail-mcp
7
+ Project-URL: Issues, https://github.com/mhbxyz/protonmail-mcp/issues
8
+ Author-email: Manoah BERNIER <manoah.bernier@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: email,imap,llm,mcp,proton-bridge,protonmail
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Communications :: Email :: Post-Office :: IMAP
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.13
21
+ Requires-Dist: imapclient>=3
22
+ Requires-Dist: mcp>=2.3
23
+ Description-Content-Type: text/markdown
24
+
25
+ # protonmail-mcp
26
+
27
+ [![CI](https://github.com/mhbxyz/protonmail-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/mhbxyz/protonmail-mcp/actions/workflows/ci.yml)
28
+
29
+ A lightweight [MCP](https://modelcontextprotocol.io) server that gives AI agents
30
+ read access to a Proton Mail mailbox through a local
31
+ [Proton Bridge](https://proton.me/mail/bridge) instance.
32
+
33
+ > **Unofficial.** This project is not affiliated with, endorsed by, or supported by
34
+ > Proton AG. "Proton Mail" and "Proton Bridge" are trademarks of Proton AG.
35
+
36
+ Proton does not provide a public API for reading your mailbox. Bridge is the supported
37
+ way in: it runs locally and exposes your account over IMAP and SMTP on `127.0.0.1`.
38
+ This server wraps that local IMAP endpoint in a small, auditable set of MCP tools.
39
+
40
+ ## Scope
41
+
42
+ The current release is **read-only**: it can list folders, list messages, search, and
43
+ read a message. Mailboxes are opened with IMAP `SELECT ... READONLY`, so nothing is
44
+ ever modified — not even the `\Seen` flag. Write tools are on the roadmap, behind
45
+ mandatory confirmation (see [Security](#security)).
46
+
47
+ ## Tools
48
+
49
+ | Tool | Description |
50
+ |---|---|
51
+ | `list_folders` | List every folder and label, with IMAP flags and whether it is selectable |
52
+ | `list_emails` | Most recent messages in a folder, newest first: `limit`, `unread_only`, `since_days`, `sender`, `subject` |
53
+ | `search_emails` | Full-text search across headers and body in a folder |
54
+ | `read_email` | Read one message by `Message-ID`: decoded text body, attachments, flags, truncation via `max_chars` |
55
+
56
+ Results are structured (Pydantic models). Every message carries its `Message-ID`; use
57
+ that for follow-up reads — IMAP UIDs are not stable across Bridge resynchronisations.
58
+
59
+ ## Requirements
60
+
61
+ - A paid Proton Mail plan (required by Bridge)
62
+ - Proton Bridge installed, running, and signed in
63
+ - Your Bridge credentials: Proton address + the mailbox password shown in the Bridge UI
64
+ - Python 3.13+ (only if you do not use `uv`)
65
+
66
+ ## Install
67
+
68
+ ```bash
69
+ # Run without installing (recommended)
70
+ uvx protonmail-mcp
71
+
72
+ # Or install it
73
+ pipx install protonmail-mcp
74
+ ```
75
+
76
+ ## Configure
77
+
78
+ | Variable | Default | Purpose |
79
+ |---|---|---|
80
+ | `PROTONMAIL_BRIDGE_USERNAME` | — | Your Proton address (required) |
81
+ | `PROTONMAIL_BRIDGE_PASSWORD` | — | Bridge mailbox password (required) |
82
+ | `PROTONMAIL_BRIDGE_HOST` | `127.0.0.1` | Bridge host |
83
+ | `PROTONMAIL_BRIDGE_IMAP_PORT` | `1143` | Bridge IMAP port |
84
+ | `PROTONMAIL_BRIDGE_IMAP_SECURITY` | `starttls` | `starttls` (Bridge 3.x on 1143) or `ssl` (direct TLS) |
85
+ | `PROTONMAIL_BRIDGE_TIMEOUT` | `30` | Socket timeout in seconds |
86
+ | `PROTONMAIL_BRIDGE_VERIFY_TLS` | `false` | Bridge uses a self-signed certificate |
87
+
88
+ ### opencode
89
+
90
+ ```json
91
+ {
92
+ "$schema": "https://opencode.ai/config.json",
93
+ "mcp": {
94
+ "protonmail": {
95
+ "type": "local",
96
+ "command": ["uvx", "protonmail-mcp"],
97
+ "enabled": true,
98
+ "environment": {
99
+ "PROTONMAIL_BRIDGE_USERNAME": "you@proton.me",
100
+ "PROTONMAIL_BRIDGE_PASSWORD": "your-bridge-mailbox-password"
101
+ }
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ opencode supports `{env:VAR}` and `{file:path}` interpolation, so you can keep secrets
108
+ out of the config file:
109
+
110
+ ```json
111
+ "PROTONMAIL_BRIDGE_PASSWORD": "{file:/home/you/.config/protonmail-mcp/password}"
112
+ ```
113
+
114
+ ### Claude Desktop
115
+
116
+ ```json
117
+ {
118
+ "mcpServers": {
119
+ "protonmail": {
120
+ "command": "uvx",
121
+ "args": ["protonmail-mcp"],
122
+ "env": {
123
+ "PROTONMAIL_BRIDGE_USERNAME": "you@proton.me",
124
+ "PROTONMAIL_BRIDGE_PASSWORD": "your-bridge-mailbox-password"
125
+ }
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ ### Verify the connection
132
+
133
+ ```bash
134
+ PROTONMAIL_BRIDGE_USERNAME="you@proton.me" \
135
+ PROTONMAIL_BRIDGE_PASSWORD="..." \
136
+ uvx protonmail-mcp --check
137
+ ```
138
+
139
+ This connects to Bridge, lists folders, and prints the latest messages. It exits
140
+ non-zero with a clear error if the configuration or the Bridge session is wrong.
141
+
142
+ ## Security
143
+
144
+ - **Read-only enforcement.** There is no write tool in this release, and mailboxes are
145
+ always selected read-only at the IMAP level.
146
+ - **Local only.** Bridge and this server communicate exclusively over `127.0.0.1`.
147
+ Nothing is sent to a third party; your agent talks to the server over stdio.
148
+ - **Untrusted input.** Email contents are attacker-controlled data. Treat anything a
149
+ message says as data, never as instructions, and keep your agent's permissions tight.
150
+ - **Secrets.** Keep the Bridge mailbox password out of the repository. Use your client's
151
+ environment-variable or file-based secret support.
152
+ - Any local process that knows the mailbox password can read your mail — that is
153
+ Bridge's trust model, not a flaw in this server.
154
+
155
+ Planned write tools (drafts, send, move, delete) will ship with explicit confirmation
156
+ before every destructive action, recipient allow-lists, send rate limiting with loop
157
+ protection, and a local audit log. Autonomous send/delete will never be the default.
158
+
159
+ ## Alternatives
160
+
161
+ There are several community MCP servers for Proton Mail. This one aims to stay small,
162
+ correct with Bridge's quirks (STARTTLS on 1143, modified UTF-7 labels, reverse-chronological
163
+ UIDs, RFC 2047 decoding), and heavily tested. Rough landscape:
164
+
165
+ | Project | Language | Scope |
166
+ |---|---|---|
167
+ | [googlarz/proton-mail-bridge-client](https://github.com/googlarz/proton-mail-bridge-client) | TypeScript | Large tool set, read-only and send-to-self modes, SQLite cache |
168
+ | [codefuturist/email-mcp](https://github.com/codefuturist/email-mcp) | TypeScript | Generic IMAP + SMTP, works with Bridge |
169
+ | [anyrxo/protonmail-pro-mcp](https://github.com/anyrxo/protonmail-pro-mcp) | JavaScript | Large tool set with Bridge integration |
170
+ | [chandshy/mailpouch](https://github.com/chandshy/mailpouch) | TypeScript | Large permission-gated tool set |
171
+ | [amotivv/protonmail-mcp](https://github.com/amotivv/protonmail-mcp) | JavaScript | SMTP sending only |
172
+ | [miketigerblue/proton-bridge-mcp](https://github.com/miketigerblue/proton-bridge-mcp) | Python | Loopback IMAP/SMTP via Bridge |
173
+
174
+ ## Development
175
+
176
+ ```bash
177
+ uv sync
178
+ uv run pytest
179
+ uv run ruff check .
180
+ uv build
181
+ ```
182
+
183
+ Tests run entirely against a fake IMAP server and the MCP SDK's in-memory transport;
184
+ no Bridge or credentials are needed.
185
+
186
+ ## Releasing
187
+
188
+ Publishing is automated with GitHub Actions and PyPI Trusted Publishing. Create a
189
+ GitHub release tagged `vX.Y.Z`; the `publish` workflow builds the sdist/wheel and
190
+ uploads them to PyPI using the `pypi` environment (configure the trusted publisher on
191
+ PyPI for owner `mhbxyz`, repository `protonmail-mcp`, workflow `publish.yml`).
192
+
193
+ ## License
194
+
195
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,171 @@
1
+ # protonmail-mcp
2
+
3
+ [![CI](https://github.com/mhbxyz/protonmail-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/mhbxyz/protonmail-mcp/actions/workflows/ci.yml)
4
+
5
+ A lightweight [MCP](https://modelcontextprotocol.io) server that gives AI agents
6
+ read access to a Proton Mail mailbox through a local
7
+ [Proton Bridge](https://proton.me/mail/bridge) instance.
8
+
9
+ > **Unofficial.** This project is not affiliated with, endorsed by, or supported by
10
+ > Proton AG. "Proton Mail" and "Proton Bridge" are trademarks of Proton AG.
11
+
12
+ Proton does not provide a public API for reading your mailbox. Bridge is the supported
13
+ way in: it runs locally and exposes your account over IMAP and SMTP on `127.0.0.1`.
14
+ This server wraps that local IMAP endpoint in a small, auditable set of MCP tools.
15
+
16
+ ## Scope
17
+
18
+ The current release is **read-only**: it can list folders, list messages, search, and
19
+ read a message. Mailboxes are opened with IMAP `SELECT ... READONLY`, so nothing is
20
+ ever modified — not even the `\Seen` flag. Write tools are on the roadmap, behind
21
+ mandatory confirmation (see [Security](#security)).
22
+
23
+ ## Tools
24
+
25
+ | Tool | Description |
26
+ |---|---|
27
+ | `list_folders` | List every folder and label, with IMAP flags and whether it is selectable |
28
+ | `list_emails` | Most recent messages in a folder, newest first: `limit`, `unread_only`, `since_days`, `sender`, `subject` |
29
+ | `search_emails` | Full-text search across headers and body in a folder |
30
+ | `read_email` | Read one message by `Message-ID`: decoded text body, attachments, flags, truncation via `max_chars` |
31
+
32
+ Results are structured (Pydantic models). Every message carries its `Message-ID`; use
33
+ that for follow-up reads — IMAP UIDs are not stable across Bridge resynchronisations.
34
+
35
+ ## Requirements
36
+
37
+ - A paid Proton Mail plan (required by Bridge)
38
+ - Proton Bridge installed, running, and signed in
39
+ - Your Bridge credentials: Proton address + the mailbox password shown in the Bridge UI
40
+ - Python 3.13+ (only if you do not use `uv`)
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ # Run without installing (recommended)
46
+ uvx protonmail-mcp
47
+
48
+ # Or install it
49
+ pipx install protonmail-mcp
50
+ ```
51
+
52
+ ## Configure
53
+
54
+ | Variable | Default | Purpose |
55
+ |---|---|---|
56
+ | `PROTONMAIL_BRIDGE_USERNAME` | — | Your Proton address (required) |
57
+ | `PROTONMAIL_BRIDGE_PASSWORD` | — | Bridge mailbox password (required) |
58
+ | `PROTONMAIL_BRIDGE_HOST` | `127.0.0.1` | Bridge host |
59
+ | `PROTONMAIL_BRIDGE_IMAP_PORT` | `1143` | Bridge IMAP port |
60
+ | `PROTONMAIL_BRIDGE_IMAP_SECURITY` | `starttls` | `starttls` (Bridge 3.x on 1143) or `ssl` (direct TLS) |
61
+ | `PROTONMAIL_BRIDGE_TIMEOUT` | `30` | Socket timeout in seconds |
62
+ | `PROTONMAIL_BRIDGE_VERIFY_TLS` | `false` | Bridge uses a self-signed certificate |
63
+
64
+ ### opencode
65
+
66
+ ```json
67
+ {
68
+ "$schema": "https://opencode.ai/config.json",
69
+ "mcp": {
70
+ "protonmail": {
71
+ "type": "local",
72
+ "command": ["uvx", "protonmail-mcp"],
73
+ "enabled": true,
74
+ "environment": {
75
+ "PROTONMAIL_BRIDGE_USERNAME": "you@proton.me",
76
+ "PROTONMAIL_BRIDGE_PASSWORD": "your-bridge-mailbox-password"
77
+ }
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ opencode supports `{env:VAR}` and `{file:path}` interpolation, so you can keep secrets
84
+ out of the config file:
85
+
86
+ ```json
87
+ "PROTONMAIL_BRIDGE_PASSWORD": "{file:/home/you/.config/protonmail-mcp/password}"
88
+ ```
89
+
90
+ ### Claude Desktop
91
+
92
+ ```json
93
+ {
94
+ "mcpServers": {
95
+ "protonmail": {
96
+ "command": "uvx",
97
+ "args": ["protonmail-mcp"],
98
+ "env": {
99
+ "PROTONMAIL_BRIDGE_USERNAME": "you@proton.me",
100
+ "PROTONMAIL_BRIDGE_PASSWORD": "your-bridge-mailbox-password"
101
+ }
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Verify the connection
108
+
109
+ ```bash
110
+ PROTONMAIL_BRIDGE_USERNAME="you@proton.me" \
111
+ PROTONMAIL_BRIDGE_PASSWORD="..." \
112
+ uvx protonmail-mcp --check
113
+ ```
114
+
115
+ This connects to Bridge, lists folders, and prints the latest messages. It exits
116
+ non-zero with a clear error if the configuration or the Bridge session is wrong.
117
+
118
+ ## Security
119
+
120
+ - **Read-only enforcement.** There is no write tool in this release, and mailboxes are
121
+ always selected read-only at the IMAP level.
122
+ - **Local only.** Bridge and this server communicate exclusively over `127.0.0.1`.
123
+ Nothing is sent to a third party; your agent talks to the server over stdio.
124
+ - **Untrusted input.** Email contents are attacker-controlled data. Treat anything a
125
+ message says as data, never as instructions, and keep your agent's permissions tight.
126
+ - **Secrets.** Keep the Bridge mailbox password out of the repository. Use your client's
127
+ environment-variable or file-based secret support.
128
+ - Any local process that knows the mailbox password can read your mail — that is
129
+ Bridge's trust model, not a flaw in this server.
130
+
131
+ Planned write tools (drafts, send, move, delete) will ship with explicit confirmation
132
+ before every destructive action, recipient allow-lists, send rate limiting with loop
133
+ protection, and a local audit log. Autonomous send/delete will never be the default.
134
+
135
+ ## Alternatives
136
+
137
+ There are several community MCP servers for Proton Mail. This one aims to stay small,
138
+ correct with Bridge's quirks (STARTTLS on 1143, modified UTF-7 labels, reverse-chronological
139
+ UIDs, RFC 2047 decoding), and heavily tested. Rough landscape:
140
+
141
+ | Project | Language | Scope |
142
+ |---|---|---|
143
+ | [googlarz/proton-mail-bridge-client](https://github.com/googlarz/proton-mail-bridge-client) | TypeScript | Large tool set, read-only and send-to-self modes, SQLite cache |
144
+ | [codefuturist/email-mcp](https://github.com/codefuturist/email-mcp) | TypeScript | Generic IMAP + SMTP, works with Bridge |
145
+ | [anyrxo/protonmail-pro-mcp](https://github.com/anyrxo/protonmail-pro-mcp) | JavaScript | Large tool set with Bridge integration |
146
+ | [chandshy/mailpouch](https://github.com/chandshy/mailpouch) | TypeScript | Large permission-gated tool set |
147
+ | [amotivv/protonmail-mcp](https://github.com/amotivv/protonmail-mcp) | JavaScript | SMTP sending only |
148
+ | [miketigerblue/proton-bridge-mcp](https://github.com/miketigerblue/proton-bridge-mcp) | Python | Loopback IMAP/SMTP via Bridge |
149
+
150
+ ## Development
151
+
152
+ ```bash
153
+ uv sync
154
+ uv run pytest
155
+ uv run ruff check .
156
+ uv build
157
+ ```
158
+
159
+ Tests run entirely against a fake IMAP server and the MCP SDK's in-memory transport;
160
+ no Bridge or credentials are needed.
161
+
162
+ ## Releasing
163
+
164
+ Publishing is automated with GitHub Actions and PyPI Trusted Publishing. Create a
165
+ GitHub release tagged `vX.Y.Z`; the `publish` workflow builds the sdist/wheel and
166
+ uploads them to PyPI using the `pypi` environment (configure the trusted publisher on
167
+ PyPI for owner `mhbxyz`, repository `protonmail-mcp`, workflow `publish.yml`).
168
+
169
+ ## License
170
+
171
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,10 @@
1
+ # Copy to .env for local use; never commit it.
2
+ PROTONMAIL_BRIDGE_USERNAME=you@proton.me
3
+ PROTONMAIL_BRIDGE_PASSWORD=the-password-shown-in-proton-bridge
4
+
5
+ # Optional
6
+ # PROTONMAIL_BRIDGE_HOST=127.0.0.1
7
+ # PROTONMAIL_BRIDGE_IMAP_PORT=1143
8
+ # PROTONMAIL_BRIDGE_IMAP_SECURITY=starttls
9
+ # PROTONMAIL_BRIDGE_TIMEOUT=30
10
+ # PROTONMAIL_BRIDGE_VERIFY_TLS=false
@@ -0,0 +1,56 @@
1
+ [project]
2
+ name = "protonmail-mcp"
3
+ version = "0.1.0"
4
+ description = "MCP server for Proton Mail via Proton Bridge (IMAP/SMTP)"
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ license = "MIT"
8
+ authors = [
9
+ { name = "Manoah BERNIER", email = "manoah.bernier@gmail.com" },
10
+ ]
11
+ keywords = ["mcp", "protonmail", "imap", "email", "proton-bridge", "llm"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Intended Audience :: Developers",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: OS Independent",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Topic :: Communications :: Email :: Post-Office :: IMAP",
20
+ "Typing :: Typed",
21
+ ]
22
+ dependencies = [
23
+ "imapclient>=3",
24
+ "mcp>=2.3",
25
+ ]
26
+
27
+ [project.scripts]
28
+ protonmail-mcp = "protonmail_mcp.__main__:main"
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/mhbxyz/protonmail-mcp"
32
+ Repository = "https://github.com/mhbxyz/protonmail-mcp"
33
+ Issues = "https://github.com/mhbxyz/protonmail-mcp/issues"
34
+
35
+ [dependency-groups]
36
+ dev = [
37
+ "pytest>=8.4",
38
+ "ruff>=0.12",
39
+ ]
40
+
41
+ [build-system]
42
+ requires = ["hatchling"]
43
+ build-backend = "hatchling.build"
44
+
45
+ [tool.hatch.build.targets.wheel]
46
+ packages = ["src/protonmail_mcp"]
47
+
48
+ [tool.ruff]
49
+ line-length = 100
50
+ target-version = "py313"
51
+ lint.select = ["E", "F", "I", "UP", "B"]
52
+ lint.ignore = ["E501"]
53
+
54
+ [tool.pytest.ini_options]
55
+ testpaths = ["tests"]
56
+ addopts = "-q"
@@ -0,0 +1,3 @@
1
+ """Read-only MCP server for Proton Mail via Proton Bridge."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import sys
5
+ from collections.abc import Sequence
6
+
7
+ from .bridge import MailboxError
8
+ from .config import ConfigError
9
+ from .server import get_client, server
10
+
11
+
12
+ def main(argv: Sequence[str] | None = None) -> None:
13
+ parser = argparse.ArgumentParser(
14
+ prog="protonmail-mcp",
15
+ description="Read-only MCP server for Proton Mail via Proton Bridge (stdio).",
16
+ )
17
+ parser.add_argument(
18
+ "--check",
19
+ action="store_true",
20
+ help="Test the Proton Bridge connection, print a short diagnostic, and exit.",
21
+ )
22
+ args = parser.parse_args(argv)
23
+ if args.check:
24
+ raise SystemExit(run_check())
25
+ server.run(transport="stdio")
26
+
27
+
28
+ def run_check() -> int:
29
+ client = None
30
+ try:
31
+ client = get_client()
32
+ folders = client.list_folders()
33
+ recent = client.list_emails(limit=3)
34
+ except (ConfigError, MailboxError) as exc:
35
+ print(f"ERROR: {exc}", file=sys.stderr)
36
+ return 1
37
+ finally:
38
+ if client is not None:
39
+ client.close()
40
+
41
+ print(f"Bridge connection OK: {client.config.username} -> {client.config.endpoint}")
42
+ print(f"Folders ({len(folders)}):")
43
+ for folder in folders:
44
+ marker = "" if folder.selectable else " [not selectable]"
45
+ print(f" - {folder.name}{marker}")
46
+ print(f"Latest INBOX messages ({len(recent)}):")
47
+ for email in recent:
48
+ state = "unread" if email.unread else "read"
49
+ print(f" - [{state}] {email.received or email.date} | {email.sender} | {email.subject}")
50
+ return 0
51
+
52
+
53
+ if __name__ == "__main__":
54
+ main()