drupal-mcp-connector 0.6.1

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,92 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.6.1] - 2026-06-04
11
+
12
+ First release published to npm.
13
+
14
+ ### Fixed
15
+ - HTTPS transport: import `randomUUID` from `node:crypto` for session IDs instead of
16
+ relying on the bare `crypto` global, which is not available unflagged on Node 18
17
+ (the minimum supported version).
18
+
19
+ ### Changed
20
+ - Comprehensive inline-documentation pass (JSDoc on all exported functions/classes,
21
+ canonical descriptor/entity typedefs) and a Node coding-standards audit across `src/`.
22
+
23
+ ## [0.6.0] - 2026-06-03
24
+
25
+ ### Changed
26
+ - Renamed the package to `drupal-mcp-connector` — clearer that it is the MCP↔Drupal connector, and avoids confusion with the Drupal `mcp_server` module. The outbound identity header is now `X-MCP-Client: drupal-mcp-connector/<version>`.
27
+ - Prepared for npm publication (`bin`, `files`, `keywords`).
28
+
29
+ ## [0.5.0] - 2026-06-03
30
+
31
+ ### Added
32
+ - **OAuth2 write-plane authentication.** Per-site `oauth` block enabling the
33
+ `client_credentials` grant against Drupal `simple_oauth`: token acquisition,
34
+ in-memory per-site caching with silent re-acquire (60s expiry skew), refresh-token
35
+ grant with fallback to `client_credentials`, concurrent-acquire de-duplication, and
36
+ a one-shot token clear + retry on `401`. The client secret is sourced from an
37
+ environment variable (`oauth.clientSecretEnv`) and is never stored in config or
38
+ surfaced in errors.
39
+ - **`write-plane` security preset** mirroring the recommended server-side governance
40
+ profile: writes enabled, no deletes, no GraphQL mutations, entity access limited to
41
+ `node`/`taxonomy_term`/`media`, `user` entities denied, `pass`/`mail` redacted.
42
+
43
+ ### Changed
44
+ - The three fetch helpers resolve auth via an async path so OAuth sites attach a
45
+ freshly-managed Bearer token; static token / Basic-auth sites are unchanged.
46
+ - `requireSecureAuth` now accepts a valid `oauth` block as satisfying the Bearer
47
+ requirement.
48
+
49
+ ## [0.4.0] - 2026-06-01
50
+
51
+ The connector is now **dual-protocol**: every tool runs against an abstract backend
52
+ (JSON:API or GraphQL), selectable per site, with one canonical entity shape across both.
53
+
54
+ ### Added
55
+ - **Dual-protocol backend layer.** A per-site `api` selector (`"jsonapi"`, `"graphql"`,
56
+ or a priority array; omit to auto-detect) routes every tool through `resolveBackend`.
57
+ JSON:API and GraphQL backends are interchangeable.
58
+ - **GraphQL backend** via [GraphQL Compose](https://www.drupal.org/project/graphql_compose):
59
+ introspection-driven, type-aware field selection (`DateTime`/`Language`/`TextSummary`
60
+ scalar wrappers, entity-reference unions), native sort for `created`/`changed`/`title`,
61
+ and client-side filtering over a bounded fetch (results flagged `approximate`/`truncated`).
62
+ - **Canonical entity shape** (`{ id, entityType, bundle, title, status, langcode, created,
63
+ changed, url, fields, relationships, _backend }`) produced by both backends.
64
+ - **Backend capability model** (`read`/`write`/`delete`/`count`/`filter`/`sort`/`revisions`).
65
+ Writes against a read-only backend raise a clear `BackendCapabilityError`.
66
+ - **Security hardening (all optional, safe defaults):** `X-MCP-Client` identity header
67
+ (override/disable via `MCP_CLIENT_ID`), bearer-authenticated HTTPS transport
68
+ (`MCP_AUTH_TOKEN`), bind-address restriction (`MCP_BIND_HOST`), tokens-from-env per site
69
+ (`apiTokenEnv`), and strict per-site auth enforcement (`requireSecureAuth`).
70
+ - **GraphQL mutation gate:** parser-based detection rejects any mutation when
71
+ `allowGraphqlMutations` is off, regardless of where it appears in the document.
72
+
73
+ ### Changed
74
+ - All 66 tools and 10 reports migrated to the backend layer and canonical output.
75
+ - HTTPS transport hardened: HTTPS mandatory, plain HTTP refused off-localhost unless
76
+ `MCP_ALLOW_HTTP=1`; loopback-only bind without TLS; security headers on every response.
77
+ - Documentation rewritten for the dual-protocol model, canonical output, capability gating,
78
+ and the optional hardening controls.
79
+
80
+ ### Removed
81
+ - Bundled `drupal-module/` reference scaffold. Server-side governance now lives in the
82
+ companion [MCP Sentinel](https://www.drupal.org/project/mcp_sentinel) module
83
+ (`drupal/mcp_sentinel`), which supersedes it.
84
+
85
+ ### Security
86
+ - Field-level PII redaction applied to canonical entities and JSON:API resources alike.
87
+ - User tools gained explicit PII-access assertions.
88
+ - Whole tree lint-clean (`npm run lint`) with object-injection sinks rewritten to safe lookups.
89
+
90
+ [0.6.0]: https://github.com/Wilkes-Liberty/drupal-mcp-connector/releases/tag/v0.6.0
91
+ [0.5.0]: https://github.com/Wilkes-Liberty/drupal-mcp-connector/releases/tag/v0.5.0
92
+ [0.4.0]: https://github.com/Wilkes-Liberty/drupal-mcp-connector/releases/tag/v0.4.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jeremy Michael Cerda and Wilkes & Liberty, LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # drupal-mcp-connector
2
+
3
+ > A secure, multi-site Model Context Protocol (MCP) connector for Drupal — dual-protocol JSON:API and GraphQL access, governed content tools, audit reports, and an SSH Drush bridge.
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org)
7
+ [![Drupal](https://img.shields.io/badge/drupal-10%20%7C%2011-blue)](https://drupal.org)
8
+ [![MCP](https://img.shields.io/badge/MCP-2025--11--25-purple)](https://modelcontextprotocol.io)
9
+
10
+ Created by **Jeremy Michael Cerda**. Built and maintained by [Wilkes & Liberty, LLC](https://github.com/Wilkes-Liberty).
11
+
12
+ ---
13
+
14
+ ## What It Does
15
+
16
+ `drupal-mcp-connector` connects any [Model Context Protocol](https://modelcontextprotocol.io) client to one or more Drupal sites. It exposes Drupal content and configuration as a set of MCP **tools**, **resources**, and **prompts**, so an MCP client can read, audit, and (where permitted) write content through structured, governed operations instead of the admin UI:
17
+
18
+ ```
19
+ "Find all articles missing a meta description and list them."
20
+ "Show me every user account that hasn't logged in for 90 days."
21
+ "Create 10 draft product nodes from this structured data."
22
+ "Run an SEO and accessibility audit on the article content type."
23
+ "What content types exist on the site and which are barely used?"
24
+ ```
25
+
26
+ The connector speaks **two Drupal backends interchangeably** — Drupal core's **JSON:API** and **GraphQL** (via [GraphQL Compose](https://www.drupal.org/project/graphql_compose)) — selectable per site. It normalizes both into one canonical entity shape, so the same tools work whether a site exposes JSON:API, GraphQL, or both. An optional SSH **Drush bridge** adds administrative operations the HTTP APIs can't reach.
27
+
28
+ ---
29
+
30
+ ## Dual-Protocol Backends
31
+
32
+ Each site declares which backend(s) it exposes via the `api` key:
33
+
34
+ ```json
35
+ "sites": {
36
+ "main": { "baseUrl": "https://example.com", "api": "jsonapi" },
37
+ "graphql_only": { "baseUrl": "https://api.example.com", "api": "graphql" },
38
+ "either": { "baseUrl": "https://example.com", "api": ["graphql", "jsonapi"] }
39
+ }
40
+ ```
41
+
42
+ - **`api` accepts** `"jsonapi"`, `"graphql"`, or a priority array like `["graphql","jsonapi"]`. Omit it to **auto-detect** (the connector probes both once and caches the result).
43
+ - **One canonical shape.** Both backends return entities as
44
+ `{ id, entityType, bundle, title, status, langcode, created, changed, url, fields, relationships, _backend }`, so tool output is identical regardless of protocol.
45
+ - **Capability-aware.** Each backend advertises what it supports (read, write, delete, server-side filter/sort, revisions). GraphQL via GraphQL Compose is **read-only** (no mutations) and has no server-side field filter, so filters are applied client-side over a bounded fetch and flagged `approximate`/`truncated`. Write tools against a read-only backend return a clear capability error rather than failing silently.
46
+ - **Writes go through JSON:API.** Use a JSON:API-enabled site as the write plane; keep GraphQL as a read plane where that suits your architecture.
47
+
48
+ See **[docs/architecture.md](docs/architecture.md)** for the backend abstraction and **[docs/graphql-local-setup.md](docs/graphql-local-setup.md)** for the GraphQL specifics.
49
+
50
+ ---
51
+
52
+ ## Features
53
+
54
+ ### 66 Tools Across 9 Modules
55
+
56
+ | Module | Tools |
57
+ |--------|-------|
58
+ | **Nodes** | CRUD for any content type with arbitrary field support |
59
+ | **Taxonomy** | Vocabulary listing + full term CRUD |
60
+ | **Users** | List, get, create, update, block/unblock, role management (PII-gated) |
61
+ | **Media** | List types, CRUD, file upload, orphaned-media detection |
62
+ | **GraphQL** | Execute a query, schema introspection (mutation-gated) |
63
+ | **Entities** | Generic CRUD for *any* Drupal entity type (paragraphs, commerce, webforms, …) |
64
+ | **Site** | Site info, content-type discovery, configured-site listing |
65
+ | **Reports** | Content summary, stale content, field completeness, SEO/accessibility audits, taxonomy usage, user activity, revision hotspots (10 read-only reports) |
66
+ | **Drush** | Cache rebuild, cron, config sync, module management, DB updates via SSH |
67
+
68
+ ### MCP Resources
69
+ Browsable, always-fresh context the client can read without calling a tool:
70
+ - **`drupal://sites`** — configured site profiles (no credentials)
71
+ - **`drupal://{site}/content-types`** — content types with field schemas
72
+ - **`drupal://{site}/security-policy`** — the active security configuration
73
+
74
+ ### MCP Prompts
75
+ Workflow templates usable as slash-commands from any MCP client:
76
+ - `drupal-content-audit` — walk through a full site content audit
77
+ - `drupal-create-article` — guided article creation with all fields
78
+ - `drupal-seo-fix` — find and fix SEO gaps
79
+ - `drupal-user-cleanup` — identify and handle inactive accounts
80
+
81
+ ### Security Model
82
+ Defense-in-depth with four one-line presets, enforced connector-side and complemented by Drupal-side governance:
83
+
84
+ ```json
85
+ "security": { "preset": "auditor" }
86
+ ```
87
+
88
+ | Preset | What it does |
89
+ |--------|-------------|
90
+ | `development` | Everything allowed — local development only |
91
+ | `content-editor` | Create/edit nodes, media, terms; no deletes; no user access |
92
+ | `auditor` | Read-only, all entity types, PII fields redacted |
93
+ | `production-strict` | Read-only, no user entities, broad PII redaction |
94
+
95
+ Presets layer with entity allow/deny lists, per-bundle operation rules, and field-level redaction. Optional transport hardening (bearer-authenticated HTTPS, bind-address restriction, secrets-from-env) is covered in **[docs/security-hardening.md](docs/security-hardening.md)**.
96
+
97
+ ---
98
+
99
+ ## Requirements
100
+
101
+ - **Node.js** 18+
102
+ - **Drupal** 10 or 11 (JSON:API ships in core)
103
+ - For the **GraphQL backend**: [GraphQL Compose](https://www.drupal.org/project/graphql_compose)
104
+ - For **token auth** (recommended): [Simple OAuth](https://www.drupal.org/project/simple_oauth)
105
+ - For the **Drush bridge**: SSH key access to the Drupal server
106
+
107
+ ---
108
+
109
+ ## Quick Start
110
+
111
+ ```bash
112
+ # 1. Clone and install
113
+ git clone https://github.com/Wilkes-Liberty/drupal-mcp-connector
114
+ cd drupal-mcp-connector
115
+ npm install
116
+
117
+ # 2. Configure
118
+ cp config/config.example.json config/config.json
119
+ # Edit config/config.json — add your site's baseUrl, api backend, and auth
120
+
121
+ # 3. Run (stdio transport)
122
+ node src/index.js
123
+ ```
124
+
125
+ ### Register with an MCP client
126
+
127
+ Most desktop and CLI MCP clients launch the connector over **stdio**. Add an entry to your client's MCP server configuration:
128
+
129
+ ```json
130
+ {
131
+ "mcpServers": {
132
+ "drupal": {
133
+ "command": "node",
134
+ "args": ["/absolute/path/to/drupal-mcp-connector/src/index.js"],
135
+ "env": {
136
+ "DRUPAL_BASE_URL": "https://mysite.com",
137
+ "DRUPAL_API_TOKEN": "your-token-here"
138
+ }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ For multi-client or remote use, run the HTTPS transport and register the endpoint instead — see **[docs/getting-started.md](docs/getting-started.md)**.
145
+
146
+ ---
147
+
148
+ ## Companion Drupal Module — MCP Sentinel
149
+
150
+ The connector works out of the box against Drupal core's JSON:API and a GraphQL Compose schema. For server-side governance, pair it with the **[MCP Sentinel](https://www.drupal.org/project/mcp_sentinel)** module (`drupal/mcp_sentinel`), which enforces policy *inside* Drupal — independent of any connector configuration:
151
+
152
+ - Role-bound policy profiles (operation gates, entity allow/deny, field redaction)
153
+ - Tamper-evident audit log of every governed MCP operation, attributed to the acting account
154
+ - Content locks that prevent edits to content a human is actively editing
155
+ - OAuth scope enforcement (`mcp:read` / `mcp:write`) per tool
156
+ - HMAC-signed webhooks on MCP-driven entity changes
157
+
158
+ ```bash
159
+ composer require drupal/mcp_sentinel drupal/mcp_server drupal/simple_oauth
160
+ drush en mcp_sentinel mcp_sentinel_server mcp_server_tool_bridge -y
161
+ drush mcp-sentinel:setup
162
+ ```
163
+
164
+ Governance keys off the authenticated account's role and OAuth scopes — not request headers. The connector sends an `X-MCP-Client` identity header purely as a log label. See the [MCP Sentinel project page](https://www.drupal.org/project/mcp_sentinel) for the full contract.
165
+
166
+ ---
167
+
168
+ ## Documentation
169
+
170
+ | Doc | Description |
171
+ |-----|-------------|
172
+ | [Getting Started](docs/getting-started.md) | Full setup: DDEV/Lando, Simple OAuth, multi-site, transports |
173
+ | [Architecture](docs/architecture.md) | Backend abstraction, canonical model, and how to extend it |
174
+ | [GraphQL Setup](docs/graphql-local-setup.md) | GraphQL Compose backend + local TLS notes |
175
+ | [Tools Reference](docs/tools-reference.md) | Full reference for all 66 tools |
176
+ | [Security Guide](docs/security.md) | Presets, entity access control, field redaction |
177
+ | [Security Hardening](docs/security-hardening.md) | Optional transport, identity, and secrets controls |
178
+ | [Integration Contract](docs/integration-contract.md) | The connector ↔ Drupal-governance contract (identity, OAuth scopes, compatibility) |
179
+ | [Whitepaper](docs/whitepaper.md) | Vision, personas, and use cases |
180
+
181
+ ---
182
+
183
+ ## Contributing
184
+
185
+ PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
186
+
187
+ ## Security
188
+
189
+ Found a vulnerability? See [SECURITY.md](SECURITY.md). Please do not open a public issue.
190
+
191
+ ## License
192
+
193
+ [MIT](LICENSE) © 2026 Jeremy Michael Cerda and [Wilkes & Liberty, LLC](https://github.com/Wilkes-Liberty)
@@ -0,0 +1,122 @@
1
+ {
2
+ "_comment": "Copy to config/config.json and fill in your values. This file is safe to commit. config.json is gitignored.",
3
+
4
+ "_api_modes": {
5
+ "_comment": "Per-site 'api' selects the backend: 'graphql' | 'jsonapi' | a priority array like ['graphql','jsonapi']. Omit to auto-detect (probes both once). GraphQL is read-only (no mutations); writes require a JSON:API site.",
6
+ "examples": ["jsonapi", "graphql", ["graphql", "jsonapi"]]
7
+ },
8
+
9
+ "_security_options": {
10
+ "_comment": "All optional. apiTokenEnv: read the Bearer token from this env var instead of apiToken (keeps secrets out of the config file). requireSecureAuth: reject anon/basic, require HTTPS+Bearer (recommended for production). Env overrides: MCP_CLIENT_ID overrides or disables the outbound identity header; MCP_AUTH_TOKEN requires bearer auth on the HTTPS /mcp endpoint; MCP_BIND_HOST restricts the listen interface (with TLS). See docs/security-hardening.md."
11
+ },
12
+
13
+ "defaultSite": "production",
14
+
15
+ "tls": {
16
+ "_comment": "TLS is required for the HTTPS transport (MCP_TRANSPORT=https). Ignored in stdio mode.",
17
+ "certPath": "/etc/ssl/certs/drupal-mcp.crt",
18
+ "keyPath": "/etc/ssl/private/drupal-mcp.key",
19
+ "port": 3443
20
+ },
21
+
22
+ "sites": {
23
+ "production": {
24
+ "baseUrl": "https://mysite.com",
25
+ "apiToken": "eyJhbGciOiJSUzI1NiJ9...",
26
+ "apiTokenEnv": "DRUPAL_TOKEN_PRODUCTION",
27
+ "requireSecureAuth": true,
28
+ "username": "",
29
+ "password": "",
30
+ "graphqlEndpoint": "/graphql",
31
+ "api": "jsonapi",
32
+
33
+ "drushSsh": {
34
+ "_comment": "Optional. Enables drupal_drush_* tools. SSH key auth only — no passwords.",
35
+ "host": "ssh.mysite.com",
36
+ "user": "deploy",
37
+ "keyPath": "~/.ssh/id_ed25519",
38
+ "drupalRoot": "/var/www/html/web",
39
+ "port": 22
40
+ },
41
+
42
+ "security": {
43
+ "_comment": "Presets: development | content-editor | auditor | production-strict",
44
+ "preset": "auditor",
45
+ "readOnly": true,
46
+ "allowDestructive": false,
47
+ "allowGraphqlMutations": false,
48
+ "allowedEntityTypes": null,
49
+ "deniedEntityTypes": ["user"],
50
+ "globalRedactedFields": ["pass", "mail", "field_api_key", "field_private"],
51
+ "entityRules": {
52
+ "node": {
53
+ "allowedOperations": ["read"],
54
+ "deniedBundles": ["private_document", "internal_memo"]
55
+ }
56
+ }
57
+ }
58
+ },
59
+
60
+ "staging": {
61
+ "baseUrl": "https://staging.mysite.com",
62
+ "username": "api-user",
63
+ "password": "change-me-use-token-instead",
64
+ "api": "jsonapi",
65
+ "security": { "preset": "content-editor" }
66
+ },
67
+
68
+ "local": {
69
+ "_comment": "Plain HTTP is allowed for localhost targets only. A warning is logged.",
70
+ "baseUrl": "http://mysite.lndo.site",
71
+ "username": "admin",
72
+ "password": "admin",
73
+ "security": { "preset": "development" }
74
+ },
75
+
76
+ "graphql_only": {
77
+ "_comment": "A site that exposes GraphQL only (JSON:API disabled). GraphQL is read-only.",
78
+ "baseUrl": "https://api.example.com",
79
+ "graphqlEndpoint": "/graphql",
80
+ "api": "graphql",
81
+ "security": { "preset": "auditor" }
82
+ },
83
+
84
+ "oauth_write_plane": {
85
+ "_comment": "OAuth2 client_credentials grant against simple_oauth. The client secret is read from the named env var and never stored here.",
86
+ "baseUrl": "https://api.example.com",
87
+ "requireSecureAuth": true,
88
+ "api": "jsonapi",
89
+ "oauth": {
90
+ "tokenUrl": "/oauth/token",
91
+ "clientId": "mcp-agent-prod",
92
+ "clientSecretEnv": "MCP_AGENT_CLIENT_SECRET",
93
+ "scopes": ["mcp:read", "mcp:write"],
94
+ "grant": "client_credentials"
95
+ },
96
+ "security": { "preset": "write-plane" }
97
+ }
98
+ },
99
+
100
+ "_security_presets": {
101
+ "development": "All operations allowed. Local dev only.",
102
+ "content-editor": "Create/edit nodes+media+terms. No deletes. No user entity access.",
103
+ "auditor": "Read-only. All entity types. User PII fields redacted.",
104
+ "production-strict": "Read-only. No user entities. Broad PII redaction.",
105
+ "write-plane": "Governed writes (no delete/mutations) on node, taxonomy_term, media. No user. Redacts pass/mail."
106
+ },
107
+
108
+ "_mcp_client_registration": {
109
+ "_comment": "Add under your MCP client's mcpServers config (stdio transport)",
110
+ "drupal": {
111
+ "command": "node",
112
+ "args": ["/absolute/path/to/drupal-mcp-connector/src/index.js"]
113
+ }
114
+ },
115
+
116
+ "_https_transport_registration": {
117
+ "_comment": "For multi-client HTTP mode — register the HTTPS endpoint instead",
118
+ "drupal": {
119
+ "url": "https://your-server:3443/mcp"
120
+ }
121
+ }
122
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "drupal-mcp-connector",
3
+ "version": "0.6.1",
4
+ "description": "A secure, multi-site Model Context Protocol (MCP) connector for Drupal — dual-protocol JSON:API and GraphQL.",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "drupal-mcp-connector": "src/index.js"
9
+ },
10
+ "files": [
11
+ "src/",
12
+ "config/config.example.json",
13
+ "README.md",
14
+ "CHANGELOG.md",
15
+ "LICENSE"
16
+ ],
17
+ "keywords": [
18
+ "drupal",
19
+ "mcp",
20
+ "model-context-protocol",
21
+ "jsonapi",
22
+ "json-api",
23
+ "graphql",
24
+ "connector",
25
+ "headless",
26
+ "decoupled",
27
+ "drush"
28
+ ],
29
+ "homepage": "https://github.com/Wilkes-Liberty/drupal-mcp-connector",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/Wilkes-Liberty/drupal-mcp-connector.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/Wilkes-Liberty/drupal-mcp-connector/issues"
36
+ },
37
+ "license": "MIT",
38
+ "author": "Jeremy Michael Cerda <jmcerda@wilkesliberty.com> (https://wilkesliberty.com)",
39
+ "contributors": [
40
+ "Wilkes & Liberty, LLC <opensource@wilkesliberty.com> (https://wilkesliberty.com)"
41
+ ],
42
+ "engines": {
43
+ "node": ">=18.0.0"
44
+ },
45
+ "scripts": {
46
+ "start": "node src/index.js",
47
+ "start:https": "MCP_TRANSPORT=https node src/index.js",
48
+ "start:dev": "MCP_TRANSPORT=https MCP_ALLOW_HTTP=1 MCP_PORT=3443 node src/index.js",
49
+ "lint": "eslint src/",
50
+ "lint:fix": "eslint src/ --fix",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest",
53
+ "audit": "npm audit --audit-level=high",
54
+ "check": "npm run lint && npm run audit",
55
+ "syntax-check": "for f in src/lib/*.js src/tools/*.js src/index.js; do node --input-type=module --check < $f && echo \"$f ✓\"; done"
56
+ },
57
+ "dependencies": {
58
+ "@modelcontextprotocol/sdk": "^1.0.0",
59
+ "graphql": "^16.9.0",
60
+ "node-fetch": "^3.3.2",
61
+ "ssh2": "^1.16.0"
62
+ },
63
+ "devDependencies": {
64
+ "eslint": "^9.0.0",
65
+ "eslint-plugin-security": "^3.0.0",
66
+ "eslint-plugin-n": "^17.0.0",
67
+ "globals": "^15.0.0",
68
+ "vitest": "^2.1.0"
69
+ }
70
+ }