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.
- magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +68 -0
- magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/config.yml +14 -0
- magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/connector_request.yml +49 -0
- magone_mcp_core-0.1.0/.github/ISSUE_TEMPLATE/question.yml +38 -0
- magone_mcp_core-0.1.0/.github/dependabot.yml +52 -0
- magone_mcp_core-0.1.0/.github/pull_request_template.md +25 -0
- magone_mcp_core-0.1.0/.github/workflows/ci.yml +358 -0
- magone_mcp_core-0.1.0/.github/workflows/codeql.yml +86 -0
- magone_mcp_core-0.1.0/.github/workflows/dco.yml +61 -0
- magone_mcp_core-0.1.0/.github/workflows/notify-platform.yml +86 -0
- magone_mcp_core-0.1.0/.github/workflows/publish.yml +276 -0
- magone_mcp_core-0.1.0/.github/workflows/scorecard.yml +96 -0
- magone_mcp_core-0.1.0/.gitignore +13 -0
- magone_mcp_core-0.1.0/CHANGELOG.md +137 -0
- magone_mcp_core-0.1.0/CODEOWNERS +23 -0
- magone_mcp_core-0.1.0/CODE_OF_CONDUCT.md +140 -0
- magone_mcp_core-0.1.0/CONTRIBUTING.md +424 -0
- magone_mcp_core-0.1.0/Dockerfile +99 -0
- magone_mcp_core-0.1.0/GOVERNANCE.md +103 -0
- magone_mcp_core-0.1.0/LICENSE +202 -0
- magone_mcp_core-0.1.0/MAINTAINERS.md +27 -0
- magone_mcp_core-0.1.0/NOTICE +10 -0
- magone_mcp_core-0.1.0/PKG-INFO +394 -0
- magone_mcp_core-0.1.0/README.md +315 -0
- magone_mcp_core-0.1.0/RELEASING.md +122 -0
- magone_mcp_core-0.1.0/SECURITY.md +84 -0
- magone_mcp_core-0.1.0/SUPPORT.md +46 -0
- magone_mcp_core-0.1.0/connectors/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/_shared/__init__.py +1 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/_shared/atlassian_auth.py +231 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/server.py +1777 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/atlassian_confluence/tests/test_site_resolution.py +66 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/_shared/__init__.py +1 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/_shared/atlassian_auth.py +231 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/server.py +2508 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/test_attachment_file_references.py +102 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/test_request_body_limit.py +101 -0
- magone_mcp_core-0.1.0/connectors/atlassian_jira/tests/test_site_resolution.py +66 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/server.py +568 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/tests/test_shared_ssrf_check.py +26 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/tools/storage.py +172 -0
- magone_mcp_core-0.1.0/connectors/cloudflare_r2/tools/url_fetch.py +11 -0
- magone_mcp_core-0.1.0/connectors/csv_to_sql/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/csv_to_sql/__main__.py +16 -0
- magone_mcp_core-0.1.0/connectors/csv_to_sql/_connection.py +148 -0
- magone_mcp_core-0.1.0/connectors/csv_to_sql/_csv.py +288 -0
- magone_mcp_core-0.1.0/connectors/csv_to_sql/server.py +628 -0
- magone_mcp_core-0.1.0/connectors/csv_to_sql/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/csv_to_sql/tests/test_csv_to_sql.py +289 -0
- magone_mcp_core-0.1.0/connectors/database/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/database/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/database/_shared/__init__.py +1 -0
- magone_mcp_core-0.1.0/connectors/database/_shared/db_errors.py +65 -0
- magone_mcp_core-0.1.0/connectors/database/_shared/sql_safety.py +154 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/__init__.py +84 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/base.py +92 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/errors.py +10 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/mongo_helpers.py +113 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/mongodb.py +161 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/mssql.py +421 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/mysql.py +271 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/oracle.py +545 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/pool.py +86 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/postgresql.py +361 -0
- magone_mcp_core-0.1.0/connectors/database/connectors/sql_common.py +254 -0
- magone_mcp_core-0.1.0/connectors/database/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/database/server.py +545 -0
- magone_mcp_core-0.1.0/connectors/database/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/database/tests/test_mysql_tls.py +75 -0
- magone_mcp_core-0.1.0/connectors/database/tests/test_tools_reach_the_driver.py +138 -0
- magone_mcp_core-0.1.0/connectors/database/tools/__init__.py +7 -0
- magone_mcp_core-0.1.0/connectors/database/tools/connection.py +284 -0
- magone_mcp_core-0.1.0/connectors/docusign/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/docusign/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/docusign/docusign_auth.py +206 -0
- magone_mcp_core-0.1.0/connectors/docusign/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/docusign/server.py +885 -0
- magone_mcp_core-0.1.0/connectors/docusign/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/docusign/tests/test_token_cache.py +81 -0
- magone_mcp_core-0.1.0/connectors/docusign/tools/__init__.py +7 -0
- magone_mcp_core-0.1.0/connectors/filesystem/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/filesystem/__main__.py +16 -0
- magone_mcp_core-0.1.0/connectors/filesystem/server.py +528 -0
- magone_mcp_core-0.1.0/connectors/filesystem/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/filesystem/tests/test_filesystem.py +218 -0
- magone_mcp_core-0.1.0/connectors/google_calendar/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/google_calendar/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/google_calendar/_shared/__init__.py +135 -0
- magone_mcp_core-0.1.0/connectors/google_calendar/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/google_calendar/server.py +306 -0
- magone_mcp_core-0.1.0/connectors/google_calendar/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/google_drive/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/google_drive/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/google_drive/_shared/__init__.py +182 -0
- magone_mcp_core-0.1.0/connectors/google_drive/server.py +289 -0
- magone_mcp_core-0.1.0/connectors/google_drive/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/google_gmail/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/google_gmail/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/google_gmail/_shared/__init__.py +135 -0
- magone_mcp_core-0.1.0/connectors/google_gmail/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/google_gmail/server.py +296 -0
- magone_mcp_core-0.1.0/connectors/google_gmail/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/image_generation/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/image_generation/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/image_generation/gemini.py +119 -0
- magone_mcp_core-0.1.0/connectors/image_generation/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/image_generation/server.py +207 -0
- magone_mcp_core-0.1.0/connectors/image_generation/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/image_generation/tests/test_generate_image.py +257 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/server.py +481 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tests/test_vendor_errors.py +56 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tools/__init__.py +7 -0
- magone_mcp_core-0.1.0/connectors/kapso_whatsapp/tools/_client.py +98 -0
- magone_mcp_core-0.1.0/connectors/linear/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/linear/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/linear/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/linear/server.py +1543 -0
- magone_mcp_core-0.1.0/connectors/linear/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/linear/tests/test_get_issue_comments.py +57 -0
- magone_mcp_core-0.1.0/connectors/linear/tests/test_issues.py +152 -0
- magone_mcp_core-0.1.0/connectors/linear/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/linear/tools/_client.py +403 -0
- magone_mcp_core-0.1.0/connectors/linkedin/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/linkedin/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/linkedin/_client.py +393 -0
- magone_mcp_core-0.1.0/connectors/linkedin/server.py +1121 -0
- magone_mcp_core-0.1.0/connectors/linkedin/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/linkedin/tests/test_linkedin.py +601 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/_shared/__init__.py +18 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/server.py +832 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tests/test_app_only_flow.py +96 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/microsoft_sharepoint/tools/_constants.py +61 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/_shared/__init__.py +144 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/server.py +1303 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/tests/test_mentions.py +89 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/tools/__init__.py +14 -0
- magone_mcp_core-0.1.0/connectors/microsoft_teams/tools/_constants.py +229 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/server.py +582 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/tests/test_code_storage.py +193 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/tests/test_generate_metadata.py +72 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/tools/__init__.py +7 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/tools/_constants.py +24 -0
- magone_mcp_core-0.1.0/connectors/otp_verification/tools/_db.py +77 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/_shared/__init__.py +144 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/server.py +1002 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/tests/test_timezones.py +24 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/__init__.py +15 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/_availability.py +114 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/_constants.py +16 -0
- magone_mcp_core-0.1.0/connectors/outlook_calendar/tools/_when.py +177 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/_shared/__init__.py +1 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/_shared/microsoft_graph.py +401 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/server.py +4052 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/_graph_mock.py +56 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_app_only_paths.py +99 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_attachment_url_ssrf.py +153 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_date_timezone.py +69 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_get_email_categories_and_empty_mailbox.py +96 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_reply_email_mailbox.py +160 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_request_body_limit.py +20 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_set_email_categories.py +107 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tests/test_strip_quoted_reply.py +120 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/__init__.py +19 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/_budget.py +50 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/_constants.py +312 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/_extract.py +182 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/_message.py +62 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/_reply_send.py +96 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/_send.py +168 -0
- magone_mcp_core-0.1.0/connectors/outlook_email/tools/download.py +200 -0
- magone_mcp_core-0.1.0/connectors/publication.json +63 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/server.py +2561 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_crud_completion.py +106 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_default_includes.py +53 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_field_completeness.py +110 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tests/test_new_tools.py +248 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tools/__init__.py +24 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tools/client.py +110 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tools/collector_settings.py +106 -0
- magone_mcp_core-0.1.0/connectors/surveymonkey/tools/filters.py +145 -0
- magone_mcp_core-0.1.0/connectors/trino/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/trino/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/trino/_shared/__init__.py +1 -0
- magone_mcp_core-0.1.0/connectors/trino/_shared/db_errors.py +65 -0
- magone_mcp_core-0.1.0/connectors/trino/_shared/sql_safety.py +154 -0
- magone_mcp_core-0.1.0/connectors/trino/connectors/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/trino/connectors/trino_connector.py +263 -0
- magone_mcp_core-0.1.0/connectors/trino/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/trino/server.py +651 -0
- magone_mcp_core-0.1.0/connectors/trino/tools/__init__.py +7 -0
- magone_mcp_core-0.1.0/connectors/trino/tools/common.py +155 -0
- magone_mcp_core-0.1.0/connectors/twitter_intel/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/twitter_intel/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/twitter_intel/client.py +173 -0
- magone_mcp_core-0.1.0/connectors/twitter_intel/server.py +565 -0
- magone_mcp_core-0.1.0/connectors/twitter_intel/tools/__init__.py +7 -0
- magone_mcp_core-0.1.0/connectors/vanna/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/vanna/__main__.py +16 -0
- magone_mcp_core-0.1.0/connectors/vanna/_connection.py +148 -0
- magone_mcp_core-0.1.0/connectors/vanna/_engine.py +105 -0
- magone_mcp_core-0.1.0/connectors/vanna/_store.py +197 -0
- magone_mcp_core-0.1.0/connectors/vanna/server.py +1119 -0
- magone_mcp_core-0.1.0/connectors/vanna/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/vanna/tests/test_vanna.py +419 -0
- magone_mcp_core-0.1.0/connectors/web_search/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/web_search/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/web_search/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/web_search/server.py +1275 -0
- magone_mcp_core-0.1.0/connectors/web_search/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/web_search/tests/test_serper_search.py +213 -0
- magone_mcp_core-0.1.0/connectors/web_search/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/zoom/__init__.py +5 -0
- magone_mcp_core-0.1.0/connectors/zoom/__main__.py +19 -0
- magone_mcp_core-0.1.0/connectors/zoom/server.json +34 -0
- magone_mcp_core-0.1.0/connectors/zoom/server.py +404 -0
- magone_mcp_core-0.1.0/connectors/zoom/tests/__init__.py +0 -0
- magone_mcp_core-0.1.0/connectors/zoom/tests/test_meeting_tools.py +194 -0
- magone_mcp_core-0.1.0/connectors/zoom/tools/__init__.py +4 -0
- magone_mcp_core-0.1.0/connectors/zoom/tools/_client.py +176 -0
- magone_mcp_core-0.1.0/docs/TOOLS.md +465 -0
- magone_mcp_core-0.1.0/docs/architecture.md +374 -0
- magone_mcp_core-0.1.0/docs/configuration.md +168 -0
- magone_mcp_core-0.1.0/docs/writing-a-connector.md +316 -0
- magone_mcp_core-0.1.0/pyproject.toml +150 -0
- magone_mcp_core-0.1.0/scripts/boundary_gate.py +129 -0
- magone_mcp_core-0.1.0/scripts/code_health_gate.py +146 -0
- magone_mcp_core-0.1.0/scripts/compile_gate.py +74 -0
- magone_mcp_core-0.1.0/scripts/credential_headers_gate.py +140 -0
- magone_mcp_core-0.1.0/scripts/dependency_gate.py +149 -0
- magone_mcp_core-0.1.0/scripts/gen_server_json.py +227 -0
- magone_mcp_core-0.1.0/scripts/gen_tool_reference.py +175 -0
- magone_mcp_core-0.1.0/scripts/golden_schema_gate.py +184 -0
- magone_mcp_core-0.1.0/scripts/permission_group_gate.py +142 -0
- magone_mcp_core-0.1.0/scripts/port_status.py +128 -0
- magone_mcp_core-0.1.0/scripts/publication_gate.py +143 -0
- magone_mcp_core-0.1.0/scripts/runner_label_gate.py +132 -0
- magone_mcp_core-0.1.0/scripts/tool_contract_lint.py +387 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/__init__.py +104 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/auth.py +233 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/budget.py +172 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/content.py +367 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/credentials.py +179 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/logging_setup.py +124 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/net.py +234 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/provenance.py +65 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/readonly.py +99 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/redact.py +191 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/results.py +145 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/schema.py +142 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/selection.py +145 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/server.py +692 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/text_args.py +169 -0
- magone_mcp_core-0.1.0/src/magone_mcp_core/transport.py +121 -0
- magone_mcp_core-0.1.0/tests/conformance/expected-failures.yaml +80 -0
- magone_mcp_core-0.1.0/tests/golden/output-schemas.json +1694 -0
- magone_mcp_core-0.1.0/tests/golden/port-budget.json +1 -0
- magone_mcp_core-0.1.0/tests/golden/tool-schemas.json +8210 -0
- magone_mcp_core-0.1.0/tests/test_all_connectors_import.py +84 -0
- magone_mcp_core-0.1.0/tests/test_authentication.py +174 -0
- magone_mcp_core-0.1.0/tests/test_budget_over_mcp.py +184 -0
- magone_mcp_core-0.1.0/tests/test_compile_gate.py +107 -0
- magone_mcp_core-0.1.0/tests/test_content.py +258 -0
- magone_mcp_core-0.1.0/tests/test_credentials.py +246 -0
- magone_mcp_core-0.1.0/tests/test_credentials_precedence.py +215 -0
- magone_mcp_core-0.1.0/tests/test_ctx_and_readonly_refusal.py +83 -0
- magone_mcp_core-0.1.0/tests/test_custom_route.py +167 -0
- magone_mcp_core-0.1.0/tests/test_declared_text_stays_text.py +281 -0
- magone_mcp_core-0.1.0/tests/test_docstring_census.py +112 -0
- magone_mcp_core-0.1.0/tests/test_entrypoints.py +92 -0
- magone_mcp_core-0.1.0/tests/test_error_surfacing.py +117 -0
- magone_mcp_core-0.1.0/tests/test_every_tool_is_callable.py +193 -0
- magone_mcp_core-0.1.0/tests/test_extra_content_over_mcp.py +78 -0
- magone_mcp_core-0.1.0/tests/test_guarantees.py +307 -0
- magone_mcp_core-0.1.0/tests/test_healthz.py +71 -0
- magone_mcp_core-0.1.0/tests/test_log_record_shape.py +46 -0
- magone_mcp_core-0.1.0/tests/test_log_redaction.py +92 -0
- magone_mcp_core-0.1.0/tests/test_net.py +196 -0
- magone_mcp_core-0.1.0/tests/test_output_schema.py +92 -0
- magone_mcp_core-0.1.0/tests/test_output_schemas_match_v1.py +55 -0
- magone_mcp_core-0.1.0/tests/test_publication_gate.py +128 -0
- magone_mcp_core-0.1.0/tests/test_readonly_env.py +107 -0
- magone_mcp_core-0.1.0/tests/test_request_body_limit.py +192 -0
- magone_mcp_core-0.1.0/tests/test_results.py +189 -0
- magone_mcp_core-0.1.0/tests/test_schema.py +143 -0
- magone_mcp_core-0.1.0/tests/test_scrape_url_ssrf.py +303 -0
- magone_mcp_core-0.1.0/tests/test_shutdown_hooks.py +59 -0
- magone_mcp_core-0.1.0/tests/test_text_arguments_every_tool.py +113 -0
- magone_mcp_core-0.1.0/tests/test_tool_names_resolve.py +196 -0
- magone_mcp_core-0.1.0/tests/test_tool_selection.py +253 -0
- magone_mcp_core-0.1.0/tests/test_transport_security.py +215 -0
- magone_mcp_core-0.1.0/tests/test_update_event_alias.py +242 -0
- magone_mcp_core-0.1.0/tests/test_user_agents.py +78 -0
- 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
|