feat: capability-scope permission model + install-docs restructure - #200
Closed
lucagattoni wants to merge 6 commits into
Closed
feat: capability-scope permission model + install-docs restructure#200lucagattoni wants to merge 6 commits into
lucagattoni wants to merge 6 commits into
Conversation
Gate every MCP tool behind a capability scope (read, draft, organize, delete, send, manage, full) configured via `permissions` in the TOML or MCP_EMAIL_SERVER_PERMISSIONS (env override held in a PrivateAttr so store() never persists a temporary grant). The server is now read-only by default — a breaking change; `permissions = ["full"]` restores the old behavior. Enforcement is two-layer: visible_if predicates hide out-of-scope tools from list_tools(), and every scoped tool re-checks at call time. Closes two mutation leaks the tool list alone wouldn't catch: get_emails_content's mark_as_read parameter now requires the organize scope, and with only the draft scope save_to_mailbox may target only drafts-type folders (organize lifts the restriction). Also relocate the README's installation/configuration detail into a dedicated docs/installation.md (added to the mkdocs nav) with the scope documentation, leaving the README a quick start plus pointers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GHu48yxodNvMb8vsuU5NSu
- Lead installation with uv (uv tool install / uvx) instead of pip; keep pip as an alternative. - Add a Claude Code (CLI) section using `claude mcp add ... --scope user -- mcp-email-server stdio`, with uvx and env-var variants. - Add an Updating section covering uv/uvx/pip/Docker/Claude Code. - README: add the Claude Code one-liner and point to the fuller guide. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GHu48yxodNvMb8vsuU5NSu
The permission-scopes section listed the scopes and the two mechanisms but didn't show how to actually apply or change them in a real setup. Add a "Setting and changing scopes" subsection: config-file vs env-var (with precedence), concrete per-client instructions (Claude Code CLI add/remove-re-add, JSON mcpServers env block, Docker), the empty-string reset, and an "after you change scopes" note (restart the client; verify via which tools appear). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GHu48yxodNvMb8vsuU5NSu
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013pd8meRq4jSiqaLq715nSD
…oupling The permission model predated Wh1isper#194 (save_to_mailbox decoupled from SMTP). save_to_mailbox is now gated on the draft scope alone — a pure IMAP APPEND that stays available without a send-capable account. Update the test that asserted the old SMTP-gated behavior. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013pd8meRq4jSiqaLq715nSD
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013pd8meRq4jSiqaLq715nSD
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
lucagattoni
marked this pull request as ready for review
July 13, 2026 14:26
Closed
4 tasks
lucagattoni
marked this pull request as draft
July 13, 2026 14:28
lucagattoni
marked this pull request as ready for review
July 13, 2026 14:29
5 tasks
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this delivers
A capability-scope permission model (read-only by default) plus a restructured installation guide, rebased cleanly onto current
main(post-#199).1. Capability-scope permission model (read-only default)
Every MCP tool is gated behind a capability scope, set via
permissionsin the config orMCP_EMAIL_SERVER_PERMISSIONS. A fresh install is read-only — it can list/read mail but cannot modify, delete, or send until scopes are granted. Out-of-scope tools are hidden from the tool list and rejected at call time.readdraftsave_to_mailbox(drafts-type folders unlessorganizealso granted)organizemove_emails,archive_emails,mark_emails_as_readdeletedelete_emailssendsend_emailmanageadd_email_accountfullUpgrading from a pre-scopes version? Set
permissions = ["full"]to restore prior behavior.2. Docs restructure →
docs/installation.mdREADME's long config reference moved into a dedicated Installation & Configuration guide (uv/pip/Docker/Claude Code install, Updating, env vars, credential storage, HTTP transport security, attachment downloads, allowlists). README keeps a quickstart + the new Permissions section + a pointer.
3. Chore
Ignore
.DS_Storeeverywhere.Reconciliation notes (why this isn't a plain cherry-pick)
This work was authored before #194/#199 landed, so integrating onto current
mainrequired resolving real semantic conflicts — surfaced honestly here:save_to_mailboxis now gated on thedraftscope only, not on send-capability. The permission model originally required a send-capable (SMTP) account, but feat: allow save_to_mailbox without SMTP configuration #194 decoupledsave_to_mailboxfrom SMTP (pure IMAP APPEND). Keeping the old gate would have re-hidden it in IMAP-only setups. Test and docs updated to match (test: reconcile save_to_mailbox visibility with #194).auto/keyring/plaintextsection, the env-override persistence note, and the full Known limitations subsection (Windows perms, backend-trust, non-transactional writes) were carried intodocs/installation.mdrather than dropped.config.pymerge keeps feat: credential security — owner-only config perms + OS keyring storage (combines #195 + #196) #199's_loaded_keyring_referencesalongside the new_permissions_override.Test plan
uv run pytest -q— 558 passeduv run ruff check/ruff format --check— cleanprettier --check README.md docs/installation.md— cleanOpened as draft — the reconciliation decisions above (esp.
save_to_mailboxgating) warrant a review before marking ready.🤖 Generated with Claude Code
https://claude.ai/code/session_013pd8meRq4jSiqaLq715nSD