Problem/Motivation
The `mcp_tools_remote` submodule declares its HTTP endpoint route (`/_mcp_tools`) with `_access: 'TRUE'` in `mcp_tools_remote.routing.yml:7`. This bypasses Drupal's entire route access system, leaving authentication and authorization entirely to the controller's `handle()` method.
While the controller does perform API key validation and security checks (IP allowlist, origin validation, etc.), this pattern is fragile:
if a bug, early return, or exception occurs in the controller before the auth checks at lines 85-101, the endpoint is completely open with no safety net.
route-level access subscribers, event listeners, and debugging tools (e.g. `devel` route info) all report this route as "open to everyone", which is misleading.
Drupal's routing access system exists specifically to prevent this class of bugs. Custom access checkers are the documented pattern for non-standard authentication (see [Drupal Access Checking documentation](https://www.drupal.org/docs/drupal-apis/routing-system/access-checking-o...)).
Steps to reproduce
1. Install `mcp_tools` with the `mcp_tools_remote` submodule enabled.
2. Inspect `modules/mcp_tools_remote/mcp_tools_remote.routing.yml`.
3. Observe `_access: 'TRUE'` on the `mcp_tools_remote.handle` route.
4. Use `drush route:list --path=/_mcp_tools` or Devel route info — the route shows as requiring no access control.
Proposed resolution
Replace `_access: 'TRUE'` with a custom route access checker that gates requests at the routing layer before the controller is invoked.
The access checker (`McpRemoteAccessCheck`) performs two lightweight gate checks:
denies access if `mcp_tools_remote.settings:enabled` is `FALSE`.
denies access if no `Authorization: Bearer ...` or `X-MCP-Api-Key` header is present. This is a **presence check only** — the controller continues to perform full key validation, scope resolution, IP allowlist, origin check, and account switching as a second defense layer.
Remaining tasks
Changes
`src/Access/McpRemoteAccessCheck.php` — implements `Drupal\Core\Routing\Access\AccessInterface`.
`mcp_tools_remote.services.yml` — registers the access checker as a tagged service (`access_check`, `applies_to: _mcp_remote_access`).
`mcp_tools_remote.routing.yml` — replaces `_access: 'TRUE'` with `_mcp_remote_access: 'TRUE'`.
The controller's existing auth logic is **not removed** — it remains as the authoritative validation layer. The access checker is a lightweight first gate that ensures unauthenticated requests are rejected before the controller is even instantiated.
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| mcp_tools_remote-route-access-checker.patch | 4.39 KB | julien |
Issue fork mcp_tools-3587523
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
jaydub commentedComment #4
mowens commentedfixed thank you for your work on this.