feat: hide tool list and instructions from users without LIT MCP access

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
2026-09-26 03:13:05 +02:00
co-authored by Claude Opus 5.5
parent 2f8a9f0c61
commit 2674bf2ed1
4 changed files with 150 additions and 0 deletions
@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Server;
use Brain\Monkey\Functions;
use LIT\MCP\Server\VisibilityFilter;
use LIT\MCP\Tests\Unit\TestCase;
use Mockery;
use WP\MCP\Core\McpServer;
use WP\McpSchema\Common\Protocol\DTO\InitializeResult;
final class VisibilityFilterTest extends TestCase
{
private function server(string $id): McpServer
{
$server = Mockery::mock(McpServer::class);
$server->allows('get_server_id')->andReturn($id);
return $server;
}
private function initializeResult(): InitializeResult
{
return InitializeResult::fromArray([
'protocolVersion' => '2025-11-25',
'capabilities' => ['tools' => ['listChanged' => false]],
'serverInfo' => ['name' => 'LIT MCP', 'version' => '0.2.0'],
'instructions' => 'Inhaltstypen: page, post, geheim',
]);
}
public function testUsersWithoutAccessSeeNoToolsOnOurServer(): void
{
Functions\when('current_user_can')->justReturn(false);
$filter = new VisibilityFilter();
self::assertSame([], $filter->filterTools(['tool-a'], $this->server('mcp-oauth-server')));
self::assertSame(['tool-a'], $filter->filterTools(['tool-a'], $this->server('other-server')));
}
public function testAllowedUsersKeepTheToolList(): void
{
Functions\when('current_user_can')->justReturn(true);
self::assertSame(['tool-a'], (new VisibilityFilter())->filterTools(['tool-a'], $this->server('mcp-oauth-server')));
}
public function testInstructionsAreReplacedForUsersWithoutAccess(): void
{
Functions\when('current_user_can')->justReturn(false);
$result = (new VisibilityFilter())->filterInitialize($this->initializeResult(), $this->server('mcp-oauth-server'));
self::assertInstanceOf(InitializeResult::class, $result);
self::assertSame(VisibilityFilter::NO_ACCESS_INSTRUCTIONS, $result->getInstructions());
self::assertSame('2025-11-25', $result->getProtocolVersion());
}
public function testInstructionsStayForAllowedUsersAndOtherServers(): void
{
Functions\when('current_user_can')->justReturn(true);
$original = $this->initializeResult();
self::assertSame($original, (new VisibilityFilter())->filterInitialize($original, $this->server('mcp-oauth-server')));
Functions\when('current_user_can')->justReturn(false);
self::assertSame($original, (new VisibilityFilter())->filterInitialize($original, $this->server('other-server')));
}
public function testRegisterHooksBothFilters(): void
{
$filter = new VisibilityFilter();
Functions\expect('add_filter')->once()->with('mcp_adapter_tools_list', [$filter, 'filterTools'], 10, 2);
Functions\expect('add_filter')->once()->with('mcp_adapter_initialize_response', [$filter, 'filterInitialize'], 10, 2);
$filter->register();
}
}