magone-mcp-core 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 (334) hide show
  1. magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +68 -0
  2. magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/config.yml +14 -0
  3. magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/connector_request.yml +49 -0
  4. magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/question.yml +38 -0
  5. magone_mcp_core-0.1.0/.github/dependabot.yml +52 -0
  6. magone_mcp_core-0.1.0/.github/pull_request_template.md +25 -0
  7. magone_mcp_core-0.1.0/.github/workflows/ci.yml +358 -0
  8. magone_mcp_core-0.1.0/.github/workflows/codeql.yml +86 -0
  9. magone_mcp_core-0.1.0/.github/workflows/dco.yml +61 -0
  10. magone_mcp_core-0.1.0/.github/workflows/notify-platform.yml +86 -0
  11. magone_mcp_core-0.1.0/.github/workflows/publish.yml +276 -0
  12. magone_mcp_core-0.1.0/.github/workflows/scorecard.yml +96 -0
  13. magone_mcp_core-0.1.0/.gitignore +13 -0
  14. magone_mcp_core-0.1.0/CHANGELOG.md +137 -0
  15. magone_mcp_core-0.1.0/CODEOWNERS +23 -0
  16. magone_mcp_core-0.1.0/CODE_OF_CONDUCT.md +140 -0
  17. magone_mcp_core-0.1.0/CONTRIBUTING.md +424 -0
  18. magone_mcp_core-0.1.0/Dockerfile +99 -0
  19. magone_mcp_core-0.1.0/GOVERNANCE.md +103 -0
  20. magone_mcp_core-0.1.0/LICENSE +202 -0
  21. magone_mcp_core-0.1.0/MAINTAINERS.md +27 -0
  22. magone_mcp_core-0.1.0/NOTICE +10 -0
  23. magone_mcp_core-0.1.0/PKG-INFO +394 -0
  24. magone_mcp_core-0.1.0/README.md +315 -0
  25. magone_mcp_core-0.1.0/RELEASING.md +122 -0
  26. magone_mcp_core-0.1.0/SECURITY.md +84 -0
  27. magone_mcp_core-0.1.0/SUPPORT.md +46 -0
  28. magone_mcp_core-0.1.0/connectors/__init__.py +5 -0
  29. magone_mcp_core-0.1.0/connectors/atlassian_confluence/__init__.py +5 -0
  30. magone_mcp_core-0.1.0/connectors/atlassian_confluence/__main__.py +19 -0
  31. magone_mcp_core-0.1.0/connectors/atlassian_confluence/_shared/__init__.py +1 -0
  32. magone_mcp_core-0.1.0/connectors/atlassian_confluence/_shared/atlassian_auth.py +231 -0
  33. magone_mcp_core-0.1.0/connectors/atlassian_confluence/server.json +34 -0
  34. magone_mcp_core-0.1.0/connectors/atlassian_confluence/server.py +1777 -0
  35. magone_mcp_core-0.1.0/connectors/atlassian_confluence/tests/__init__.py +0 -0
  36. magone_mcp_core-0.1.0/connectors/atlassian_confluence/tests/test_site_resolution.py +66 -0
  37. magone_mcp_core-0.1.0/connectors/atlassian_jira/__init__.py +5 -0
  38. magone_mcp_core-0.1.0/connectors/atlassian_jira/__main__.py +19 -0
  39. magone_mcp_core-0.1.0/connectors/atlassian_jira/_shared/__init__.py +1 -0
  40. magone_mcp_core-0.1.0/connectors/atlassian_jira/_shared/atlassian_auth.py +231 -0
  41. magone_mcp_core-0.1.0/connectors/atlassian_jira/server.json +34 -0
  42. magone_mcp_core-0.1.0/connectors/atlassian_jira/server.py +2508 -0
  43. magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/__init__.py +0 -0
  44. magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/test_attachment_file_references.py +102 -0
  45. magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/test_request_body_limit.py +101 -0
  46. magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/test_site_resolution.py +66 -0
  47. magone_mcp_core-0.1.0/connectors/cloudflare_r2/__init__.py +5 -0
  48. magone_mcp_core-0.1.0/connectors/cloudflare_r2/__main__.py +19 -0
  49. magone_mcp_core-0.1.0/connectors/cloudflare_r2/server.json +34 -0
  50. magone_mcp_core-0.1.0/connectors/cloudflare_r2/server.py +568 -0
  51. magone_mcp_core-0.1.0/connectors/cloudflare_r2/tests/__init__.py +0 -0
  52. magone_mcp_core-0.1.0/connectors/cloudflare_r2/tests/test_shared_ssrf_check.py +26 -0
  53. magone_mcp_core-0.1.0/connectors/cloudflare_r2/tools/__init__.py +4 -0
  54. magone_mcp_core-0.1.0/connectors/cloudflare_r2/tools/storage.py +172 -0
  55. magone_mcp_core-0.1.0/connectors/cloudflare_r2/tools/url_fetch.py +11 -0
  56. magone_mcp_core-0.1.0/connectors/csv_to_sql/__init__.py +5 -0
  57. magone_mcp_core-0.1.0/connectors/csv_to_sql/__main__.py +16 -0
  58. magone_mcp_core-0.1.0/connectors/csv_to_sql/_connection.py +148 -0
  59. magone_mcp_core-0.1.0/connectors/csv_to_sql/_csv.py +288 -0
  60. magone_mcp_core-0.1.0/connectors/csv_to_sql/server.py +628 -0
  61. magone_mcp_core-0.1.0/connectors/csv_to_sql/tests/__init__.py +0 -0
  62. magone_mcp_core-0.1.0/connectors/csv_to_sql/tests/test_csv_to_sql.py +289 -0
  63. magone_mcp_core-0.1.0/connectors/database/__init__.py +5 -0
  64. magone_mcp_core-0.1.0/connectors/database/__main__.py +19 -0
  65. magone_mcp_core-0.1.0/connectors/database/_shared/__init__.py +1 -0
  66. magone_mcp_core-0.1.0/connectors/database/_shared/db_errors.py +65 -0
  67. magone_mcp_core-0.1.0/connectors/database/_shared/sql_safety.py +154 -0
  68. magone_mcp_core-0.1.0/connectors/database/connectors/__init__.py +84 -0
  69. magone_mcp_core-0.1.0/connectors/database/connectors/base.py +92 -0
  70. magone_mcp_core-0.1.0/connectors/database/connectors/errors.py +10 -0
  71. magone_mcp_core-0.1.0/connectors/database/connectors/mongo_helpers.py +113 -0
  72. magone_mcp_core-0.1.0/connectors/database/connectors/mongodb.py +161 -0
  73. magone_mcp_core-0.1.0/connectors/database/connectors/mssql.py +421 -0
  74. magone_mcp_core-0.1.0/connectors/database/connectors/mysql.py +271 -0
  75. magone_mcp_core-0.1.0/connectors/database/connectors/oracle.py +545 -0
  76. magone_mcp_core-0.1.0/connectors/database/connectors/pool.py +86 -0
  77. magone_mcp_core-0.1.0/connectors/database/connectors/postgresql.py +361 -0
  78. magone_mcp_core-0.1.0/connectors/database/connectors/sql_common.py +254 -0
  79. magone_mcp_core-0.1.0/connectors/database/server.json +34 -0
  80. magone_mcp_core-0.1.0/connectors/database/server.py +545 -0
  81. magone_mcp_core-0.1.0/connectors/database/tests/__init__.py +0 -0
  82. magone_mcp_core-0.1.0/connectors/database/tests/test_mysql_tls.py +75 -0
  83. magone_mcp_core-0.1.0/connectors/database/tests/test_tools_reach_the_driver.py +138 -0
  84. magone_mcp_core-0.1.0/connectors/database/tools/__init__.py +7 -0
  85. magone_mcp_core-0.1.0/connectors/database/tools/connection.py +284 -0
  86. magone_mcp_core-0.1.0/connectors/docusign/__init__.py +5 -0
  87. magone_mcp_core-0.1.0/connectors/docusign/__main__.py +19 -0
  88. magone_mcp_core-0.1.0/connectors/docusign/docusign_auth.py +206 -0
  89. magone_mcp_core-0.1.0/connectors/docusign/server.json +34 -0
  90. magone_mcp_core-0.1.0/connectors/docusign/server.py +885 -0
  91. magone_mcp_core-0.1.0/connectors/docusign/tests/__init__.py +0 -0
  92. magone_mcp_core-0.1.0/connectors/docusign/tests/test_token_cache.py +81 -0
  93. magone_mcp_core-0.1.0/connectors/docusign/tools/__init__.py +7 -0
  94. magone_mcp_core-0.1.0/connectors/filesystem/__init__.py +5 -0
  95. magone_mcp_core-0.1.0/connectors/filesystem/__main__.py +16 -0
  96. magone_mcp_core-0.1.0/connectors/filesystem/server.py +528 -0
  97. magone_mcp_core-0.1.0/connectors/filesystem/tests/__init__.py +0 -0
  98. magone_mcp_core-0.1.0/connectors/filesystem/tests/test_filesystem.py +218 -0
  99. magone_mcp_core-0.1.0/connectors/google_calendar/__init__.py +5 -0
  100. magone_mcp_core-0.1.0/connectors/google_calendar/__main__.py +19 -0
  101. magone_mcp_core-0.1.0/connectors/google_calendar/_shared/__init__.py +135 -0
  102. magone_mcp_core-0.1.0/connectors/google_calendar/server.json +34 -0
  103. magone_mcp_core-0.1.0/connectors/google_calendar/server.py +306 -0
  104. magone_mcp_core-0.1.0/connectors/google_calendar/tools/__init__.py +4 -0
  105. magone_mcp_core-0.1.0/connectors/google_drive/__init__.py +5 -0
  106. magone_mcp_core-0.1.0/connectors/google_drive/__main__.py +19 -0
  107. magone_mcp_core-0.1.0/connectors/google_drive/_shared/__init__.py +182 -0
  108. magone_mcp_core-0.1.0/connectors/google_drive/server.py +289 -0
  109. magone_mcp_core-0.1.0/connectors/google_drive/tools/__init__.py +4 -0
  110. magone_mcp_core-0.1.0/connectors/google_gmail/__init__.py +5 -0
  111. magone_mcp_core-0.1.0/connectors/google_gmail/__main__.py +19 -0
  112. magone_mcp_core-0.1.0/connectors/google_gmail/_shared/__init__.py +135 -0
  113. magone_mcp_core-0.1.0/connectors/google_gmail/server.json +34 -0
  114. magone_mcp_core-0.1.0/connectors/google_gmail/server.py +296 -0
  115. magone_mcp_core-0.1.0/connectors/google_gmail/tools/__init__.py +4 -0
  116. magone_mcp_core-0.1.0/connectors/image_generation/__init__.py +5 -0
  117. magone_mcp_core-0.1.0/connectors/image_generation/__main__.py +19 -0
  118. magone_mcp_core-0.1.0/connectors/image_generation/gemini.py +119 -0
  119. magone_mcp_core-0.1.0/connectors/image_generation/server.json +34 -0
  120. magone_mcp_core-0.1.0/connectors/image_generation/server.py +207 -0
  121. magone_mcp_core-0.1.0/connectors/image_generation/tests/__init__.py +0 -0
  122. magone_mcp_core-0.1.0/connectors/image_generation/tests/test_generate_image.py +257 -0
  123. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/__init__.py +5 -0
  124. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/__main__.py +19 -0
  125. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/server.json +34 -0
  126. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/server.py +481 -0
  127. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tests/__init__.py +0 -0
  128. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tests/test_vendor_errors.py +56 -0
  129. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tools/__init__.py +7 -0
  130. magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tools/_client.py +98 -0
  131. magone_mcp_core-0.1.0/connectors/linear/__init__.py +5 -0
  132. magone_mcp_core-0.1.0/connectors/linear/__main__.py +19 -0
  133. magone_mcp_core-0.1.0/connectors/linear/server.json +34 -0
  134. magone_mcp_core-0.1.0/connectors/linear/server.py +1543 -0
  135. magone_mcp_core-0.1.0/connectors/linear/tests/__init__.py +0 -0
  136. magone_mcp_core-0.1.0/connectors/linear/tests/test_get_issue_comments.py +57 -0
  137. magone_mcp_core-0.1.0/connectors/linear/tests/test_issues.py +152 -0
  138. magone_mcp_core-0.1.0/connectors/linear/tools/__init__.py +4 -0
  139. magone_mcp_core-0.1.0/connectors/linear/tools/_client.py +403 -0
  140. magone_mcp_core-0.1.0/connectors/linkedin/__init__.py +5 -0
  141. magone_mcp_core-0.1.0/connectors/linkedin/__main__.py +19 -0
  142. magone_mcp_core-0.1.0/connectors/linkedin/_client.py +393 -0
  143. magone_mcp_core-0.1.0/connectors/linkedin/server.py +1121 -0
  144. magone_mcp_core-0.1.0/connectors/linkedin/tests/__init__.py +0 -0
  145. magone_mcp_core-0.1.0/connectors/linkedin/tests/test_linkedin.py +601 -0
  146. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/__init__.py +5 -0
  147. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/__main__.py +19 -0
  148. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/_shared/__init__.py +18 -0
  149. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/server.json +34 -0
  150. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/server.py +832 -0
  151. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tests/__init__.py +0 -0
  152. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tests/test_app_only_flow.py +96 -0
  153. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tools/__init__.py +4 -0
  154. magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tools/_constants.py +61 -0
  155. magone_mcp_core-0.1.0/connectors/microsoft_teams/__init__.py +5 -0
  156. magone_mcp_core-0.1.0/connectors/microsoft_teams/__main__.py +19 -0
  157. magone_mcp_core-0.1.0/connectors/microsoft_teams/_shared/__init__.py +144 -0
  158. magone_mcp_core-0.1.0/connectors/microsoft_teams/server.json +34 -0
  159. magone_mcp_core-0.1.0/connectors/microsoft_teams/server.py +1303 -0
  160. magone_mcp_core-0.1.0/connectors/microsoft_teams/tests/__init__.py +0 -0
  161. magone_mcp_core-0.1.0/connectors/microsoft_teams/tests/test_mentions.py +89 -0
  162. magone_mcp_core-0.1.0/connectors/microsoft_teams/tools/__init__.py +14 -0
  163. magone_mcp_core-0.1.0/connectors/microsoft_teams/tools/_constants.py +229 -0
  164. magone_mcp_core-0.1.0/connectors/otp_verification/__init__.py +5 -0
  165. magone_mcp_core-0.1.0/connectors/otp_verification/__main__.py +19 -0
  166. magone_mcp_core-0.1.0/connectors/otp_verification/server.json +34 -0
  167. magone_mcp_core-0.1.0/connectors/otp_verification/server.py +582 -0
  168. magone_mcp_core-0.1.0/connectors/otp_verification/tests/__init__.py +0 -0
  169. magone_mcp_core-0.1.0/connectors/otp_verification/tests/test_code_storage.py +193 -0
  170. magone_mcp_core-0.1.0/connectors/otp_verification/tests/test_generate_metadata.py +72 -0
  171. magone_mcp_core-0.1.0/connectors/otp_verification/tools/__init__.py +7 -0
  172. magone_mcp_core-0.1.0/connectors/otp_verification/tools/_constants.py +24 -0
  173. magone_mcp_core-0.1.0/connectors/otp_verification/tools/_db.py +77 -0
  174. magone_mcp_core-0.1.0/connectors/outlook_calendar/__init__.py +5 -0
  175. magone_mcp_core-0.1.0/connectors/outlook_calendar/__main__.py +19 -0
  176. magone_mcp_core-0.1.0/connectors/outlook_calendar/_shared/__init__.py +144 -0
  177. magone_mcp_core-0.1.0/connectors/outlook_calendar/server.json +34 -0
  178. magone_mcp_core-0.1.0/connectors/outlook_calendar/server.py +1002 -0
  179. magone_mcp_core-0.1.0/connectors/outlook_calendar/tests/__init__.py +0 -0
  180. magone_mcp_core-0.1.0/connectors/outlook_calendar/tests/test_timezones.py +24 -0
  181. magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/__init__.py +15 -0
  182. magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/_availability.py +114 -0
  183. magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/_constants.py +16 -0
  184. magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/_when.py +177 -0
  185. magone_mcp_core-0.1.0/connectors/outlook_email/__init__.py +5 -0
  186. magone_mcp_core-0.1.0/connectors/outlook_email/__main__.py +19 -0
  187. magone_mcp_core-0.1.0/connectors/outlook_email/_shared/__init__.py +1 -0
  188. magone_mcp_core-0.1.0/connectors/outlook_email/_shared/microsoft_graph.py +401 -0
  189. magone_mcp_core-0.1.0/connectors/outlook_email/server.json +34 -0
  190. magone_mcp_core-0.1.0/connectors/outlook_email/server.py +4052 -0
  191. magone_mcp_core-0.1.0/connectors/outlook_email/tests/__init__.py +0 -0
  192. magone_mcp_core-0.1.0/connectors/outlook_email/tests/_graph_mock.py +56 -0
  193. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_app_only_paths.py +99 -0
  194. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_attachment_url_ssrf.py +153 -0
  195. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_date_timezone.py +69 -0
  196. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_get_email_categories_and_empty_mailbox.py +96 -0
  197. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_reply_email_mailbox.py +160 -0
  198. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_request_body_limit.py +20 -0
  199. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_set_email_categories.py +107 -0
  200. magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_strip_quoted_reply.py +120 -0
  201. magone_mcp_core-0.1.0/connectors/outlook_email/tools/__init__.py +19 -0
  202. magone_mcp_core-0.1.0/connectors/outlook_email/tools/_budget.py +50 -0
  203. magone_mcp_core-0.1.0/connectors/outlook_email/tools/_constants.py +312 -0
  204. magone_mcp_core-0.1.0/connectors/outlook_email/tools/_extract.py +182 -0
  205. magone_mcp_core-0.1.0/connectors/outlook_email/tools/_message.py +62 -0
  206. magone_mcp_core-0.1.0/connectors/outlook_email/tools/_reply_send.py +96 -0
  207. magone_mcp_core-0.1.0/connectors/outlook_email/tools/_send.py +168 -0
  208. magone_mcp_core-0.1.0/connectors/outlook_email/tools/download.py +200 -0
  209. magone_mcp_core-0.1.0/connectors/publication.json +63 -0
  210. magone_mcp_core-0.1.0/connectors/surveymonkey/__init__.py +5 -0
  211. magone_mcp_core-0.1.0/connectors/surveymonkey/__main__.py +19 -0
  212. magone_mcp_core-0.1.0/connectors/surveymonkey/server.py +2561 -0
  213. magone_mcp_core-0.1.0/connectors/surveymonkey/tests/__init__.py +0 -0
  214. magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_crud_completion.py +106 -0
  215. magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_default_includes.py +53 -0
  216. magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_field_completeness.py +110 -0
  217. magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_new_tools.py +248 -0
  218. magone_mcp_core-0.1.0/connectors/surveymonkey/tools/__init__.py +24 -0
  219. magone_mcp_core-0.1.0/connectors/surveymonkey/tools/client.py +110 -0
  220. magone_mcp_core-0.1.0/connectors/surveymonkey/tools/collector_settings.py +106 -0
  221. magone_mcp_core-0.1.0/connectors/surveymonkey/tools/filters.py +145 -0
  222. magone_mcp_core-0.1.0/connectors/trino/__init__.py +5 -0
  223. magone_mcp_core-0.1.0/connectors/trino/__main__.py +19 -0
  224. magone_mcp_core-0.1.0/connectors/trino/_shared/__init__.py +1 -0
  225. magone_mcp_core-0.1.0/connectors/trino/_shared/db_errors.py +65 -0
  226. magone_mcp_core-0.1.0/connectors/trino/_shared/sql_safety.py +154 -0
  227. magone_mcp_core-0.1.0/connectors/trino/connectors/__init__.py +5 -0
  228. magone_mcp_core-0.1.0/connectors/trino/connectors/trino_connector.py +263 -0
  229. magone_mcp_core-0.1.0/connectors/trino/server.json +34 -0
  230. magone_mcp_core-0.1.0/connectors/trino/server.py +651 -0
  231. magone_mcp_core-0.1.0/connectors/trino/tools/__init__.py +7 -0
  232. magone_mcp_core-0.1.0/connectors/trino/tools/common.py +155 -0
  233. magone_mcp_core-0.1.0/connectors/twitter_intel/__init__.py +5 -0
  234. magone_mcp_core-0.1.0/connectors/twitter_intel/__main__.py +19 -0
  235. magone_mcp_core-0.1.0/connectors/twitter_intel/client.py +173 -0
  236. magone_mcp_core-0.1.0/connectors/twitter_intel/server.py +565 -0
  237. magone_mcp_core-0.1.0/connectors/twitter_intel/tools/__init__.py +7 -0
  238. magone_mcp_core-0.1.0/connectors/vanna/__init__.py +5 -0
  239. magone_mcp_core-0.1.0/connectors/vanna/__main__.py +16 -0
  240. magone_mcp_core-0.1.0/connectors/vanna/_connection.py +148 -0
  241. magone_mcp_core-0.1.0/connectors/vanna/_engine.py +105 -0
  242. magone_mcp_core-0.1.0/connectors/vanna/_store.py +197 -0
  243. magone_mcp_core-0.1.0/connectors/vanna/server.py +1119 -0
  244. magone_mcp_core-0.1.0/connectors/vanna/tests/__init__.py +0 -0
  245. magone_mcp_core-0.1.0/connectors/vanna/tests/test_vanna.py +419 -0
  246. magone_mcp_core-0.1.0/connectors/web_search/__init__.py +5 -0
  247. magone_mcp_core-0.1.0/connectors/web_search/__main__.py +19 -0
  248. magone_mcp_core-0.1.0/connectors/web_search/server.json +34 -0
  249. magone_mcp_core-0.1.0/connectors/web_search/server.py +1275 -0
  250. magone_mcp_core-0.1.0/connectors/web_search/tests/__init__.py +0 -0
  251. magone_mcp_core-0.1.0/connectors/web_search/tests/test_serper_search.py +213 -0
  252. magone_mcp_core-0.1.0/connectors/web_search/tools/__init__.py +4 -0
  253. magone_mcp_core-0.1.0/connectors/zoom/__init__.py +5 -0
  254. magone_mcp_core-0.1.0/connectors/zoom/__main__.py +19 -0
  255. magone_mcp_core-0.1.0/connectors/zoom/server.json +34 -0
  256. magone_mcp_core-0.1.0/connectors/zoom/server.py +404 -0
  257. magone_mcp_core-0.1.0/connectors/zoom/tests/__init__.py +0 -0
  258. magone_mcp_core-0.1.0/connectors/zoom/tests/test_meeting_tools.py +194 -0
  259. magone_mcp_core-0.1.0/connectors/zoom/tools/__init__.py +4 -0
  260. magone_mcp_core-0.1.0/connectors/zoom/tools/_client.py +176 -0
  261. magone_mcp_core-0.1.0/docs/TOOLS.md +465 -0
  262. magone_mcp_core-0.1.0/docs/architecture.md +374 -0
  263. magone_mcp_core-0.1.0/docs/configuration.md +168 -0
  264. magone_mcp_core-0.1.0/docs/writing-a-connector.md +316 -0
  265. magone_mcp_core-0.1.0/pyproject.toml +150 -0
  266. magone_mcp_core-0.1.0/scripts/boundary_gate.py +129 -0
  267. magone_mcp_core-0.1.0/scripts/code_health_gate.py +146 -0
  268. magone_mcp_core-0.1.0/scripts/compile_gate.py +74 -0
  269. magone_mcp_core-0.1.0/scripts/credential_headers_gate.py +140 -0
  270. magone_mcp_core-0.1.0/scripts/dependency_gate.py +149 -0
  271. magone_mcp_core-0.1.0/scripts/gen_server_json.py +227 -0
  272. magone_mcp_core-0.1.0/scripts/gen_tool_reference.py +175 -0
  273. magone_mcp_core-0.1.0/scripts/golden_schema_gate.py +184 -0
  274. magone_mcp_core-0.1.0/scripts/permission_group_gate.py +142 -0
  275. magone_mcp_core-0.1.0/scripts/port_status.py +128 -0
  276. magone_mcp_core-0.1.0/scripts/publication_gate.py +143 -0
  277. magone_mcp_core-0.1.0/scripts/runner_label_gate.py +132 -0
  278. magone_mcp_core-0.1.0/scripts/tool_contract_lint.py +387 -0
  279. magone_mcp_core-0.1.0/src/magone_mcp_core/__init__.py +104 -0
  280. magone_mcp_core-0.1.0/src/magone_mcp_core/auth.py +233 -0
  281. magone_mcp_core-0.1.0/src/magone_mcp_core/budget.py +172 -0
  282. magone_mcp_core-0.1.0/src/magone_mcp_core/content.py +367 -0
  283. magone_mcp_core-0.1.0/src/magone_mcp_core/credentials.py +179 -0
  284. magone_mcp_core-0.1.0/src/magone_mcp_core/logging_setup.py +124 -0
  285. magone_mcp_core-0.1.0/src/magone_mcp_core/net.py +234 -0
  286. magone_mcp_core-0.1.0/src/magone_mcp_core/provenance.py +65 -0
  287. magone_mcp_core-0.1.0/src/magone_mcp_core/readonly.py +99 -0
  288. magone_mcp_core-0.1.0/src/magone_mcp_core/redact.py +191 -0
  289. magone_mcp_core-0.1.0/src/magone_mcp_core/results.py +145 -0
  290. magone_mcp_core-0.1.0/src/magone_mcp_core/schema.py +142 -0
  291. magone_mcp_core-0.1.0/src/magone_mcp_core/selection.py +145 -0
  292. magone_mcp_core-0.1.0/src/magone_mcp_core/server.py +692 -0
  293. magone_mcp_core-0.1.0/src/magone_mcp_core/text_args.py +169 -0
  294. magone_mcp_core-0.1.0/src/magone_mcp_core/transport.py +121 -0
  295. magone_mcp_core-0.1.0/tests/conformance/expected-failures.yaml +80 -0
  296. magone_mcp_core-0.1.0/tests/golden/output-schemas.json +1694 -0
  297. magone_mcp_core-0.1.0/tests/golden/port-budget.json +1 -0
  298. magone_mcp_core-0.1.0/tests/golden/tool-schemas.json +8210 -0
  299. magone_mcp_core-0.1.0/tests/test_all_connectors_import.py +84 -0
  300. magone_mcp_core-0.1.0/tests/test_authentication.py +174 -0
  301. magone_mcp_core-0.1.0/tests/test_budget_over_mcp.py +184 -0
  302. magone_mcp_core-0.1.0/tests/test_compile_gate.py +107 -0
  303. magone_mcp_core-0.1.0/tests/test_content.py +258 -0
  304. magone_mcp_core-0.1.0/tests/test_credentials.py +246 -0
  305. magone_mcp_core-0.1.0/tests/test_credentials_precedence.py +215 -0
  306. magone_mcp_core-0.1.0/tests/test_ctx_and_readonly_refusal.py +83 -0
  307. magone_mcp_core-0.1.0/tests/test_custom_route.py +167 -0
  308. magone_mcp_core-0.1.0/tests/test_declared_text_stays_text.py +281 -0
  309. magone_mcp_core-0.1.0/tests/test_docstring_census.py +112 -0
  310. magone_mcp_core-0.1.0/tests/test_entrypoints.py +92 -0
  311. magone_mcp_core-0.1.0/tests/test_error_surfacing.py +117 -0
  312. magone_mcp_core-0.1.0/tests/test_every_tool_is_callable.py +193 -0
  313. magone_mcp_core-0.1.0/tests/test_extra_content_over_mcp.py +78 -0
  314. magone_mcp_core-0.1.0/tests/test_guarantees.py +307 -0
  315. magone_mcp_core-0.1.0/tests/test_healthz.py +71 -0
  316. magone_mcp_core-0.1.0/tests/test_log_record_shape.py +46 -0
  317. magone_mcp_core-0.1.0/tests/test_log_redaction.py +92 -0
  318. magone_mcp_core-0.1.0/tests/test_net.py +196 -0
  319. magone_mcp_core-0.1.0/tests/test_output_schema.py +92 -0
  320. magone_mcp_core-0.1.0/tests/test_output_schemas_match_v1.py +55 -0
  321. magone_mcp_core-0.1.0/tests/test_publication_gate.py +128 -0
  322. magone_mcp_core-0.1.0/tests/test_readonly_env.py +107 -0
  323. magone_mcp_core-0.1.0/tests/test_request_body_limit.py +192 -0
  324. magone_mcp_core-0.1.0/tests/test_results.py +189 -0
  325. magone_mcp_core-0.1.0/tests/test_schema.py +143 -0
  326. magone_mcp_core-0.1.0/tests/test_scrape_url_ssrf.py +303 -0
  327. magone_mcp_core-0.1.0/tests/test_shutdown_hooks.py +59 -0
  328. magone_mcp_core-0.1.0/tests/test_text_arguments_every_tool.py +113 -0
  329. magone_mcp_core-0.1.0/tests/test_tool_names_resolve.py +196 -0
  330. magone_mcp_core-0.1.0/tests/test_tool_selection.py +253 -0
  331. magone_mcp_core-0.1.0/tests/test_transport_security.py +215 -0
  332. magone_mcp_core-0.1.0/tests/test_update_event_alias.py +242 -0
  333. magone_mcp_core-0.1.0/tests/test_user_agents.py +78 -0
  334. magone_mcp_core-0.1.0/tests/test_web_search_robots.py +179 -0
@@ -0,0 +1,68 @@
1
+ name: Bug report
2
+ description: A connector or the framework does something it should not, or fails to do what it says.
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for taking the time to report this.
9
+
10
+ **Security issues do not belong here.** If this could let someone misuse a credential, reach an internal address, bypass read-only mode or tool selection, or read another caller's data, report it privately instead: see SECURITY.md.
11
+
12
+ Never paste a token, API key, refresh token or private URL into an issue. Redact them.
13
+ - type: input
14
+ id: connector
15
+ attributes:
16
+ label: Connector
17
+ description: The directory under `connectors/`, or `magone-mcp-core` for the framework.
18
+ placeholder: e.g. linear
19
+ validations:
20
+ required: true
21
+ - type: input
22
+ id: tool
23
+ attributes:
24
+ label: Tool
25
+ description: The tool name, if the problem is in one tool.
26
+ placeholder: e.g. get_issue
27
+ - type: textarea
28
+ id: what-happened
29
+ attributes:
30
+ label: What happened
31
+ description: What you did, what you expected, and what happened instead. Include the tool arguments (with secrets removed) and the result or error.
32
+ validations:
33
+ required: true
34
+ - type: textarea
35
+ id: reproduce
36
+ attributes:
37
+ label: How to reproduce
38
+ description: The smallest set of steps that shows the problem.
39
+ placeholder: |
40
+ 1. pip install -e ".[linear]"
41
+ 2. MCP_MODE=local python -m connectors.linear
42
+ 3. call get_issue with ...
43
+ - type: input
44
+ id: commit
45
+ attributes:
46
+ label: Commit
47
+ description: Output of `git rev-parse --short HEAD` in your checkout.
48
+ - type: dropdown
49
+ id: mode
50
+ attributes:
51
+ label: MCP_MODE
52
+ options:
53
+ - local
54
+ - platform
55
+ - hosted
56
+ - not sure
57
+ - type: input
58
+ id: environment
59
+ attributes:
60
+ label: Environment
61
+ description: Python version, operating system, and the MCP client you used.
62
+ placeholder: Python 3.11.9, macOS 15, MCP Inspector
63
+ - type: textarea
64
+ id: logs
65
+ attributes:
66
+ label: Logs
67
+ description: Relevant server log lines, with credentials removed.
68
+ render: text
@@ -0,0 +1,14 @@
1
+ # Blank issues are off so every report arrives with the details a maintainer
2
+ # needs. Questions, bugs and connector requests each have a template; anything
3
+ # else belongs in one of the links below.
4
+ blank_issues_enabled: false
5
+ contact_links:
6
+ - name: Report a security vulnerability
7
+ url: https://github.com/magurelabs/magoneai-mcp/security/advisories/new
8
+ about: Please report vulnerabilities privately, never in a public issue. See SECURITY.md.
9
+ - name: Read the documentation
10
+ url: https://github.com/magurelabs/magoneai-mcp/blob/main/SUPPORT.md
11
+ about: Where to find the configuration reference, the architecture overview and the connector guide.
12
+ - name: Contribute a connector
13
+ url: https://github.com/magurelabs/magoneai-mcp/blob/main/CONTRIBUTING.md
14
+ about: The boundary rule, how to run every gate locally, and the step-by-step guide.
@@ -0,0 +1,49 @@
1
+ name: Connector or tool request
2
+ description: Ask for a new connector, or a tool missing from an existing one.
3
+ labels: ["connector-request"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ A connector here wraps somebody else's API, called with the caller's own credentials and storage. See "The boundary rule" in CONTRIBUTING.md before asking: a connector belongs here only if an outside developer can use it against their own account and their own storage. A tool that needs a hosted platform's own database, object store or tenant id, or that is built for one customer's systems, does not belong in this repository.
9
+ - type: dropdown
10
+ id: kind
11
+ attributes:
12
+ label: What are you asking for?
13
+ options:
14
+ - A new connector
15
+ - A new tool in an existing connector
16
+ - A change to an existing tool
17
+ validations:
18
+ required: true
19
+ - type: input
20
+ id: service
21
+ attributes:
22
+ label: Service and API
23
+ description: The vendor API, with a link to its documentation.
24
+ placeholder: e.g. Example CRM REST API v2, https://developer.example.com/api
25
+ validations:
26
+ required: true
27
+ - type: textarea
28
+ id: tools
29
+ attributes:
30
+ label: Tools you need
31
+ description: For each tool, what it should do and whether it only reads or also writes or deletes.
32
+ validations:
33
+ required: true
34
+ - type: textarea
35
+ id: auth
36
+ attributes:
37
+ label: Authentication
38
+ description: How the API authenticates (API key, OAuth 2.0 and which flow, service account) and which scopes the tools would need.
39
+ - type: textarea
40
+ id: use-case
41
+ attributes:
42
+ label: Why
43
+ description: What you are trying to do with it.
44
+ - type: checkboxes
45
+ id: contribute
46
+ attributes:
47
+ label: Contributing
48
+ options:
49
+ - label: I would like to open a pull request for this myself.
@@ -0,0 +1,38 @@
1
+ name: Question
2
+ description: Ask how to use a connector or the framework.
3
+ labels: ["question"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Please check the README, docs/configuration.md and docs/architecture.md first, and search existing issues.
9
+
10
+ Never paste a token, API key, refresh token or private URL into an issue. Redact them.
11
+ - type: input
12
+ id: connector
13
+ attributes:
14
+ label: Connector
15
+ description: The directory under `connectors/`, or `magone-mcp-core` for the framework.
16
+ placeholder: e.g. outlook_calendar
17
+ - type: textarea
18
+ id: question
19
+ attributes:
20
+ label: Your question
21
+ description: What you are trying to do, what you tried, and what happened.
22
+ validations:
23
+ required: true
24
+ - type: dropdown
25
+ id: mode
26
+ attributes:
27
+ label: MCP_MODE
28
+ options:
29
+ - local
30
+ - platform
31
+ - hosted
32
+ - not sure
33
+ - type: input
34
+ id: environment
35
+ attributes:
36
+ label: Environment
37
+ description: Python version, operating system, how you run it (source checkout or container), and the MCP client you used.
38
+ placeholder: Python 3.11.9, macOS 15, container, MCP Inspector
@@ -0,0 +1,52 @@
1
+ # Dependency updates, weekly and grouped so they arrive as a few reviewable
2
+ # pull requests rather than a stream of single bumps.
3
+ #
4
+ # Every update is an ordinary pull request: it runs the full CI, needs a
5
+ # maintainer's review like any other change, and is never merged
6
+ # automatically.
7
+ #
8
+ # GitHub Actions stay pinned to full commit SHAs. Dependabot updates the SHA
9
+ # and the version comment beside it together.
10
+ #
11
+ # ruff is pinned twice, in the `dev` extra and in ci.yml's "Install ruff"
12
+ # step. Dependabot can only update the first, so a ruff bump must update
13
+ # ci.yml in the same pull request before it is merged.
14
+
15
+ version: 2
16
+ updates:
17
+ - package-ecosystem: github-actions
18
+ directory: /
19
+ schedule:
20
+ interval: weekly
21
+ day: monday
22
+ open-pull-requests-limit: 5
23
+ commit-message:
24
+ prefix: ci
25
+ groups:
26
+ github-actions:
27
+ patterns: ["*"]
28
+
29
+ # pyproject.toml: the core's dependencies, `dev`, and every connector extra.
30
+ - package-ecosystem: pip
31
+ directory: /
32
+ schedule:
33
+ interval: weekly
34
+ day: monday
35
+ open-pull-requests-limit: 5
36
+ commit-message:
37
+ prefix: build
38
+ groups:
39
+ python-minor-and-patch:
40
+ update-types: ["minor", "patch"]
41
+ python-major:
42
+ update-types: ["major"]
43
+
44
+ # The Dockerfile pins its base image by digest.
45
+ - package-ecosystem: docker
46
+ directory: /
47
+ schedule:
48
+ interval: weekly
49
+ day: monday
50
+ open-pull-requests-limit: 2
51
+ commit-message:
52
+ prefix: build
@@ -0,0 +1,25 @@
1
+ ## What this changes
2
+
3
+ <!-- One or two sentences: what, and why. Link the issue if there is one ("Fixes #123"). -->
4
+
5
+ ## How it was tested
6
+
7
+ <!-- The commands you ran and what they showed. The whole suite runs without credentials or network:
8
+ pytest tests/ connectors/ -q
9
+ Every gate is listed in CONTRIBUTING.md under "Running the tests and every gate". -->
10
+
11
+ ## Checklist
12
+
13
+ <!-- Tick only what is true. Strike through (~~like this~~) anything that does not apply. -->
14
+
15
+ - [ ] Every commit is signed off (`git commit -s`) by its author, as the DCO check requires
16
+ - [ ] Commit messages follow the convention in CONTRIBUTING.md (`type(scope): summary`)
17
+ - [ ] `ruff check .` and `ruff format --check .` pass
18
+ - [ ] `pytest tests/ connectors/ -q` passes, and new behaviour has a test that needs no credentials or network
19
+ - [ ] Every gate in CONTRIBUTING.md passes locally
20
+ - [ ] New or changed tools take credentials per call through `credential_headers=`, carry both `readOnlyHint` and `destructiveHint`, declare a `permission_group`, and every schema property has a description
21
+ - [ ] If a tool's schema changed or tools were added, `python scripts/golden_schema_gate.py --update` was run and the baseline is in its own commit
22
+ - [ ] If tools were added, removed or re-described, `python scripts/gen_tool_reference.py` was run
23
+ - [ ] A new connector meets the boundary rule, has an entry in `connectors/publication.json` (new connectors start `blocked` with a reason), and is in the conformance scope in `ci.yml`
24
+ - [ ] Documentation and `CHANGELOG.md` (under `Unreleased`) are updated where behaviour changed
25
+ - [ ] No credential, token, private URL, internal hostname, customer name or personal data appears in code, tests, fixtures or this description
@@ -0,0 +1,358 @@
1
+ # Jobs run on GitHub-hosted runners only.
2
+ #
3
+ # Never point a job at a self-hosted runner while this repository is public.
4
+ # ci.yml runs on pull_request, so a fork's branch would execute on that machine
5
+ # with whatever it can reach in scope. That is not left to memory:
6
+ # `scripts/runner_label_gate.py` runs below and fails if a self-hosted label and
7
+ # a public repository are ever true at the same time.
8
+ #
9
+ # Every action is pinned to a full commit SHA, with the release it corresponds
10
+ # to in a trailing comment. A tag can be moved after review; a SHA cannot.
11
+
12
+ name: CI
13
+
14
+ # `pull_request`, never `pull_request_target`.
15
+ #
16
+ # `pull_request_target` runs the workflow from the base branch with repository
17
+ # secrets available, against a fork's code. In a public repository that hands
18
+ # any contributor a way to read every secret this workflow can see. This
19
+ # repository is about to accept pull requests from strangers, so the
20
+ # distinction is load-bearing rather than stylistic.
21
+ #
22
+ # No job here needs a secret. Publication lives in its own workflow, gated on a
23
+ # protected environment rather than on a branch name, because a branch name is
24
+ # something a contributor can choose.
25
+ on:
26
+ pull_request:
27
+ push:
28
+ branches: [main]
29
+
30
+ permissions:
31
+ contents: read
32
+
33
+ concurrency:
34
+ group: ${{ github.workflow }}-${{ github.ref }}
35
+ cancel-in-progress: true
36
+
37
+ jobs:
38
+ # Which connectors can this change possibly have broken?
39
+ #
40
+ # Conformance is 25 jobs, one per connector, and it was the single most
41
+ # expensive thing in this CI. Every one of them ran on every pull request,
42
+ # including a pull request that touched one connector's docstring.
43
+ #
44
+ # The rule is deliberately conservative: a change to anything outside
45
+ # `connectors/` runs all 25, because shared code is shared. Only a diff
46
+ # confined to `connectors/<name>/` narrows the matrix, and only to the
47
+ # connectors it actually touched. Anything unrecognised falls back to all 25.
48
+ #
49
+ # Push to `main` always runs all 25, so a cross-connector break that a
50
+ # narrowed pull request could not have seen is still caught before publish.
51
+ scope:
52
+ name: Scope
53
+ runs-on: ubuntu-latest
54
+ timeout-minutes: 10
55
+ outputs:
56
+ connectors: ${{ steps.scope.outputs.connectors }}
57
+ steps:
58
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
59
+ with:
60
+ # The three-dot diff needs a real merge base. A shallow clone has none.
61
+ fetch-depth: 0
62
+ - name: Work out which connectors are in scope
63
+ id: scope
64
+ # Passed through env rather than interpolated into the script. These are
65
+ # commit SHAs so they are not attacker-controlled, but a `run:` block is
66
+ # the wrong place to learn that habit.
67
+ env:
68
+ EVENT: ${{ github.event_name }}
69
+ BASE: ${{ github.event.pull_request.base.sha }}
70
+ HEAD: ${{ github.event.pull_request.head.sha }}
71
+ run: |
72
+ set -euo pipefail
73
+ ALL="atlassian_confluence atlassian_jira cloudflare_r2 csv_to_sql database docusign filesystem google_calendar google_drive google_gmail image_generation kapso_whatsapp linear linkedin microsoft_sharepoint microsoft_teams otp_verification outlook_calendar outlook_email surveymonkey trino twitter_intel vanna web_search zoom"
74
+ to_json() { printf '%s' "$1" | tr ' ' '\n' | grep -v '^$' | sed 's/.*/"&"/' | paste -sd, - | sed 's/^/[/;s/$/]/'; }
75
+
76
+ pick="$ALL"
77
+ reason="all 25 (not a pull request)"
78
+
79
+ if [ "$EVENT" = "pull_request" ]; then
80
+ changed="$(git diff --name-only "$BASE" "$HEAD")"
81
+ if [ -z "$changed" ]; then
82
+ reason="all 25 (empty diff)"
83
+ elif printf '%s\n' "$changed" | grep -qv '^connectors/'; then
84
+ reason="all 25 (shared code changed)"
85
+ else
86
+ names="$(printf '%s\n' "$changed" | sed -n 's|^connectors/\([^/][^/]*\)/.*|\1|p' | sort -u)"
87
+ keep=""
88
+ for c in $ALL; do
89
+ if printf '%s\n' "$names" | grep -qx "$c"; then keep="$keep $c"; fi
90
+ done
91
+ if [ -n "$keep" ]; then
92
+ pick="${keep# }"
93
+ reason="only the connectors this pull request touches"
94
+ else
95
+ reason="all 25 (no known connector matched the diff)"
96
+ fi
97
+ fi
98
+ fi
99
+
100
+ echo "connectors=$(to_json "$pick")" >> "$GITHUB_OUTPUT"
101
+ echo "Conformance scope: $reason"
102
+ # Word splitting is the point: one connector per line.
103
+ # shellcheck disable=SC2086
104
+ printf '%s\n' $pick | sed 's/^/ - /'
105
+
106
+ # One job, ten gates.
107
+ #
108
+ # These ran as ten separate jobs. Each finished in six to twelve seconds and
109
+ # each was billed a whole minute, because GitHub meters per job and rounds up:
110
+ # roughly ninety per cent of what they cost was rounding, not compute. Run
111
+ # back to back in one job they cost two billable minutes instead of ten, and
112
+ # add about forty seconds of wall clock.
113
+ #
114
+ # `!cancelled()` on every gate after the first preserves the property that
115
+ # made ten jobs attractive: one run still reports every gate that is failing,
116
+ # rather than stopping at the first and making you discover the rest one push
117
+ # at a time.
118
+ static-gates:
119
+ name: Static gates
120
+ runs-on: ubuntu-latest
121
+ timeout-minutes: 20
122
+ steps:
123
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
124
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
125
+ with:
126
+ python-version: "3.11"
127
+
128
+ # FIRST, and before anything is installed. This gate exists to see what
129
+ # `pip install magone-mcp-core` alone fails to provide, and that gap is
130
+ # only visible in an environment that has nothing else in it. Installing
131
+ # ruff below would not change its answer, but ordering it first means
132
+ # nobody has to reason about that.
133
+ #
134
+ # Installing the core package plus a connector's own extra must be
135
+ # enough to start that connector. Once it was not: an empty virtualenv
136
+ # started 10 of 23 connectors, and `web_search` failed on `trafilatura`,
137
+ # declared nowhere, because the port left every per-server requirements
138
+ # file behind.
139
+ - name: Dependencies
140
+ run: python scripts/dependency_gate.py
141
+
142
+ # Schemas here are declared, not derived, so the expected diff is empty
143
+ # by construction. Any diff means a tool's wire contract moved, which
144
+ # changes what every live agent is told it may pass.
145
+ - name: Golden schema
146
+ if: ${{ !cancelled() }}
147
+ run: python scripts/golden_schema_gate.py --check
148
+
149
+ # Every other gate here reads source with `ast.parse`, deliberately, so
150
+ # it needs no credentials and no vendor dependencies. `ast.parse` is not
151
+ # the compiler though: it accepts a misplaced `from __future__` import
152
+ # that fails at container start. Two connectors shipped in exactly that
153
+ # state with every gate green. `compile()` executes nothing and needs no
154
+ # more than `ast.parse` did.
155
+ - name: Compile
156
+ if: ${{ !cancelled() }}
157
+ run: python scripts/compile_gate.py
158
+
159
+ # server.json is derived from each connector's own SERVER_NAME and
160
+ # SERVER_VERSION, so a manifest that drifts from the server it describes
161
+ # is a manifest that would publish a lie. Regenerating and diffing is
162
+ # cheaper than trusting anyone to remember.
163
+ - name: Server manifests
164
+ if: ${{ !cancelled() }}
165
+ run: python scripts/gen_server_json.py --check
166
+
167
+ # docs/TOOLS.md is the only list of every tool. A hand-kept
168
+ # list of hundreds of anything is wrong within a week, and this
169
+ # repository has already produced three documents that became
170
+ # false because something else changed correctly.
171
+ - name: Tool reference
172
+ if: ${{ !cancelled() }}
173
+ run: python scripts/gen_tool_reference.py --check
174
+
175
+ # Publishing is the one step here that cannot be undone. Some
176
+ # connectors are blocked for a reason that is nothing to do with code
177
+ # quality and everything to do with being easy to forget: none of them
178
+ # has been verified against a live deployment yet.
179
+ - name: Publication
180
+ if: ${{ !cancelled() }}
181
+ run: python scripts/publication_gate.py
182
+
183
+ # A tool whose credential headers stayed a comment receives an empty
184
+ # credentials dict and fails against its vendor with "missing
185
+ # credentials", which reads as a misconfigured connection rather than a
186
+ # port defect. 66 tools were in that state once, silently, because a
187
+ # repair script's idempotency check was per file instead of per tool.
188
+ - name: Credential headers
189
+ if: ${{ !cancelled() }}
190
+ run: python scripts/credential_headers_gate.py
191
+
192
+ # The second half of the same lesson: a permission group that stays a
193
+ # comment narrows nothing, and fails in the dangerous direction. All 263
194
+ # tools were in that state while the platform kept sending
195
+ # X-MCP-Enabled-Groups, so a connection that selected read-only Jira was
196
+ # served deleteJiraIssue and could call it.
197
+ - name: Permission groups
198
+ if: ${{ !cancelled() }}
199
+ run: python scripts/permission_group_gate.py
200
+
201
+ # ci.yml is on: pull_request, so a self-hosted label plus a public
202
+ # repository means a stranger's branch runs on somebody's own machine.
203
+ # Visibility comes from the event payload, so this needs no token;
204
+ # --require-visibility means the gate cannot pass by not knowing.
205
+ - name: Runner labels
206
+ if: ${{ !cancelled() }}
207
+ env:
208
+ REPO_VISIBILITY: ${{ github.event.repository.visibility }}
209
+ run: python scripts/runner_label_gate.py --require-visibility
210
+
211
+ - name: Boundary
212
+ if: ${{ !cancelled() }}
213
+ run: python scripts/boundary_gate.py
214
+
215
+ # The allowance covers descriptions inherited from the v1 catalogue and
216
+ # is meant to come down, not to stay. Everything else is blocking.
217
+ - name: Tool contract
218
+ if: ${{ !cancelled() }}
219
+ run: python scripts/tool_contract_lint.py --max-undescribed 152
220
+
221
+ # Pinned. An unpinned linter can turn every open pull request red on the
222
+ # day it releases, for a change nobody in this repository made.
223
+ - name: Install ruff
224
+ if: ${{ !cancelled() }}
225
+ run: pip install ruff==0.16.1
226
+
227
+ - name: Lint
228
+ if: ${{ !cancelled() }}
229
+ run: ruff check .
230
+
231
+ - name: Format
232
+ if: ${{ !cancelled() }}
233
+ run: ruff format --check .
234
+
235
+ # Undefined names over whole modules, functions defined twice,
236
+ # constants reassigned with a different value, relative imports that do
237
+ # not resolve (including inside functions). Each shipped once and broke
238
+ # tools at runtime with every other gate green.
239
+ - name: Code health
240
+ if: ${{ !cancelled() }}
241
+ run: python scripts/code_health_gate.py
242
+
243
+ # The unresolved-name budget is 0 and only comes down.
244
+ - name: Port status
245
+ if: ${{ !cancelled() }}
246
+ run: python scripts/port_status.py --check
247
+
248
+ framework:
249
+ name: Framework tests
250
+ runs-on: ubuntu-latest
251
+ timeout-minutes: 20
252
+ steps:
253
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
254
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
255
+ with:
256
+ python-version: "3.11"
257
+ cache: pip
258
+ cache-dependency-path: pyproject.toml
259
+ - run: pip install -e ".[dev]"
260
+ # No credentials and no network. That is the property an outside
261
+ # contributor needs: they can run most of the suite before opening a
262
+ # pull request, and CI can judge a fork the same way it judges a branch.
263
+ #
264
+ # `-m "not requires_connectors"` because `[dev]` installs the framework's
265
+ # dependencies and not each connector's - a connector that talks to
266
+ # Oracle should not drag `oracledb` into an install that only wanted the
267
+ # framework. The tests that DO import a connector run in the job below,
268
+ # which installs everything.
269
+ - run: pytest tests/ -q -m "not requires_connectors"
270
+
271
+ connector-tests:
272
+ name: Connector tests
273
+ runs-on: ubuntu-latest
274
+ timeout-minutes: 30
275
+ steps:
276
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
277
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
278
+ with:
279
+ python-version: "3.11"
280
+ cache: pip
281
+ cache-dependency-path: pyproject.toml
282
+ # Every connector dependency. This job exists because the two gates that
283
+ # matter most are worthless if they skip, and both were written from a
284
+ # failure that had already shipped: eleven connectors that would not
285
+ # import, and twenty-five tools that raised NameError on call while
286
+ # importing perfectly. A skipped gate reports the same green as a passing
287
+ # one.
288
+ - run: pip install -e ".[dev,all]"
289
+ # The framework's connector-dependent tests, then every connector's own
290
+ # suite. `connectors/*/tests` was never collected here, so the
291
+ # per-connector regression tests ran only on a laptop.
292
+ - run: pytest tests/ -q -m "requires_connectors"
293
+ - run: pytest connectors/ -q
294
+
295
+ conformance:
296
+ name: Conformance
297
+ needs: scope
298
+ runs-on: ubuntu-latest
299
+ timeout-minutes: 20
300
+ strategy:
301
+ fail-fast: false
302
+ matrix:
303
+ # Package names, which use underscores: a hyphen fails at `python -m`
304
+ # with a confusing module-not-found error.
305
+ #
306
+ # The list comes from the `scope` job above rather than being written
307
+ # out here. On push, and on any pull request that touches shared code,
308
+ # that is all 25. The canonical list lives in `scope`; this must not be
309
+ # duplicated here, or the two will disagree the first time a connector
310
+ # is added.
311
+ connector: ${{ fromJSON(needs.scope.outputs.connectors) }}
312
+ steps:
313
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
314
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
315
+ with:
316
+ python-version: "3.11"
317
+ cache: pip
318
+ cache-dependency-path: pyproject.toml
319
+ - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
320
+ with:
321
+ node-version: "22"
322
+ # Every per-connector extra, because the matrix now covers all 25 and
323
+ # eight of them need a third-party library. Installing only [dev] would
324
+ # fail those at start-up for a reason this job is not about.
325
+ - run: pip install -e ".[dev,cloudflare_r2,csv_to_sql,database,otp_verification,outlook_email,trino,vanna,web_search]"
326
+ - name: Start the connector
327
+ env:
328
+ CONNECTOR: ${{ matrix.connector }}
329
+ run: |
330
+ MCP_MODE=local PORT=8111 python -m "connectors.$CONNECTOR" &
331
+ # Readiness by POST, not GET: /mcp answers 404 to GET, so a `curl -sf`
332
+ # probe never succeeds and the loop just burns its 30 seconds and
333
+ # then tests a server that may not be listening. That is how the
334
+ # first run of this job scored a server that had never started.
335
+ for _ in $(seq 1 40); do
336
+ code=$(curl -s -o /dev/null -w '%{http_code}' -m 2 -X POST \
337
+ -H 'Content-Type: application/json' \
338
+ -H 'Accept: application/json, text/event-stream' \
339
+ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
340
+ http://127.0.0.1:8111/mcp || true)
341
+ [ "$code" != "000" ] && echo "connector answering (HTTP $code)" && break
342
+ sleep 1
343
+ done
344
+ [ "$code" = "000" ] && { echo "connector never started"; exit 1; } || true
345
+ # Pinned to the alpha deliberately. The `latest` dist-tag is 0.1.16,
346
+ # which has no support for 2026-07-28 at all: an unpinned invocation
347
+ # would produce a green gate that never tested the target revision,
348
+ # which is the same class of defect this repository exists to fix.
349
+ # The baseline records the scenarios a tools-only connector does not
350
+ # satisfy (prompts, resources, tasks, sampling). Its purpose is to make
351
+ # the passing set a regression gate: anything failing that is NOT in the
352
+ # baseline turns this red. tools-list, tools-call, initialize and
353
+ # dns-rebinding-protection are deliberately not in it.
354
+ - name: Conformance
355
+ run: |
356
+ npx -y @modelcontextprotocol/conformance@0.2.0-alpha.11 server \
357
+ --url http://127.0.0.1:8111/mcp --requirements 2026-07-28 \
358
+ --expected-failures tests/conformance/expected-failures.yaml