drupal-mcp-server 0.1.0__tar.gz → 0.2.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 (153) hide show
  1. drupal_mcp_server-0.2.0/.codecov.yml +17 -0
  2. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/workflows/ci.yml +4 -1
  3. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/workflows/docs.yml +9 -0
  4. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.gitignore +12 -0
  5. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/PKG-INFO +49 -11
  6. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/README.md +48 -10
  7. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/CHANGELOG.md +13 -1
  8. drupal_mcp_server-0.2.0/docs/agents.md +221 -0
  9. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/index.md +11 -7
  10. drupal_mcp_server-0.2.0/docs/migration.md +188 -0
  11. drupal_mcp_server-0.2.0/docs/quickstart.md +86 -0
  12. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/index.md +3 -1
  13. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/mkdocs.yml +7 -0
  14. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/pyproject.toml +2 -2
  15. drupal_mcp_server-0.2.0/scripts/live-migration-d7d11.sh +240 -0
  16. drupal_mcp_server-0.2.0/scripts/live-migration-d9d11-run.py +127 -0
  17. drupal_mcp_server-0.2.0/scripts/live-migration-d9d11.sh +193 -0
  18. drupal_mcp_server-0.2.0/scripts/live-migration-smoke-run.py +115 -0
  19. drupal_mcp_server-0.2.0/scripts/live-migration-smoke.sh +166 -0
  20. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/__init__.py +1 -1
  21. drupal_mcp_server-0.2.0/src/drupal_mcp_server/cli.py +58 -0
  22. drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/__init__.py +319 -0
  23. drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/indexer.py +229 -0
  24. drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/parsers.py +301 -0
  25. drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/search.py +272 -0
  26. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/config.py +13 -0
  27. drupal_mcp_server-0.2.0/src/drupal_mcp_server/installer.py +792 -0
  28. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/server.py +8 -2
  29. drupal_mcp_server-0.2.0/src/drupal_mcp_server/services/migration_service.py +855 -0
  30. drupal_mcp_server-0.2.0/src/drupal_mcp_server/tools/codebase.py +231 -0
  31. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/drupal_org.py +363 -0
  32. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/migration.py +218 -0
  33. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/integration/test_server.py +54 -0
  34. drupal_mcp_server-0.2.0/tests/unit/test_codebase.py +588 -0
  35. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_drupal_org.py +285 -3
  36. drupal_mcp_server-0.2.0/tests/unit/test_installer.py +445 -0
  37. drupal_mcp_server-0.2.0/tests/unit/test_migration_service.py +246 -0
  38. drupal_mcp_server-0.1.0/docs/migration.md +0 -139
  39. drupal_mcp_server-0.1.0/src/drupal_mcp_server/services/migration_service.py +0 -20
  40. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.env.example +0 -0
  41. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  42. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  43. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  44. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/workflows/release.yml +0 -0
  45. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/LICENSE +0 -0
  46. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/MAINTAINERS.md +0 -0
  47. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/CODE_OF_CONDUCT.md +0 -0
  48. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/CONTRIBUTING.md +0 -0
  49. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/SECURITY.md +0 -0
  50. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0001-use-fastmcp.md +0 -0
  51. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0002-pydantic-settings.md +0 -0
  52. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0003-subprocess-drush.md +0 -0
  53. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0004-http-transport.md +0 -0
  54. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/architecture.md +0 -0
  55. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/configuration.md +0 -0
  56. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/docstring_standard.md +0 -0
  57. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/installation.md +0 -0
  58. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/content.md +0 -0
  59. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/devops.md +0 -0
  60. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/users.md +0 -0
  61. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/.env.example +0 -0
  62. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/README.md +0 -0
  63. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/basic_usage.py +0 -0
  64. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/content_workflow.py +0 -0
  65. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/custom_tool.py +0 -0
  66. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/migration_workflow.py +0 -0
  67. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/lint.sh +0 -0
  68. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/run.sh +0 -0
  69. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/setup.sh +0 -0
  70. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/test.sh +0 -0
  71. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/__init__.py +0 -0
  72. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/basic.py +0 -0
  73. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/mcp_oauth.py +0 -0
  74. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/session.py +0 -0
  75. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/token.py +0 -0
  76. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/__init__.py +0 -0
  77. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/base.py +0 -0
  78. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/drush.py +0 -0
  79. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/graphql.py +0 -0
  80. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/jsonapi.py +0 -0
  81. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/errors.py +0 -0
  82. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/exceptions.py +0 -0
  83. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/logging_config.py +0 -0
  84. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/schemas.py +0 -0
  85. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/services/__init__.py +0 -0
  86. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/services/ai_service.py +0 -0
  87. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/services/site_manager.py +0 -0
  88. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/__init__.py +0 -0
  89. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/_utils.py +0 -0
  90. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/accessibility.py +0 -0
  91. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/ai.py +0 -0
  92. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/analysis.py +0 -0
  93. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/code_audit.py +0 -0
  94. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/comments.py +0 -0
  95. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/commerce.py +0 -0
  96. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/config.py +0 -0
  97. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/contact.py +0 -0
  98. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/content.py +0 -0
  99. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/database.py +0 -0
  100. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/devops.py +0 -0
  101. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/feeds.py +0 -0
  102. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/fields.py +0 -0
  103. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/headless.py +0 -0
  104. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/layout_builder.py +0 -0
  105. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/media_enhanced.py +0 -0
  106. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/menus.py +0 -0
  107. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/metatag.py +0 -0
  108. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/moderation.py +0 -0
  109. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/module_dev.py +0 -0
  110. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/multilingual.py +0 -0
  111. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/paragraphs.py +0 -0
  112. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/pathauto.py +0 -0
  113. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/performance.py +0 -0
  114. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/redirects.py +0 -0
  115. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/revisions.py +0 -0
  116. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/scheduler.py +0 -0
  117. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/search_api.py +0 -0
  118. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/security_audit.py +0 -0
  119. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/taxonomy.py +0 -0
  120. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/testing.py +0 -0
  121. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/theme_dev.py +0 -0
  122. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/users.py +0 -0
  123. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/views.py +0 -0
  124. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/webform.py +0 -0
  125. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/validation.py +0 -0
  126. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/__init__.py +0 -0
  127. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/README.md +0 -0
  128. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/bootstrap.py +0 -0
  129. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/filter_check.py +0 -0
  130. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/install_modules.py +0 -0
  131. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/layout_builder_test.py +0 -0
  132. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/mcp_call.py +0 -0
  133. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/queue_test.py +0 -0
  134. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/resource_check.py +0 -0
  135. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/seed.php +0 -0
  136. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/smoke_test.py +0 -0
  137. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/sweep.py +0 -0
  138. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/__init__.py +0 -0
  139. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_auth.py +0 -0
  140. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_clients.py +0 -0
  141. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_content_tools.py +0 -0
  142. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_errors.py +0 -0
  143. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_handler_and_translation_tools.py +0 -0
  144. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_logging_config.py +0 -0
  145. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_moderation_transitions.py +0 -0
  146. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_resource_names.py +0 -0
  147. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_revisions.py +0 -0
  148. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_scheduler_tools.py +0 -0
  149. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_schemas.py +0 -0
  150. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_sweep_harness.py +0 -0
  151. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_tool_utils.py +0 -0
  152. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_tools.py +0 -0
  153. {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: drupal-mcp-server
3
- Version: 0.1.0
3
+ Version: 0.2.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
@@ -44,11 +44,12 @@ Description-Content-Type: text/markdown
44
44
 
45
45
  [![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
46
  [![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)
47
+ [![PyPI version](https://img.shields.io/pypi/v/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
48
48
  [![Python versions](https://img.shields.io/pypi/pyversions/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
49
+ [![PyPI downloads](https://img.shields.io/pypi/dm/drupal-mcp-server.svg)](https://pypi.org/project/drupal-mcp-server/)
49
50
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/vloganathane/drupal-mcp-server/blob/main/LICENSE)
50
51
 
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.
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.
52
53
 
53
54
  ## Why Use This?
54
55
 
@@ -130,6 +131,27 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
130
131
  }
131
132
  ```
132
133
 
134
+ ## AI Coding Agents
135
+
136
+ Register the server with any MCP client in one command:
137
+
138
+ ```bash
139
+ drupal-mcp install
140
+ ```
141
+
142
+ It detects the agents on your machine — Claude Code, Claude Desktop, Cursor,
143
+ Codex CLI, OpenCode, Windsurf, Pi, Hermes Agent and OpenClaw — gathers
144
+ `DRUPAL_*` settings from `./.env` or the environment, and writes each client's
145
+ config (preferring the client's own `mcp add` command when it has one).
146
+
147
+ ```bash
148
+ 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
+ ```
151
+
152
+ See the [AI Coding Agents guide](docs/agents.md) for per-client copy-paste
153
+ snippets, options, and caveats.
154
+
133
155
  ## Configuration
134
156
 
135
157
  ### Drupal connection
@@ -181,7 +203,7 @@ Set `MCP_TRANSPORT` to one of:
181
203
  - `sse` (for Server-Sent Events)
182
204
  - `streamable-http` (for Streamable HTTP)
183
205
 
184
- ## Tools (367 total)
206
+ ## Tools (392 total)
185
207
 
186
208
  ### Accessibility (5)
187
209
  - `accessibility_axe_scan` — Run axe-core accessibility scan
@@ -213,6 +235,11 @@ Set `MCP_TRANSPORT` to one of:
213
235
  - `composer_audit` — Composer dependency audit
214
236
  - `code_quality_report` — Combined code quality report
215
237
 
238
+ ### Codebase (12)
239
+ - `codebase_index_refresh`, `codebase_search`, `codebase_module_list`, `codebase_module_describe`
240
+ - `codebase_unused_modules`, `codebase_redundancy_check`, `codebase_hooks_find`, `codebase_paths_list`
241
+ - `codebase_files_list`, `codebase_directory_tree`, `codebase_file_read`, `codebase_function_read`
242
+
216
243
  ### Comments (10)
217
244
  - `comment_list`, `comment_get`, `comment_create`, `comment_update`, `comment_delete`
218
245
  - `comment_thread_list`, `comment_approve`, `comment_unapprove`
@@ -251,9 +278,10 @@ Set `MCP_TRANSPORT` to one of:
251
278
  - `composer_install`, `composer_require`, `composer_update`
252
279
  - `drush_cron`, `drush_watchdog`, `cache_clear`, `drush_updb`, `drush_php_eval`
253
280
 
254
- ### Drupal.org (9)
281
+ ### Drupal.org (12)
255
282
  - `module_search`, `module_get`, `module_versions`, `module_dependencies`, `module_compatibility`
256
283
  - `theme_search`, `theme_get`, `release_history`, `project_usage`
284
+ - `module_issues_search`, `module_popular`, `module_recommendation`
257
285
 
258
286
  ### Feeds (12)
259
287
  - `feeds_feed_list`, `feeds_feed_get`, `feeds_feed_create`, `feeds_feed_update`, `feeds_feed_delete`
@@ -298,7 +326,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
298
326
  - `metatag_defaults_get`, `metatag_defaults_set`, `metatag_token_list`
299
327
  - `metatag_canonical_set`, `metatag_jsonld_generate`
300
328
 
301
- ### Migration (7)
329
+ ### Migration (17)
302
330
  - `generate_migration_yaml` — Generate migration YAML
303
331
  - `generate_module_migration` — Generate migration module
304
332
  - `run_migration_test` — Test migration with limited records
@@ -306,6 +334,16 @@ displays have Layout Builder enabled; `layout_builder_get`,
306
334
  - `rollback_migration` — Rollback a migration
307
335
  - `sync_media_files` — Sync media between paths
308
336
  - `migrate_taxonomy` — Migrate taxonomy vocabularies
337
+ - `create_migration_plan` — Create a persisted migration manifest
338
+ - `get_migration_plan` — Read a migration manifest and tracked state
339
+ - `list_migration_plans` — List migration manifests
340
+ - `migration_status` — Summarize migration progress
341
+ - `migrate_records` — Copy a batch of source records to the target site
342
+ - `record_migration_result` — Record externally executed migration outcomes
343
+ - `analyze_source_site` — Analyze a source Drupal JSON:API resource type
344
+ - `reconcile_migration_counts` — Compare source and target counts
345
+ - `run_migration_wave` — Fetch and migrate one source resource type
346
+ - `run_migration` — Run an ordered end-to-end migration for all planned types
309
347
 
310
348
  ### Moderation (13)
311
349
  - `moderation_state_list`, `moderation_state_get`, `moderation_state_create`, `moderation_state_update`, `moderation_state_delete`
@@ -393,10 +431,10 @@ displays have Layout Builder enabled; `layout_builder_get`,
393
431
 
394
432
  ## Documentation
395
433
 
396
- - [Contributing Guide](CONTRIBUTING.md)
397
- - [Changelog](CHANGELOG.md)
398
- - [Security Policy](SECURITY.md)
399
- - [Code of Conduct](CODE_OF_CONDUCT.md)
434
+ - [Contributing Guide](docs/CONTRIBUTING.md)
435
+ - [Changelog](docs/CHANGELOG.md)
436
+ - [Security Policy](docs/SECURITY.md)
437
+ - [Code of Conduct](docs/CODE_OF_CONDUCT.md)
400
438
  - [Architecture](docs/architecture.md)
401
439
  - [Migration Guide](docs/migration.md)
402
440
  - [Docstring Standard](docs/docstring_standard.md)
@@ -491,7 +529,7 @@ python tests/live/queue_test.py # 18 cron/queue cases, ~60s
491
529
  python tests/live/filter_check.py # every hard-coded JSON:API filter
492
530
  python tests/live/resource_check.py # every resource name, asked of Drupal
493
531
  python tests/live/install_modules.py # the modules the tools assume, ~10 min
494
- python tests/live/sweep.py # all 367 tools, ~30 min
532
+ python tests/live/sweep.py # all 392 tools, ~30 min
495
533
  python tests/live/mcp_call.py content_list '{}' # one call, for spot checks
496
534
  ```
497
535
 
@@ -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 **392 tools across 38 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 (392 total)
143
165
 
144
166
  ### Accessibility (5)
145
167
  - `accessibility_axe_scan` — Run axe-core accessibility scan
@@ -171,6 +193,11 @@ Set `MCP_TRANSPORT` to one of:
171
193
  - `composer_audit` — Composer dependency audit
172
194
  - `code_quality_report` — Combined code quality report
173
195
 
196
+ ### Codebase (12)
197
+ - `codebase_index_refresh`, `codebase_search`, `codebase_module_list`, `codebase_module_describe`
198
+ - `codebase_unused_modules`, `codebase_redundancy_check`, `codebase_hooks_find`, `codebase_paths_list`
199
+ - `codebase_files_list`, `codebase_directory_tree`, `codebase_file_read`, `codebase_function_read`
200
+
174
201
  ### Comments (10)
175
202
  - `comment_list`, `comment_get`, `comment_create`, `comment_update`, `comment_delete`
176
203
  - `comment_thread_list`, `comment_approve`, `comment_unapprove`
@@ -209,9 +236,10 @@ Set `MCP_TRANSPORT` to one of:
209
236
  - `composer_install`, `composer_require`, `composer_update`
210
237
  - `drush_cron`, `drush_watchdog`, `cache_clear`, `drush_updb`, `drush_php_eval`
211
238
 
212
- ### Drupal.org (9)
239
+ ### Drupal.org (12)
213
240
  - `module_search`, `module_get`, `module_versions`, `module_dependencies`, `module_compatibility`
214
241
  - `theme_search`, `theme_get`, `release_history`, `project_usage`
242
+ - `module_issues_search`, `module_popular`, `module_recommendation`
215
243
 
216
244
  ### Feeds (12)
217
245
  - `feeds_feed_list`, `feeds_feed_get`, `feeds_feed_create`, `feeds_feed_update`, `feeds_feed_delete`
@@ -256,7 +284,7 @@ displays have Layout Builder enabled; `layout_builder_get`,
256
284
  - `metatag_defaults_get`, `metatag_defaults_set`, `metatag_token_list`
257
285
  - `metatag_canonical_set`, `metatag_jsonld_generate`
258
286
 
259
- ### Migration (7)
287
+ ### Migration (17)
260
288
  - `generate_migration_yaml` — Generate migration YAML
261
289
  - `generate_module_migration` — Generate migration module
262
290
  - `run_migration_test` — Test migration with limited records
@@ -264,6 +292,16 @@ displays have Layout Builder enabled; `layout_builder_get`,
264
292
  - `rollback_migration` — Rollback a migration
265
293
  - `sync_media_files` — Sync media between paths
266
294
  - `migrate_taxonomy` — Migrate taxonomy vocabularies
295
+ - `create_migration_plan` — Create a persisted migration manifest
296
+ - `get_migration_plan` — Read a migration manifest and tracked state
297
+ - `list_migration_plans` — List migration manifests
298
+ - `migration_status` — Summarize migration progress
299
+ - `migrate_records` — Copy a batch of source records to the target site
300
+ - `record_migration_result` — Record externally executed migration outcomes
301
+ - `analyze_source_site` — Analyze a source Drupal JSON:API resource type
302
+ - `reconcile_migration_counts` — Compare source and target counts
303
+ - `run_migration_wave` — Fetch and migrate one source resource type
304
+ - `run_migration` — Run an ordered end-to-end migration for all planned types
267
305
 
268
306
  ### Moderation (13)
269
307
  - `moderation_state_list`, `moderation_state_get`, `moderation_state_create`, `moderation_state_update`, `moderation_state_delete`
@@ -351,10 +389,10 @@ displays have Layout Builder enabled; `layout_builder_get`,
351
389
 
352
390
  ## Documentation
353
391
 
354
- - [Contributing Guide](CONTRIBUTING.md)
355
- - [Changelog](CHANGELOG.md)
356
- - [Security Policy](SECURITY.md)
357
- - [Code of Conduct](CODE_OF_CONDUCT.md)
392
+ - [Contributing Guide](docs/CONTRIBUTING.md)
393
+ - [Changelog](docs/CHANGELOG.md)
394
+ - [Security Policy](docs/SECURITY.md)
395
+ - [Code of Conduct](docs/CODE_OF_CONDUCT.md)
358
396
  - [Architecture](docs/architecture.md)
359
397
  - [Migration Guide](docs/migration.md)
360
398
  - [Docstring Standard](docs/docstring_standard.md)
@@ -449,7 +487,7 @@ python tests/live/queue_test.py # 18 cron/queue cases, ~60s
449
487
  python tests/live/filter_check.py # every hard-coded JSON:API filter
450
488
  python tests/live/resource_check.py # every resource name, asked of Drupal
451
489
  python tests/live/install_modules.py # the modules the tools assume, ~10 min
452
- python tests/live/sweep.py # all 367 tools, ~30 min
490
+ python tests/live/sweep.py # all 392 tools, ~30 min
453
491
  python tests/live/mcp_call.py content_list '{}' # one call, for spot checks
454
492
  ```
455
493
 
@@ -5,7 +5,7 @@ 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]
8
+ ## [0.2.0] - 2026-10-16
9
9
 
10
10
  ### Security
11
11
 
@@ -17,6 +17,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
17
 
18
18
  ### Added
19
19
 
20
+ - Add `drupal-mcp install`, a self-installer that registers the server with
21
+ local MCP clients (Claude Code, Claude Desktop, Cursor, Codex CLI,
22
+ OpenCode, Windsurf, Pi, Hermes Agent, OpenClaw), with `--print`/`--json`
23
+ for scripted setup and an AI Coding Agents guide
24
+ - Add `module_issues_search`, `module_popular`, and `module_recommendation`
25
+ (client-side issue-queue relevance scoring, usage-ranked module lists by
26
+ category, local-index + drupal.org recommendations), plus the `DRUPAL_ROOT`
27
+ and `DRUPAL_MODULES_PATH` settings for local codebase analysis
28
+ - Add a local codebase index with 12 `codebase_*` tools: functionality
29
+ search, module inventory/descriptions, unused and redundant module
30
+ detection, hook implementation lookup, and safe module file/tree/function
31
+ reading (all reads confined to `DRUPAL_ROOT`)
20
32
  - Add `moderation_transition_delete`, giving `moderation_transition_create` the
21
33
  counterpart it never had. The tool count is now 367
22
34
  - Add Lando support to SiteManager
@@ -0,0 +1,221 @@
1
+ # Use with AI Coding Agents
2
+
3
+ Every MCP client needs the same three things: a command to spawn, arguments,
4
+ and the `DRUPAL_*` environment variables. Assembling those by hand differs
5
+ per client, so the server ships a self-installer that does it for you.
6
+
7
+ ## One command
8
+
9
+ ```bash
10
+ drupal-mcp install
11
+ ```
12
+
13
+ With no arguments it:
14
+
15
+ 1. **Detects** the MCP clients on this machine (Claude Code, Claude Desktop,
16
+ Cursor, Codex CLI, OpenCode, Windsurf, Pi, Hermes Agent, OpenClaw) — by
17
+ finding their CLI on `PATH` or a known config path.
18
+ 2. **Gathers** `DRUPAL_*` settings from `./.env`, the process environment and
19
+ any `--env` flags (precedence: dotenv < environment < flags).
20
+ 3. **Writes** each client's config — preferring the client's own `mcp add`
21
+ command when it has one, otherwise writing the documented file directly.
22
+
23
+ ```
24
+ ✓ claude-code: Added stdio MCP server drupal ... to local config
25
+ ✓ codex: Added global MCP server 'drupal'.
26
+ ✓ opencode: MCP server "drupal" added to ./opencode.json
27
+ ```
28
+
29
+ ## Useful options
30
+
31
+ | Option | Effect |
32
+ |--------|--------|
33
+ | `--client NAME` | Configure only this client (repeatable) |
34
+ | `--all` | Configure every supported client |
35
+ | `--list` | List supported client names |
36
+ | `--print` | Print the config/commands without writing anything |
37
+ | `--json` | Emit results as JSON (for scripted/agent-driven setup) |
38
+ | `--env KEY=VALUE` | Extra environment variable (repeatable) |
39
+ | `--dotenv PATH` | Env file to read (default `./.env` if present) |
40
+ | `--name NAME` | Server name inside the client config (default `drupal`) |
41
+ | `--command CMD` | Launch command override, e.g. `--command 'uvx drupal-mcp-server'` |
42
+ | `--scope local\|user\|project` | Claude Code configuration scope |
43
+ | `--global` | OpenCode: write the global config instead of the project one |
44
+
45
+ ## What gets written where
46
+
47
+ | Client | Config | Mechanism |
48
+ |--------|--------|-----------|
49
+ | Claude Code | `claude mcp add` (or `./.mcp.json` with `--scope project`) | client CLI |
50
+ | Claude Desktop | `claude_desktop_config.json` (`mcpServers`) | direct write |
51
+ | Cursor | `~/.cursor/mcp.json` (`mcpServers`) | direct write |
52
+ | Codex CLI | `codex mcp add` (or `~/.codex/config.toml`) | client CLI |
53
+ | OpenCode | `opencode mcp add` (or `opencode.json` → `mcp.servers`) | client CLI |
54
+ | Windsurf | `~/.codeium/windsurf/mcp_config.json` (`mcpServers`) | direct write |
55
+ | Pi | `pi mcp add` (or `~/.pi/agent/mcp.json`) | client CLI |
56
+ | Hermes Agent | `~/.hermes/config.yaml` (`mcp_servers`) | direct write |
57
+ | OpenClaw | `openclaw mcp add` | client CLI (required) |
58
+
59
+ The launch command is the absolute path to the `drupal-mcp` script when it is
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.
63
+
64
+ Existing configs are merged, never clobbered: other servers in the same file
65
+ survive, a server of the same name is replaced (so re-running is idempotent),
66
+ and a config that fails to parse is left untouched with an error instead of
67
+ being overwritten.
68
+
69
+ ## Manual setup (copy-paste)
70
+
71
+ If you would rather wire it up yourself — every command below is verified
72
+ against the client's current CLI or docs:
73
+
74
+ === "Claude Code"
75
+
76
+ ```bash
77
+ claude mcp add drupal \
78
+ -e DRUPAL_BASE_URL=https://your-site.example \
79
+ -e DRUPAL_USERNAME=admin \
80
+ -e DRUPAL_PASSWORD=secret \
81
+ -- drupal-mcp
82
+ ```
83
+
84
+ === "Claude Desktop"
85
+
86
+ ```json
87
+ {
88
+ "mcpServers": {
89
+ "drupal": {
90
+ "command": "drupal-mcp",
91
+ "args": [],
92
+ "env": {
93
+ "DRUPAL_BASE_URL": "https://your-site.example",
94
+ "DRUPAL_USERNAME": "admin",
95
+ "DRUPAL_PASSWORD": "secret"
96
+ }
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ === "Cursor"
103
+
104
+ ```json
105
+ {
106
+ "mcpServers": {
107
+ "drupal": {
108
+ "command": "drupal-mcp",
109
+ "args": [],
110
+ "env": {
111
+ "DRUPAL_BASE_URL": "https://your-site.example",
112
+ "DRUPAL_USERNAME": "admin",
113
+ "DRUPAL_PASSWORD": "secret"
114
+ }
115
+ }
116
+ }
117
+ }
118
+ ```
119
+
120
+ === "Codex CLI"
121
+
122
+ ```bash
123
+ codex mcp add drupal \
124
+ --env DRUPAL_BASE_URL=https://your-site.example \
125
+ --env DRUPAL_USERNAME=admin \
126
+ --env DRUPAL_PASSWORD=secret \
127
+ -- drupal-mcp
128
+ ```
129
+
130
+ === "OpenCode"
131
+
132
+ ```bash
133
+ opencode mcp add drupal \
134
+ --env DRUPAL_BASE_URL=https://your-site.example \
135
+ --env DRUPAL_USERNAME=admin \
136
+ --env DRUPAL_PASSWORD=secret \
137
+ -- drupal-mcp
138
+ ```
139
+
140
+ === "Windsurf"
141
+
142
+ ```json
143
+ {
144
+ "mcpServers": {
145
+ "drupal": {
146
+ "command": "drupal-mcp",
147
+ "args": [],
148
+ "env": {
149
+ "DRUPAL_BASE_URL": "https://your-site.example",
150
+ "DRUPAL_USERNAME": "admin",
151
+ "DRUPAL_PASSWORD": "secret"
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ === "Pi"
159
+
160
+ ```bash
161
+ pi mcp add drupal \
162
+ --env DRUPAL_BASE_URL=https://your-site.example \
163
+ --env DRUPAL_USERNAME=admin \
164
+ --env DRUPAL_PASSWORD=secret \
165
+ -- drupal-mcp
166
+ ```
167
+
168
+ === "Hermes Agent"
169
+
170
+ ```yaml
171
+ # ~/.hermes/config.yaml
172
+ mcp_servers:
173
+ drupal:
174
+ command: "drupal-mcp"
175
+ env:
176
+ DRUPAL_BASE_URL: "https://your-site.example"
177
+ DRUPAL_USERNAME: "admin"
178
+ DRUPAL_PASSWORD: "secret"
179
+ ```
180
+
181
+ === "OpenClaw"
182
+
183
+ ```bash
184
+ openclaw mcp add drupal \
185
+ --command drupal-mcp \
186
+ --env DRUPAL_BASE_URL=https://your-site.example \
187
+ --env DRUPAL_USERNAME=admin \
188
+ --env DRUPAL_PASSWORD=secret \
189
+ --no-probe
190
+ ```
191
+
192
+ OpenClaw's `mcp add` refuses to run while the local Gateway is up — stop it
193
+ first, then verify with `openclaw mcp doctor drupal --probe`.
194
+
195
+ ## No local install?
196
+
197
+ Point any client at PyPI directly:
198
+
199
+ ```bash
200
+ drupal-mcp install --command 'uvx drupal-mcp-server'
201
+ ```
202
+
203
+ ## Verify
204
+
205
+ After installing, restart the client and ask it something that must touch
206
+ Drupal, for example *"list my content types"* (the agent should call
207
+ `content_list`). Client-side checks also help:
208
+
209
+ - Claude Code: `/mcp` shows the server and its connection state
210
+ - OpenClaw: `openclaw mcp status --verbose`, then `openclaw mcp probe drupal`
211
+ - Hermes: `hermes mcp test drupal`
212
+ - Pi: `pi mcp list`
213
+
214
+ ## Security notes
215
+
216
+ The written config contains your `DRUPAL_*` values, including the password.
217
+ Project-scope files that live inside a repository (`.mcp.json`,
218
+ `opencode.json`) can end up committed — the installer warns when it writes
219
+ credentials into the current directory. Prefer `--scope local` for Claude
220
+ Code (stored outside the repo) or keep secrets in `~/.env`-style files
221
+ outside the project and reference them from the client yourself.
@@ -1,6 +1,6 @@
1
1
  # Drupal MCP Server
2
2
 
3
- A Model Context Protocol (MCP) server for Drupal operations. Provides 35+ tools for site analysis, migration, content management, configuration, and DevOps operations.
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.
4
4
 
5
5
  ## Quick Links
6
6
 
@@ -11,15 +11,19 @@ A Model Context Protocol (MCP) server for Drupal operations. Provides 35+ 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).
16
+
14
17
  | Category | Tools | Description |
15
18
  |----------|-------|-------------|
16
- | Content | 12 | CRUD for nodes, media, users, taxonomy, comments |
17
- | Users | 8 | User management, roles, permissions |
18
- | DevOps | 10 | DDEV/Lando, Drush, database, cron |
19
- | Security | 6 | Audits, scanning, permission checks |
20
- | Migration | 7 | D7 to D10 upgrade assistance |
19
+ | Content | 14 | CRUD for nodes, media, users, taxonomy, comments |
20
+ | Users | 12 | User management, roles, permissions |
21
+ | DevOps | 20 | DDEV/Lando, Drush, database, cron |
22
+ | Security Audit | 8 | Audits, scanning, permission checks |
23
+ | Migration | 17 | Plans, batch import, reconciliation between Drupal sites |
21
24
  | AI | 4 | Content analysis, field mapping, planning |
22
- | Module Dev | 10 | Scaffolding for modules, plugins, forms |
25
+ | Module Dev | 12 | Scaffolding for modules, plugins, forms |
26
+ | Codebase | 12 | Local codebase index, hook search, unused module detection |
23
27
 
24
28
  ## Example: Create a Node
25
29