drupal-mcp-server 0.2.0__tar.gz → 0.3.1__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 (162) hide show
  1. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.gitignore +2 -0
  2. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/PKG-INFO +29 -9
  3. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/README.md +27 -8
  4. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/CHANGELOG.md +109 -0
  5. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/agents.md +4 -4
  6. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/index.md +7 -4
  7. drupal_mcp_server-0.3.1/docs/tools/index.md +442 -0
  8. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/pyproject.toml +5 -1
  9. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/live-migration-d7d11.sh +2 -5
  10. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/__init__.py +1 -1
  11. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/clients/drush.py +12 -1
  12. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/installer.py +9 -4
  13. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/server.py +4 -1
  14. drupal_mcp_server-0.3.1/src/drupal_mcp_server/tools/_utils.py +492 -0
  15. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/analysis.py +419 -0
  16. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/config.py +59 -0
  17. drupal_mcp_server-0.3.1/src/drupal_mcp_server/tools/exports.py +658 -0
  18. drupal_mcp_server-0.3.1/src/drupal_mcp_server/tools/security_audit.py +1044 -0
  19. drupal_mcp_server-0.3.1/src/drupal_mcp_server/tools/status.py +527 -0
  20. drupal_mcp_server-0.3.1/src/drupal_mcp_server/tools/theme_analysis.py +785 -0
  21. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_clients.py +16 -0
  22. drupal_mcp_server-0.3.1/tests/unit/test_exports.py +726 -0
  23. drupal_mcp_server-0.3.1/tests/unit/test_insight_tools.py +399 -0
  24. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_installer.py +1 -1
  25. drupal_mcp_server-0.3.1/tests/unit/test_security_scanners.py +471 -0
  26. drupal_mcp_server-0.3.1/tests/unit/test_status_tools.py +445 -0
  27. drupal_mcp_server-0.3.1/tests/unit/test_theme_analysis.py +567 -0
  28. drupal_mcp_server-0.2.0/docs/tools/index.md +0 -90
  29. drupal_mcp_server-0.2.0/src/drupal_mcp_server/tools/_utils.py +0 -239
  30. drupal_mcp_server-0.2.0/src/drupal_mcp_server/tools/security_audit.py +0 -265
  31. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.codecov.yml +0 -0
  32. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.env.example +0 -0
  33. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  34. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  35. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  36. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.github/workflows/ci.yml +0 -0
  37. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.github/workflows/docs.yml +0 -0
  38. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/.github/workflows/release.yml +0 -0
  39. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/LICENSE +0 -0
  40. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/MAINTAINERS.md +0 -0
  41. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/CODE_OF_CONDUCT.md +0 -0
  42. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/CONTRIBUTING.md +0 -0
  43. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/SECURITY.md +0 -0
  44. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/adr/0001-use-fastmcp.md +0 -0
  45. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/adr/0002-pydantic-settings.md +0 -0
  46. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/adr/0003-subprocess-drush.md +0 -0
  47. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/adr/0004-http-transport.md +0 -0
  48. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/architecture.md +0 -0
  49. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/configuration.md +0 -0
  50. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/docstring_standard.md +0 -0
  51. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/installation.md +0 -0
  52. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/migration.md +0 -0
  53. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/quickstart.md +0 -0
  54. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/tools/content.md +0 -0
  55. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/tools/devops.md +0 -0
  56. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/docs/tools/users.md +0 -0
  57. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/examples/.env.example +0 -0
  58. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/examples/README.md +0 -0
  59. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/examples/basic_usage.py +0 -0
  60. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/examples/content_workflow.py +0 -0
  61. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/examples/custom_tool.py +0 -0
  62. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/examples/migration_workflow.py +0 -0
  63. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/mkdocs.yml +0 -0
  64. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/lint.sh +0 -0
  65. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/live-migration-d9d11-run.py +0 -0
  66. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/live-migration-d9d11.sh +0 -0
  67. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/live-migration-smoke-run.py +0 -0
  68. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/live-migration-smoke.sh +0 -0
  69. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/run.sh +0 -0
  70. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/setup.sh +0 -0
  71. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/scripts/test.sh +0 -0
  72. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/auth/__init__.py +0 -0
  73. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/auth/basic.py +0 -0
  74. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/auth/mcp_oauth.py +0 -0
  75. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/auth/session.py +0 -0
  76. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/auth/token.py +0 -0
  77. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/cli.py +0 -0
  78. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/clients/__init__.py +0 -0
  79. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/clients/base.py +0 -0
  80. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/clients/graphql.py +0 -0
  81. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/clients/jsonapi.py +0 -0
  82. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/codebase/__init__.py +0 -0
  83. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/codebase/indexer.py +0 -0
  84. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/codebase/parsers.py +0 -0
  85. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/codebase/search.py +0 -0
  86. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/config.py +0 -0
  87. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/errors.py +0 -0
  88. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/exceptions.py +0 -0
  89. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/logging_config.py +0 -0
  90. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/schemas.py +0 -0
  91. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/services/__init__.py +0 -0
  92. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/services/ai_service.py +0 -0
  93. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/services/migration_service.py +0 -0
  94. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/services/site_manager.py +0 -0
  95. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/__init__.py +0 -0
  96. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/accessibility.py +0 -0
  97. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/ai.py +0 -0
  98. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/code_audit.py +0 -0
  99. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/codebase.py +0 -0
  100. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/comments.py +0 -0
  101. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/commerce.py +0 -0
  102. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/contact.py +0 -0
  103. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/content.py +0 -0
  104. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/database.py +0 -0
  105. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/devops.py +0 -0
  106. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/drupal_org.py +0 -0
  107. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/feeds.py +0 -0
  108. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/fields.py +0 -0
  109. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/headless.py +0 -0
  110. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/layout_builder.py +0 -0
  111. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/media_enhanced.py +0 -0
  112. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/menus.py +0 -0
  113. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/metatag.py +0 -0
  114. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/migration.py +0 -0
  115. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/moderation.py +0 -0
  116. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/module_dev.py +0 -0
  117. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/multilingual.py +0 -0
  118. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/paragraphs.py +0 -0
  119. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/pathauto.py +0 -0
  120. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/performance.py +0 -0
  121. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/redirects.py +0 -0
  122. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/revisions.py +0 -0
  123. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/scheduler.py +0 -0
  124. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/search_api.py +0 -0
  125. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/taxonomy.py +0 -0
  126. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/testing.py +0 -0
  127. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/theme_dev.py +0 -0
  128. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/users.py +0 -0
  129. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/views.py +0 -0
  130. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/tools/webform.py +0 -0
  131. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/src/drupal_mcp_server/validation.py +0 -0
  132. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/__init__.py +0 -0
  133. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/integration/test_server.py +0 -0
  134. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/README.md +0 -0
  135. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/bootstrap.py +0 -0
  136. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/filter_check.py +0 -0
  137. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/install_modules.py +0 -0
  138. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/layout_builder_test.py +0 -0
  139. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/mcp_call.py +0 -0
  140. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/queue_test.py +0 -0
  141. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/resource_check.py +0 -0
  142. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/seed.php +0 -0
  143. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/smoke_test.py +0 -0
  144. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/live/sweep.py +0 -0
  145. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/__init__.py +0 -0
  146. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_auth.py +0 -0
  147. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_codebase.py +0 -0
  148. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_content_tools.py +0 -0
  149. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_drupal_org.py +0 -0
  150. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_errors.py +0 -0
  151. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_handler_and_translation_tools.py +0 -0
  152. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_logging_config.py +0 -0
  153. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_migration_service.py +0 -0
  154. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_moderation_transitions.py +0 -0
  155. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_resource_names.py +0 -0
  156. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_revisions.py +0 -0
  157. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_scheduler_tools.py +0 -0
  158. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_schemas.py +0 -0
  159. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_sweep_harness.py +0 -0
  160. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_tool_utils.py +0 -0
  161. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_tools.py +0 -0
  162. {drupal_mcp_server-0.2.0 → drupal_mcp_server-0.3.1}/tests/unit/test_validation.py +0 -0
@@ -88,3 +88,5 @@ config/sync/
88
88
  .omc
89
89
  .pi
90
90
  .mutagen-*
91
+ # export tools' default destination when DRUPAL_ROOT points at the repo
92
+ exports/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: drupal-mcp-server
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: MCP server for Drupal operations - JSON:API, GraphQL, Drush, AI-powered migration
5
5
  Author: Loganathane V
6
6
  License: MIT
@@ -15,6 +15,7 @@ Requires-Python: >=3.11
15
15
  Requires-Dist: click>=8.1.7
16
16
  Requires-Dist: fastmcp>=2.0.0
17
17
  Requires-Dist: httpx>=0.27.0
18
+ Requires-Dist: openpyxl>=3.1.2
18
19
  Requires-Dist: pydantic-settings>=2.3.0
19
20
  Requires-Dist: pydantic>=2.8.0
20
21
  Requires-Dist: python-dotenv>=1.0.0
@@ -49,7 +50,7 @@ Description-Content-Type: text/markdown
49
50
  [![PyPI downloads](https://img.shields.io/pypi/dm/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
50
51
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/vloganathane/drupal-mcp-server/blob/main/LICENSE)
51
52
 
52
- A Model Context Protocol (MCP) server for Drupal operations. Provides **392 tools across 38 modules** for site analysis, migration, content management, configuration, commerce, headless, DevOps, security, and more.
53
+ A Model Context Protocol (MCP) server for Drupal operations. Provides **414 tools across 41 modules** for site analysis, migration, content management, configuration, commerce, headless, DevOps, security, and more.
53
54
 
54
55
  ## Why Use This?
55
56
 
@@ -146,7 +147,7 @@ config (preferring the client's own `mcp add` command when it has one).
146
147
 
147
148
  ```bash
148
149
  drupal-mcp install --client claude-code --print # preview without writing
149
- drupal-mcp install --command 'uvx drupal-mcp-server' # run from PyPI, no install
150
+ drupal-mcp install --command 'uvx --from drupal-mcp-server drupal-mcp' # run from PyPI, no install
150
151
  ```
151
152
 
152
153
  See the [AI Coding Agents guide](docs/agents.md) for per-client copy-paste
@@ -203,7 +204,7 @@ Set `MCP_TRANSPORT` to one of:
203
204
  - `sse` (for Server-Sent Events)
204
205
  - `streamable-http` (for Streamable HTTP)
205
206
 
206
- ## Tools (392 total)
207
+ ## Tools (414 total)
207
208
 
208
209
  ### Accessibility (5)
209
210
  - `accessibility_axe_scan` — Run axe-core accessibility scan
@@ -218,13 +219,16 @@ Set `MCP_TRANSPORT` to one of:
218
219
  - `ai_generate_migration_plan` — Generate migration plan with AI
219
220
  - `ai_translate_content` — Translate content with AI
220
221
 
221
- ### Analysis (6)
222
+ ### Analysis (9)
222
223
  - `analyze_d7_site` — Analyze D7 site for D10 readiness
223
224
  - `analyze_d9_site` — Analyze D9+ for deprecated APIs
224
225
  - `inventory_content_types` — List all content types
225
226
  - `inventory_modules` — List all modules
226
227
  - `map_modules_d7_to_d10` — AI-powered module mapping D7→D10
227
228
  - `find_deprecated_code` — Scan for deprecated APIs
229
+ - `find_entity_references` — Bundles whose reference fields target an entity type
230
+ - `search_entities` — Substring search across titles, names, and subjects
231
+ - `find_entity_by_path` — Resolve a URL path or alias to its entity
228
232
 
229
233
  ### Code Audit (7)
230
234
  - `code_audit_phpstan` — Run PHPStan static analysis
@@ -253,8 +257,8 @@ Set `MCP_TRANSPORT` to one of:
253
257
  - `commerce_promotion_list`, `commerce_promotion_create`
254
258
  - `commerce_shipping_method_list`, `commerce_shipping_method_create`
255
259
 
256
- ### Config (7)
257
- - `config_get`, `config_set`, `export_config`, `import_config`, `sync_config`, `diff_config`, `split_config`
260
+ ### Config (8)
261
+ - `config_get`, `config_set`, `export_config`, `import_config`, `sync_config`, `diff_config`, `split_config`, `config_status`
258
262
 
259
263
  ### Contact (9)
260
264
  - `contact_form_list`, `contact_form_get`, `contact_form_create`, `contact_form_update`, `contact_form_delete`
@@ -283,6 +287,9 @@ Set `MCP_TRANSPORT` to one of:
283
287
  - `theme_search`, `theme_get`, `release_history`, `project_usage`
284
288
  - `module_issues_search`, `module_popular`, `module_recommendation`
285
289
 
290
+ ### Exports (4)
291
+ - `export_nodes`, `export_users`, `export_media`, `export_taxonomy`
292
+
286
293
  ### Feeds (12)
287
294
  - `feeds_feed_list`, `feeds_feed_get`, `feeds_feed_create`, `feeds_feed_update`, `feeds_feed_delete`
288
295
  - `feeds_import`, `feeds_import_status`, `feeds_log_list`
@@ -391,7 +398,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
391
398
  - `search_api_index_list`, `search_api_index_get`, `search_api_index_create`, `search_api_index_update`
392
399
  - `search_api_index_reindex`, `search_api_index_clear`, `search_api_facet_list`, `search_api_facet_create`
393
400
 
394
- ### Security Audit (8)
401
+ ### Security Audit (10)
395
402
  - `security_scan` — PHPStan with security extensions
396
403
  - `dependency_scan` — Composer audit
397
404
  - `config_security_check` — Drupal config security
@@ -400,6 +407,14 @@ displays have Layout Builder enabled; `layout_builder_get`,
400
407
  - `xss_scan` — XSS vulnerability detection
401
408
  - `csp_audit` — Content Security Policy audit
402
409
  - `file_permissions_audit` — File permissions audit
410
+ - `code_security_scan` — Local pattern scan, nothing to install
411
+ - `route_access_audit` — Route access control classification
412
+
413
+ ### Status (4)
414
+ - `status_report` — The site's status report (/admin/reports/status), read-only
415
+ - `database_updates` — Pending database updates, read-only
416
+ - `available_updates` — Packages with newer versions, from composer
417
+ - `health_check` — Drush, database, JSON:API, and module diagnostics
403
418
 
404
419
  ### Taxonomy (10)
405
420
  - `create_vocabulary`, `get_vocabulary`, `update_vocabulary`, `delete_vocabulary`, `list_vocabularies`
@@ -410,6 +425,11 @@ displays have Layout Builder enabled; `layout_builder_get`,
410
425
  - `test_scaffold_phpunit`, `test_scaffold_behat`, `test_scaffold_nightwatch`
411
426
  - `test_coverage_report`, `test_list_suites`
412
427
 
428
+ ### Theme Analysis (8)
429
+ - `theme_active`, `theme_info`, `theme_regions`, `theme_blocks`
430
+ - `theme_templates`, `theme_template_overrides`, `template_suggestions`
431
+ - `view_template_info`
432
+
413
433
  ### Theme Development (11)
414
434
  - `theme_create`, `theme_library_create`, `theme_region_create`, `theme_template_override`
415
435
  - `theme_preprocess_function`, `theme_breakpoint_create`, `theme_base_change`
@@ -529,7 +549,7 @@ python tests/live/queue_test.py # 18 cron/queue cases, ~60s
529
549
  python tests/live/filter_check.py # every hard-coded JSON:API filter
530
550
  python tests/live/resource_check.py # every resource name, asked of Drupal
531
551
  python tests/live/install_modules.py # the modules the tools assume, ~10 min
532
- python tests/live/sweep.py # all 392 tools, ~30 min
552
+ python tests/live/sweep.py # all 414 tools, ~30 min
533
553
  python tests/live/mcp_call.py content_list '{}' # one call, for spot checks
534
554
  ```
535
555
 
@@ -7,7 +7,7 @@
7
7
  [![PyPI downloads](https://img.shields.io/pypi/dm/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/vloganathane/drupal-mcp-server/blob/main/LICENSE)
9
9
 
10
- A Model Context Protocol (MCP) server for Drupal operations. Provides **392 tools across 38 modules** for site analysis, migration, content management, configuration, commerce, headless, DevOps, security, and more.
10
+ A Model Context Protocol (MCP) server for Drupal operations. Provides **414 tools across 41 modules** for site analysis, migration, content management, configuration, commerce, headless, DevOps, security, and more.
11
11
 
12
12
  ## Why Use This?
13
13
 
@@ -104,7 +104,7 @@ config (preferring the client's own `mcp add` command when it has one).
104
104
 
105
105
  ```bash
106
106
  drupal-mcp install --client claude-code --print # preview without writing
107
- drupal-mcp install --command 'uvx drupal-mcp-server' # run from PyPI, no install
107
+ drupal-mcp install --command 'uvx --from drupal-mcp-server drupal-mcp' # run from PyPI, no install
108
108
  ```
109
109
 
110
110
  See the [AI Coding Agents guide](docs/agents.md) for per-client copy-paste
@@ -161,7 +161,7 @@ Set `MCP_TRANSPORT` to one of:
161
161
  - `sse` (for Server-Sent Events)
162
162
  - `streamable-http` (for Streamable HTTP)
163
163
 
164
- ## Tools (392 total)
164
+ ## Tools (414 total)
165
165
 
166
166
  ### Accessibility (5)
167
167
  - `accessibility_axe_scan` — Run axe-core accessibility scan
@@ -176,13 +176,16 @@ Set `MCP_TRANSPORT` to one of:
176
176
  - `ai_generate_migration_plan` — Generate migration plan with AI
177
177
  - `ai_translate_content` — Translate content with AI
178
178
 
179
- ### Analysis (6)
179
+ ### Analysis (9)
180
180
  - `analyze_d7_site` — Analyze D7 site for D10 readiness
181
181
  - `analyze_d9_site` — Analyze D9+ for deprecated APIs
182
182
  - `inventory_content_types` — List all content types
183
183
  - `inventory_modules` — List all modules
184
184
  - `map_modules_d7_to_d10` — AI-powered module mapping D7→D10
185
185
  - `find_deprecated_code` — Scan for deprecated APIs
186
+ - `find_entity_references` — Bundles whose reference fields target an entity type
187
+ - `search_entities` — Substring search across titles, names, and subjects
188
+ - `find_entity_by_path` — Resolve a URL path or alias to its entity
186
189
 
187
190
  ### Code Audit (7)
188
191
  - `code_audit_phpstan` — Run PHPStan static analysis
@@ -211,8 +214,8 @@ Set `MCP_TRANSPORT` to one of:
211
214
  - `commerce_promotion_list`, `commerce_promotion_create`
212
215
  - `commerce_shipping_method_list`, `commerce_shipping_method_create`
213
216
 
214
- ### Config (7)
215
- - `config_get`, `config_set`, `export_config`, `import_config`, `sync_config`, `diff_config`, `split_config`
217
+ ### Config (8)
218
+ - `config_get`, `config_set`, `export_config`, `import_config`, `sync_config`, `diff_config`, `split_config`, `config_status`
216
219
 
217
220
  ### Contact (9)
218
221
  - `contact_form_list`, `contact_form_get`, `contact_form_create`, `contact_form_update`, `contact_form_delete`
@@ -241,6 +244,9 @@ Set `MCP_TRANSPORT` to one of:
241
244
  - `theme_search`, `theme_get`, `release_history`, `project_usage`
242
245
  - `module_issues_search`, `module_popular`, `module_recommendation`
243
246
 
247
+ ### Exports (4)
248
+ - `export_nodes`, `export_users`, `export_media`, `export_taxonomy`
249
+
244
250
  ### Feeds (12)
245
251
  - `feeds_feed_list`, `feeds_feed_get`, `feeds_feed_create`, `feeds_feed_update`, `feeds_feed_delete`
246
252
  - `feeds_import`, `feeds_import_status`, `feeds_log_list`
@@ -349,7 +355,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
349
355
  - `search_api_index_list`, `search_api_index_get`, `search_api_index_create`, `search_api_index_update`
350
356
  - `search_api_index_reindex`, `search_api_index_clear`, `search_api_facet_list`, `search_api_facet_create`
351
357
 
352
- ### Security Audit (8)
358
+ ### Security Audit (10)
353
359
  - `security_scan` — PHPStan with security extensions
354
360
  - `dependency_scan` — Composer audit
355
361
  - `config_security_check` — Drupal config security
@@ -358,6 +364,14 @@ displays have Layout Builder enabled; `layout_builder_get`,
358
364
  - `xss_scan` — XSS vulnerability detection
359
365
  - `csp_audit` — Content Security Policy audit
360
366
  - `file_permissions_audit` — File permissions audit
367
+ - `code_security_scan` — Local pattern scan, nothing to install
368
+ - `route_access_audit` — Route access control classification
369
+
370
+ ### Status (4)
371
+ - `status_report` — The site's status report (/admin/reports/status), read-only
372
+ - `database_updates` — Pending database updates, read-only
373
+ - `available_updates` — Packages with newer versions, from composer
374
+ - `health_check` — Drush, database, JSON:API, and module diagnostics
361
375
 
362
376
  ### Taxonomy (10)
363
377
  - `create_vocabulary`, `get_vocabulary`, `update_vocabulary`, `delete_vocabulary`, `list_vocabularies`
@@ -368,6 +382,11 @@ displays have Layout Builder enabled; `layout_builder_get`,
368
382
  - `test_scaffold_phpunit`, `test_scaffold_behat`, `test_scaffold_nightwatch`
369
383
  - `test_coverage_report`, `test_list_suites`
370
384
 
385
+ ### Theme Analysis (8)
386
+ - `theme_active`, `theme_info`, `theme_regions`, `theme_blocks`
387
+ - `theme_templates`, `theme_template_overrides`, `template_suggestions`
388
+ - `view_template_info`
389
+
371
390
  ### Theme Development (11)
372
391
  - `theme_create`, `theme_library_create`, `theme_region_create`, `theme_template_override`
373
392
  - `theme_preprocess_function`, `theme_breakpoint_create`, `theme_base_change`
@@ -487,7 +506,7 @@ python tests/live/queue_test.py # 18 cron/queue cases, ~60s
487
506
  python tests/live/filter_check.py # every hard-coded JSON:API filter
488
507
  python tests/live/resource_check.py # every resource name, asked of Drupal
489
508
  python tests/live/install_modules.py # the modules the tools assume, ~10 min
490
- python tests/live/sweep.py # all 392 tools, ~30 min
509
+ python tests/live/sweep.py # all 414 tools, ~30 min
491
510
  python tests/live/mcp_call.py content_list '{}' # one call, for spot checks
492
511
  ```
493
512
 
@@ -5,6 +5,115 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.3.1] - 2026-10-17
11
+
12
+ ### Fixed
13
+
14
+ - Make `uvx drupal-mcp-server` actually run the server. The package
15
+ shipped only a `drupal-mcp` executable, and current uv refuses to
16
+ guess when the tool name differs from the package name ("Use `uvx
17
+ --from drupal-mcp-server drupal-mcp` instead"), so the documented
18
+ no-install command — including the PATH fallback the installer
19
+ writes into client configs — failed to start. A `drupal-mcp-server`
20
+ console-script alias now runs the same entry point, and the
21
+ installer's fallback, help text, README and AI-agents guide name the
22
+ unambiguous `uvx --from drupal-mcp-server drupal-mcp` form, which
23
+ works on every uv version.
24
+
25
+ ## [0.3.0] - 2026-10-17
26
+
27
+ ### Added
28
+
29
+ - Wave 5 of the drupal-scout-mcp port — 2 local security tools
30
+ (414 total, 41 modules): `code_security_scan` runs scout's
31
+ zero-dependency pattern engine (XSS, SQL injection, command injection,
32
+ path traversal, hardcoded secrets, access control, CSRF, deprecated
33
+ API — 8 families, category/severity filters, per-finding file/line/
34
+ snippet/fix recommendation) with its Drupal-aware false-positive table
35
+ (EntityQuery conditions, stream wrappers, escapeshellarg, example
36
+ secrets, comment lines), so a site without PHPStan gets concrete
37
+ findings; counts stay complete when `max_findings` truncates the list.
38
+ `route_access_audit` is the routing half of scout's anonymous-exploit
39
+ scan done properly per route: every `*.routing.yml` route classified
40
+ as anonymous / permission / role / entity / custom / a named
41
+ underscore requirement / an alias (whose definition may live in a
42
+ PHP route provider this YAML pass cannot read) / denied / **missing**,
43
+ with its controller mapped to the declaring file. Targets confine to
44
+ DRUPAL_ROOT and prune vendor, tests, and contrib from the default scan;
45
+ symlinks are skipped. Two accuracy corrections over scout's registry:
46
+ `t(` is a live D8+ function (scout flagged every translation call as a
47
+ Drupal 7 leftover) and scout's CSRF `$request` pattern was escaped so
48
+ it could never match PHP. Scout's `verify_vulnerability` was not
49
+ ported — it returns static advice rather than site-specific data —
50
+ and the optional tree-sitter AST layer is skipped: the pattern pass
51
+ carries the signal. Live testing on D11.4.10's core node module
52
+ (115 files) caught five accuracy bugs before release: JS template
53
+ literals matched the PHP backtick-shell pattern, Drupal's `{table}` /
54
+ `->...Table()` placeholder concatenation read as SQL injection,
55
+ unrecognized underscore requirements and alias-only entries were both
56
+ reported as missing access (node went from five "missing" routes to
57
+ zero real ones), and a zero-file scan read as a clean bill of health.
58
+ - Wave 4 of the drupal-scout-mcp port — 8 read-only theme analysis tools
59
+ (412 total, 41 modules): `theme_active` (default/admin/enabled themes
60
+ from `system.theme` + `pm:list`), `theme_info` (pm:list metadata merged
61
+ with a safe YAML parse of the theme's info.yml — regions in declaration
62
+ order, libraries, dependencies, and the base-theme chain followed
63
+ upward), `theme_regions` (regions with their block placements and
64
+ counts, empty regions visible, placements in regions the theme no
65
+ longer defines flagged), `theme_blocks` (every `block.block.*`
66
+ placement with theme/region/search filters — search matches labels and
67
+ plugins, folding scout's separate `search_blocks` into one tool),
68
+ `theme_templates` (pruned `*.html.twig` walk with sizes),
69
+ `theme_template_overrides` (one docroot-wide index splits templates
70
+ that shadow same-named core/module files from theme originals),
71
+ `template_suggestions` (the Twig suggestion chain per entity type, each
72
+ marked with whether the default theme already ships that file), and
73
+ `view_template_info` (the chain for a view display, looked up in the
74
+ JSON:API view collection by its machine id — Views config names differ
75
+ between Drupal generations, `view.*` on older sites and `views.view.*`
76
+ on Drupal 11.4+, so the entity collection is the stable source — with
77
+ an unknown display_id erroring with the display list and an unknown
78
+ view listing the ones the site has). Every file path resolves inside
79
+ DRUPAL_ROOT before a read — symlinks and `..` segments that leave the
80
+ docroot are rejected — and no caller input reaches a shell; theme
81
+ blocks come from JSON:API rather than scout's interpolated `drush ev`
82
+ - The shared JSON:API helpers (`jsonapi_collect`, `jsonapi_attrs`,
83
+ `jsonapi_bundle`, `jsonapi_rel_ids`), `flag_label`, and the export
84
+ path/write helpers moved from the exports module into `_utils` so both
85
+ waves page collections and confine destinations the same way
86
+ - Wave 3 of the drupal-scout-mcp port — 4 export tools (404 total, 40
87
+ modules): `export_nodes`, `export_users`, `export_media`,
88
+ `export_taxonomy` write CSV (UTF-8 with BOM) or Excel files
89
+ (`openpyxl`, new runtime dependency) and return only the path,
90
+ row/column counts, size, and a three-row preview. Destination paths are
91
+ confined to the Drupal root, the system temp directory, or the home
92
+ directory; data is paged per bundle over JSON:API (never through the
93
+ shared merged offset, which skips rows), and taxonomy usage counts come
94
+ from one validated `GROUP BY` query per field storage targeting
95
+ taxonomy terms, with unreadable tables reported in a note instead of
96
+ failing the export (and a `safe_to_delete` verdict withheld entirely
97
+ whenever the counts are incomplete). Entries with no internal id —
98
+ Drupal's uid-0 anonymous user serves only a display_name — are skipped
99
+ and counted as `skipped_without_id`, and an unreadable status stays
100
+ empty in the CSV rather than being presented as "blocked"
101
+ - `sql_output`/`sql_rows` moved from the analysis module into `_utils` so
102
+ the export tools parse `drush sql:query` text the same way
103
+ - Wave 2 of the drupal-scout-mcp port — 8 tools (400 total, 39 modules):
104
+ - Status section (4): `status_report` (drush core:requirements, severity
105
+ filter), `database_updates` (read-only pending DB updates),
106
+ `available_updates` (composer outdated with dev filtering and a
107
+ security-only mode intersected with composer audit), `health_check`
108
+ (Drush, database, JSON:API, and module probes with a fix per failure)
109
+ - Analysis: `find_entity_references` (bundles whose reference fields
110
+ target an entity type, via JSON:API field config), `search_entities`
111
+ (escaped LIKE search across six entity tables), `find_entity_by_path`
112
+ (route or path-alias resolution to an entity)
113
+ - Config: `config_status` (read-only active vs sync comparison)
114
+ - `run_composer` gained a `tail` argument so tools that parse full JSON
115
+ documents (`composer outdated`) are not truncated
116
+
8
117
  ## [0.2.0] - 2026-10-16
9
118
 
10
119
  ### Security
@@ -38,7 +38,7 @@ With no arguments it:
38
38
  | `--env KEY=VALUE` | Extra environment variable (repeatable) |
39
39
  | `--dotenv PATH` | Env file to read (default `./.env` if present) |
40
40
  | `--name NAME` | Server name inside the client config (default `drupal`) |
41
- | `--command CMD` | Launch command override, e.g. `--command 'uvx drupal-mcp-server'` |
41
+ | `--command CMD` | Launch command override, e.g. `--command 'uvx --from drupal-mcp-server drupal-mcp'` |
42
42
  | `--scope local\|user\|project` | Claude Code configuration scope |
43
43
  | `--global` | OpenCode: write the global config instead of the project one |
44
44
 
@@ -58,8 +58,8 @@ With no arguments it:
58
58
 
59
59
  The launch command is the absolute path to the `drupal-mcp` script when it is
60
60
  on `PATH` (GUI clients like Claude Desktop launch servers with a sanitized
61
- environment, so a bare name can fail there); otherwise `uvx drupal-mcp-server`
62
- runs it straight from PyPI.
61
+ environment, so a bare name can fail there); otherwise
62
+ `uvx --from drupal-mcp-server drupal-mcp` runs it straight from PyPI.
63
63
 
64
64
  Existing configs are merged, never clobbered: other servers in the same file
65
65
  survive, a server of the same name is replaced (so re-running is idempotent),
@@ -197,7 +197,7 @@ against the client's current CLI or docs:
197
197
  Point any client at PyPI directly:
198
198
 
199
199
  ```bash
200
- drupal-mcp install --command 'uvx drupal-mcp-server'
200
+ drupal-mcp install --command 'uvx --from drupal-mcp-server drupal-mcp'
201
201
  ```
202
202
 
203
203
  ## Verify
@@ -1,6 +1,6 @@
1
1
  # Drupal MCP Server
2
2
 
3
- A Model Context Protocol (MCP) server for Drupal operations. Provides 392 tools across 38 modules for site analysis, migration, content management, configuration, commerce, headless, DevOps, security, and more.
3
+ A Model Context Protocol (MCP) server for Drupal operations. Provides 414 tools across 41 modules for site analysis, migration, content management, configuration, commerce, headless, DevOps, security, and more.
4
4
 
5
5
  ## Quick Links
6
6
 
@@ -11,19 +11,22 @@ A Model Context Protocol (MCP) server for Drupal operations. Provides 392 tools
11
11
 
12
12
  ## Features at a Glance
13
13
 
14
- A sample of the catalog — the full list of all 392 tools lives in the
15
- [README's Tools section](https://github.com/vloganathane/drupal-mcp-server#tools-392-total).
14
+ A sample of the catalog — the full list of all 414 tools lives in the
15
+ [README's Tools section](https://github.com/vloganathane/drupal-mcp-server#tools-414-total).
16
16
 
17
17
  | Category | Tools | Description |
18
18
  |----------|-------|-------------|
19
19
  | Content | 14 | CRUD for nodes, media, users, taxonomy, comments |
20
20
  | Users | 12 | User management, roles, permissions |
21
21
  | DevOps | 20 | DDEV/Lando, Drush, database, cron |
22
- | Security Audit | 8 | Audits, scanning, permission checks |
22
+ | Security Audit | 10 | Audits, scanning, permission checks |
23
23
  | Migration | 17 | Plans, batch import, reconciliation between Drupal sites |
24
24
  | AI | 4 | Content analysis, field mapping, planning |
25
25
  | Module Dev | 12 | Scaffolding for modules, plugins, forms |
26
26
  | Codebase | 12 | Local codebase index, hook search, unused module detection |
27
+ | Status | 4 | Status report, pending updates, health diagnostics |
28
+ | Exports | 4 | CSV/Excel inventories of content, users, media, taxonomy |
29
+ | Theme Analysis | 8 | Theme metadata, regions, block placements, Twig templates |
27
30
 
28
31
  ## Example: Create a Node
29
32