drupal-mcp-connector 2.10.0 → 2.10.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 +16 -0
- package/package.json +1 -1
- package/src/index.js +3 -0
- package/src/lib/backends/jsonapi.js +10 -5
- package/src/lib/http-auth.js +20 -0
- package/src/lib/verify.js +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.10.1] - 2026-08-28
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Node reads include the numeric Drupal node ID (#237).** JSON:API-backed
|
|
14
|
+
`drupal_get_node` and `drupal_entity_get` results retain
|
|
15
|
+
`fields.drupal_internal__nid`, matching schema discovery while preserving
|
|
16
|
+
entity allowlists and configured field redaction. The canonical top-level
|
|
17
|
+
`id` remains the UUID.
|
|
18
|
+
|
|
19
|
+
### Deprecated
|
|
20
|
+
- **Loopback `shared_bearer` inbound auth (#231).** Startup warns when
|
|
21
|
+
`resolveInboundAuthMode` is `shared_bearer`, naming removal in v3.0.0.
|
|
22
|
+
Resource-server mode is silent. `npm run verify` lists the residual.
|
|
23
|
+
This is the deprecation half only; removal waits for the next major.
|
|
24
|
+
|
|
10
25
|
## [2.10.0] - 2026-08-27
|
|
11
26
|
|
|
12
27
|
### Security
|
|
@@ -1314,6 +1329,7 @@ The connector is now **dual-protocol**: every tool runs against an abstract back
|
|
|
1314
1329
|
- User tools gained explicit PII-access assertions.
|
|
1315
1330
|
- Whole tree lint-clean (`npm run lint`) with object-injection sinks rewritten to safe lookups.
|
|
1316
1331
|
|
|
1332
|
+
[2.10.1]: https://github.com/Wilkes-Liberty/drupal-mcp-connector/releases/tag/v2.10.1
|
|
1317
1333
|
[1.0.0]: https://github.com/Wilkes-Liberty/drupal-mcp-connector/releases/tag/v1.0.0
|
|
1318
1334
|
[0.10.0]: https://github.com/Wilkes-Liberty/drupal-mcp-connector/releases/tag/v0.10.0
|
|
1319
1335
|
[0.9.1]: https://github.com/Wilkes-Liberty/drupal-mcp-connector/releases/tag/v0.9.1
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
makeBearerCheck,
|
|
40
40
|
resolveInboundAuthConfig,
|
|
41
41
|
resolveInboundAuthMode,
|
|
42
|
+
inboundAuthDeprecationWarning,
|
|
42
43
|
createInboundHttpsAuth,
|
|
43
44
|
} from "./lib/http-auth.js";
|
|
44
45
|
import { createLegacySessionHandler, createMcpRequestHandler } from "./lib/http-handler.js";
|
|
@@ -404,6 +405,8 @@ if (transport === "stdio") {
|
|
|
404
405
|
console.error(`[drupal-mcp-connector] FATAL: ${inboundMode.reason}`);
|
|
405
406
|
process.exit(1);
|
|
406
407
|
}
|
|
408
|
+
const deprecation = inboundAuthDeprecationWarning(inboundMode.mode);
|
|
409
|
+
if (deprecation) console.error(deprecation);
|
|
407
410
|
|
|
408
411
|
let checkAuth = makeBearerCheck(inboundMode.mode === "shared_bearer" ? authToken : "");
|
|
409
412
|
let authenticate = null;
|
|
@@ -17,8 +17,9 @@ import {
|
|
|
17
17
|
BASE_ATTRIBUTE_FIELDS,
|
|
18
18
|
} from "../canonical.js";
|
|
19
19
|
|
|
20
|
-
// Drupal exposes internal
|
|
21
|
-
//
|
|
20
|
+
// Drupal exposes internal identifiers under drupal_internal__* attributes.
|
|
21
|
+
// They are dropped from canonical `fields` except for the identifiers that
|
|
22
|
+
// governed read/write workflows explicitly need.
|
|
22
23
|
const INTERNAL_ATTR_RE = /^drupal_internal__/;
|
|
23
24
|
|
|
24
25
|
// countEntities() pagination. Drupal core JSON:API returns no total in `meta`,
|
|
@@ -194,8 +195,9 @@ export class JsonApiBackend extends Backend {
|
|
|
194
195
|
|
|
195
196
|
/**
|
|
196
197
|
* Convert a JSON:API resource object into a CanonicalEntity. Base attributes
|
|
197
|
-
* (title/status/...) are promoted;
|
|
198
|
-
* stripped from `fields`; relationships
|
|
198
|
+
* (title/status/...) are promoted; base fields and unneeded
|
|
199
|
+
* drupal_internal__* attributes are stripped from `fields`; relationships
|
|
200
|
+
* are normalized to canonical refs.
|
|
199
201
|
* @param {object} resource A JSON:API resource object.
|
|
200
202
|
* @returns {import("../canonical.js").CanonicalEntity}
|
|
201
203
|
*/
|
|
@@ -208,10 +210,13 @@ export class JsonApiBackend extends Backend {
|
|
|
208
210
|
Object.entries(attrs).filter(([k]) => {
|
|
209
211
|
if (BASE_ATTRIBUTE_FIELDS.includes(k)) return false;
|
|
210
212
|
if (INTERNAL_ATTR_RE.test(k)) {
|
|
213
|
+
// Node reads expose the numeric nid advertised by schema discovery
|
|
214
|
+
// while the UUID remains the canonical top-level id (#237).
|
|
211
215
|
// Paragraph ERR attach needs the current revision id (#192).
|
|
212
216
|
// Node / revisionable writes need the working vs live vid (#166).
|
|
213
217
|
// Other drupal_internal__* attributes stay stripped.
|
|
214
|
-
return k === "
|
|
218
|
+
return (entityType === "node" && k === "drupal_internal__nid")
|
|
219
|
+
|| k === "drupal_internal__vid"
|
|
215
220
|
|| (entityType === "paragraph" && k === "drupal_internal__revision_id");
|
|
216
221
|
}
|
|
217
222
|
return true;
|
package/src/lib/http-auth.js
CHANGED
|
@@ -479,6 +479,26 @@ export function resolveInboundAuthMode({
|
|
|
479
479
|
};
|
|
480
480
|
}
|
|
481
481
|
|
|
482
|
+
/**
|
|
483
|
+
* Startup deprecation warning for inbound auth mode `shared_bearer` (#231).
|
|
484
|
+
*
|
|
485
|
+
* Removal is the next major (v3.0.0). Resource-server and unauthenticated
|
|
486
|
+
* modes are silent. The warning names the issue and the removal version so
|
|
487
|
+
* a loopback install cannot miss the kill criterion.
|
|
488
|
+
*
|
|
489
|
+
* @param {string} mode
|
|
490
|
+
* @returns {?string} Warning text, or null when this mode is not deprecated.
|
|
491
|
+
*/
|
|
492
|
+
export function inboundAuthDeprecationWarning(mode) {
|
|
493
|
+
if (mode !== "shared_bearer") return null;
|
|
494
|
+
return (
|
|
495
|
+
"[drupal-mcp-connector] WARNING: inbound auth mode shared_bearer is deprecated " +
|
|
496
|
+
"and will be removed in v3.0.0 (#231). Configure an OAuth resource server " +
|
|
497
|
+
"(auth.issuer + auth.audience) or run unauthenticated loopback. " +
|
|
498
|
+
"MCP_ALLOW_UNAUTHENTICATED remains the explicit trusted-proxy opt-in."
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
|
|
482
502
|
/**
|
|
483
503
|
* Merge config.auth with environment overrides.
|
|
484
504
|
* @param {object} [cfg]
|
package/src/lib/verify.js
CHANGED
|
@@ -75,6 +75,16 @@ export const RESIDUALS = [
|
|
|
75
75
|
"responsibility; the connector reads secrets from the environment and never " +
|
|
76
76
|
"stores them.",
|
|
77
77
|
},
|
|
78
|
+
{
|
|
79
|
+
id: "loopback_shared_bearer",
|
|
80
|
+
status: "managed",
|
|
81
|
+
detail:
|
|
82
|
+
"Loopback MCP_AUTH_TOKEN (inbound mode shared_bearer) still ships. It is " +
|
|
83
|
+
"deprecated as of this release and will be removed in v3.0.0 (#231). " +
|
|
84
|
+
"Network-facing product paths already refuse it. MCP_ALLOW_UNAUTHENTICATED " +
|
|
85
|
+
"is a separate named residual: an explicit trusted-proxy opt-in, not a " +
|
|
86
|
+
"shared credential, and is not retired by #231.",
|
|
87
|
+
},
|
|
78
88
|
];
|
|
79
89
|
|
|
80
90
|
/** Hostname suffixes reserved for documentation and testing (RFC 2606/6761). */
|