universal-mcp-applications 0.1.25__tar.gz → 0.1.26__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.

Potentially problematic release.


This version of universal-mcp-applications might be problematic. Click here for more details.

Files changed (294) hide show
  1. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/PKG-INFO +1 -1
  2. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/pyproject.toml +1 -1
  3. universal_mcp_applications-0.1.26/src/universal_mcp/applications/outlook/app.py +524 -0
  4. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/reddit/app.py +30 -47
  5. universal_mcp_applications-0.1.26/test.py +56 -0
  6. universal_mcp_applications-0.1.26/uv.lock +5765 -0
  7. universal_mcp_applications-0.1.25/src/universal_mcp/applications/outlook/app.py +0 -480
  8. universal_mcp_applications-0.1.25/uv.lock +0 -5150
  9. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/.gitignore +0 -0
  10. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/GEMINI.md +0 -0
  11. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/LICENSE +0 -0
  12. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/README.md +0 -0
  13. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/bump_and_release.sh +0 -0
  14. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/scripts/docgen.py +0 -0
  15. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/scripts/prompts.py +0 -0
  16. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/scripts/readme.py +0 -0
  17. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/scripts/run_docgen.py +0 -0
  18. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/tests/test_applications.py +0 -0
  19. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/BEST_PRACTICES.md +0 -0
  20. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ahrefs/README.md +0 -0
  21. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ahrefs/__init__.py +0 -0
  22. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ahrefs/app.py +0 -0
  23. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/airtable/README.md +0 -0
  24. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/airtable/__init__.py +0 -0
  25. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/airtable/app.py +0 -0
  26. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/apollo/README.md +0 -0
  27. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/apollo/__init__.py +0 -0
  28. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/apollo/app.py +0 -0
  29. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/asana/README.md +0 -0
  30. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/asana/__init__.py +0 -0
  31. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/asana/app.py +0 -0
  32. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/aws_s3/README.md +0 -0
  33. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/aws_s3/__init__.py +0 -0
  34. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/aws_s3/app.py +0 -0
  35. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/bill/README.md +0 -0
  36. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/bill/__init__.py +0 -0
  37. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/bill/app.py +0 -0
  38. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/box/README.md +0 -0
  39. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/box/__init__.py +0 -0
  40. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/box/app.py +0 -0
  41. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/braze/README.md +0 -0
  42. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/braze/__init__.py +0 -0
  43. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/braze/app.py +0 -0
  44. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/browser_use/README.md +0 -0
  45. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/browser_use/__init__.py +0 -0
  46. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/browser_use/app.py +0 -0
  47. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/cal_com_v2/README.md +0 -0
  48. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/cal_com_v2/__init__.py +0 -0
  49. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/cal_com_v2/app.py +0 -0
  50. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/calendly/README.md +0 -0
  51. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/calendly/__init__.py +0 -0
  52. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/calendly/app.py +0 -0
  53. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/canva/README.md +0 -0
  54. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/canva/__init__.py +0 -0
  55. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/canva/app.py +0 -0
  56. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/clickup/README.md +0 -0
  57. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/clickup/__init__.py +0 -0
  58. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/clickup/app.py +0 -0
  59. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/coda/README.md +0 -0
  60. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/coda/__init__.py +0 -0
  61. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/coda/app.py +0 -0
  62. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/confluence/README.md +0 -0
  63. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/confluence/__init__.py +0 -0
  64. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/confluence/app.py +0 -0
  65. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/contentful/README.md +0 -0
  66. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/contentful/__init__.py +0 -0
  67. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/contentful/app.py +0 -0
  68. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/crustdata/README.md +0 -0
  69. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/crustdata/__init__.py +0 -0
  70. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/crustdata/app.py +0 -0
  71. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/dialpad/README.md +0 -0
  72. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/dialpad/__init__.py +0 -0
  73. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/dialpad/app.py +0 -0
  74. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/digitalocean/README.md +0 -0
  75. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/digitalocean/__init__.py +0 -0
  76. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/digitalocean/app.py +0 -0
  77. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/domain_checker/README.md +0 -0
  78. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/domain_checker/__init__.py +0 -0
  79. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/domain_checker/app.py +0 -0
  80. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/e2b/README.md +0 -0
  81. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/e2b/__init__.py +0 -0
  82. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/e2b/app.py +0 -0
  83. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/elevenlabs/README.md +0 -0
  84. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/elevenlabs/__init__.py +0 -0
  85. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/elevenlabs/app.py +0 -0
  86. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/exa/README.md +0 -0
  87. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/exa/__init__.py +0 -0
  88. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/exa/app.py +0 -0
  89. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/falai/README.md +0 -0
  90. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/falai/__init__.py +0 -0
  91. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/falai/app.py +0 -0
  92. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/figma/README.md +0 -0
  93. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/figma/__init__.py +0 -0
  94. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/figma/app.py +0 -0
  95. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/file_system/README.md +0 -0
  96. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/file_system/__init__.py +0 -0
  97. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/file_system/app.py +0 -0
  98. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/firecrawl/README.md +0 -0
  99. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/firecrawl/__init__.py +0 -0
  100. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/firecrawl/app.py +0 -0
  101. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fireflies/README.md +0 -0
  102. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fireflies/__init__.py +0 -0
  103. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fireflies/app.py +0 -0
  104. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/README.md +0 -0
  105. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/__init__.py +0 -0
  106. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/app.py +0 -0
  107. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/utils/api.py +0 -0
  108. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/utils/fixtures.py +0 -0
  109. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/utils/helper.py +0 -0
  110. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/utils/league_utils.py +0 -0
  111. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/fpl/utils/position_utils.py +0 -0
  112. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ghost_content/README.md +0 -0
  113. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ghost_content/__init__.py +0 -0
  114. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ghost_content/app.py +0 -0
  115. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/github/README.md +0 -0
  116. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/github/__init__.py +0 -0
  117. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/github/app.py +0 -0
  118. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/gong/README.md +0 -0
  119. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/gong/__init__.py +0 -0
  120. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/gong/app.py +0 -0
  121. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_calendar/README.md +0 -0
  122. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_calendar/__init__.py +0 -0
  123. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_calendar/app.py +0 -0
  124. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_docs/README.md +0 -0
  125. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_docs/__init__.py +0 -0
  126. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_docs/app.py +0 -0
  127. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_drive/README.md +0 -0
  128. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_drive/__init__.py +0 -0
  129. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_drive/app.py +0 -0
  130. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_gemini/README.md +0 -0
  131. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_gemini/__init__.py +0 -0
  132. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_gemini/app.py +0 -0
  133. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_mail/README.md +0 -0
  134. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_mail/__init__.py +0 -0
  135. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_mail/app.py +0 -0
  136. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_searchconsole/README.md +0 -0
  137. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_searchconsole/__init__.py +0 -0
  138. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_searchconsole/app.py +0 -0
  139. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_sheet/README.md +0 -0
  140. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_sheet/__init__.py +0 -0
  141. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_sheet/app.py +0 -0
  142. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/google_sheet/helper.py +0 -0
  143. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hashnode/README.md +0 -0
  144. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hashnode/__init__.py +0 -0
  145. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hashnode/app.py +0 -0
  146. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/heygen/README.md +0 -0
  147. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/heygen/__init__.py +0 -0
  148. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/heygen/app.py +0 -0
  149. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/http_tools/README.md +0 -0
  150. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/http_tools/__init__.py +0 -0
  151. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/http_tools/app.py +0 -0
  152. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hubspot/README.md +0 -0
  153. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hubspot/__init__.py +0 -0
  154. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
  155. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hubspot/api_segments/api_segment_base.py +0 -0
  156. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hubspot/api_segments/crm_api.py +0 -0
  157. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hubspot/api_segments/marketing_api.py +0 -0
  158. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/hubspot/app.py +0 -0
  159. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/jira/README.md +0 -0
  160. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/jira/__init__.py +0 -0
  161. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/jira/app.py +0 -0
  162. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/klaviyo/README.md +0 -0
  163. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/klaviyo/__init__.py +0 -0
  164. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/klaviyo/app.py +0 -0
  165. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/linkedin/README.md +0 -0
  166. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/linkedin/__init__.py +0 -0
  167. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/linkedin/app.py +0 -0
  168. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/mailchimp/README.md +0 -0
  169. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/mailchimp/__init__.py +0 -0
  170. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/mailchimp/app.py +0 -0
  171. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/markitdown/README.md +0 -0
  172. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/markitdown/__init__.py +0 -0
  173. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/markitdown/app.py +0 -0
  174. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/miro/README.md +0 -0
  175. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/miro/__init__.py +0 -0
  176. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/miro/app.py +0 -0
  177. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ms_teams/README.md +0 -0
  178. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ms_teams/__init__.py +0 -0
  179. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/ms_teams/app.py +0 -0
  180. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/neon/README.md +0 -0
  181. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/neon/__init__.py +0 -0
  182. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/neon/app.py +0 -0
  183. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/notion/README.md +0 -0
  184. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/notion/__init__.py +0 -0
  185. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/notion/app.py +0 -0
  186. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/openai/README.md +0 -0
  187. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/openai/__init__.py +0 -0
  188. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/openai/app.py +0 -0
  189. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/outlook/README.md +0 -0
  190. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/outlook/__init__.py +0 -0
  191. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/perplexity/README.md +0 -0
  192. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/perplexity/__init__.py +0 -0
  193. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/perplexity/app.py +0 -0
  194. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/pipedrive/README.md +0 -0
  195. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/pipedrive/__init__.py +0 -0
  196. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/pipedrive/app.py +0 -0
  197. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/posthog/README.md +0 -0
  198. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/posthog/__init__.py +0 -0
  199. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/posthog/app.py +0 -0
  200. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/reddit/README.md +0 -0
  201. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/reddit/__init__.py +0 -0
  202. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/resend/README.md +0 -0
  203. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/resend/__init__.py +0 -0
  204. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/resend/app.py +0 -0
  205. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/retell/README.md +0 -0
  206. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/retell/__init__.py +0 -0
  207. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/retell/app.py +0 -0
  208. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/rocketlane/README.md +0 -0
  209. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/rocketlane/__init__.py +0 -0
  210. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/rocketlane/app.py +0 -0
  211. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/scraper/README.md +0 -0
  212. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/scraper/__init__.py +0 -0
  213. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/scraper/app.py +0 -0
  214. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/semanticscholar/README.md +0 -0
  215. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/semanticscholar/__init__.py +0 -0
  216. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/semanticscholar/app.py +0 -0
  217. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/semrush/README.md +0 -0
  218. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/semrush/__init__.py +0 -0
  219. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/semrush/app.py +0 -0
  220. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sendgrid/README.md +0 -0
  221. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sendgrid/__init__.py +0 -0
  222. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sendgrid/app.py +0 -0
  223. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sentry/README.md +0 -0
  224. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sentry/__init__.py +0 -0
  225. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sentry/app.py +0 -0
  226. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/serpapi/README.md +0 -0
  227. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/serpapi/__init__.py +0 -0
  228. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/serpapi/app.py +0 -0
  229. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sharepoint/README.md +0 -0
  230. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sharepoint/__init__.py +0 -0
  231. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/sharepoint/app.py +0 -0
  232. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/shopify/README.md +0 -0
  233. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/shopify/__init__.py +0 -0
  234. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/shopify/app.py +0 -0
  235. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/shortcut/README.md +0 -0
  236. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/shortcut/__init__.py +0 -0
  237. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/shortcut/app.py +0 -0
  238. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/slack/README.md +0 -0
  239. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/slack/__init__.py +0 -0
  240. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/slack/app.py +0 -0
  241. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/spotify/README.md +0 -0
  242. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/spotify/__init__.py +0 -0
  243. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/spotify/app.py +0 -0
  244. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/supabase/README.md +0 -0
  245. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/supabase/__init__.py +0 -0
  246. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/supabase/app.py +0 -0
  247. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/tavily/README.md +0 -0
  248. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/tavily/__init__.py +0 -0
  249. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/tavily/app.py +0 -0
  250. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/trello/README.md +0 -0
  251. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/trello/__init__.py +0 -0
  252. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/trello/app.py +0 -0
  253. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twilio/README.md +0 -0
  254. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twilio/__init__.py +0 -0
  255. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twilio/app.py +0 -0
  256. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/README.md +0 -0
  257. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/__init__.py +0 -0
  258. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/__init__.py +0 -0
  259. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/api_segment_base.py +0 -0
  260. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/compliance_api.py +0 -0
  261. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +0 -0
  262. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/dm_events_api.py +0 -0
  263. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/likes_api.py +0 -0
  264. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/lists_api.py +0 -0
  265. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/openapi_json_api.py +0 -0
  266. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/spaces_api.py +0 -0
  267. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/trends_api.py +0 -0
  268. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/tweets_api.py +0 -0
  269. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/usage_api.py +0 -0
  270. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/api_segments/users_api.py +0 -0
  271. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/twitter/app.py +0 -0
  272. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/unipile/README.md +0 -0
  273. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/unipile/__init__.py +0 -0
  274. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/unipile/app.py +0 -0
  275. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp/README.md +0 -0
  276. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp/__init__.py +0 -0
  277. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp/app.py +0 -0
  278. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp/audio.py +0 -0
  279. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp/whatsapp.py +0 -0
  280. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp_business/README.md +0 -0
  281. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp_business/__init__.py +0 -0
  282. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/whatsapp_business/app.py +0 -0
  283. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/wrike/README.md +0 -0
  284. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/wrike/__init__.py +0 -0
  285. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/wrike/app.py +0 -0
  286. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/yahoo_finance/README.md +0 -0
  287. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/yahoo_finance/__init__.py +0 -0
  288. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/yahoo_finance/app.py +0 -0
  289. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/youtube/README.md +0 -0
  290. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/youtube/__init__.py +0 -0
  291. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/youtube/app.py +0 -0
  292. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/zenquotes/README.md +0 -0
  293. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/zenquotes/__init__.py +0 -0
  294. {universal_mcp_applications-0.1.25 → universal_mcp_applications-0.1.26}/src/universal_mcp/applications/zenquotes/app.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: universal-mcp-applications
3
- Version: 0.1.25
3
+ Version: 0.1.26
4
4
  Summary: A Universal MCP Application: universal_mcp_applications
5
5
  Project-URL: Homepage, https://github.com/universal-mcp/applications
6
6
  Project-URL: Repository, https://github.com/universal-mcp/applications
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "universal-mcp-applications"
9
- version = "0.1.25"
9
+ version = "0.1.26"
10
10
  description = "A Universal MCP Application: universal_mcp_applications"
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.11"
@@ -0,0 +1,524 @@
1
+ from typing import Any
2
+ from urllib.parse import parse_qs, urlparse
3
+
4
+ from universal_mcp.applications.application import APIApplication
5
+ from universal_mcp.integrations import Integration
6
+
7
+
8
+ class OutlookApp(APIApplication):
9
+ def __init__(self, integration: Integration = None, **kwargs) -> None:
10
+ super().__init__(name="outlook", integration=integration, **kwargs)
11
+ self.base_url = "https://graph.microsoft.com/v1.0"
12
+
13
+ def reply_to_email(
14
+ self,
15
+ message_id: str,
16
+ comment: str,
17
+ user_id: str | None = None,
18
+ attachments: list[dict[str, Any]] | None = None,
19
+ ) -> dict[str, Any]:
20
+ """
21
+ Replies to a specific email message.
22
+
23
+ Args:
24
+ message_id (str): The ID of the email message to reply to.
25
+ comment (str): The body of the reply.
26
+ user_id (str, optional): The ID of the user to send the reply from. Defaults to the authenticated user.
27
+ attachments (list[dict[str, Any]], optional): A list of attachment objects to include in the reply.
28
+ Each attachment dictionary should conform to the Microsoft Graph API specification.
29
+ Example:
30
+ [
31
+ {
32
+ "@odata.type": "#microsoft.graph.fileAttachment",
33
+ "name": "attachment.txt",
34
+ "contentType": "text/plain",
35
+ "contentBytes": "SGVsbG8gV29ybGQh"
36
+ }
37
+ ]
38
+
39
+ Returns:
40
+ dict[str, Any]: A dictionary confirming the reply action.
41
+
42
+ Raises:
43
+ HTTPStatusError: If the API request fails.
44
+ ValueError: If the user_id cannot be retrieved or message_id is missing.
45
+
46
+ Tags:
47
+ important
48
+ """
49
+ if user_id is None:
50
+ user_info = self.get_my_profile()
51
+ user_id = user_info.get("userPrincipalName")
52
+ if not user_id:
53
+ raise ValueError("Could not retrieve user ID from get_my_profile response.")
54
+ if not message_id:
55
+ raise ValueError("Missing required parameter 'message_id'.")
56
+
57
+ request_body_data = {"comment": comment}
58
+ if attachments:
59
+ request_body_data["message"] = {"attachments": attachments}
60
+
61
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}/reply"
62
+
63
+ response = self._post(
64
+ url,
65
+ data=request_body_data,
66
+ params={},
67
+ content_type="application/json",
68
+ )
69
+ return self._handle_response(response)
70
+
71
+ def send_email(
72
+ self,
73
+ subject: str,
74
+ body: str,
75
+ to_recipients: list[str],
76
+ user_id: str | None = None,
77
+ cc_recipients: list[str] | None = None,
78
+ bcc_recipients: list[str] | None = None,
79
+ attachments: list[dict[str, Any]] | None = None,
80
+ body_content_type: str = "Text",
81
+ save_to_sent_items: bool = True,
82
+ ) -> dict[str, Any]:
83
+ """
84
+ Sends a new email.
85
+
86
+ Args:
87
+ subject (str): The subject of the email.
88
+ body (str): The body of the email.
89
+ to_recipients (list[str]): A list of email addresses for the 'To' recipients.
90
+ user_id (str, optional): The ID of the user to send the email from. Defaults to the authenticated user.
91
+ cc_recipients (list[str], optional): A list of email addresses for the 'Cc' recipients.
92
+ bcc_recipients (list[str], optional): A list of email addresses for the 'Bcc' recipients.
93
+ attachments (list[dict[str, Any]], optional): A list of attachment objects. See `reply_to_email` for an example.
94
+ body_content_type (str, optional): The content type of the email body, e.g., "Text" or "HTML". Defaults to "Text".
95
+ save_to_sent_items (bool, optional): Whether to save the email to the 'Sent Items' folder. Defaults to True.
96
+
97
+ Returns:
98
+ dict[str, Any]: A dictionary confirming the send action.
99
+
100
+ Raises:
101
+ HTTPStatusError: If the API request fails.
102
+ ValueError: If the user_id cannot be retrieved.
103
+
104
+ Tags:
105
+ important
106
+ """
107
+ if user_id is None:
108
+ user_info = self.get_my_profile()
109
+ user_id = user_info.get("userPrincipalName")
110
+ if not user_id:
111
+ raise ValueError("Could not retrieve user ID from get_my_profile response.")
112
+
113
+ message = {
114
+ "subject": subject,
115
+ "body": {"contentType": body_content_type, "content": body},
116
+ "toRecipients": [{"emailAddress": {"address": email}} for email in to_recipients],
117
+ }
118
+ if cc_recipients:
119
+ message["ccRecipients"] = [{"emailAddress": {"address": email}} for email in cc_recipients]
120
+ if bcc_recipients:
121
+ message["bccRecipients"] = [{"emailAddress": {"address": email}} for email in bcc_recipients]
122
+ if attachments:
123
+ message["attachments"] = attachments
124
+
125
+ request_body_data = {
126
+ "message": message,
127
+ "saveToSentItems": save_to_sent_items,
128
+ }
129
+
130
+ url = f"{self.base_url}/users/{user_id}/sendMail"
131
+
132
+ response = self._post(
133
+ url,
134
+ data=request_body_data,
135
+ params={},
136
+ content_type="application/json",
137
+ )
138
+ return self._handle_response(response)
139
+
140
+ def get_email_folder(
141
+ self,
142
+ folder_id: str,
143
+ user_id: str | None = None,
144
+ include_hidden: bool | None = None,
145
+ select: list[str] | None = None,
146
+ expand: list[str] | None = None,
147
+ ) -> dict[str, Any]:
148
+ """
149
+ Retrieves a specific email folder's metadata by its ID.
150
+
151
+ Args:
152
+ folder_id (str): The unique identifier for the mail folder.
153
+ user_id (str, optional): The ID of the user who owns the folder. Defaults to the authenticated user.
154
+ include_hidden (bool, optional): If true, includes hidden folders in the results.
155
+ select (list[str], optional): A list of properties to return.
156
+ expand (list[str], optional): A list of related entities to expand.
157
+
158
+ Returns:
159
+ dict[str, Any]: A dictionary containing the mail folder's metadata.
160
+
161
+ Raises:
162
+ HTTPStatusError: If the API request fails.
163
+ ValueError: If user_id cannot be retrieved or folder_id is missing.
164
+ Tags:
165
+ important
166
+ """
167
+ if user_id is None:
168
+ user_info = self.get_my_profile()
169
+ user_id = user_info.get("userPrincipalName")
170
+ if not user_id:
171
+ raise ValueError("Could not retrieve user ID from get_my_profile response.")
172
+ if not folder_id:
173
+ raise ValueError("Missing required parameter 'folder_id'.")
174
+
175
+ url = f"{self.base_url}/users/{user_id}/mailFolders/{folder_id}"
176
+ select_str = ",".join(select) if select else None
177
+ expand_str = ",".join(expand) if expand else None
178
+
179
+ query_params = {
180
+ k: v
181
+ for k, v in [
182
+ ("includeHiddenFolders", include_hidden),
183
+ ("$select", select_str),
184
+ ("$expand", expand_str),
185
+ ]
186
+ if v is not None
187
+ }
188
+ response = self._get(url, params=query_params)
189
+ return self._handle_response(response)
190
+
191
+ def list_emails(
192
+ self,
193
+ user_id: str | None = None,
194
+ select: list[str] = ["bodyPreview"],
195
+ include_hidden: bool | None = None,
196
+ top: int | None = None,
197
+ skip: int | None = None,
198
+ search: str | None = None,
199
+ filter: str | None = None,
200
+ count: bool | None = None,
201
+ orderby: list[str] | None = None,
202
+ expand: list[str] | None = None,
203
+ ) -> dict[str, Any]:
204
+ """
205
+ Retrieves a list of emails from a user's mailbox.
206
+
207
+ Args:
208
+ user_id (str, optional): The ID of the user. Defaults to the authenticated user.
209
+ select (list[str], optional): A list of properties to return for each email. Defaults to ['bodyPreview'].
210
+ include_hidden (bool, optional): If true, includes hidden messages.
211
+ top (int, optional): The maximum number of emails to return.
212
+ skip (int, optional): The number of emails to skip. Cannot be used with 'search'.
213
+ search (str, optional): A search query. Cannot be used with 'filter', 'orderby', or 'skip'.
214
+ filter (str, optional): A filter query. Cannot be used with 'search'.
215
+ count (bool, optional): If true, includes the total count of emails in the response.
216
+ orderby (list[str], optional): A list of properties to sort the results by. Cannot be used with 'search'.
217
+ expand (list[str], optional): A list of related entities to expand.
218
+
219
+ Returns:
220
+ dict[str, Any]: A dictionary containing a list of emails and pagination information.
221
+
222
+ Raises:
223
+ ValueError: If incompatible parameters are used together (e.g., 'search' with 'filter').
224
+ HTTPStatusError: If the API request fails.
225
+ Tags:
226
+ important
227
+ """
228
+ if search:
229
+ if filter:
230
+ raise ValueError("The 'search' parameter cannot be used with 'filter'.")
231
+ if orderby:
232
+ raise ValueError("The 'search' parameter cannot be used with 'orderby'.")
233
+ if skip:
234
+ raise ValueError("The 'search' parameter cannot be used with 'skip'. Use pagination via @odata.nextLink instead.")
235
+
236
+ if user_id is None:
237
+ user_info = self.get_my_profile()
238
+ user_id = user_info.get("userPrincipalName")
239
+ if not user_id:
240
+ raise ValueError("Could not retrieve user ID from get_my_profile response.")
241
+
242
+ url = f"{self.base_url}/users/{user_id}/messages"
243
+ select_str = ",".join(select) if select else None
244
+ orderby_str = ",".join(orderby) if orderby else None
245
+ expand_str = ",".join(expand) if expand else None
246
+
247
+ query_params = {
248
+ k: v
249
+ for k, v in [
250
+ ("includeHiddenMessages", include_hidden),
251
+ ("$top", top),
252
+ ("$skip", skip),
253
+ ("$search", search),
254
+ ("$filter", filter),
255
+ ("$count", count),
256
+ ("$orderby", orderby_str),
257
+ ("$select", select_str),
258
+ ("$expand", expand_str),
259
+ ]
260
+ if v is not None
261
+ }
262
+
263
+ response = self._get(url, params=query_params)
264
+ return self._handle_response(response)
265
+
266
+ def get_email(
267
+ self,
268
+ message_id: str,
269
+ user_id: str | None = None,
270
+ include_hidden: bool | None = None,
271
+ select: list[str] | None = None,
272
+ expand: list[str] | None = None,
273
+ ) -> dict[str, Any]:
274
+ """
275
+ Retrieves a specific email by its ID.
276
+
277
+ Args:
278
+ message_id (str): The unique identifier for the email.
279
+ user_id (str, optional): The ID of the user who owns the email. Defaults to the authenticated user.
280
+ include_hidden (bool, optional): If true, includes hidden messages.
281
+ select (list[str], optional): A list of properties to return.
282
+ expand (list[str], optional): A list of related entities to expand.
283
+
284
+ Returns:
285
+ dict[str, Any]: A dictionary containing the email's details.
286
+
287
+ Raises:
288
+ HTTPStatusError: If the API request fails.
289
+ ValueError: If user_id cannot be retrieved or message_id is missing.
290
+ Tags:
291
+ important
292
+ """
293
+ if user_id is None:
294
+ user_info = self.get_my_profile()
295
+ user_id = user_info.get("userPrincipalName")
296
+ if not user_id:
297
+ raise ValueError("Could not retrieve user ID from get_my_profile response.")
298
+ if not message_id:
299
+ raise ValueError("Missing required parameter 'message_id'.")
300
+
301
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}"
302
+ select_str = ",".join(select) if select else None
303
+ expand_str = ",".join(expand) if expand else None
304
+
305
+ query_params = {
306
+ k: v
307
+ for k, v in [
308
+ ("includeHiddenMessages", include_hidden),
309
+ ("$select", select_str),
310
+ ("$expand", expand_str),
311
+ ]
312
+ if v is not None
313
+ }
314
+ response = self._get(url, params=query_params)
315
+ return self._handle_response(response)
316
+
317
+ def delete_email(self, message_id: str, user_id: str | None = None) -> dict[str, Any]:
318
+ """
319
+ Permanently deletes a specific email by its ID.
320
+
321
+ Args:
322
+ message_id (str): The unique identifier for the email to be deleted.
323
+ user_id (str, optional): The ID of the user who owns the email. Defaults to the authenticated user.
324
+
325
+ Returns:
326
+ dict[str, Any]: A dictionary confirming the deletion.
327
+
328
+ Raises:
329
+ HTTPStatusError: If the API request fails.
330
+ ValueError: If user_id cannot be retrieved or message_id is missing.
331
+ Tags:
332
+ important
333
+ """
334
+ if user_id is None:
335
+ user_info = self.get_my_profile()
336
+ user_id = user_info.get("userPrincipalName")
337
+ if not user_id:
338
+ raise ValueError("Could not retrieve user ID from get_my_profile response.")
339
+ if not message_id:
340
+ raise ValueError("Missing required parameter 'message_id'.")
341
+
342
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}"
343
+ response = self._delete(url, params={})
344
+ return self._handle_response(response)
345
+
346
+ def list_email_attachments(
347
+ self,
348
+ message_id: str,
349
+ user_id: str | None = None,
350
+ top: int | None = None,
351
+ skip: int | None = None,
352
+ search: str | None = None,
353
+ filter: str | None = None,
354
+ count: bool | None = None,
355
+ orderby: list[str] | None = None,
356
+ select: list[str] | None = None,
357
+ expand: list[str] | None = None,
358
+ ) -> dict[str, Any]:
359
+ """
360
+ Retrieves attachments for a specific email.
361
+
362
+ Args:
363
+ message_id (str): The unique identifier for the email.
364
+ user_id (str, optional): The ID of the user who owns the email. Defaults to the authenticated user.
365
+ top (int, optional): The maximum number of attachments to return.
366
+ skip (int, optional): The number of attachments to skip. Cannot be used with 'search'.
367
+ search (str, optional): A search query. Cannot be used with 'filter', 'orderby', or 'skip'.
368
+ filter (str, optional): A filter query. Cannot be used with 'search'.
369
+ count (bool, optional): If true, includes the total count of attachments.
370
+ orderby (list[str], optional): A list of properties to sort by. Cannot be used with 'search'.
371
+ select (list[str], optional): A list of properties to return.
372
+ expand (list[str], optional): A list of related entities to expand.
373
+
374
+ Returns:
375
+ dict[str, Any]: A dictionary containing a list of attachments.
376
+
377
+ Raises:
378
+ ValueError: If incompatible parameters are used together.
379
+ HTTPStatusError: If the API request fails.
380
+ Tags:
381
+ important
382
+ """
383
+ if search:
384
+ if filter:
385
+ raise ValueError("The 'search' parameter cannot be used with 'filter'.")
386
+ if orderby:
387
+ raise ValueError("The 'search' parameter cannot be used with 'orderby'.")
388
+ if skip:
389
+ raise ValueError("The 'search' parameter cannot be used with 'skip'. Use pagination via @odata.nextLink instead.")
390
+
391
+ if user_id is None:
392
+ user_info = self.get_my_profile()
393
+ user_id = user_info.get("userPrincipalName")
394
+ if not user_id:
395
+ raise ValueError("Could not retrieve user ID from get_my_profile response.")
396
+ if not message_id:
397
+ raise ValueError("Missing required parameter 'message_id'.")
398
+
399
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}/attachments"
400
+ orderby_str = ",".join(orderby) if orderby else None
401
+ select_str = ",".join(select) if select else None
402
+ expand_str = ",".join(expand) if expand else None
403
+
404
+ query_params = {
405
+ k: v
406
+ for k, v in [
407
+ ("$top", top),
408
+ ("$skip", skip),
409
+ ("$search", search),
410
+ ("$filter", filter),
411
+ ("$count", count),
412
+ ("$orderby", orderby_str),
413
+ ("$select", select_str),
414
+ ("$expand", expand_str),
415
+ ]
416
+ if v is not None
417
+ }
418
+ response = self._get(url, params=query_params)
419
+ return self._handle_response(response)
420
+
421
+ def get_attachment(
422
+ self,
423
+ message_id: str,
424
+ attachment_id: str,
425
+ user_id: str | None = None,
426
+ ) -> dict[str, Any]:
427
+ """
428
+ Retrieves a specific attachment from an email message and formats it as a dictionary.
429
+
430
+ Args:
431
+ message_id (str): The ID of the email message.
432
+ attachment_id (str): The ID of the attachment.
433
+ user_id (str, optional): The ID of the user. Defaults to the authenticated user.
434
+
435
+ Returns:
436
+ dict[str, Any]: A dictionary containing the attachment details:
437
+ - 'type' (str): The general type of the attachment (e.g., "image", "audio", "video", "file").
438
+ - 'data' (str): The base64 encoded content of the attachment.
439
+ - 'mime_type' (str): The MIME type of the attachment.
440
+ - 'file_name' (str): The name of the attachment file.
441
+ Tags:
442
+ important
443
+ """
444
+ if user_id is None:
445
+ user_info = self.get_my_profile()
446
+ user_id = user_info.get("userPrincipalName")
447
+ if not user_id:
448
+ raise ValueError("Could not retrieve user ID.")
449
+ if not message_id or not attachment_id:
450
+ raise ValueError("Missing required parameter 'message_id' or 'attachment_id'.")
451
+
452
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}/attachments/{attachment_id}"
453
+
454
+ response = self._get(url, params={})
455
+ attachment_data = self._handle_response(response)
456
+
457
+ content_type = attachment_data.get("contentType", "application/octet-stream")
458
+ attachment_type = content_type.split("/")[0] if "/" in content_type else "file"
459
+ if attachment_type not in ["image", "audio", "video", "text"]:
460
+ attachment_type = "file"
461
+
462
+ return {
463
+ "type": attachment_type,
464
+ "data": attachment_data.get("contentBytes"),
465
+ "mime_type": content_type,
466
+ "file_name": attachment_data.get("name"),
467
+ }
468
+
469
+ def get_my_profile(self) -> dict[str, Any]:
470
+ """
471
+ Fetches the userPrincipalName for the currently authenticated user.
472
+
473
+ Returns:
474
+ dict[str, Any]: A dictionary containing the user's principal name.
475
+
476
+ Raises:
477
+ HTTPStatusError: If the API request fails.
478
+ """
479
+ url = f"{self.base_url}/me"
480
+ query_params = {"$select": "userPrincipalName"}
481
+ response = self._get(url, params=query_params)
482
+ return self._handle_response(response)
483
+
484
+ def get_next_page_results(self, url: str) -> dict[str, Any]:
485
+ """
486
+ Retrieves the next page of results from a paginated API response.
487
+
488
+ Args:
489
+ url (str): The full URL for the next page of results (@odata.nextLink).
490
+
491
+ Returns:
492
+ dict[str, Any]: A dictionary containing the next page of results.
493
+
494
+ Raises:
495
+ ValueError: If the URL is missing or invalid.
496
+ Tags:
497
+ important
498
+ """
499
+ if not url:
500
+ raise ValueError("Missing required parameter 'url'.")
501
+ if not url.startswith(self.base_url):
502
+ raise ValueError(f"The provided URL must start with '{self.base_url}'.")
503
+
504
+ relative_part = url[len(self.base_url) :]
505
+ parsed_relative = urlparse(relative_part)
506
+ path_only = parsed_relative.path
507
+ params = {k: v[0] for k, v in parse_qs(parsed_relative.query).items()}
508
+
509
+ response = self._get(path_only, params=params)
510
+ return self._handle_response(response)
511
+
512
+ def list_tools(self):
513
+ return [
514
+ self.reply_to_email,
515
+ self.send_email,
516
+ self.get_email_folder,
517
+ self.list_emails,
518
+ self.get_email,
519
+ self.delete_email,
520
+ self.list_email_attachments,
521
+ self.get_attachment,
522
+ self.get_my_profile,
523
+ self.get_next_page_results,
524
+ ]