drupal-mcp-server 0.1.0__tar.gz → 0.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 (165) hide show
  1. drupal_mcp_server-0.3.0/.codecov.yml +17 -0
  2. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.github/workflows/ci.yml +4 -1
  3. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.github/workflows/docs.yml +9 -0
  4. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.gitignore +14 -0
  5. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/PKG-INFO +73 -15
  6. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/README.md +71 -14
  7. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0/docs}/CHANGELOG.md +106 -0
  8. drupal_mcp_server-0.3.0/docs/agents.md +221 -0
  9. drupal_mcp_server-0.3.0/docs/index.md +46 -0
  10. drupal_mcp_server-0.3.0/docs/migration.md +188 -0
  11. drupal_mcp_server-0.3.0/docs/quickstart.md +86 -0
  12. drupal_mcp_server-0.3.0/docs/tools/index.md +442 -0
  13. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/mkdocs.yml +7 -0
  14. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/pyproject.toml +3 -2
  15. drupal_mcp_server-0.3.0/scripts/live-migration-d7d11.sh +240 -0
  16. drupal_mcp_server-0.3.0/scripts/live-migration-d9d11-run.py +127 -0
  17. drupal_mcp_server-0.3.0/scripts/live-migration-d9d11.sh +193 -0
  18. drupal_mcp_server-0.3.0/scripts/live-migration-smoke-run.py +115 -0
  19. drupal_mcp_server-0.3.0/scripts/live-migration-smoke.sh +166 -0
  20. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/__init__.py +1 -1
  21. drupal_mcp_server-0.3.0/src/drupal_mcp_server/cli.py +58 -0
  22. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/clients/drush.py +12 -1
  23. drupal_mcp_server-0.3.0/src/drupal_mcp_server/codebase/__init__.py +319 -0
  24. drupal_mcp_server-0.3.0/src/drupal_mcp_server/codebase/indexer.py +229 -0
  25. drupal_mcp_server-0.3.0/src/drupal_mcp_server/codebase/parsers.py +301 -0
  26. drupal_mcp_server-0.3.0/src/drupal_mcp_server/codebase/search.py +272 -0
  27. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/config.py +13 -0
  28. drupal_mcp_server-0.3.0/src/drupal_mcp_server/installer.py +792 -0
  29. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/server.py +11 -2
  30. drupal_mcp_server-0.3.0/src/drupal_mcp_server/services/migration_service.py +855 -0
  31. drupal_mcp_server-0.3.0/src/drupal_mcp_server/tools/_utils.py +492 -0
  32. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/analysis.py +419 -0
  33. drupal_mcp_server-0.3.0/src/drupal_mcp_server/tools/codebase.py +231 -0
  34. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/config.py +59 -0
  35. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/drupal_org.py +363 -0
  36. drupal_mcp_server-0.3.0/src/drupal_mcp_server/tools/exports.py +658 -0
  37. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/migration.py +218 -0
  38. drupal_mcp_server-0.3.0/src/drupal_mcp_server/tools/security_audit.py +1044 -0
  39. drupal_mcp_server-0.3.0/src/drupal_mcp_server/tools/status.py +527 -0
  40. drupal_mcp_server-0.3.0/src/drupal_mcp_server/tools/theme_analysis.py +785 -0
  41. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/integration/test_server.py +54 -0
  42. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_clients.py +16 -0
  43. drupal_mcp_server-0.3.0/tests/unit/test_codebase.py +588 -0
  44. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_drupal_org.py +285 -3
  45. drupal_mcp_server-0.3.0/tests/unit/test_exports.py +726 -0
  46. drupal_mcp_server-0.3.0/tests/unit/test_insight_tools.py +399 -0
  47. drupal_mcp_server-0.3.0/tests/unit/test_installer.py +445 -0
  48. drupal_mcp_server-0.3.0/tests/unit/test_migration_service.py +246 -0
  49. drupal_mcp_server-0.3.0/tests/unit/test_security_scanners.py +471 -0
  50. drupal_mcp_server-0.3.0/tests/unit/test_status_tools.py +445 -0
  51. drupal_mcp_server-0.3.0/tests/unit/test_theme_analysis.py +567 -0
  52. drupal_mcp_server-0.1.0/docs/index.md +0 -39
  53. drupal_mcp_server-0.1.0/docs/migration.md +0 -139
  54. drupal_mcp_server-0.1.0/docs/tools/index.md +0 -88
  55. drupal_mcp_server-0.1.0/src/drupal_mcp_server/services/migration_service.py +0 -20
  56. drupal_mcp_server-0.1.0/src/drupal_mcp_server/tools/_utils.py +0 -239
  57. drupal_mcp_server-0.1.0/src/drupal_mcp_server/tools/security_audit.py +0 -265
  58. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.env.example +0 -0
  59. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  60. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  61. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  62. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/.github/workflows/release.yml +0 -0
  63. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/LICENSE +0 -0
  64. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/MAINTAINERS.md +0 -0
  65. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0/docs}/CODE_OF_CONDUCT.md +0 -0
  66. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0/docs}/CONTRIBUTING.md +0 -0
  67. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0/docs}/SECURITY.md +0 -0
  68. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/adr/0001-use-fastmcp.md +0 -0
  69. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/adr/0002-pydantic-settings.md +0 -0
  70. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/adr/0003-subprocess-drush.md +0 -0
  71. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/adr/0004-http-transport.md +0 -0
  72. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/architecture.md +0 -0
  73. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/configuration.md +0 -0
  74. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/docstring_standard.md +0 -0
  75. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/installation.md +0 -0
  76. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/tools/content.md +0 -0
  77. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/tools/devops.md +0 -0
  78. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/docs/tools/users.md +0 -0
  79. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/examples/.env.example +0 -0
  80. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/examples/README.md +0 -0
  81. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/examples/basic_usage.py +0 -0
  82. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/examples/content_workflow.py +0 -0
  83. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/examples/custom_tool.py +0 -0
  84. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/examples/migration_workflow.py +0 -0
  85. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/scripts/lint.sh +0 -0
  86. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/scripts/run.sh +0 -0
  87. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/scripts/setup.sh +0 -0
  88. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/scripts/test.sh +0 -0
  89. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/auth/__init__.py +0 -0
  90. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/auth/basic.py +0 -0
  91. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/auth/mcp_oauth.py +0 -0
  92. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/auth/session.py +0 -0
  93. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/auth/token.py +0 -0
  94. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/clients/__init__.py +0 -0
  95. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/clients/base.py +0 -0
  96. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/clients/graphql.py +0 -0
  97. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/clients/jsonapi.py +0 -0
  98. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/errors.py +0 -0
  99. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/exceptions.py +0 -0
  100. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/logging_config.py +0 -0
  101. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/schemas.py +0 -0
  102. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/services/__init__.py +0 -0
  103. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/services/ai_service.py +0 -0
  104. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/services/site_manager.py +0 -0
  105. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/__init__.py +0 -0
  106. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/accessibility.py +0 -0
  107. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/ai.py +0 -0
  108. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/code_audit.py +0 -0
  109. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/comments.py +0 -0
  110. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/commerce.py +0 -0
  111. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/contact.py +0 -0
  112. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/content.py +0 -0
  113. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/database.py +0 -0
  114. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/devops.py +0 -0
  115. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/feeds.py +0 -0
  116. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/fields.py +0 -0
  117. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/headless.py +0 -0
  118. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/layout_builder.py +0 -0
  119. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/media_enhanced.py +0 -0
  120. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/menus.py +0 -0
  121. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/metatag.py +0 -0
  122. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/moderation.py +0 -0
  123. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/module_dev.py +0 -0
  124. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/multilingual.py +0 -0
  125. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/paragraphs.py +0 -0
  126. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/pathauto.py +0 -0
  127. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/performance.py +0 -0
  128. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/redirects.py +0 -0
  129. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/revisions.py +0 -0
  130. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/scheduler.py +0 -0
  131. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/search_api.py +0 -0
  132. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/taxonomy.py +0 -0
  133. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/testing.py +0 -0
  134. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/theme_dev.py +0 -0
  135. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/users.py +0 -0
  136. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/views.py +0 -0
  137. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/tools/webform.py +0 -0
  138. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/src/drupal_mcp_server/validation.py +0 -0
  139. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/__init__.py +0 -0
  140. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/README.md +0 -0
  141. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/bootstrap.py +0 -0
  142. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/filter_check.py +0 -0
  143. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/install_modules.py +0 -0
  144. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/layout_builder_test.py +0 -0
  145. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/mcp_call.py +0 -0
  146. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/queue_test.py +0 -0
  147. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/resource_check.py +0 -0
  148. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/seed.php +0 -0
  149. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/smoke_test.py +0 -0
  150. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/live/sweep.py +0 -0
  151. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/__init__.py +0 -0
  152. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_auth.py +0 -0
  153. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_content_tools.py +0 -0
  154. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_errors.py +0 -0
  155. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_handler_and_translation_tools.py +0 -0
  156. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_logging_config.py +0 -0
  157. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_moderation_transitions.py +0 -0
  158. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_resource_names.py +0 -0
  159. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_revisions.py +0 -0
  160. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_scheduler_tools.py +0 -0
  161. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_schemas.py +0 -0
  162. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_sweep_harness.py +0 -0
  163. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_tool_utils.py +0 -0
  164. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_tools.py +0 -0
  165. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.3.0}/tests/unit/test_validation.py +0 -0
@@ -0,0 +1,17 @@
1
+ coverage:
2
+ # The 367 tool modules are thin wrappers exercised by the live test harness,
3
+ # which needs a real Drupal site and cannot run in CI. The CI gate (70%)
4
+ # deliberately excludes them, so keep Codecov consistent with CI.
5
+ ignore:
6
+ - "src/drupal_mcp_server/tools/*"
7
+
8
+ status:
9
+ project:
10
+ default:
11
+ target: 80%
12
+ threshold: 2%
13
+ informational: true
14
+ patch:
15
+ default:
16
+ target: 80%
17
+ informational: true
@@ -46,10 +46,13 @@ jobs:
46
46
  uses: codecov/codecov-action@v4
47
47
  with:
48
48
  files: ./coverage.xml
49
+ token: ${{ secrets.CODECOV_TOKEN }}
49
50
  fail_ci_if_error: true
50
51
 
51
52
  - name: Dependency vulnerability scan
52
- run: pip-audit
53
+ run: |
54
+ pip install --upgrade "setuptools>=83.0.0"
55
+ pip-audit
53
56
 
54
57
  build:
55
58
  runs-on: ubuntu-latest
@@ -7,15 +7,24 @@ on:
7
7
  - 'docs/**'
8
8
  - 'mkdocs.yml'
9
9
  - 'README.md'
10
+ - '.github/workflows/docs.yml'
10
11
  pull_request:
11
12
  paths:
12
13
  - 'docs/**'
13
14
  - 'mkdocs.yml'
14
15
  - 'README.md'
16
+ - '.github/workflows/docs.yml'
15
17
 
16
18
  jobs:
17
19
  docs:
18
20
  runs-on: ubuntu-latest
21
+ # peaceiris/actions-gh-pages pushes the built site to the gh-pages
22
+ # branch, which requires write access. The repo's default workflow
23
+ # token is read-only, so grant it explicitly here.
24
+ permissions:
25
+ contents: write
26
+ pages: write
27
+ id-token: write
19
28
 
20
29
  steps:
21
30
  - uses: actions/checkout@v4
@@ -56,10 +56,22 @@ htmlcov/
56
56
  # Ruff
57
57
  .ruff_cache/
58
58
 
59
+ # mkdocs build output
60
+ site/
61
+
59
62
  # Environment
60
63
  .env
61
64
  .env.local
62
65
  .env.*.local
66
+ .env.live-smoke
67
+ # Env files generated by the live migration harness scripts (contain
68
+ # local dev credentials).
69
+ .env.live
70
+ .env.d9d11
71
+ .env.d7d11
72
+
73
+ # Runtime migration-plan state written by MigrationService
74
+ .drupal-mcp/
63
75
 
64
76
  # OS
65
77
  .DS_Store
@@ -76,3 +88,5 @@ config/sync/
76
88
  .omc
77
89
  .pi
78
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.1.0
3
+ Version: 0.3.0
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
@@ -44,11 +45,12 @@ Description-Content-Type: text/markdown
44
45
 
45
46
  [![CI](https://github.com/vloganathane/drupal-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/vloganathane/drupal-mcp-server/actions/workflows/ci.yml)
46
47
  [![codecov](https://codecov.io/gh/vloganathane/drupal-mcp-server/branch/main/graph/badge.svg)](https://codecov.io/gh/vloganathane/drupal-mcp-server)
47
- [![PyPI version](https://badge.fury.io/py/drupal-mcp-server.svg)](https://badge.fury.io/py/drupal-mcp-server)
48
+ [![PyPI version](https://img.shields.io/pypi/v/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
48
49
  [![Python versions](https://img.shields.io/pypi/pyversions/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
50
+ [![PyPI downloads](https://img.shields.io/pypi/dm/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
49
51
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/vloganathane/drupal-mcp-server/blob/main/LICENSE)
50
52
 
51
- A Model Context Protocol (MCP) server for Drupal operations. Provides **367 tools across 37 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.
52
54
 
53
55
  ## Why Use This?
54
56
 
@@ -130,6 +132,27 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
130
132
  }
131
133
  ```
132
134
 
135
+ ## AI Coding Agents
136
+
137
+ Register the server with any MCP client in one command:
138
+
139
+ ```bash
140
+ drupal-mcp install
141
+ ```
142
+
143
+ It detects the agents on your machine — Claude Code, Claude Desktop, Cursor,
144
+ Codex CLI, OpenCode, Windsurf, Pi, Hermes Agent and OpenClaw — gathers
145
+ `DRUPAL_*` settings from `./.env` or the environment, and writes each client's
146
+ config (preferring the client's own `mcp add` command when it has one).
147
+
148
+ ```bash
149
+ drupal-mcp install --client claude-code --print # preview without writing
150
+ drupal-mcp install --command 'uvx drupal-mcp-server' # run from PyPI, no install
151
+ ```
152
+
153
+ See the [AI Coding Agents guide](docs/agents.md) for per-client copy-paste
154
+ snippets, options, and caveats.
155
+
133
156
  ## Configuration
134
157
 
135
158
  ### Drupal connection
@@ -181,7 +204,7 @@ Set `MCP_TRANSPORT` to one of:
181
204
  - `sse` (for Server-Sent Events)
182
205
  - `streamable-http` (for Streamable HTTP)
183
206
 
184
- ## Tools (367 total)
207
+ ## Tools (414 total)
185
208
 
186
209
  ### Accessibility (5)
187
210
  - `accessibility_axe_scan` — Run axe-core accessibility scan
@@ -196,13 +219,16 @@ Set `MCP_TRANSPORT` to one of:
196
219
  - `ai_generate_migration_plan` — Generate migration plan with AI
197
220
  - `ai_translate_content` — Translate content with AI
198
221
 
199
- ### Analysis (6)
222
+ ### Analysis (9)
200
223
  - `analyze_d7_site` — Analyze D7 site for D10 readiness
201
224
  - `analyze_d9_site` — Analyze D9+ for deprecated APIs
202
225
  - `inventory_content_types` — List all content types
203
226
  - `inventory_modules` — List all modules
204
227
  - `map_modules_d7_to_d10` — AI-powered module mapping D7→D10
205
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
206
232
 
207
233
  ### Code Audit (7)
208
234
  - `code_audit_phpstan` — Run PHPStan static analysis
@@ -213,6 +239,11 @@ Set `MCP_TRANSPORT` to one of:
213
239
  - `composer_audit` — Composer dependency audit
214
240
  - `code_quality_report` — Combined code quality report
215
241
 
242
+ ### Codebase (12)
243
+ - `codebase_index_refresh`, `codebase_search`, `codebase_module_list`, `codebase_module_describe`
244
+ - `codebase_unused_modules`, `codebase_redundancy_check`, `codebase_hooks_find`, `codebase_paths_list`
245
+ - `codebase_files_list`, `codebase_directory_tree`, `codebase_file_read`, `codebase_function_read`
246
+
216
247
  ### Comments (10)
217
248
  - `comment_list`, `comment_get`, `comment_create`, `comment_update`, `comment_delete`
218
249
  - `comment_thread_list`, `comment_approve`, `comment_unapprove`
@@ -226,8 +257,8 @@ Set `MCP_TRANSPORT` to one of:
226
257
  - `commerce_promotion_list`, `commerce_promotion_create`
227
258
  - `commerce_shipping_method_list`, `commerce_shipping_method_create`
228
259
 
229
- ### Config (7)
230
- - `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`
231
262
 
232
263
  ### Contact (9)
233
264
  - `contact_form_list`, `contact_form_get`, `contact_form_create`, `contact_form_update`, `contact_form_delete`
@@ -251,9 +282,13 @@ Set `MCP_TRANSPORT` to one of:
251
282
  - `composer_install`, `composer_require`, `composer_update`
252
283
  - `drush_cron`, `drush_watchdog`, `cache_clear`, `drush_updb`, `drush_php_eval`
253
284
 
254
- ### Drupal.org (9)
285
+ ### Drupal.org (12)
255
286
  - `module_search`, `module_get`, `module_versions`, `module_dependencies`, `module_compatibility`
256
287
  - `theme_search`, `theme_get`, `release_history`, `project_usage`
288
+ - `module_issues_search`, `module_popular`, `module_recommendation`
289
+
290
+ ### Exports (4)
291
+ - `export_nodes`, `export_users`, `export_media`, `export_taxonomy`
257
292
 
258
293
  ### Feeds (12)
259
294
  - `feeds_feed_list`, `feeds_feed_get`, `feeds_feed_create`, `feeds_feed_update`, `feeds_feed_delete`
@@ -298,7 +333,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
298
333
  - `metatag_defaults_get`, `metatag_defaults_set`, `metatag_token_list`
299
334
  - `metatag_canonical_set`, `metatag_jsonld_generate`
300
335
 
301
- ### Migration (7)
336
+ ### Migration (17)
302
337
  - `generate_migration_yaml` — Generate migration YAML
303
338
  - `generate_module_migration` — Generate migration module
304
339
  - `run_migration_test` — Test migration with limited records
@@ -306,6 +341,16 @@ displays have Layout Builder enabled; `layout_builder_get`,
306
341
  - `rollback_migration` — Rollback a migration
307
342
  - `sync_media_files` — Sync media between paths
308
343
  - `migrate_taxonomy` — Migrate taxonomy vocabularies
344
+ - `create_migration_plan` — Create a persisted migration manifest
345
+ - `get_migration_plan` — Read a migration manifest and tracked state
346
+ - `list_migration_plans` — List migration manifests
347
+ - `migration_status` — Summarize migration progress
348
+ - `migrate_records` — Copy a batch of source records to the target site
349
+ - `record_migration_result` — Record externally executed migration outcomes
350
+ - `analyze_source_site` — Analyze a source Drupal JSON:API resource type
351
+ - `reconcile_migration_counts` — Compare source and target counts
352
+ - `run_migration_wave` — Fetch and migrate one source resource type
353
+ - `run_migration` — Run an ordered end-to-end migration for all planned types
309
354
 
310
355
  ### Moderation (13)
311
356
  - `moderation_state_list`, `moderation_state_get`, `moderation_state_create`, `moderation_state_update`, `moderation_state_delete`
@@ -353,7 +398,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
353
398
  - `search_api_index_list`, `search_api_index_get`, `search_api_index_create`, `search_api_index_update`
354
399
  - `search_api_index_reindex`, `search_api_index_clear`, `search_api_facet_list`, `search_api_facet_create`
355
400
 
356
- ### Security Audit (8)
401
+ ### Security Audit (10)
357
402
  - `security_scan` — PHPStan with security extensions
358
403
  - `dependency_scan` — Composer audit
359
404
  - `config_security_check` — Drupal config security
@@ -362,6 +407,14 @@ displays have Layout Builder enabled; `layout_builder_get`,
362
407
  - `xss_scan` — XSS vulnerability detection
363
408
  - `csp_audit` — Content Security Policy audit
364
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
365
418
 
366
419
  ### Taxonomy (10)
367
420
  - `create_vocabulary`, `get_vocabulary`, `update_vocabulary`, `delete_vocabulary`, `list_vocabularies`
@@ -372,6 +425,11 @@ displays have Layout Builder enabled; `layout_builder_get`,
372
425
  - `test_scaffold_phpunit`, `test_scaffold_behat`, `test_scaffold_nightwatch`
373
426
  - `test_coverage_report`, `test_list_suites`
374
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
+
375
433
  ### Theme Development (11)
376
434
  - `theme_create`, `theme_library_create`, `theme_region_create`, `theme_template_override`
377
435
  - `theme_preprocess_function`, `theme_breakpoint_create`, `theme_base_change`
@@ -393,10 +451,10 @@ displays have Layout Builder enabled; `layout_builder_get`,
393
451
 
394
452
  ## Documentation
395
453
 
396
- - [Contributing Guide](CONTRIBUTING.md)
397
- - [Changelog](CHANGELOG.md)
398
- - [Security Policy](SECURITY.md)
399
- - [Code of Conduct](CODE_OF_CONDUCT.md)
454
+ - [Contributing Guide](docs/CONTRIBUTING.md)
455
+ - [Changelog](docs/CHANGELOG.md)
456
+ - [Security Policy](docs/SECURITY.md)
457
+ - [Code of Conduct](docs/CODE_OF_CONDUCT.md)
400
458
  - [Architecture](docs/architecture.md)
401
459
  - [Migration Guide](docs/migration.md)
402
460
  - [Docstring Standard](docs/docstring_standard.md)
@@ -491,7 +549,7 @@ python tests/live/queue_test.py # 18 cron/queue cases, ~60s
491
549
  python tests/live/filter_check.py # every hard-coded JSON:API filter
492
550
  python tests/live/resource_check.py # every resource name, asked of Drupal
493
551
  python tests/live/install_modules.py # the modules the tools assume, ~10 min
494
- python tests/live/sweep.py # all 367 tools, ~30 min
552
+ python tests/live/sweep.py # all 414 tools, ~30 min
495
553
  python tests/live/mcp_call.py content_list '{}' # one call, for spot checks
496
554
  ```
497
555
 
@@ -2,11 +2,12 @@
2
2
 
3
3
  [![CI](https://github.com/vloganathane/drupal-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/vloganathane/drupal-mcp-server/actions/workflows/ci.yml)
4
4
  [![codecov](https://codecov.io/gh/vloganathane/drupal-mcp-server/branch/main/graph/badge.svg)](https://codecov.io/gh/vloganathane/drupal-mcp-server)
5
- [![PyPI version](https://badge.fury.io/py/drupal-mcp-server.svg)](https://badge.fury.io/py/drupal-mcp-server)
5
+ [![PyPI version](https://img.shields.io/pypi/v/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
6
6
  [![Python versions](https://img.shields.io/pypi/pyversions/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
7
+ [![PyPI downloads](https://img.shields.io/pypi/dm/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
7
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/vloganathane/drupal-mcp-server/blob/main/LICENSE)
8
9
 
9
- A Model Context Protocol (MCP) server for Drupal operations. Provides **367 tools across 37 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.
10
11
 
11
12
  ## Why Use This?
12
13
 
@@ -88,6 +89,27 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
88
89
  }
89
90
  ```
90
91
 
92
+ ## AI Coding Agents
93
+
94
+ Register the server with any MCP client in one command:
95
+
96
+ ```bash
97
+ drupal-mcp install
98
+ ```
99
+
100
+ It detects the agents on your machine — Claude Code, Claude Desktop, Cursor,
101
+ Codex CLI, OpenCode, Windsurf, Pi, Hermes Agent and OpenClaw — gathers
102
+ `DRUPAL_*` settings from `./.env` or the environment, and writes each client's
103
+ config (preferring the client's own `mcp add` command when it has one).
104
+
105
+ ```bash
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
108
+ ```
109
+
110
+ See the [AI Coding Agents guide](docs/agents.md) for per-client copy-paste
111
+ snippets, options, and caveats.
112
+
91
113
  ## Configuration
92
114
 
93
115
  ### Drupal connection
@@ -139,7 +161,7 @@ Set `MCP_TRANSPORT` to one of:
139
161
  - `sse` (for Server-Sent Events)
140
162
  - `streamable-http` (for Streamable HTTP)
141
163
 
142
- ## Tools (367 total)
164
+ ## Tools (414 total)
143
165
 
144
166
  ### Accessibility (5)
145
167
  - `accessibility_axe_scan` — Run axe-core accessibility scan
@@ -154,13 +176,16 @@ Set `MCP_TRANSPORT` to one of:
154
176
  - `ai_generate_migration_plan` — Generate migration plan with AI
155
177
  - `ai_translate_content` — Translate content with AI
156
178
 
157
- ### Analysis (6)
179
+ ### Analysis (9)
158
180
  - `analyze_d7_site` — Analyze D7 site for D10 readiness
159
181
  - `analyze_d9_site` — Analyze D9+ for deprecated APIs
160
182
  - `inventory_content_types` — List all content types
161
183
  - `inventory_modules` — List all modules
162
184
  - `map_modules_d7_to_d10` — AI-powered module mapping D7→D10
163
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
164
189
 
165
190
  ### Code Audit (7)
166
191
  - `code_audit_phpstan` — Run PHPStan static analysis
@@ -171,6 +196,11 @@ Set `MCP_TRANSPORT` to one of:
171
196
  - `composer_audit` — Composer dependency audit
172
197
  - `code_quality_report` — Combined code quality report
173
198
 
199
+ ### Codebase (12)
200
+ - `codebase_index_refresh`, `codebase_search`, `codebase_module_list`, `codebase_module_describe`
201
+ - `codebase_unused_modules`, `codebase_redundancy_check`, `codebase_hooks_find`, `codebase_paths_list`
202
+ - `codebase_files_list`, `codebase_directory_tree`, `codebase_file_read`, `codebase_function_read`
203
+
174
204
  ### Comments (10)
175
205
  - `comment_list`, `comment_get`, `comment_create`, `comment_update`, `comment_delete`
176
206
  - `comment_thread_list`, `comment_approve`, `comment_unapprove`
@@ -184,8 +214,8 @@ Set `MCP_TRANSPORT` to one of:
184
214
  - `commerce_promotion_list`, `commerce_promotion_create`
185
215
  - `commerce_shipping_method_list`, `commerce_shipping_method_create`
186
216
 
187
- ### Config (7)
188
- - `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`
189
219
 
190
220
  ### Contact (9)
191
221
  - `contact_form_list`, `contact_form_get`, `contact_form_create`, `contact_form_update`, `contact_form_delete`
@@ -209,9 +239,13 @@ Set `MCP_TRANSPORT` to one of:
209
239
  - `composer_install`, `composer_require`, `composer_update`
210
240
  - `drush_cron`, `drush_watchdog`, `cache_clear`, `drush_updb`, `drush_php_eval`
211
241
 
212
- ### Drupal.org (9)
242
+ ### Drupal.org (12)
213
243
  - `module_search`, `module_get`, `module_versions`, `module_dependencies`, `module_compatibility`
214
244
  - `theme_search`, `theme_get`, `release_history`, `project_usage`
245
+ - `module_issues_search`, `module_popular`, `module_recommendation`
246
+
247
+ ### Exports (4)
248
+ - `export_nodes`, `export_users`, `export_media`, `export_taxonomy`
215
249
 
216
250
  ### Feeds (12)
217
251
  - `feeds_feed_list`, `feeds_feed_get`, `feeds_feed_create`, `feeds_feed_update`, `feeds_feed_delete`
@@ -256,7 +290,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
256
290
  - `metatag_defaults_get`, `metatag_defaults_set`, `metatag_token_list`
257
291
  - `metatag_canonical_set`, `metatag_jsonld_generate`
258
292
 
259
- ### Migration (7)
293
+ ### Migration (17)
260
294
  - `generate_migration_yaml` — Generate migration YAML
261
295
  - `generate_module_migration` — Generate migration module
262
296
  - `run_migration_test` — Test migration with limited records
@@ -264,6 +298,16 @@ displays have Layout Builder enabled; `layout_builder_get`,
264
298
  - `rollback_migration` — Rollback a migration
265
299
  - `sync_media_files` — Sync media between paths
266
300
  - `migrate_taxonomy` — Migrate taxonomy vocabularies
301
+ - `create_migration_plan` — Create a persisted migration manifest
302
+ - `get_migration_plan` — Read a migration manifest and tracked state
303
+ - `list_migration_plans` — List migration manifests
304
+ - `migration_status` — Summarize migration progress
305
+ - `migrate_records` — Copy a batch of source records to the target site
306
+ - `record_migration_result` — Record externally executed migration outcomes
307
+ - `analyze_source_site` — Analyze a source Drupal JSON:API resource type
308
+ - `reconcile_migration_counts` — Compare source and target counts
309
+ - `run_migration_wave` — Fetch and migrate one source resource type
310
+ - `run_migration` — Run an ordered end-to-end migration for all planned types
267
311
 
268
312
  ### Moderation (13)
269
313
  - `moderation_state_list`, `moderation_state_get`, `moderation_state_create`, `moderation_state_update`, `moderation_state_delete`
@@ -311,7 +355,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
311
355
  - `search_api_index_list`, `search_api_index_get`, `search_api_index_create`, `search_api_index_update`
312
356
  - `search_api_index_reindex`, `search_api_index_clear`, `search_api_facet_list`, `search_api_facet_create`
313
357
 
314
- ### Security Audit (8)
358
+ ### Security Audit (10)
315
359
  - `security_scan` — PHPStan with security extensions
316
360
  - `dependency_scan` — Composer audit
317
361
  - `config_security_check` — Drupal config security
@@ -320,6 +364,14 @@ displays have Layout Builder enabled; `layout_builder_get`,
320
364
  - `xss_scan` — XSS vulnerability detection
321
365
  - `csp_audit` — Content Security Policy audit
322
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
323
375
 
324
376
  ### Taxonomy (10)
325
377
  - `create_vocabulary`, `get_vocabulary`, `update_vocabulary`, `delete_vocabulary`, `list_vocabularies`
@@ -330,6 +382,11 @@ displays have Layout Builder enabled; `layout_builder_get`,
330
382
  - `test_scaffold_phpunit`, `test_scaffold_behat`, `test_scaffold_nightwatch`
331
383
  - `test_coverage_report`, `test_list_suites`
332
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
+
333
390
  ### Theme Development (11)
334
391
  - `theme_create`, `theme_library_create`, `theme_region_create`, `theme_template_override`
335
392
  - `theme_preprocess_function`, `theme_breakpoint_create`, `theme_base_change`
@@ -351,10 +408,10 @@ displays have Layout Builder enabled; `layout_builder_get`,
351
408
 
352
409
  ## Documentation
353
410
 
354
- - [Contributing Guide](CONTRIBUTING.md)
355
- - [Changelog](CHANGELOG.md)
356
- - [Security Policy](SECURITY.md)
357
- - [Code of Conduct](CODE_OF_CONDUCT.md)
411
+ - [Contributing Guide](docs/CONTRIBUTING.md)
412
+ - [Changelog](docs/CHANGELOG.md)
413
+ - [Security Policy](docs/SECURITY.md)
414
+ - [Code of Conduct](docs/CODE_OF_CONDUCT.md)
358
415
  - [Architecture](docs/architecture.md)
359
416
  - [Migration Guide](docs/migration.md)
360
417
  - [Docstring Standard](docs/docstring_standard.md)
@@ -449,7 +506,7 @@ python tests/live/queue_test.py # 18 cron/queue cases, ~60s
449
506
  python tests/live/filter_check.py # every hard-coded JSON:API filter
450
507
  python tests/live/resource_check.py # every resource name, asked of Drupal
451
508
  python tests/live/install_modules.py # the modules the tools assume, ~10 min
452
- python tests/live/sweep.py # all 367 tools, ~30 min
509
+ python tests/live/sweep.py # all 414 tools, ~30 min
453
510
  python tests/live/mcp_call.py content_list '{}' # one call, for spot checks
454
511
  ```
455
512
 
@@ -7,6 +7,100 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2026-10-17
11
+
12
+ ### Added
13
+
14
+ - Wave 5 of the drupal-scout-mcp port — 2 local security tools
15
+ (414 total, 41 modules): `code_security_scan` runs scout's
16
+ zero-dependency pattern engine (XSS, SQL injection, command injection,
17
+ path traversal, hardcoded secrets, access control, CSRF, deprecated
18
+ API — 8 families, category/severity filters, per-finding file/line/
19
+ snippet/fix recommendation) with its Drupal-aware false-positive table
20
+ (EntityQuery conditions, stream wrappers, escapeshellarg, example
21
+ secrets, comment lines), so a site without PHPStan gets concrete
22
+ findings; counts stay complete when `max_findings` truncates the list.
23
+ `route_access_audit` is the routing half of scout's anonymous-exploit
24
+ scan done properly per route: every `*.routing.yml` route classified
25
+ as anonymous / permission / role / entity / custom / a named
26
+ underscore requirement / an alias (whose definition may live in a
27
+ PHP route provider this YAML pass cannot read) / denied / **missing**,
28
+ with its controller mapped to the declaring file. Targets confine to
29
+ DRUPAL_ROOT and prune vendor, tests, and contrib from the default scan;
30
+ symlinks are skipped. Two accuracy corrections over scout's registry:
31
+ `t(` is a live D8+ function (scout flagged every translation call as a
32
+ Drupal 7 leftover) and scout's CSRF `$request` pattern was escaped so
33
+ it could never match PHP. Scout's `verify_vulnerability` was not
34
+ ported — it returns static advice rather than site-specific data —
35
+ and the optional tree-sitter AST layer is skipped: the pattern pass
36
+ carries the signal. Live testing on D11.4.10's core node module
37
+ (115 files) caught five accuracy bugs before release: JS template
38
+ literals matched the PHP backtick-shell pattern, Drupal's `{table}` /
39
+ `->...Table()` placeholder concatenation read as SQL injection,
40
+ unrecognized underscore requirements and alias-only entries were both
41
+ reported as missing access (node went from five "missing" routes to
42
+ zero real ones), and a zero-file scan read as a clean bill of health.
43
+ - Wave 4 of the drupal-scout-mcp port — 8 read-only theme analysis tools
44
+ (412 total, 41 modules): `theme_active` (default/admin/enabled themes
45
+ from `system.theme` + `pm:list`), `theme_info` (pm:list metadata merged
46
+ with a safe YAML parse of the theme's info.yml — regions in declaration
47
+ order, libraries, dependencies, and the base-theme chain followed
48
+ upward), `theme_regions` (regions with their block placements and
49
+ counts, empty regions visible, placements in regions the theme no
50
+ longer defines flagged), `theme_blocks` (every `block.block.*`
51
+ placement with theme/region/search filters — search matches labels and
52
+ plugins, folding scout's separate `search_blocks` into one tool),
53
+ `theme_templates` (pruned `*.html.twig` walk with sizes),
54
+ `theme_template_overrides` (one docroot-wide index splits templates
55
+ that shadow same-named core/module files from theme originals),
56
+ `template_suggestions` (the Twig suggestion chain per entity type, each
57
+ marked with whether the default theme already ships that file), and
58
+ `view_template_info` (the chain for a view display, looked up in the
59
+ JSON:API view collection by its machine id — Views config names differ
60
+ between Drupal generations, `view.*` on older sites and `views.view.*`
61
+ on Drupal 11.4+, so the entity collection is the stable source — with
62
+ an unknown display_id erroring with the display list and an unknown
63
+ view listing the ones the site has). Every file path resolves inside
64
+ DRUPAL_ROOT before a read — symlinks and `..` segments that leave the
65
+ docroot are rejected — and no caller input reaches a shell; theme
66
+ blocks come from JSON:API rather than scout's interpolated `drush ev`
67
+ - The shared JSON:API helpers (`jsonapi_collect`, `jsonapi_attrs`,
68
+ `jsonapi_bundle`, `jsonapi_rel_ids`), `flag_label`, and the export
69
+ path/write helpers moved from the exports module into `_utils` so both
70
+ waves page collections and confine destinations the same way
71
+ - Wave 3 of the drupal-scout-mcp port — 4 export tools (404 total, 40
72
+ modules): `export_nodes`, `export_users`, `export_media`,
73
+ `export_taxonomy` write CSV (UTF-8 with BOM) or Excel files
74
+ (`openpyxl`, new runtime dependency) and return only the path,
75
+ row/column counts, size, and a three-row preview. Destination paths are
76
+ confined to the Drupal root, the system temp directory, or the home
77
+ directory; data is paged per bundle over JSON:API (never through the
78
+ shared merged offset, which skips rows), and taxonomy usage counts come
79
+ from one validated `GROUP BY` query per field storage targeting
80
+ taxonomy terms, with unreadable tables reported in a note instead of
81
+ failing the export (and a `safe_to_delete` verdict withheld entirely
82
+ whenever the counts are incomplete). Entries with no internal id —
83
+ Drupal's uid-0 anonymous user serves only a display_name — are skipped
84
+ and counted as `skipped_without_id`, and an unreadable status stays
85
+ empty in the CSV rather than being presented as "blocked"
86
+ - `sql_output`/`sql_rows` moved from the analysis module into `_utils` so
87
+ the export tools parse `drush sql:query` text the same way
88
+ - Wave 2 of the drupal-scout-mcp port — 8 tools (400 total, 39 modules):
89
+ - Status section (4): `status_report` (drush core:requirements, severity
90
+ filter), `database_updates` (read-only pending DB updates),
91
+ `available_updates` (composer outdated with dev filtering and a
92
+ security-only mode intersected with composer audit), `health_check`
93
+ (Drush, database, JSON:API, and module probes with a fix per failure)
94
+ - Analysis: `find_entity_references` (bundles whose reference fields
95
+ target an entity type, via JSON:API field config), `search_entities`
96
+ (escaped LIKE search across six entity tables), `find_entity_by_path`
97
+ (route or path-alias resolution to an entity)
98
+ - Config: `config_status` (read-only active vs sync comparison)
99
+ - `run_composer` gained a `tail` argument so tools that parse full JSON
100
+ documents (`composer outdated`) are not truncated
101
+
102
+ ## [0.2.0] - 2026-10-16
103
+
10
104
  ### Security
11
105
 
12
106
  - Fix command injection vulnerabilities in code audit and security audit tools
@@ -17,6 +111,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
111
 
18
112
  ### Added
19
113
 
114
+ - Add `drupal-mcp install`, a self-installer that registers the server with
115
+ local MCP clients (Claude Code, Claude Desktop, Cursor, Codex CLI,
116
+ OpenCode, Windsurf, Pi, Hermes Agent, OpenClaw), with `--print`/`--json`
117
+ for scripted setup and an AI Coding Agents guide
118
+ - Add `module_issues_search`, `module_popular`, and `module_recommendation`
119
+ (client-side issue-queue relevance scoring, usage-ranked module lists by
120
+ category, local-index + drupal.org recommendations), plus the `DRUPAL_ROOT`
121
+ and `DRUPAL_MODULES_PATH` settings for local codebase analysis
122
+ - Add a local codebase index with 12 `codebase_*` tools: functionality
123
+ search, module inventory/descriptions, unused and redundant module
124
+ detection, hook implementation lookup, and safe module file/tree/function
125
+ reading (all reads confined to `DRUPAL_ROOT`)
20
126
  - Add `moderation_transition_delete`, giving `moderation_transition_create` the
21
127
  counterpart it never had. The tool count is now 367
22
128
  - Add Lando support to SiteManager