@drupal-forge/server-testing
v0.1.1
Published
Safe Drupal test discovery, selection, scaffolding, allowlisted execution, quality checks, artifacts
Readme
🧪 Drupal Testing (Spec 09)
MCP server for safe Drupal test discovery, deterministic changeset-to-test selection, bounded scaffolding, allowlisted execution, quality checks, and artifact collection.
It reports technical execution evidence only. It never decides whether a failing test is a meaningful TDD Red and never assigns requirement-level verdicts — those remain skill responsibilities.
✨ Features
- Independent Capability Inspection: Reports Unit, Kernel, Functional, FunctionalJavascript, JavaScript, and quality-tool readiness without inferring a Drupal runtime rung.
- Deterministic Selection: Maps normalized changeset and reference evidence to focused tests, fallback suites, confidence, and uncovered surfaces.
- Bounded Scaffolding: Generates ledger-backed PHPUnit/JS skeletons and content-model fixture code; workspace writes require explicit opt-in.
- Allowlisted Execution: Runs structured PHPUnit or package-script targets via
spawnwith argument arrays (shell: false) under Local, Lando, or DDEV. - Read-Only Quality Gates: PHPCS, PHPStan, Drupal Check, Rector dry-run, Twig CS, ESLint, Stylelint, Composer validate/audit — never autofix.
- Artifact Provenance: Persists bounded run manifests under a project-scoped artifact root, keyed by
test_run_id. - Credential Safety: Database-backed tests require an allowlisted
SIMPLETEST_DBfingerprint; output and artifacts redact secrets.
🧰 Available Tools (8)
| Tool | Purpose |
|---|---|
| inspect_test_environment | Report independent Unit, Kernel, Functional, FunctionalJavascript, JavaScript, and quality-tool capabilities plus missing prerequisites. |
| discover_tests | Discover PHPUnit and JavaScript tests with stable IDs, levels, groups, methods, and module/path associations. |
| select_tests_for_changeset | Select focused tests from normalized drupal-codebase-introspect changeset/reference evidence. |
| scaffold_test_skeleton | Generate a ledger-backed test preview; write only when write=true and output_path are set. |
| scaffold_test_fixtures | Generate fixture code from caller-supplied content-model evidence without creating live content. |
| run_test | Execute one structured, allowlisted test target and return a test_run_id with technical outcome. |
| run_quality_checks | Run read-only analyzers without autofix; classify findings against changed-line metadata. |
| collect_test_artifacts | Read the bounded artifact manifest for exactly one test_run_id. |
Shared Required Parameter
Every tool requires project_root — an absolute path to the Drupal project root (the directory containing composer.json). Unlike bootstrap-based servers, there is no cwd fallback: the caller must always supply it.
🚀 Installation & Configuration
Via npm (Recommended)
Install the server globally:
npm install -g @drupal-forge/server-testingAdd the following to your MCP client configuration (e.g.,
claude_desktop_config.jsonor Cursor settings):{ "mcpServers": { "drupal-testing": { "command": "npx", "args": [ "-y", "@drupal-forge/server-testing" ] } } }
Project Configuration
Copy .drupal-testing.example.json to .drupal-testing.json in the Drupal project root and review it before enabling database-backed tests.
inspect_test_environment returns a password-free SHA-256 fingerprint for SIMPLETEST_DB. Kernel, Functional, and FunctionalJavascript tests remain blocked until that fingerprint appears in allowed_test_db_fingerprints.
Defaults:
| Setting | Default |
|---|---|
| Executors | local, lando, ddev (default_executor: auto) |
| Artifact root | .agent-forge/artifacts/drupal-testing |
| Timeout | 15 minutes (max 60 minutes) |
| Returned stdout/stderr | 2 MiB per stream |
| Persisted artifact | 50 MiB per file |
| Retention | 14 days |
| Allowed package scripts | test, test:unit, test:js |
Contrib discovery, network checks, scaffold writes, and overwrites are disabled unless explicitly requested. JavaScript runners use executor=local in v0.1 because container-specific Node tool names are project policy.
From the Monorepo
pnpm --filter @drupal-forge/server-testing typecheck
pnpm --filter @drupal-forge/server-testing test
pnpm --filter @drupal-forge/server-testing build
node servers/drupal-testing/dist/index.js🛡️ Security
- No arbitrary command or shell-string input exists.
- Commands use
spawnwith argument arrays andshell: false. - Database-backed tests require an explicitly allowlisted connection fingerprint.
- Output and artifacts redact credentials, tokens, JWTs, and credential-bearing URLs.
- Artifact and scaffold paths cannot escape the project root.
- Quality tools run without autofix; Rector always receives
--dry-run. - Composer audit requires both
allow_network=trueon the call andallow_network_checks=truein project configuration. - MCP servers do not call each other directly. Skills pass normalized upstream evidence into this server.
🧭 Interactive Developer Journey & Capability Demo
Follow this walkthrough to explore capability inspection, discovery, selection, scaffolding, execution, quality checks, and artifact collection.
Phase 1: Capability Preflight
inspect_test_environmentwith{ project_root: "/abs/path/to/drupal" }.- Discovery: Independent availability for Unit / Kernel / Functional / FunctionalJavascript / JavaScript, plus quality-tool readiness and the safe
SIMPLETEST_DBfingerprint to allowlist when needed.
- Discovery: Independent availability for Unit / Kernel / Functional / FunctionalJavascript / JavaScript, plus quality-tool readiness and the safe
Phase 2: Inventory & Selection
discover_testswith optionalmodule,levels, andlimit.- Discovery: Stable test IDs, runners, levels, and explicit module/path associations (custom code by default; contrib is opt-in).
select_tests_for_changesetwith normalizedchangesetand optionalreference_edgesfromdrupal-codebase-introspect.- Discovery: Focused tests, module fallbacks, confidence, unsupported dynamic references, and affected surfaces with no known coverage.
Phase 3: Scaffolding (Preview First)
scaffold_test_skeletonwith a ledger-backedrequirement,level,module_name, andclass_name(writedefaults tofalse).- Discovery: Proposed test content, suggested
$modules/mocks, unresolved dependencies, andrequires_human_review.
- Discovery: Proposed test content, suggested
scaffold_test_fixtureswithentity_typeplus normalized content-model evidence.- Discovery: Fixture code proposal without creating live Drupal content.
Phase 4: Execute & Collect Evidence
run_testwith an allowlisted structured target (test_levelplustest_path/filter/group/package_scriptas appropriate).- Discovery: A
test_run_idand technicalexecution_outcome(PASSED,ASSERTION_FAILED,COMPILE_ERROR, …). TDD Red/Green and requirement verdicts stay with the skill.
- Discovery: A
run_quality_checkswithcheckssuch as["phpcs", "phpstan"]and optionalchanged_lines.- Discovery:
new_or_changed_findingsvsaffected_existing_findings; missing tools and unverified scope remain explicit.
- Discovery:
collect_test_artifactswith thetest_run_idfrom step 6.- Discovery: Bounded artifact manifest and explicit unavailable instrumentation sources.
