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.
- drupal_mcp_server-0.2.0/.codecov.yml +17 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/workflows/ci.yml +4 -1
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/workflows/docs.yml +9 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.gitignore +12 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/PKG-INFO +49 -11
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/README.md +48 -10
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/CHANGELOG.md +13 -1
- drupal_mcp_server-0.2.0/docs/agents.md +221 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/index.md +11 -7
- drupal_mcp_server-0.2.0/docs/migration.md +188 -0
- drupal_mcp_server-0.2.0/docs/quickstart.md +86 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/index.md +3 -1
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/mkdocs.yml +7 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/pyproject.toml +2 -2
- drupal_mcp_server-0.2.0/scripts/live-migration-d7d11.sh +240 -0
- drupal_mcp_server-0.2.0/scripts/live-migration-d9d11-run.py +127 -0
- drupal_mcp_server-0.2.0/scripts/live-migration-d9d11.sh +193 -0
- drupal_mcp_server-0.2.0/scripts/live-migration-smoke-run.py +115 -0
- drupal_mcp_server-0.2.0/scripts/live-migration-smoke.sh +166 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/__init__.py +1 -1
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/cli.py +58 -0
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/__init__.py +319 -0
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/indexer.py +229 -0
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/parsers.py +301 -0
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/codebase/search.py +272 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/config.py +13 -0
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/installer.py +792 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/server.py +8 -2
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/services/migration_service.py +855 -0
- drupal_mcp_server-0.2.0/src/drupal_mcp_server/tools/codebase.py +231 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/drupal_org.py +363 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/migration.py +218 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/integration/test_server.py +54 -0
- drupal_mcp_server-0.2.0/tests/unit/test_codebase.py +588 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_drupal_org.py +285 -3
- drupal_mcp_server-0.2.0/tests/unit/test_installer.py +445 -0
- drupal_mcp_server-0.2.0/tests/unit/test_migration_service.py +246 -0
- drupal_mcp_server-0.1.0/docs/migration.md +0 -139
- drupal_mcp_server-0.1.0/src/drupal_mcp_server/services/migration_service.py +0 -20
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.env.example +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/.github/workflows/release.yml +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/LICENSE +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/MAINTAINERS.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/CODE_OF_CONDUCT.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/CONTRIBUTING.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0/docs}/SECURITY.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0001-use-fastmcp.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0002-pydantic-settings.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0003-subprocess-drush.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/adr/0004-http-transport.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/architecture.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/configuration.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/docstring_standard.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/installation.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/content.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/devops.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/docs/tools/users.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/.env.example +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/README.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/basic_usage.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/content_workflow.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/custom_tool.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/examples/migration_workflow.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/lint.sh +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/run.sh +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/setup.sh +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/scripts/test.sh +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/__init__.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/basic.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/mcp_oauth.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/session.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/auth/token.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/__init__.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/base.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/drush.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/graphql.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/clients/jsonapi.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/errors.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/exceptions.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/logging_config.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/schemas.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/services/__init__.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/services/ai_service.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/services/site_manager.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/__init__.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/_utils.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/accessibility.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/ai.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/analysis.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/code_audit.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/comments.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/commerce.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/config.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/contact.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/content.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/database.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/devops.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/feeds.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/fields.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/headless.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/layout_builder.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/media_enhanced.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/menus.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/metatag.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/moderation.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/module_dev.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/multilingual.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/paragraphs.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/pathauto.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/performance.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/redirects.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/revisions.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/scheduler.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/search_api.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/security_audit.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/taxonomy.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/testing.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/theme_dev.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/users.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/views.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/tools/webform.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/src/drupal_mcp_server/validation.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/__init__.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/README.md +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/bootstrap.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/filter_check.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/install_modules.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/layout_builder_test.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/mcp_call.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/queue_test.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/resource_check.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/seed.php +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/smoke_test.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/live/sweep.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/__init__.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_auth.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_clients.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_content_tools.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_errors.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_handler_and_translation_tools.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_logging_config.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_moderation_transitions.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_resource_names.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_revisions.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_scheduler_tools.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_schemas.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_sweep_harness.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_tool_utils.py +0 -0
- {drupal_mcp_server-0.1.0 → drupal_mcp_server-0.2.0}/tests/unit/test_tools.py +0 -0
- {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:
|
|
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.
|
|
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
|
[](https://github.com/vloganathane/drupal-mcp-server/actions/workflows/ci.yml)
|
|
46
46
|
[](https://codecov.io/gh/vloganathane/drupal-mcp-server)
|
|
47
|
-
[](https://pypi.org/project/drupal-mcp-server/)
|
|
48
48
|
[](https://pypi.org/project/drupal-mcp-server/)
|
|
49
|
+
[](https://pypi.org/project/drupal-mcp-server/)
|
|
49
50
|
[](https://github.com/vloganathane/drupal-mcp-server/blob/main/LICENSE)
|
|
50
51
|
|
|
51
|
-
A Model Context Protocol (MCP) server for Drupal operations. Provides **
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
[](https://github.com/vloganathane/drupal-mcp-server/actions/workflows/ci.yml)
|
|
4
4
|
[](https://codecov.io/gh/vloganathane/drupal-mcp-server)
|
|
5
|
-
[](https://pypi.org/project/drupal-mcp-server/)
|
|
6
6
|
[](https://pypi.org/project/drupal-mcp-server/)
|
|
7
|
+
[](https://pypi.org/project/drupal-mcp-server/)
|
|
7
8
|
[](https://github.com/vloganathane/drupal-mcp-server/blob/main/LICENSE)
|
|
8
9
|
|
|
9
|
-
A Model Context Protocol (MCP) server for Drupal operations. Provides **
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
-
## [
|
|
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
|
|
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 |
|
|
17
|
-
| Users |
|
|
18
|
-
| DevOps |
|
|
19
|
-
| Security |
|
|
20
|
-
| Migration |
|
|
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 |
|
|
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
|
|