feat: configurable exposure policy for direct, indirect and disabled tools

Introduces ExposurePolicy (option lit_mcp_exposure) deciding per ability
whether it is a direct MCP tool, only reachable via mcp-adapter's
execute-ability meta-tool, or disabled entirely (not registered with the
Abilities API at all). Ability::isDirect() remains the default when no
override applies. lit/guide can never be disabled or made indirect;
lit/media-preview and lit/media-download (image/embedded-resource results)
can never be made indirect, only direct or disabled.

AbilityRegistrar and ServerRegistrar take an optional ExposurePolicy and
use it to filter registered abilities / compute the direct tool list.
IntegrationRegistry::directAbilityNames() is removed (superseded by
ExposurePolicy::directNames()). InstructionsBuilder now also takes the
policy and lists the currently direct tools by name (lit-<name>), noting
the rest are reachable via mcp-adapter-execute-ability as lit/<name>.

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:04:14 +02:00
co-authored by Claude Opus 5.5
parent 7f136f6f4c
commit 2f8a9f0c61
11 changed files with 362 additions and 26 deletions
+7 -2
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LIT\MCP\Server;
use LIT\MCP\Abilities\ExposurePolicy;
use LIT\MCP\Guides\InstructionsBuilder;
use LIT\MCP\Integrations\IntegrationRegistry;
use LIT\MCP\Plugin;
@@ -48,13 +49,17 @@ final class ServerRegistrar
/** @var callable(string): bool */
private $classExists;
private ExposurePolicy $policy;
public function __construct(
private IntegrationRegistry $registry,
private InstructionsBuilder $instructions,
?callable $oauthEnabled = null,
?callable $createAdapterServer = null,
?callable $classExists = null
?callable $classExists = null,
?ExposurePolicy $policy = null
) {
$this->policy = $policy ?? new ExposurePolicy();
$this->oauthEnabled = $oauthEnabled
?? static fn (): bool => (new OAuthContext())->is_enabled();
$this->classExists = $classExists
@@ -102,7 +107,7 @@ final class ServerRegistrar
'name' => 'LIT MCP',
'description' => $this->instructions->build(),
'version' => Plugin::VERSION,
'tools' => array_merge($this->registry->directAbilityNames(), self::META_TOOLS),
'tools' => array_merge($this->policy->directNames($this->registry->abilities()), self::META_TOOLS),
];
}