From de5fc229d5e534a3dce9f1ed24340ff078eb57ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20Falco=CC=81n?= Date: Fri, 17 Jul 2026 15:35:13 +0200 Subject: [PATCH] test(mcp): cover the HTTP endpoint auth boundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assert POST /mcp rejects requests without a token (401), rejects tokens lacking the mcp:read ability (403, enforcing MCP-only tokens), and accepts a valid mcp:read token (200) — the auth/abilities layer the tool-helper tests bypass. --- tests/Feature/Mcp/McpEndpointAuthTest.php | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/Feature/Mcp/McpEndpointAuthTest.php diff --git a/tests/Feature/Mcp/McpEndpointAuthTest.php b/tests/Feature/Mcp/McpEndpointAuthTest.php new file mode 100644 index 00000000..89986465 --- /dev/null +++ b/tests/Feature/Mcp/McpEndpointAuthTest.php @@ -0,0 +1,32 @@ + '2.0', 'id' => 1, 'method' => 'tools/list']; + +it('rejects the MCP endpoint without a token', function () use ($rpc) { + postJson('/mcp', $rpc)->assertUnauthorized(); +}); + +it('rejects a token without the mcp:read ability', function () use ($rpc) { + $user = User::factory()->create(); + $plain = $user->createToken('not-mcp', ['other'])->plainTextToken; + + withHeaders(['Authorization' => "Bearer {$plain}"]) + ->postJson('/mcp', $rpc) + ->assertForbidden(); +}); + +it('accepts a token carrying the mcp:read ability', function () use ($rpc) { + $user = User::factory()->create(); + $plain = $user->createToken('mcp', ['mcp:read'])->plainTextToken; + + // Auth + ability middleware pass, so the request reaches the MCP transport + // (which answers the JSON-RPC envelope) rather than being rejected. + withHeaders(['Authorization' => "Bearer {$plain}"]) + ->postJson('/mcp', $rpc) + ->assertOk(); +});