agentic-mail-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.
Files changed (212) hide show
  1. agentic_mail_mcp-0.1.0/.env.example +39 -0
  2. agentic_mail_mcp-0.1.0/.gitignore +28 -0
  3. agentic_mail_mcp-0.1.0/CHANGELOG.md +138 -0
  4. agentic_mail_mcp-0.1.0/LICENSE +21 -0
  5. agentic_mail_mcp-0.1.0/PKG-INFO +385 -0
  6. agentic_mail_mcp-0.1.0/README.md +334 -0
  7. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/Composition.py +262 -0
  8. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/DependencyContainer.py +78 -0
  9. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/Lifespan.py +31 -0
  10. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/Logging.py +73 -0
  11. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/Settings.py +127 -0
  12. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/__init__.py +6 -0
  13. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/cli.py +96 -0
  14. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Bootstrap/wiring.py +114 -0
  15. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Audit/__init__.py +0 -0
  16. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Audit/audit_log.py +26 -0
  17. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Audit/correlation.py +25 -0
  18. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/Events/__init__.py +73 -0
  19. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/Exceptions/__init__.py +26 -0
  20. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/Repository/__init__.py +0 -0
  21. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/Specifications/__init__.py +56 -0
  22. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/ValueObjects/__init__.py +0 -0
  23. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/ValueObjects/base.py +28 -0
  24. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/ValueObjects/uuid_id.py +26 -0
  25. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Domain/__init__.py +0 -0
  26. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Clock/__init__.py +33 -0
  27. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/IdGenerator/__init__.py +17 -0
  28. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/LLM/__init__.py +0 -0
  29. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Messaging/__init__.py +0 -0
  30. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Persistence/Migrations/__init__.py +0 -0
  31. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Persistence/__init__.py +0 -0
  32. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Persistence/audit_models.py +22 -0
  33. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Persistence/database.py +81 -0
  34. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Persistence/migrations_runner.py +24 -0
  35. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/Persistence/sqlite_audit_repository.py +49 -0
  36. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Infrastructure/__init__.py +0 -0
  37. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Railguards/__init__.py +0 -0
  38. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Railguards/config.py +68 -0
  39. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/Railguards/validator.py +103 -0
  40. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Common/__init__.py +0 -0
  41. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/Commands/__init__.py +0 -0
  42. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/Commands/commands.py +86 -0
  43. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/DTO/__init__.py +0 -0
  44. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/DTO/dtos.py +143 -0
  45. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/Handlers/__init__.py +0 -0
  46. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/Handlers/audit_log_handler.py +62 -0
  47. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/Queries/__init__.py +0 -0
  48. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/Queries/queries.py +82 -0
  49. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/__init__.py +0 -0
  50. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/add_label.py +44 -0
  51. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/archive_email.py +47 -0
  52. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/delete_email.py +50 -0
  53. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/drafts.py +42 -0
  54. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/forward_email.py +49 -0
  55. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/get_email.py +37 -0
  56. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/get_thread.py +19 -0
  57. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/list_labels.py +18 -0
  58. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/list_unread.py +18 -0
  59. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/message_builder.py +43 -0
  60. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/UseCases/search_emails.py +89 -0
  61. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Application/__init__.py +0 -0
  62. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Entities/__init__.py +3 -0
  63. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Entities/attachment.py +30 -0
  64. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Entities/email.py +106 -0
  65. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Entities/label.py +41 -0
  66. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Entities/thread.py +78 -0
  67. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Events/__init__.py +53 -0
  68. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Gateway/__init__.py +29 -0
  69. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Gateway/gmail_gateway.py +143 -0
  70. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Mapper/__init__.py +4 -0
  71. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Mapper/email_mapper.py +58 -0
  72. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Mapper/thread_mapper.py +22 -0
  73. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Repository/__init__.py +4 -0
  74. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Repository/email_repository.py +23 -0
  75. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/Repository/thread_repository.py +17 -0
  76. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/ValueObjects/__init__.py +13 -0
  77. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/ValueObjects/email_address.py +36 -0
  78. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/ValueObjects/gmail_message_id.py +13 -0
  79. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/ValueObjects/gmail_query.py +57 -0
  80. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/ValueObjects/history_id.py +13 -0
  81. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/ValueObjects/thread_id.py +13 -0
  82. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Domain/__init__.py +0 -0
  83. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/__init__.py +0 -0
  84. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/gmail_api_gateway.py +214 -0
  85. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/gmail_history_synchronizer.py +56 -0
  86. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/gmail_watcher.py +39 -0
  87. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/lazy_gateway.py +114 -0
  88. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/message_parser.py +100 -0
  89. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/oauth_provider.py +125 -0
  90. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/rate_limiter.py +36 -0
  91. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Google/retry.py +41 -0
  92. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/MCP/__init__.py +0 -0
  93. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/PostgreSQL/__init__.py +0 -0
  94. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/PostgreSQL/postgres_repositories.py +24 -0
  95. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/Mappers/__init__.py +0 -0
  96. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/Mappers/orm_mappers.py +145 -0
  97. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/Models/__init__.py +0 -0
  98. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/Models/models.py +64 -0
  99. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/Repositories/__init__.py +0 -0
  100. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/Repositories/sqlite_email_repository.py +80 -0
  101. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/Repositories/sqlite_thread_repository.py +44 -0
  102. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/SqlAlchemy/__init__.py +0 -0
  103. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/__init__.py +0 -0
  104. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/Persistence/cached_email_repository.py +130 -0
  105. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/Infrastructure/__init__.py +0 -0
  106. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Gmail/__init__.py +0 -0
  107. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/DTO/__init__.py +0 -0
  108. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/DTO/dtos.py +80 -0
  109. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/UseCases/__init__.py +0 -0
  110. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/UseCases/classify_email.py +81 -0
  111. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/UseCases/digest.py +114 -0
  112. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/UseCases/extract_action_items.py +67 -0
  113. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/UseCases/suggest_reply.py +64 -0
  114. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/UseCases/summarize_email.py +63 -0
  115. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Application/__init__.py +0 -0
  116. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Entities/__init__.py +5 -0
  117. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Entities/classification.py +32 -0
  118. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Entities/suggestion.py +23 -0
  119. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Entities/summary.py +18 -0
  120. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Gateway/__init__.py +3 -0
  121. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Gateway/llm_gateway.py +25 -0
  122. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Repository/__init__.py +0 -0
  123. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/Repository/repositories.py +22 -0
  124. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/ValueObjects/__init__.py +4 -0
  125. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/ValueObjects/model_config.py +20 -0
  126. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/ValueObjects/prompt_template.py +27 -0
  127. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Domain/__init__.py +0 -0
  128. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Infrastructure/InMemory/__init__.py +0 -0
  129. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Infrastructure/InMemory/repositories.py +36 -0
  130. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Infrastructure/LlamaCpp/__init__.py +0 -0
  131. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Infrastructure/LlamaCpp/llama_cpp_gateway.py +128 -0
  132. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/Infrastructure/__init__.py +0 -0
  133. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Intelligence/__init__.py +0 -0
  134. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Prompts.py +128 -0
  135. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Resources.py +76 -0
  136. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Server.py +149 -0
  137. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/ToolRegistry.py +132 -0
  138. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/__init__.py +0 -0
  139. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/arguments.py +50 -0
  140. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/builder.py +30 -0
  141. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/intelligence_tools.py +162 -0
  142. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/read_tools.py +152 -0
  143. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/search_tools.py +42 -0
  144. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/use_cases.py +79 -0
  145. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/Tools/write_tools.py +166 -0
  146. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/__init__.py +0 -0
  147. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/errors.py +45 -0
  148. agentic_mail_mcp-0.1.0/agentic_mail_mcp/MCP/serialization.py +30 -0
  149. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Application/UseCases/__init__.py +0 -0
  150. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Application/UseCases/notify_important_email.py +45 -0
  151. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Application/UseCases/publish_inbox_event.py +51 -0
  152. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Application/__init__.py +0 -0
  153. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Domain/Events/__init__.py +9 -0
  154. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Domain/Events/digest_ready.py +18 -0
  155. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Domain/Events/important_email_detected.py +18 -0
  156. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Domain/Events/inbox_changed.py +11 -0
  157. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Domain/Gateway/__init__.py +3 -0
  158. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Domain/Gateway/notification_gateway.py +6 -0
  159. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Domain/__init__.py +0 -0
  160. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Infrastructure/RabbitMQ/__init__.py +0 -0
  161. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Infrastructure/Redis/__init__.py +0 -0
  162. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Infrastructure/Redis/redis_notification_gateway.py +42 -0
  163. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Infrastructure/Webhook/__init__.py +0 -0
  164. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Infrastructure/Webhook/webhook_notification_gateway.py +49 -0
  165. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/Infrastructure/__init__.py +0 -0
  166. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Notification/__init__.py +0 -0
  167. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Application/UseCases/__init__.py +0 -0
  168. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Application/UseCases/dtos.py +29 -0
  169. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Application/UseCases/index_email.py +61 -0
  170. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Application/UseCases/rebuild_index.py +24 -0
  171. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Application/UseCases/semantic_search.py +26 -0
  172. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Application/__init__.py +0 -0
  173. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Domain/Entities/__init__.py +3 -0
  174. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Domain/Entities/search_document.py +48 -0
  175. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Domain/Gateway/__init__.py +3 -0
  176. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Domain/Gateway/embedding_gateway.py +9 -0
  177. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Domain/Repository/__init__.py +3 -0
  178. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Domain/Repository/vector_search_repository.py +31 -0
  179. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Domain/__init__.py +0 -0
  180. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Infrastructure/BGE/__init__.py +0 -0
  181. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Infrastructure/BGE/bge_embedding_gateway.py +47 -0
  182. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Infrastructure/PgVector/__init__.py +0 -0
  183. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Infrastructure/PgVector/pgvector_repository.py +100 -0
  184. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Infrastructure/SqliteVec/__init__.py +0 -0
  185. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Infrastructure/SqliteVec/sqlite_vec_repository.py +103 -0
  186. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/Infrastructure/__init__.py +0 -0
  187. agentic_mail_mcp-0.1.0/agentic_mail_mcp/Search/__init__.py +0 -0
  188. agentic_mail_mcp-0.1.0/agentic_mail_mcp/__init__.py +0 -0
  189. agentic_mail_mcp-0.1.0/alembic.ini +40 -0
  190. agentic_mail_mcp-0.1.0/migrations/env.py +58 -0
  191. agentic_mail_mcp-0.1.0/migrations/script.py.mako +26 -0
  192. agentic_mail_mcp-0.1.0/migrations/versions/0001_initial_schema.py +82 -0
  193. agentic_mail_mcp-0.1.0/migrations/versions/0002_audit_log.py +39 -0
  194. agentic_mail_mcp-0.1.0/pyproject.toml +137 -0
  195. agentic_mail_mcp-0.1.0/specs/docs/adr/0001-shared-primitives.md +21 -0
  196. agentic_mail_mcp-0.1.0/specs/docs/adr/0002-ddd-vertical-slicing.md +13 -0
  197. agentic_mail_mcp-0.1.0/specs/docs/adr/0003-persistence-strategy.md +13 -0
  198. agentic_mail_mcp-0.1.0/specs/docs/adr/0004-railguards-write-safety.md +23 -0
  199. agentic_mail_mcp-0.1.0/specs/docs/adr/0005-mcp-stdio-transport.md +13 -0
  200. agentic_mail_mcp-0.1.0/specs/docs/adr/0006-caller-first-intelligence.md +19 -0
  201. agentic_mail_mcp-0.1.0/specs/docs/adr/0007-persistence-read-through-cache.md +20 -0
  202. agentic_mail_mcp-0.1.0/specs/docs/adr/0008-bring-your-own-google-app.md +19 -0
  203. agentic_mail_mcp-0.1.0/specs/docs/api.md +222 -0
  204. agentic_mail_mcp-0.1.0/specs/docs/architechture.md +240 -0
  205. agentic_mail_mcp-0.1.0/specs/docs/configuration.md +272 -0
  206. agentic_mail_mcp-0.1.0/specs/docs/data-model.md +94 -0
  207. agentic_mail_mcp-0.1.0/specs/docs/domain-model.md +404 -0
  208. agentic_mail_mcp-0.1.0/specs/docs/events.md +169 -0
  209. agentic_mail_mcp-0.1.0/specs/docs/implementation_plan.md +607 -0
  210. agentic_mail_mcp-0.1.0/specs/docs/project.md +97 -0
  211. agentic_mail_mcp-0.1.0/specs/docs/project_brainstorming.md +18 -0
  212. agentic_mail_mcp-0.1.0/specs/docs/project_structure.md +254 -0
@@ -0,0 +1,39 @@
1
+ # Bring your own Google app. Easiest: point at the credentials.json you
2
+ # downloaded from Google Cloud. (Or set the client id/secret below instead.)
3
+ AGENTIC_MAIL_MCP_GMAIL_CLIENT_SECRETS_FILE=
4
+ AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
5
+ AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_SECRET=your-client-secret
6
+ AGENTIC_MAIL_MCP_GMAIL_SCOPES=["https://www.googleapis.com/auth/gmail.modify"]
7
+ AGENTIC_MAIL_MCP_GMAIL_TOKEN_STORAGE_PATH=token.json
8
+ AGENTIC_MAIL_MCP_GMAIL_TOKEN_ENCRYPTION_KEY=your-encryption-key
9
+ AGENTIC_MAIL_MCP_DATABASE_URL=sqlite:///./agentic_mail_mcp.db
10
+ AGENTIC_MAIL_MCP_DATABASE_DRIVER=sqlite
11
+ # Read-through email cache TTL (metadata only; bodies are never persisted).
12
+ AGENTIC_MAIL_MCP_DATABASE_CACHE_TTL_SECONDS=900
13
+ AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL=read_only
14
+ AGENTIC_MAIL_MCP_RAILGUARDS_ALLOWED_RECIPIENTS=[]
15
+ AGENTIC_MAIL_MCP_RAILGUARDS_BLOCKED_ACTIONS=[]
16
+ AGENTIC_MAIL_MCP_RAILGUARDS_RATE_LIMITS={}
17
+ AGENTIC_MAIL_MCP_RAILGUARDS_ARCHIVE_FIRST_POLICY=false
18
+ AGENTIC_MAIL_MCP_MCP_SERVER_NAME=Agentic-Mail-MCP
19
+ AGENTIC_MAIL_MCP_MCP_TRANSPORT=stdio
20
+ AGENTIC_MAIL_MCP_MCP_HOST=127.0.0.1
21
+ AGENTIC_MAIL_MCP_MCP_PORT=8080
22
+ AGENTIC_MAIL_MCP_LLM_PROVIDER=openai
23
+ AGENTIC_MAIL_MCP_LLM_MODEL=gpt-4
24
+ # LLM is OPTIONAL. The calling agent is itself an LLM, so per-email reasoning is
25
+ # exposed as MCP prompts by default. An LLM key only enables the digest tools
26
+ # (map-reduce over many emails). Leave empty to run without one.
27
+ AGENTIC_MAIL_MCP_LLM_API_KEY=
28
+ AGENTIC_MAIL_MCP_LLM_BASE_URL=
29
+ AGENTIC_MAIL_MCP_LLM_MODEL_PATH=
30
+ # Set true to ALSO expose per-email summarize/classify/reply/action-items as
31
+ # server-side tools (adds latency + needs a configured LLM). Default: caller-first.
32
+ AGENTIC_MAIL_MCP_LLM_INTERNAL_TOOLS=false
33
+ AGENTIC_MAIL_MCP_SEARCH_BACKEND=sqlite_vss
34
+ AGENTIC_MAIL_MCP_SEARCH_EMBEDDING_MODEL=BAAI/bge-small-en-v1.5
35
+ AGENTIC_MAIL_MCP_SEARCH_EMBEDDING_DIMENSION=384
36
+ AGENTIC_MAIL_MCP_NOTIFICATIONS_WEBHOOK_URL=
37
+ AGENTIC_MAIL_MCP_NOTIFICATIONS_REDIS_URL=
38
+ AGENTIC_MAIL_MCP_LOGGING_LEVEL=INFO
39
+ AGENTIC_MAIL_MCP_LOGGING_JSON_FORMAT=true
@@ -0,0 +1,28 @@
1
+ # Secrets and OAuth credentials โ€” never commit these
2
+ /token.json
3
+ /credentials.json
4
+ # Default token_storage_path (Settings.gmail.token_storage_path)
5
+ token.json
6
+ # Encrypted token store (Settings.gmail.token_storage_path)
7
+ /.secrets/
8
+ # Build artifacts
9
+ /dist/
10
+ /build/
11
+ *.egg-info/
12
+ # Local persistence, encrypted token store, and downloaded model artifacts
13
+ *.db
14
+ *.sqlite
15
+ *.sqlite3
16
+ /models/
17
+ .config/agentic-mail-mcp/
18
+ __pycache__/
19
+ *.py[codz]
20
+ *$py.class
21
+ .env
22
+ .env*.local
23
+ .env.development
24
+ .env.production
25
+ backend/keys/
26
+ *.pem
27
+ *.log
28
+ /.coverage
@@ -0,0 +1,138 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ### โš  Breaking
8
+
9
+ - **Railguards default is now read-only** (Phase 6): `railguards.access_level` defaults to `read_only` (was `owner`), so all write operations (forward/archive/delete/draft) are denied until a deployment sets `AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL=read_write`.
10
+
11
+ ### Fixed
12
+
13
+ - **Environment-variable configuration now works** (Phase 8): the `Settings`
14
+ sub-sections (`gmail`, `database`, `railguards`, `mcp`, `llm`, `search`,
15
+ `notifications`, `logging`) previously ignored their `AGENTIC_MAIL_MCP_<SECTION>_<FIELD>`
16
+ environment variables and always used defaults. Each section now carries its
17
+ own env prefix, so documented variables such as
18
+ `AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL`, `AGENTIC_MAIL_MCP_MCP_TRANSPORT`, and
19
+ `AGENTIC_MAIL_MCP_DATABASE_URL` take effect โ€” required for pip/Docker deployments to
20
+ be configurable.
21
+
22
+ ### Changed
23
+
24
+ - **Caller-first intelligence** ([ADR 0006](specs/docs/adr/0006-caller-first-intelligence.md)):
25
+ the calling agent is itself an LLM, so per-email reasoning (summarize, classify,
26
+ draft reply, extract action items) is now exposed as **MCP prompts** the agent
27
+ runs โ€” no server-side inference, no added latency, and **no LLM key required**
28
+ for the core experience. Internal LLM inference is reserved for the digest tools
29
+ (map-reduce over many emails), which register only when an LLM is configured;
30
+ set `AGENTIC_MAIL_MCP_LLM_INTERNAL_TOOLS=true` to also expose the per-email tools
31
+ server-side. Embeddings for semantic search remain internal.
32
+
33
+ ### Added
34
+
35
+ - **Live write-path smoke test** (`tests/e2e/test_live_write_path.py`, opt-in via
36
+ `AGENTIC_MAIL_MCP_LIVE_WRITE_E2E=1`). Self-contained and safe: it creates its own
37
+ throwaway message and exercises `create_draft` โ†’ `send_draft` โ†’ `add_label` โ†’
38
+ `forward_email` (to self) โ†’ `archive_email` โ†’ `delete_email`, then trashes its
39
+ own artifacts. Verified green against a real account. Documented finding:
40
+ permanent delete needs the `https://mail.google.com/` scope (soft delete works
41
+ under `gmail.modify`); `add_label` uses Gmail label **ids** (system labels like
42
+ `STARRED`), not arbitrary user-label names.
43
+ - **Bring-your-own Google app** ([ADR 0008](specs/docs/adr/0008-bring-your-own-google-app.md)).
44
+ The server is a local, bring-your-own-credentials tool โ€” no central app, no
45
+ Google verification. Point `AGENTIC_MAIL_MCP_GMAIL_CLIENT_SECRETS_FILE` at the
46
+ `credentials.json` you download from your own Google Cloud project (or set the
47
+ client id/secret directly); credentials and token stay on your machine. Docs
48
+ now cover the full self-service Google setup, the unverified-app screen, and
49
+ avoiding the 7-day testing-token expiry.
50
+ - **Persistence: read-through cache** ([ADR 0007](specs/docs/adr/0007-persistence-read-through-cache.md)).
51
+ Gmail is the source of truth; local persistence is a `CachedEmailRepository`, not
52
+ a mirror: single-email reads are live (fresh, full body), the SQLite cache stores
53
+ **metadata only โ€” never bodies**, list views are served within a TTL
54
+ (`AGENTIC_MAIL_MCP_DATABASE_CACHE_TTL_SECONDS`, default 900s), and emails gone from the
55
+ server are evicted (no sync engine, no delete-propagation). Tools now identify an
56
+ email by its Gmail **`message_id`** end to end (write commands carry `message_id`;
57
+ the internal UUID is an implementation detail). The Gmailโ†’domain mapper extracts
58
+ bare addresses from display-name headers (`"Name <a@b.com>"`) instead of failing.
59
+ - **Runtime composition root + auth** (makes the server usable end to end)
60
+ - `agentic_mail_mcp/Bootstrap/Composition.py` assembles every use case from `Settings` โ€”
61
+ SQLite persistence (schema applied via Alembic), a lazy OAuth-backed Gmail
62
+ gateway, railguard validator, event bus, LLM gateway, and optional semantic
63
+ search โ€” into the `McpUseCases` bundle the server registers. The launched
64
+ `agentic-mail-mcp` now exposes its tools (previously zero).
65
+ - `LazyGmailGateway` builds the authenticated Gmail client on first use, so
66
+ tools register at startup and calls before authorization return a clear
67
+ "run `agentic-mail-mcp auth`" error.
68
+ - `agentic-mail-mcp auth` subcommand performs the one-time interactive Google
69
+ authorization and stores the encrypted token (`make auth`).
70
+ - Semantic search degrades gracefully: `semantic_search` is registered only
71
+ when the `search` extra (sentence-transformers + sqlite-vec) is installed.
72
+ - **Distribution and polish** (Phase 8)
73
+ - `LICENSE` (MIT); `pyproject.toml` distribution metadata (`readme`,
74
+ `project.urls`, `license-files`) and a scoped sdist target producing a clean
75
+ source distribution + wheel with the `agentic-mail-mcp` entry point
76
+ - `specs/docs/api.md` โ€” the MCP tool/resource/prompt reference with input
77
+ schemas, output shapes, and the structured error format
78
+ - Architecture ADRs `0002`โ€“`0005` (DDD + vertical slicing, SQLite/PostgreSQL
79
+ persistence, railguards write-safety, MCP stdio transport)
80
+ - Expanded `README.md` (tool catalog, railguards security model, stdio
81
+ integration example, contributing, and the automated PyPI release flow)
82
+ - Multi-stage `Dockerfile` (builder + slim non-root runtime, health check),
83
+ multi-arch build support
84
+ - End-to-end MCP session tests (`tests/e2e/`) covering the read/write tool
85
+ flow, railguard enforcement, and a container health-check smoke test
86
+ - Removed the superseded pre-DDD `main.py` / `server.py` skeletons from the
87
+ repo root (replaced by `agentic_mail_mcp/MCP/Server.py` and `agentic_mail_mcp/Bootstrap/cli.py`)
88
+
89
+ - **MCP server layer** (Phase 7)
90
+ - `create_server` bootstrap that assembles the server from the dependency container and integrates the application lifespan; configurable transport (`stdio` default, streamable HTTP) via `Settings.mcp.transport`; the `agentic-mail-mcp` console entry point launches it
91
+ - `ToolRegistry` with category-grouped tools (read/write/intelligence/search) and JSON-Schema input schemas; **defense-in-depth**: write-category tools are not registered when `railguards.access_level` is `read_only`, so they are never exposed to the agent
92
+ - Read tools: `search_emails`, `get_email`, `get_thread`, `list_unread`, `list_labels`
93
+ - Write tools (railguarded): `forward_email`, `archive_email`, `delete_email`, `create_draft`, `send_draft`, `add_label`
94
+ - Intelligence tools: `summarize_email`, `classify_email`, `suggest_reply`, `extract_action_items`, `daily_digest`, `weekly_digest`
95
+ - Search tool: `semantic_search`
96
+ - MCP resources (account info, watch status, index status) and prompts (search strategy, email management); structured tool-error mapping for railguard denials, missing entities, and invalid input
97
+ - `AddLabelUseCase` (railguarded) emitting `EmailLabeled`; digest use cases accept an optional date anchor
98
+ - `Settings.mcp.transport` (`stdio` default)
99
+ - **Railguards framework** (Phase 6)
100
+ - `RailguardConfig` (access level, recipient allowlist with address/domain matching, action blocklist, windowed rate limits, archive-first policy) and `RailguardValidator` raising `PermissionError` on violation
101
+ - `audit_log` table, `AuditLogRepository` (SQLite), and `AuditLogHandler` event subscriber recording every write with a correlation id
102
+ - Railguarded write use cases: `ForwardEmailUseCase`, `ArchiveEmailUseCase`, `DeleteEmailUseCase` (soft-delete default, archive-first for permanent), `CreateDraftUseCase` / `SendDraftUseCase` (draft-first sending)
103
+ - `GmailGateway` draft operations (`create_draft`/`send_draft`/`delete_draft`) and their `GmailApiGateway` implementation
104
+ - `Settings.railguards.archive_first_policy`; Alembic migration `0002`
105
+ - **Shared domain primitives** (Phase 2)
106
+ - `ValueObject` base class with structural equality, hashing, and repr
107
+ - `UUIDId` value object wrapping `uuid.UUID` with `generate()` factory
108
+ - Typed exception hierarchy: `DomainError`, `ValidationError`, `NotFoundError`, `PermissionError`, `ConcurrencyError`
109
+ - `EventBus` protocol and `InMemoryEventBus` implementation
110
+ - `Specification[T]` pattern with `And`, `Or`, `Not` composables
111
+ - `Clock` protocol with `SystemClock` and `FrozenClock` implementations
112
+ - `IdGenerator` protocol with `UuidIdGenerator` implementation
113
+ - Exhaustive unit test coverage for all shared primitives
114
+ - **Domain models for all bounded contexts** (Phase 3)
115
+ - Gmail: `Email`, `Thread`, `Attachment`, `Label` aggregates; `EmailAddress`, `GmailMessageId`, `ThreadId`, `HistoryId`, `GmailQuery` value objects; repository and `GmailGateway` ports; mappers; domain events
116
+ - Intelligence: `Summary`, `Classification`, `Suggestion` entities; `PromptTemplate`, `ModelConfig` value objects; `LlmGateway` port
117
+ - Search: `SearchDocument` entity; `EmbeddingGateway` and `VectorSearchRepository` ports
118
+ - Notification: `ImportantEmailDetected`, `InboxChanged`, `DigestReady` events; `NotificationGateway` port
119
+ - **Application use cases** (Phase 4)
120
+ - Gmail read use cases: `SearchEmailsUseCase`, `GetEmailUseCase`, `GetThreadUseCase`, `ListUnreadUseCase`, `ListLabelsUseCase`; query/command objects and read DTOs
121
+ - Intelligence use cases: `SummarizeEmailUseCase`, `SuggestReplyUseCase`, `ClassifyEmailUseCase`, `DailyDigestUseCase`, `WeeklyDigestUseCase`, `ExtractActionItemsUseCase`
122
+ - Search use cases: `SemanticSearchUseCase`, `IndexEmailUseCase`, `RebuildIndexUseCase`
123
+ - Notification use cases: `NotifyImportantEmailUseCase`, `PublishInboxEventUseCase` (domain-event subscribers)
124
+
125
+ ### Changed
126
+
127
+ - `EventBus` is now generic over concrete event types: handlers are registered and dispatched by the event's exact type, so domain events are no longer required to inherit `DomainEvent` (it remains an optional base for standard metadata).
128
+ - **Database default is now a synchronous SQLite driver** (`sqlite:///โ€ฆ`) to match the synchronous repository ports (Phase 5). Set `AGENTIC_MAIL_MCP_DATABASE_URL` to a `postgresql+psycopg2://โ€ฆ` URL for PostgreSQL.
129
+
130
+ ### Added (Phase 5 โ€” Infrastructure Adapters)
131
+
132
+ - **Persistence**: synchronous SQLAlchemy engine/session wiring with a UTC-normalizing datetime type; ORM models and domainโ†”ORM mappers for Email/Thread/Attachment/Label; `SqliteEmailRepository` / `SqliteThreadRepository`; initial Alembic migration (`alembic.ini` + `migrations/`); PostgreSQL repository variants sharing the schema.
133
+ - **Gmail Google adapter**: `GmailOAuthProvider` (Fernet-encrypted token storage), `GmailApiGateway` (Gmail API with retry/backoff and rate limiting), `GmailWatcher` (push notifications + webhook parsing), `GmailHistorySynchronizer` (idempotent history sync emitting domain events).
134
+ - **Intelligence**: `LlamaCppGateway` implementing `LlmGateway` over an OpenAI-compatible endpoint or a local llama.cpp model.
135
+ - **Search**: `BgeEmbeddingGateway` (`EmbeddingGateway`); `SqliteVecRepository` (default) and `PgVectorRepository` (optional) implementing `VectorSearchRepository`, verified interchangeable by a shared contract test.
136
+ - **Notification**: `WebhookNotificationGateway` and `RedisNotificationGateway` implementing `NotificationGateway`.
137
+ - **Wiring**: `register_infrastructure()` binds the default adapter stack on the DI container.
138
+ - New Settings keys (`llm.base_url`, `llm.model_path`, `search.*`) and optional dependency extras (`postgresql`, `search`, `notifications`, `llm`); see `specs/docs/configuration.md` and `specs/docs/data-model.md`.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Agentic Mail MCP Team
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,385 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentic-mail-mcp
3
+ Version: 0.1.0
4
+ Summary: A Model Context Protocol (MCP) server exposing Gmail operations for AI agents
5
+ Project-URL: Homepage, https://github.com/CoolDevGuys/agentic-mail-mcp
6
+ Project-URL: Repository, https://github.com/CoolDevGuys/agentic-mail-mcp
7
+ Project-URL: Documentation, https://github.com/CoolDevGuys/agentic-mail-mcp/tree/main/specs/docs
8
+ Project-URL: Changelog, https://github.com/CoolDevGuys/agentic-mail-mcp/blob/main/CHANGELOG.md
9
+ Author: Agentic Mail MCP Team
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.11
18
+ Requires-Dist: alembic
19
+ Requires-Dist: cryptography
20
+ Requires-Dist: google-api-python-client
21
+ Requires-Dist: google-auth-oauthlib
22
+ Requires-Dist: httpx
23
+ Requires-Dist: mcp
24
+ Requires-Dist: pydantic
25
+ Requires-Dist: pydantic-settings
26
+ Requires-Dist: python-dotenv
27
+ Requires-Dist: sqlalchemy
28
+ Provides-Extra: dev
29
+ Requires-Dist: build; extra == 'dev'
30
+ Requires-Dist: fakeredis; extra == 'dev'
31
+ Requires-Dist: mypy; extra == 'dev'
32
+ Requires-Dist: pytest; extra == 'dev'
33
+ Requires-Dist: pytest-asyncio; extra == 'dev'
34
+ Requires-Dist: pytest-cov; extra == 'dev'
35
+ Requires-Dist: pytest-httpserver; extra == 'dev'
36
+ Requires-Dist: respx; extra == 'dev'
37
+ Requires-Dist: ruff==0.16.1; extra == 'dev'
38
+ Requires-Dist: setuptools>=83.0.0; extra == 'dev'
39
+ Requires-Dist: twine; extra == 'dev'
40
+ Provides-Extra: llm
41
+ Requires-Dist: llama-cpp-python; extra == 'llm'
42
+ Provides-Extra: notifications
43
+ Requires-Dist: redis; extra == 'notifications'
44
+ Provides-Extra: postgresql
45
+ Requires-Dist: pgvector; extra == 'postgresql'
46
+ Requires-Dist: psycopg2-binary; extra == 'postgresql'
47
+ Provides-Extra: search
48
+ Requires-Dist: sentence-transformers; extra == 'search'
49
+ Requires-Dist: sqlite-vec; extra == 'search'
50
+ Description-Content-Type: text/markdown
51
+
52
+ # ๐Ÿ“ง Agentic Mail MCP
53
+
54
+ > A [Model Context Protocol](https://modelcontextprotocol.io) server that lets AI
55
+ > agents work with a Gmail account **safely** โ€” read, search, summarize, and
56
+ > (opt-in) forward/archive/label โ€” behind a layered safety model.
57
+
58
+ > **๐Ÿ” You bring your own Google app.** This is a **local tool, not a hosted
59
+ > service** โ€” you create your own OAuth client in your own Google Cloud project
60
+ > and authorize your own mailbox. Your credentials and token never leave your
61
+ > machine, and because the app only ever authorizes you, **there's no central
62
+ > service and no Google verification to wait for.**
63
+
64
+ > **โ„น๏ธ Status:** pre-release (`0.1.0`), fully functional locally. Not yet on PyPI โ€”
65
+ > install from source (below).
66
+
67
+ ## โœจ Features
68
+
69
+ | | |
70
+ |---|---|
71
+ | ๐Ÿ“ฅ **Email operations** | Search, read, forward, archive, delete, draft, and label |
72
+ | ๐Ÿง  **Intelligence** | Caller-first prompts (summarize, classify, reply, action items) + optional server-side digests |
73
+ | ๐Ÿ”Ž **Semantic search** | Natural-language vector search over your mail |
74
+ | ๐Ÿ”” **Notifications** | Webhook / Redis event fan-out |
75
+ | ๐Ÿ›ก๏ธ **Railguards** | Read-only by default, allowlists, rate limits, archive-first delete, draft-first send, audit log |
76
+
77
+ ## ๐Ÿš€ Quick start
78
+
79
+ You need **Python 3.11+** and a Google account. Five minutes end to end.
80
+
81
+ ```mermaid
82
+ flowchart LR
83
+ A[1. Install] --> B[2. Google<br/>credentials]
84
+ B --> C[3. Configure<br/>.env]
85
+ C --> D[4. Authorize<br/>agentic-mail-mcp auth]
86
+ D --> E[5. Connect agent<br/>or run HTTP]
87
+ ```
88
+
89
+ **1. Install** (from source until published โ€” see [Installation](#-installation)):
90
+
91
+ ```bash
92
+ pip install "git+https://github.com/CoolDevGuys/agentic-mail-mcp.git"
93
+ ```
94
+
95
+ **2. Get Google credentials** โ€” in *your* Google Cloud project, enable the Gmail
96
+ API, make a **Desktop-app OAuth client**, and **download its `credentials.json`**.
97
+ Full walkthrough with the exact clicks:
98
+ [Getting your Google credentials ๐Ÿ‘‰](specs/docs/configuration.md#getting-your-google-credentials-oauth).
99
+
100
+ **3. Configure** โ€” copy `.env.example` to `.env` and point at your downloaded file:
101
+
102
+ ```bash
103
+ # Easiest: just point at the credentials.json you downloaded.
104
+ AGENTIC_MAIL_MCP_GMAIL_CLIENT_SECRETS_FILE=/path/to/credentials.json
105
+ AGENTIC_MAIL_MCP_GMAIL_TOKEN_ENCRYPTION_KEY=<any long random string>
106
+ # ๐Ÿ”’ Writes are denied by default. Keep read_only until you trust the setup.
107
+ AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL=read_only
108
+ ```
109
+
110
+ **4. Authorize** (one-time browser consent โ€” stores an encrypted token):
111
+
112
+ ```bash
113
+ agentic-mail-mcp auth
114
+ ```
115
+
116
+ **5. Use it** โ€” connect an AI agent over **stdio** or run the **HTTP** server.
117
+ See [Usage](#-usage).
118
+
119
+ ## โœ… Requirements
120
+
121
+ - ๐Ÿ Python 3.11+
122
+ - ๐Ÿ”‘ Your own Google OAuth **`credentials.json`** (a Desktop-app client from your
123
+ Google Cloud project โ€” [how to get it](specs/docs/configuration.md#getting-your-google-credentials-oauth))
124
+ - ๐Ÿค– *(optional)* an LLM API key for the digest tools (OpenAI-compatible by default)
125
+
126
+ ## ๐Ÿ“ฆ Installation
127
+
128
+ **From source (works today):**
129
+
130
+ ```bash
131
+ pip install "git+https://github.com/CoolDevGuys/agentic-mail-mcp.git"
132
+ # or, from a clone:
133
+ pip install .
134
+ ```
135
+
136
+ **Optional extras** (combine as needed, e.g. `".[postgresql,search]"`):
137
+
138
+ | Extra | Adds |
139
+ |---|---|
140
+ | `postgresql` | PostgreSQL + pgvector backends |
141
+ | `search` | local embeddings + sqlite-vec semantic search |
142
+ | `notifications` | Redis pub/sub notifications |
143
+ | `llm` | local llama.cpp inference |
144
+ | `dev` | test / lint / build tooling |
145
+
146
+ **Docker:** `docker compose up --build` (see [HTTP server](#http-server-deployment)).
147
+
148
+ > ๐Ÿ’ก Once published to PyPI, the recommended install for MCP clients will be
149
+ > `uvx agentic-mail-mcp` / `pipx run agentic-mail-mcp` โ€” no virtualenv to manage.
150
+
151
+ ## โš™๏ธ Configuration
152
+
153
+ Set environment variables with the `AGENTIC_MAIL_MCP_` prefix, or use a `.env` file
154
+ (copy `.env.example`). The table below covers the essentials; **every** setting,
155
+ with defaults and purpose โ€” and the **Google OAuth walkthrough** โ€” is in
156
+ [`specs/docs/configuration.md`](specs/docs/configuration.md).
157
+
158
+ | Variable | Description | Default |
159
+ |---|---|---|
160
+ | `AGENTIC_MAIL_MCP_GMAIL_CLIENT_SECRETS_FILE` | Path to your downloaded `credentials.json` (recommended) | (one of these two) |
161
+ | `AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_ID` / `_SECRET` | โ€ฆor the OAuth client id/secret directly | (one of these two) |
162
+ | `AGENTIC_MAIL_MCP_GMAIL_TOKEN_ENCRYPTION_KEY` | Secret used to encrypt the stored token | (required to store tokens) |
163
+ | `AGENTIC_MAIL_MCP_GMAIL_TOKEN_STORAGE_PATH` | Encrypted token file path (set outside the repo in prod) | `token.json` |
164
+ | `AGENTIC_MAIL_MCP_DATABASE_URL` | SQLAlchemy URL (synchronous driver) | `sqlite:///./agentic_mail_mcp.db` |
165
+ | `AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL` | `read_only` or `read_write` โ€” **writes denied by default** | `read_only` |
166
+ | `AGENTIC_MAIL_MCP_LLM_PROVIDER` | `openai` (HTTP) or `llamacpp` (local) | `openai` |
167
+ | `AGENTIC_MAIL_MCP_LLM_API_KEY` | LLM API key | (required for intelligence) |
168
+ | `AGENTIC_MAIL_MCP_MCP_TRANSPORT` | `stdio` (default) or `http` | `stdio` |
169
+ | `AGENTIC_MAIL_MCP_MCP_HOST` / `AGENTIC_MAIL_MCP_MCP_PORT` | HTTP transport bind address | `127.0.0.1` / `8080` |
170
+
171
+ ## ๐Ÿ”Œ Usage
172
+
173
+ The server speaks MCP over two transports:
174
+
175
+ | Transport | Best for | How |
176
+ |---|---|---|
177
+ | **stdio** (default) | one user on a laptop (Claude Desktop, IDE agents) | agent launches the process |
178
+ | **HTTP** (streamable) | shared / containerized deployments | long-running server on a port |
179
+
180
+ > โš ๏ธ **Authorize first.** Run `agentic-mail-mcp auth` once (browser consent) before
181
+ > starting the server โ€” it stores the encrypted token the server reads on every
182
+ > start. Details:
183
+ > [Authorize](specs/docs/configuration.md#6-authorize-one-time-consent).
184
+ >
185
+ > **Headless server (no browser)?** `auth` needs a browser + loopback redirect,
186
+ > so you don't run it on the server. Authorize once on a machine that has a
187
+ > browser, then copy the encrypted token file across โ€” see
188
+ > [Headless / server deployment](specs/docs/configuration.md#7-headless--server-deployment-no-browser).
189
+
190
+ ### ๐Ÿ’ป Local (stdio) โ€” connect an AI agent
191
+
192
+ Point your MCP client at the `agentic-mail-mcp` command. Example client config:
193
+
194
+ ```json
195
+ {
196
+ "mcpServers": {
197
+ "gmail": {
198
+ "command": "agentic-mail-mcp",
199
+ "env": {
200
+ "AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_ID": "...",
201
+ "AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_SECRET": "...",
202
+ "AGENTIC_MAIL_MCP_GMAIL_TOKEN_ENCRYPTION_KEY": "...",
203
+ "AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL": "read_only"
204
+ }
205
+ }
206
+ }
207
+ }
208
+ ```
209
+
210
+ The agent then discovers the tools, resources, and prompts described in the
211
+ [MCP API reference](specs/docs/api.md). Start with `read_only` and enable
212
+ `read_write` deliberately once you understand the [railguards](#railguards-security-model).
213
+
214
+ ### HTTP server (deployment)
215
+
216
+ Run a standalone streamable-HTTP server:
217
+
218
+ ```bash
219
+ AGENTIC_MAIL_MCP_MCP_TRANSPORT=http AGENTIC_MAIL_MCP_MCP_HOST=0.0.0.0 AGENTIC_MAIL_MCP_MCP_PORT=8080 \
220
+ agentic-mail-mcp
221
+ ```
222
+
223
+ Or with Docker (the compose file already sets HTTP transport and a health check):
224
+
225
+ ```bash
226
+ docker compose up --build # server on http://localhost:8080
227
+ ```
228
+
229
+ > ๐Ÿ”‘ **Auth on a headless host:** authorize on your laptop and mount the
230
+ > encrypted token into the container (e.g. `-v /etc/agentic-mail-mcp:/secrets:ro`)
231
+ > โ€” full steps under
232
+ > [Headless / server deployment](specs/docs/configuration.md#7-headless--server-deployment-no-browser).
233
+
234
+ Point an HTTP-capable MCP client at `http://<host>:8080`. Keep the server behind
235
+ your own auth/TLS if it's reachable beyond localhost.
236
+
237
+ ## ๐Ÿงฐ MCP Tools
238
+
239
+ Full input/output schemas, resources, prompts, and error formats are in the
240
+ [MCP API reference](specs/docs/api.md).
241
+
242
+ ### Read Tools (always available)
243
+
244
+ - `search_emails` โ€” Search emails by subject, sender, recipient, date range, labels, attachments, unread status
245
+ - `get_email` โ€” Read a specific email by ID
246
+ - `get_thread` โ€” Read a conversation thread
247
+ - `list_unread` โ€” List unread emails
248
+ - `list_labels` โ€” List labels (system, user, or all)
249
+
250
+ ### Write Tools (require `read_write` access)
251
+
252
+ - `forward_email` โ€” Forward an email (recipient allowlist enforced)
253
+ - `archive_email` โ€” Archive an email or thread
254
+ - `delete_email` โ€” Delete an email (trash by default, archive-first policy)
255
+ - `create_draft` โ€” Create a draft for review
256
+ - `send_draft` โ€” Send a reviewed draft
257
+ - `add_label` โ€” Add a label to an email
258
+
259
+ ### Intelligence โ€” caller-first ๐Ÿง 
260
+
261
+ The calling agent is itself an LLM, so per-email reasoning ships as **MCP prompts**
262
+ the agent runs on data it fetches with `get_email` โ€” **no server-side inference,
263
+ no added latency, no LLM key required**:
264
+
265
+ - prompts: `summarize_email` ยท `classify_email` ยท `draft_reply` ยท `extract_action_items`
266
+
267
+ Internal LLM inference is reserved for where it pays off (map-reduce over many
268
+ emails), and registers **only when an LLM is configured**:
269
+
270
+ - tools: `daily_digest` ยท `weekly_digest`
271
+ - *(opt-in)* set `AGENTIC_MAIL_MCP_LLM_INTERNAL_TOOLS=true` to also expose the per-email
272
+ ones as server-side tools. See [ADR 0006](specs/docs/adr/0006-caller-first-intelligence.md).
273
+
274
+ ### Search Tools
275
+
276
+ - `semantic_search` โ€” natural-language vector search *(needs the `search` extra)*
277
+
278
+ ## Project Structure
279
+
280
+ ```
281
+ agentic_mail_mcp/
282
+ Bootstrap/ CLI, Settings, Logging, Lifespan, DI Container
283
+ Common/ Shared domain primitives
284
+ Gmail/ Gmail bounded context
285
+ Intelligence/ LLM-powered email analysis
286
+ Search/ Semantic/vector search
287
+ Notification/ Event notifications
288
+ MCP/ MCP server, tools, resources, prompts
289
+ tests/
290
+ unit/ Unit tests
291
+ integration/ Integration tests
292
+ fakes/ Test doubles
293
+ ```
294
+
295
+ ## Railguards (security model)
296
+
297
+ Writes are **denied by default**. Safety is layered so an AI agent cannot mutate
298
+ a mailbox unless a human deliberately enables it:
299
+
300
+ - **Access level** โ€” `read_only` (default) or `read_write`. The master switch.
301
+ Under `read_only`, write tools are **not even registered** with the MCP server
302
+ (defense in depth), so the agent never sees them โ€” not merely blocked at call
303
+ time.
304
+ - **Recipient allowlist** โ€” forwarding is restricted to configured addresses or
305
+ domains (`@example.com`).
306
+ - **Rate limits** โ€” per-action caps within a trailing 1-hour window
307
+ (e.g. `{"forward": 50}`).
308
+ - **Archive-first policy** โ€” an email must be archived before it can be
309
+ permanently deleted; deletes are soft (Trash) by default.
310
+ - **Draft-first sending** โ€” the agent creates a draft for human review;
311
+ `send_draft` is a separate, explicit step.
312
+ - **Audit log** โ€” every write is recorded (action, email id, correlation id).
313
+
314
+ A railguard denial surfaces to the agent as a structured `permission_denied`
315
+ error, never as an unhandled exception. See the
316
+ [railguards configuration](specs/docs/configuration.md#railguards) and
317
+ [ADR 0004](specs/docs/adr/0004-railguards-write-safety.md).
318
+
319
+ ## Development
320
+
321
+ A `Makefile` wraps the common tasks (run `make` to list them):
322
+
323
+ ```bash
324
+ make setup # first-time: create .venv, install dev deps, .env, run migrations
325
+ make auth # one-time Google authorization (browser consent)
326
+ make run # start the server (stdio); make run-http for HTTP transport
327
+ make test # full test suite with coverage gates (as CI runs)
328
+ make check # lint (ruff) + type-check (mypy) + tests
329
+ make format # auto-format and fix imports
330
+ make migrate # apply DB migrations; make migration m="..." to autogenerate
331
+ make build # build the sdist + wheel and validate metadata
332
+ ```
333
+
334
+ Prefer raw tools? They work too: `pytest`, `ruff check agentic_mail_mcp tests`, `mypy agentic_mail_mcp`,
335
+ `alembic upgrade head`. All `make` targets run inside a local `.venv`.
336
+
337
+ ## Contributing
338
+
339
+ - The architecture (DDD + vertical slicing) and key decisions are recorded as
340
+ [ADRs](specs/docs/adr/); read them before adding a bounded context or changing
341
+ a boundary.
342
+ - Changes follow the OpenSpec workflow under `openspec/` โ€” propose a change,
343
+ generate its spec deltas, implement, then archive.
344
+ - Keep the tiered coverage floors green (โ‰ฅ90% on `Domain/`, โ‰ฅ80% overall) and
345
+ ensure `ruff check` and `mypy agentic_mail_mcp/` pass before opening a PR.
346
+
347
+ ## ๐Ÿ“ค Distribution
348
+
349
+ The recommended distribution is a **PyPI package launched via `uvx` / `pipx`**,
350
+ not a compiled binary. MCP clients already know how to run
351
+ `command: "uvx"` / `"pipx run"`, so users get a one-line config with no
352
+ virtualenv to manage, and Python-native OAuth/optional-dependency handling stays
353
+ simple. A single-file binary would fight the OAuth browser flow and the optional
354
+ native extras (llama.cpp, sentence-transformers, sqlite-vec) for little gain. The
355
+ **Docker image** covers HTTP/server deployments.
356
+
357
+ ### Releasing (maintainers)
358
+
359
+ Releases are **fully automated** by the `publish` job in
360
+ [`.github/workflows/ci.yml`](.github/workflows/ci.yml). Publishing a GitHub
361
+ Release is the entire flow โ€” it builds the sdist + wheel and uploads them to
362
+ PyPI via **Trusted Publishing (OIDC)**, so no API token is stored in the repo.
363
+
364
+ **One-time PyPI setup** (per project, done once in the PyPI web UI):
365
+
366
+ 1. On [PyPI](https://pypi.org/manage/account/publishing/) โ†’ *Publishing* โ†’ add a
367
+ **pending trusted publisher** with:
368
+ - **PyPI Project Name**: `agentic-mail-mcp`
369
+ - **Owner**: your GitHub org/user ยท **Repository**: this repo
370
+ - **Workflow name**: `ci.yml` ยท **Environment name**: `pypi`
371
+ 2. In GitHub โ†’ *Settings โ†’ Environments* โ†’ create an environment named **`pypi`**
372
+ (optionally add required reviewers to gate publishes).
373
+
374
+ **To cut a release:**
375
+
376
+ 1. Bump `project.version` in `pyproject.toml`, move the `CHANGELOG.md`
377
+ `[Unreleased]` section under the new version, and merge to `main`.
378
+ 2. On GitHub โ†’ *Releases โ†’ Draft a new release* โ†’ create a tag (e.g. `v0.1.0`)
379
+ โ†’ **Publish release**.
380
+ 3. CI runs lint / type-check / tests / audit, then the `publish` job builds and
381
+ uploads to PyPI. Done โ€” `uvx agentic-mail-mcp` now resolves the new version.
382
+
383
+ ## License
384
+
385
+ Released under the [MIT License](LICENSE).