mcphub-server 3.1.0__tar.gz → 3.3.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 (228) hide show
  1. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/PKG-INFO +20 -5
  2. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/README.md +19 -4
  3. mcphub_server-3.3.0/core/admin_utils.py +27 -0
  4. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/api_keys.py +16 -10
  5. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/config_snippets.py +14 -1
  6. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/dashboard/auth.py +19 -10
  7. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/dashboard/routes.py +613 -45
  8. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/database.py +70 -5
  9. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/health.py +18 -5
  10. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/client_registry.py +3 -1
  11. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/schemas.py +6 -2
  12. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/server.py +6 -1
  13. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/token_manager.py +11 -1
  14. mcphub_server-3.3.0/core/plugin_visibility.py +59 -0
  15. mcphub_server-3.3.0/core/settings.py +162 -0
  16. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/site_api.py +142 -13
  17. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/404.html +21 -9
  18. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/api-keys/list.html +7 -7
  19. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/auth-login.html +3 -2
  20. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/base.html +26 -7
  21. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/connect.html +115 -12
  22. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/health/index.html +1 -1
  23. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/index.html +39 -55
  24. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/oauth-clients/list.html +4 -4
  25. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/partials/head_assets.html +1 -3
  26. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/projects/list.html +5 -5
  27. mcphub_server-3.3.0/core/templates/dashboard/service.html +185 -0
  28. mcphub_server-3.3.0/core/templates/dashboard/services_list.html +57 -0
  29. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/settings/index.html +115 -2
  30. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/sites/add.html +27 -4
  31. mcphub_server-3.3.0/core/templates/dashboard/sites/edit.html +172 -0
  32. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/sites/list.html +63 -13
  33. mcphub_server-3.3.0/core/templates/dashboard/user-oauth-clients.html +241 -0
  34. mcphub_server-3.3.0/core/templates/oauth/authorize.html +268 -0
  35. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/user_endpoints.py +72 -21
  36. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/user_keys.py +2 -5
  37. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/mcphub_server.egg-info/PKG-INFO +20 -5
  38. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/mcphub_server.egg-info/SOURCES.txt +15 -0
  39. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/client.py +245 -96
  40. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/handlers/auth.py +0 -18
  41. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/handlers/database.py +29 -12
  42. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/plugin.py +15 -6
  43. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/woocommerce/plugin.py +20 -6
  44. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/client.py +1 -1
  45. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/seo.py +3 -3
  46. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/wp_cli.py +66 -25
  47. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/pyproject.toml +1 -1
  48. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/server.py +264 -42
  49. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/server_multi.py +8 -13
  50. mcphub_server-3.3.0/tests/test_admin_system.py +188 -0
  51. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_config_snippets.py +10 -5
  52. mcphub_server-3.3.0/tests/test_f3_admin_stats.py +17 -0
  53. mcphub_server-3.3.0/tests/test_f3_last_tested.py +77 -0
  54. mcphub_server-3.3.0/tests/test_f3_service_pages.py +35 -0
  55. mcphub_server-3.3.0/tests/test_oauth_basic_auth.py +165 -0
  56. mcphub_server-3.3.0/tests/test_oauth_resource.py +333 -0
  57. mcphub_server-3.3.0/tests/test_oauth_revoke.py +227 -0
  58. mcphub_server-3.3.0/tests/test_plugin_visibility.py +148 -0
  59. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_woocommerce_plugin.py +6 -5
  60. mcphub_server-3.1.0/core/templates/oauth/authorize.html +0 -170
  61. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/LICENSE +0 -0
  62. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/__init__.py +0 -0
  63. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/audit_log.py +0 -0
  64. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/auth.py +0 -0
  65. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/context.py +0 -0
  66. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/dashboard/__init__.py +0 -0
  67. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/encryption.py +0 -0
  68. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/endpoints/__init__.py +0 -0
  69. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/endpoints/config.py +0 -0
  70. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/endpoints/factory.py +0 -0
  71. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/endpoints/middleware.py +0 -0
  72. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/endpoints/registry.py +0 -0
  73. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/i18n.py +0 -0
  74. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/middleware/__init__.py +0 -0
  75. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/__init__.py +0 -0
  76. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/csrf.py +0 -0
  77. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/pkce.py +0 -0
  78. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/oauth/storage.py +0 -0
  79. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/project_manager.py +0 -0
  80. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/rate_limiter.py +0 -0
  81. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/site_manager.py +0 -0
  82. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/base.html +0 -0
  83. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/audit-logs/list.html +0 -0
  84. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/health/projects-partial.html +0 -0
  85. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/login.html +0 -0
  86. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/profile.html +0 -0
  87. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/dashboard/projects/detail.html +0 -0
  88. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/templates/oauth/error.html +0 -0
  89. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/tool_generator.py +0 -0
  90. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/tool_registry.py +0 -0
  91. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/core/user_auth.py +0 -0
  92. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/mcphub_server.egg-info/dependency_links.txt +0 -0
  93. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/mcphub_server.egg-info/entry_points.txt +0 -0
  94. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/mcphub_server.egg-info/requires.txt +0 -0
  95. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/mcphub_server.egg-info/top_level.txt +0 -0
  96. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/__init__.py +0 -0
  97. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/__init__.py +0 -0
  98. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/client.py +0 -0
  99. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/__init__.py +0 -0
  100. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/databases.py +0 -0
  101. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/documents.py +0 -0
  102. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/functions.py +0 -0
  103. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/messaging.py +0 -0
  104. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/storage.py +0 -0
  105. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/system.py +0 -0
  106. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/teams.py +0 -0
  107. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/handlers/users.py +0 -0
  108. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/appwrite/plugin.py +0 -0
  109. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/base.py +0 -0
  110. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/__init__.py +0 -0
  111. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/client.py +0 -0
  112. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/__init__.py +0 -0
  113. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/access.py +0 -0
  114. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/automation.py +0 -0
  115. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/collections.py +0 -0
  116. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/content.py +0 -0
  117. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/dashboards.py +0 -0
  118. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/files.py +0 -0
  119. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/items.py +0 -0
  120. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/system.py +0 -0
  121. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/handlers/users.py +0 -0
  122. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/directus/plugin.py +0 -0
  123. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/__init__.py +0 -0
  124. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/client.py +0 -0
  125. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/handlers/__init__.py +0 -0
  126. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/handlers/issues.py +0 -0
  127. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/handlers/pull_requests.py +0 -0
  128. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/handlers/repositories.py +0 -0
  129. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/handlers/users.py +0 -0
  130. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/handlers/webhooks.py +0 -0
  131. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/plugin.py +0 -0
  132. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/schemas/__init__.py +0 -0
  133. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/schemas/common.py +0 -0
  134. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/schemas/issue.py +0 -0
  135. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/schemas/pull_request.py +0 -0
  136. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/schemas/repository.py +0 -0
  137. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/schemas/user.py +0 -0
  138. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/gitea/schemas/webhook.py +0 -0
  139. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/__init__.py +0 -0
  140. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/client.py +0 -0
  141. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/__init__.py +0 -0
  142. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/credentials.py +0 -0
  143. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/executions.py +0 -0
  144. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/projects.py +0 -0
  145. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/system.py +0 -0
  146. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/tags.py +0 -0
  147. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/users.py +0 -0
  148. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/variables.py +0 -0
  149. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/handlers/workflows.py +0 -0
  150. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/n8n/plugin.py +0 -0
  151. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/__init__.py +0 -0
  152. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/client.py +0 -0
  153. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/__init__.py +0 -0
  154. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/clients.py +0 -0
  155. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/dashboards.py +0 -0
  156. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/events.py +0 -0
  157. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/export.py +0 -0
  158. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/funnels.py +0 -0
  159. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/profiles.py +0 -0
  160. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/projects.py +0 -0
  161. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/reports.py +0 -0
  162. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/system.py +0 -0
  163. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/handlers/utils.py +0 -0
  164. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/openpanel/plugin.py +0 -0
  165. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/__init__.py +0 -0
  166. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/handlers/__init__.py +0 -0
  167. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/handlers/admin.py +0 -0
  168. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/handlers/functions.py +0 -0
  169. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/handlers/storage.py +0 -0
  170. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/supabase/handlers/system.py +0 -0
  171. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/woocommerce/__init__.py +0 -0
  172. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/__init__.py +0 -0
  173. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/__init__.py +0 -0
  174. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/comments.py +0 -0
  175. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/coupons.py +0 -0
  176. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/customers.py +0 -0
  177. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/media.py +0 -0
  178. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/menus.py +0 -0
  179. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/orders.py +0 -0
  180. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/posts.py +0 -0
  181. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/products.py +0 -0
  182. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/reports.py +0 -0
  183. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/site.py +0 -0
  184. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/taxonomy.py +0 -0
  185. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/users.py +0 -0
  186. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/handlers/wp_cli.py +0 -0
  187. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/plugin.py +0 -0
  188. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/plugin_old_backup.py +0 -0
  189. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/schemas/__init__.py +0 -0
  190. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/schemas/common.py +0 -0
  191. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/schemas/media.py +0 -0
  192. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/schemas/order.py +0 -0
  193. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/schemas/post.py +0 -0
  194. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/schemas/product.py +0 -0
  195. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress/schemas/seo.py +0 -0
  196. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/__init__.py +0 -0
  197. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/handlers/__init__.py +0 -0
  198. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/handlers/bulk.py +0 -0
  199. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/handlers/database.py +0 -0
  200. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/handlers/system.py +0 -0
  201. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/plugin.py +0 -0
  202. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/schemas/__init__.py +0 -0
  203. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/schemas/bulk.py +0 -0
  204. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/schemas/database.py +0 -0
  205. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/plugins/wordpress_advanced/schemas/system.py +0 -0
  206. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/setup.cfg +0 -0
  207. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_api_keys.py +0 -0
  208. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_auth.py +0 -0
  209. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_auth_logic.py +0 -0
  210. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_dashboard.py +0 -0
  211. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_database.py +0 -0
  212. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_dynamic_endpoints_integration.py +0 -0
  213. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_encryption.py +0 -0
  214. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_oauth_client_registry.py +0 -0
  215. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_oauth_integration.py +0 -0
  216. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_oauth_pkce.py +0 -0
  217. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_oauth_schemas.py +0 -0
  218. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_oauth_storage.py +0 -0
  219. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_oauth_token_manager.py +0 -0
  220. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_rate_limiter.py +0 -0
  221. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_site_api.py +0 -0
  222. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_site_manager.py +0 -0
  223. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_tenant_isolation.py +0 -0
  224. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_tool_registry.py +0 -0
  225. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_user_auth.py +0 -0
  226. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_user_endpoints.py +0 -0
  227. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_user_keys.py +0 -0
  228. {mcphub_server-3.1.0 → mcphub_server-3.3.0}/tests/test_wordpress_plugin.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcphub-server
3
- Version: 3.1.0
3
+ Version: 3.3.0
4
4
  Summary: AI-native management hub for WordPress, WooCommerce, and self-hosted services via Model Context Protocol (MCP)
5
5
  Author-email: MCP Hub <contact@mcphub.dev>
6
6
  License-Expression: MIT
@@ -62,7 +62,7 @@ Connect your sites, stores, repos, and databases — manage them all through Cla
62
62
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-3776ab.svg)](https://www.python.org/)
63
63
  [![PyPI](https://img.shields.io/pypi/v/mcphub-server.svg)](https://pypi.org/project/mcphub-server/)
64
64
  [![Docker](https://img.shields.io/docker/v/airano/mcphub?label=docker)](https://hub.docker.com/r/airano/mcphub)
65
- [![Tests: 290 passing](https://img.shields.io/badge/tests-290%20passing-brightgreen.svg)]()
65
+ [![Tests: 481 passing](https://img.shields.io/badge/tests-481%20passing-brightgreen.svg)]()
66
66
  [![Tools: 596](https://img.shields.io/badge/tools-596-orange.svg)]()
67
67
  [![CI](https://github.com/airano-ir/mcphub/actions/workflows/ci.yml/badge.svg)](https://github.com/airano-ir/mcphub/actions/workflows/ci.yml)
68
68
 
@@ -157,7 +157,20 @@ curl http://localhost:8000/health
157
157
 
158
158
  Open the **web dashboard** in your browser: **http://localhost:8000/dashboard**
159
159
 
160
- You should see the login page. Use your `MASTER_API_KEY` to log in.
160
+ You should see the login page. Log in with your `MASTER_API_KEY` or via **GitHub/Google OAuth** (if configured).
161
+
162
+ ### Try It Now (No Setup Required)
163
+
164
+ **Don't want to self-host?** Try the demo instance at **[mcp.palebluedot.live](https://mcp.palebluedot.live)**:
165
+
166
+ 1. Log in with **GitHub** or **Google**
167
+ 2. Add your sites via the dashboard (My Sites → Add Service)
168
+ 3. Go to **Connect** page — generate config for your AI client
169
+ 4. Copy-paste the config into Claude Desktop, VS Code, or Claude Code
170
+
171
+ Your personal MCP endpoint: `https://mcp.palebluedot.live/u/{your-user-id}/{alias}/mcp`
172
+
173
+ ---
161
174
 
162
175
  ### Configure Your Sites
163
176
 
@@ -346,12 +359,14 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au
346
359
  /appwrite/mcp → Appwrite tools (100 tools)
347
360
  /directus/mcp → Directus tools (100 tools)
348
361
  /project/{alias}/mcp → Per-project endpoint (auto-injects site)
362
+ /u/{user_id}/{alias}/mcp → Per-user endpoint (hosted/OAuth users)
349
363
  ```
350
364
 
351
365
  **Recommendation**: Use plugin-specific endpoints instead of `/mcp` (596 tools) to minimize token usage.
352
366
 
353
367
  | Endpoint | Use Case | Tools |
354
368
  |----------|----------|------:|
369
+ | `/u/{user_id}/{alias}/mcp` | Hosted users (OAuth login) | 22-100 |
355
370
  | `/project/{alias}/mcp` | Single-site workflow (recommended) | 22-100 |
356
371
  | `/{plugin}/mcp` | Multi-site management | 23-101 |
357
372
  | `/mcp` | Admin & discovery only | 596 |
@@ -372,7 +387,7 @@ Some MCP Hub tools require companion WordPress plugins:
372
387
 
373
388
  | Tools | Requirement |
374
389
  |-------|-------------|
375
- | SEO tools (`wordpress_get_post_seo`, etc.) | [SEO API Bridge](wordpress-plugin/seo-api-bridge/) ([Download ZIP](wordpress-plugin/seo-api-bridge.zip)) + Rank Math or Yoast SEO |
390
+ | SEO tools (`wordpress_get_post_seo`, etc.) | [Airano MCP SEO Bridge](https://wordpress.org/plugins/airano-mcp-seo-bridge/) ([GitHub](wordpress-plugin/airano-mcp-seo-bridge/)) + Rank Math or Yoast SEO |
376
391
  | WP-CLI tools (15 tools: `wp_cache_*`, `wp_db_*`, etc.) | Docker socket + `CONTAINER` env var |
377
392
  | WordPress Advanced database/system tools | Docker socket + `CONTAINER` env var |
378
393
  | OpenPanel analytics integration | [OpenPanel Self-Hosted](wordpress-plugin/openpanel-self-hosted/) ([Download ZIP](wordpress-plugin/openpanel-self-hosted.zip)) |
@@ -412,7 +427,7 @@ Without Docker socket, WP-CLI tools return "not available" but all REST API tool
412
427
  # Install with dev dependencies
413
428
  pip install -e ".[dev]"
414
429
 
415
- # Run tests (290 tests)
430
+ # Run tests (481 tests)
416
431
  pytest
417
432
 
418
433
  # Format and lint
@@ -13,7 +13,7 @@ Connect your sites, stores, repos, and databases — manage them all through Cla
13
13
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-3776ab.svg)](https://www.python.org/)
14
14
  [![PyPI](https://img.shields.io/pypi/v/mcphub-server.svg)](https://pypi.org/project/mcphub-server/)
15
15
  [![Docker](https://img.shields.io/docker/v/airano/mcphub?label=docker)](https://hub.docker.com/r/airano/mcphub)
16
- [![Tests: 290 passing](https://img.shields.io/badge/tests-290%20passing-brightgreen.svg)]()
16
+ [![Tests: 481 passing](https://img.shields.io/badge/tests-481%20passing-brightgreen.svg)]()
17
17
  [![Tools: 596](https://img.shields.io/badge/tools-596-orange.svg)]()
18
18
  [![CI](https://github.com/airano-ir/mcphub/actions/workflows/ci.yml/badge.svg)](https://github.com/airano-ir/mcphub/actions/workflows/ci.yml)
19
19
 
@@ -108,7 +108,20 @@ curl http://localhost:8000/health
108
108
 
109
109
  Open the **web dashboard** in your browser: **http://localhost:8000/dashboard**
110
110
 
111
- You should see the login page. Use your `MASTER_API_KEY` to log in.
111
+ You should see the login page. Log in with your `MASTER_API_KEY` or via **GitHub/Google OAuth** (if configured).
112
+
113
+ ### Try It Now (No Setup Required)
114
+
115
+ **Don't want to self-host?** Try the demo instance at **[mcp.palebluedot.live](https://mcp.palebluedot.live)**:
116
+
117
+ 1. Log in with **GitHub** or **Google**
118
+ 2. Add your sites via the dashboard (My Sites → Add Service)
119
+ 3. Go to **Connect** page — generate config for your AI client
120
+ 4. Copy-paste the config into Claude Desktop, VS Code, or Claude Code
121
+
122
+ Your personal MCP endpoint: `https://mcp.palebluedot.live/u/{your-user-id}/{alias}/mcp`
123
+
124
+ ---
112
125
 
113
126
  ### Configure Your Sites
114
127
 
@@ -297,12 +310,14 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au
297
310
  /appwrite/mcp → Appwrite tools (100 tools)
298
311
  /directus/mcp → Directus tools (100 tools)
299
312
  /project/{alias}/mcp → Per-project endpoint (auto-injects site)
313
+ /u/{user_id}/{alias}/mcp → Per-user endpoint (hosted/OAuth users)
300
314
  ```
301
315
 
302
316
  **Recommendation**: Use plugin-specific endpoints instead of `/mcp` (596 tools) to minimize token usage.
303
317
 
304
318
  | Endpoint | Use Case | Tools |
305
319
  |----------|----------|------:|
320
+ | `/u/{user_id}/{alias}/mcp` | Hosted users (OAuth login) | 22-100 |
306
321
  | `/project/{alias}/mcp` | Single-site workflow (recommended) | 22-100 |
307
322
  | `/{plugin}/mcp` | Multi-site management | 23-101 |
308
323
  | `/mcp` | Admin & discovery only | 596 |
@@ -323,7 +338,7 @@ Some MCP Hub tools require companion WordPress plugins:
323
338
 
324
339
  | Tools | Requirement |
325
340
  |-------|-------------|
326
- | SEO tools (`wordpress_get_post_seo`, etc.) | [SEO API Bridge](wordpress-plugin/seo-api-bridge/) ([Download ZIP](wordpress-plugin/seo-api-bridge.zip)) + Rank Math or Yoast SEO |
341
+ | SEO tools (`wordpress_get_post_seo`, etc.) | [Airano MCP SEO Bridge](https://wordpress.org/plugins/airano-mcp-seo-bridge/) ([GitHub](wordpress-plugin/airano-mcp-seo-bridge/)) + Rank Math or Yoast SEO |
327
342
  | WP-CLI tools (15 tools: `wp_cache_*`, `wp_db_*`, etc.) | Docker socket + `CONTAINER` env var |
328
343
  | WordPress Advanced database/system tools | Docker socket + `CONTAINER` env var |
329
344
  | OpenPanel analytics integration | [OpenPanel Self-Hosted](wordpress-plugin/openpanel-self-hosted/) ([Download ZIP](wordpress-plugin/openpanel-self-hosted.zip)) |
@@ -363,7 +378,7 @@ Without Docker socket, WP-CLI tools return "not available" but all REST API tool
363
378
  # Install with dev dependencies
364
379
  pip install -e ".[dev]"
365
380
 
366
- # Run tests (290 tests)
381
+ # Run tests (481 tests)
367
382
  pytest
368
383
 
369
384
  # Format and lint
@@ -0,0 +1,27 @@
1
+ """Admin utility functions for role determination.
2
+
3
+ Centralizes admin email checking so it can be used in OAuth callback,
4
+ dashboard auth, and future admin/user panel unification (F.5+).
5
+ """
6
+
7
+ import os
8
+
9
+
10
+ def is_admin_email(email: str | None) -> bool:
11
+ """Check if an email is in the ADMIN_EMAILS env var list.
12
+
13
+ Args:
14
+ email: Email address to check.
15
+
16
+ Returns:
17
+ True if email matches an admin email (case-insensitive).
18
+ """
19
+ if not email:
20
+ return False
21
+
22
+ admin_emails_raw = os.environ.get("ADMIN_EMAILS", "")
23
+ if not admin_emails_raw.strip():
24
+ return False
25
+
26
+ admin_emails = {e.strip().lower() for e in admin_emails_raw.split(",") if e.strip()}
27
+ return email.strip().lower() in admin_emails
@@ -14,6 +14,8 @@ from dataclasses import asdict, dataclass
14
14
  from datetime import datetime, timedelta
15
15
  from pathlib import Path
16
16
 
17
+ import bcrypt
18
+
17
19
  logger = logging.getLogger(__name__)
18
20
 
19
21
 
@@ -79,7 +81,7 @@ class APIKey:
79
81
  """
80
82
 
81
83
  key_id: str
82
- key_hash: str
84
+ key_hash: str # bcrypt hash (new keys) or SHA-256 hex (legacy)
83
85
  project_id: str
84
86
  scope: Scope
85
87
  created_at: str
@@ -180,8 +182,16 @@ class APIKeyManager:
180
182
  logger.error(f"Failed to save keys: {e}")
181
183
 
182
184
  def _hash_key(self, api_key: str) -> str:
183
- """Hash API key for storage."""
184
- return hashlib.sha256(api_key.encode()).hexdigest()
185
+ """Hash API key for storage using bcrypt."""
186
+ return bcrypt.hashpw(api_key.encode(), bcrypt.gensalt()).decode()
187
+
188
+ def _verify_key(self, api_key: str, key_hash: str) -> bool:
189
+ """Verify API key against stored hash (supports bcrypt and legacy SHA-256)."""
190
+ if key_hash.startswith("$2"):
191
+ # bcrypt hash
192
+ return bcrypt.checkpw(api_key.encode(), key_hash.encode())
193
+ # Legacy SHA-256 fallback
194
+ return hashlib.sha256(api_key.encode()).hexdigest() == key_hash
185
195
 
186
196
  def create_key(
187
197
  self,
@@ -269,11 +279,9 @@ class APIKeyManager:
269
279
  Returns:
270
280
  Optional[str]: key_id if valid, None otherwise
271
281
  """
272
- key_hash = self._hash_key(api_key)
273
-
274
- # Find key by hash
282
+ # Find key by verifying against stored hash (bcrypt or legacy SHA-256)
275
283
  for key_id, key in self.keys.items():
276
- if key.key_hash != key_hash:
284
+ if not self._verify_key(api_key, key.key_hash):
277
285
  continue
278
286
 
279
287
  # Check if valid (not revoked, not expired)
@@ -341,10 +349,8 @@ class APIKeyManager:
341
349
  Returns:
342
350
  Optional[APIKey]: The APIKey object if found, None otherwise
343
351
  """
344
- key_hash = self._hash_key(api_key)
345
-
346
352
  for key_id, key in self.keys.items():
347
- if key.key_hash == key_hash:
353
+ if self._verify_key(api_key, key.key_hash):
348
354
  logger.debug(f"Found API key {key_id} by token")
349
355
  return key
350
356
 
@@ -20,6 +20,11 @@ import json
20
20
 
21
21
  # Supported MCP client types
22
22
  SUPPORTED_CLIENTS = [
23
+ {
24
+ "id": "claude_connectors",
25
+ "label": "Claude.ai Connectors",
26
+ "description": "claude.ai/customize/connectors",
27
+ },
23
28
  {
24
29
  "id": "claude_desktop",
25
30
  "label": "Claude Desktop",
@@ -47,6 +52,9 @@ SUPPORTED_CLIENTS = [
47
52
  },
48
53
  ]
49
54
 
55
+ # Clients that only need a URL (no JSON config snippet, no transport Note)
56
+ WEB_CLIENTS = {"claude_connectors", "chatgpt"}
57
+
50
58
 
51
59
  def get_supported_clients() -> list[dict[str, str]]:
52
60
  """Return the list of supported MCP client types."""
@@ -79,10 +87,14 @@ def generate_config(
79
87
  endpoint_url = f"{base_url}/u/{user_id}/{alias}/mcp"
80
88
  server_name = f"mcphub-{alias}"
81
89
 
90
+ # Claude Desktop uses streamableHttp; Claude Code, VS Code, Cursor use http
91
+ transport_type = "streamableHttp" if client_type == "claude_desktop" else "http"
92
+
82
93
  if client_type in ("claude_desktop", "claude_code"):
83
94
  config = {
84
95
  "mcpServers": {
85
96
  server_name: {
97
+ "type": transport_type,
86
98
  "url": endpoint_url,
87
99
  "headers": {
88
100
  "Authorization": f"Bearer {api_key}",
@@ -97,6 +109,7 @@ def generate_config(
97
109
  "mcp": {
98
110
  "servers": {
99
111
  server_name: {
112
+ "type": transport_type,
100
113
  "url": endpoint_url,
101
114
  "headers": {
102
115
  "Authorization": f"Bearer {api_key}",
@@ -107,7 +120,7 @@ def generate_config(
107
120
  }
108
121
  return json.dumps(config, indent=2)
109
122
 
110
- elif client_type == "chatgpt":
123
+ elif client_type in ("claude_connectors", "chatgpt"):
111
124
  return endpoint_url
112
125
 
113
126
  else:
@@ -90,21 +90,29 @@ class DashboardAuth:
90
90
  return False, "", None
91
91
 
92
92
  api_key_clean = api_key.strip()
93
+ # Check if master key dashboard login is disabled
94
+ master_login_disabled = (
95
+ os.environ.get("DISABLE_MASTER_KEY_LOGIN", "false").lower() == "true"
96
+ )
97
+
93
98
  # Check master API key (from env var)
94
- if self.master_api_key and secrets.compare_digest(
95
- api_key_clean, self.master_api_key.strip()
99
+ if (
100
+ not master_login_disabled
101
+ and self.master_api_key
102
+ and secrets.compare_digest(api_key_clean, self.master_api_key.strip())
96
103
  ):
97
104
  return True, "master", None
98
105
 
99
106
  # Check AuthManager's master key (covers auto-generated temp keys)
100
- try:
101
- from core.auth import get_auth_manager
107
+ if not master_login_disabled:
108
+ try:
109
+ from core.auth import get_auth_manager
102
110
 
103
- auth_mgr = get_auth_manager()
104
- if auth_mgr.validate_master_key(api_key):
105
- return True, "master", None
106
- except Exception as e:
107
- logger.debug(f"AuthManager check skipped: {e}")
111
+ auth_mgr = get_auth_manager()
112
+ if auth_mgr.validate_master_key(api_key):
113
+ return True, "master", None
114
+ except Exception as e:
115
+ logger.debug(f"AuthManager check skipped: {e}")
108
116
 
109
117
  # Check project API keys with admin scope
110
118
  try:
@@ -353,9 +361,10 @@ def get_session_display_info(session) -> dict:
353
361
  if isinstance(session, DashboardSession):
354
362
  return {"name": "Admin", "type": "admin", "email": None, "avatar": None}
355
363
  if isinstance(session, dict):
364
+ session_type = "admin" if session.get("role") == "admin" else "user"
356
365
  return {
357
366
  "name": session.get("name") or session.get("email", "User"),
358
- "type": "user",
367
+ "type": session_type,
359
368
  "email": session.get("email"),
360
369
  "avatar": None,
361
370
  }