Skip to content

2.x: rebuild on mcp/sdk and OAuth 2.1 support - #1

Draft
ajibarra wants to merge 49 commits into
2.next-cake5from
feature/2.1-oauth
Draft

ajibarra wants to merge 49 commits into
2.next-cake5from
feature/2.1-oauth

Conversation

@ajibarra

Copy link
Copy Markdown
Member

2.x of the plugin for CakePHP 5, built on the official mcp/sdk (^0.9). This branch carries two milestones:

2.0: rewrite on mcp/sdk

  • Streamable HTTP endpoint at a Cake route and bin/cake mcp server over stdio.
  • Tools, resources and prompts discovered from src/Mcp (#[McpTool], #[McpResource], ...), plus the Mcp.server.configure builder hook.
  • Authentication delegated to the host's cakephp/authentication identity, with an injectable CurrentIdentity.
  • Per-tool authorization through ToolAuthorizerInterface, with RbacToolAuthorizer on cakedc/auth.
  • ToolError::invalid(), McpTestTrait for in-memory tool tests, and bin/cake mcp inspector.
  • Checked against the official MCP conformance suite, behind nginx and php-fpm (tests/Conformance/run.sh, also in CI).

2.1: OAuth 2.1 for remote clients (claude.ai and others)

  • Mcp.auth modes: host (default, as 2.0), oauth (tokens of cakedc/cakephp-oauth-server in the same app) and external (JWT from any OpenID Connect issuer).
  • RFC 9728 protected resource metadata, the 401 challenge, a per-tool scope policy with implies, and step-up via 403 insufficient_scope.
  • McpConfig::isEndpoint() for the CSRF skip, bin/cake mcp check, and scope support in McpTestTrait.

The changes are listed in CHANGELOG.md (2.0.0-beta1 and 2.1.0-beta1), with the docs under docs/.

Status

  • 259 tests, coding standard and PHPStan level 8 pass locally. CI runs the suite, the conformance job and static analysis.
  • In use on the KVERGE staging site behind nginx and Cloudflare: claude.ai connects through OAuth (CIMD), and editors manage content and media through it.
  • mcp/sdk is now the released ^0.9, no longer a pinned commit.

Notes for review

  • This is large: 47 commits over the initial commit of 2.next-cake5. If it is easier to review in parts, it can be split by commit range: up to the 2.0 rewrite, then OAuth.
  • Tagging 2.0.0-beta1 / 2.1.0-beta1 is left for after the merge.

Reject null, false and scalar identities from Mcp.auth.identity, expand
oauth test scopes with the declared resource's implies, add
McpConfig::rbacPermissions(), make mcp check read the cakedc/users
authenticators and guard the oauth plugin class.

@steinkel steinkel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of the 2.x rewrite: no blocking issues in the security path I read (auth fails closed, check ordering is sound). Two non-blocking comments inline.

$maxBodyBytes,
);
$response = $factory->create()->run($transport);
} catch (Throwable $exception) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 [3] Configuration errors are reported as a generic 500.

This catch (Throwable) also swallows the exceptions AuthSettings throws on invalid Mcp.auth settings (the fail-closed path). Clients only see Internal error, and the cause is visible only if the McpLogger::SCOPE log scope is configured.

Suggestion: catch InvalidArgumentException / LogicException from the auth settings separately, log them at critical, and point to bin/cake mcp check in the message, so a misconfigured production endpoint is easy to diagnose.

*
* @implements \Mcp\Server\Handler\Request\RequestHandlerInterface<mixed>
*/
final class ToolCallGuard implements RequestHandlerInterface

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 [5] Resources and prompts have no per-item authorization.

ToolCallGuard and ToolListFilter only cover tools/call and tools/list. docs/authorization.md states this, but it is security-relevant: anyone exposing resources next to RBAC-gated tools may assume they are protected too, and any identified caller can read every resource and prompt.

Suggestion: mention it in the README, and have bin/cake mcp check warn when an authorizer other than allow-all is configured and resources or prompts are discovered. Longer term, consider an equivalent guard for resources/read and prompts/get.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants