1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Client\Exception;
15:
16: use Nexus\Mcp\Core\Exception\McpExceptionInterface;
17: use Nexus\Mcp\Core\SafeDisplay;
18:
19: /**
20: * Thrown when an MCP server answers that the token's scopes are insufficient and no scope upgrade is available.
21: *
22: * @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
23: */
24: final class InsufficientScopeException extends \RuntimeException implements McpExceptionInterface
25: {
26: /**
27: * @param list<non-empty-string> $required Scopes the challenge named that this client can use
28: * @param bool $named Whether the challenge named a scope at all
29: */
30: public function __construct(
31: public readonly array $required,
32: bool $named = false,
33: ) {
34: parent::__construct(match (true) {
35: [] !== $required => \sprintf('The MCP server requires the scope "%s".', SafeDisplay::sanitiseCause(implode(' ', $required))),
36: $named => 'The MCP server named only scopes that are not RFC 6749 scope-tokens, so none can be requested.',
37: default => 'The MCP server answered insufficient_scope without naming a scope.',
38: });
39: }
40: }
41: