Class McpToolGrantService

java.lang.Object
io.meeds.mcp.server.service.McpToolGrantService

@Service public class McpToolGrantService extends Object
Decides whether a standing approval covers an approval-gated tool call, and turns an "Always allow" answer into a grant. The decision is taken here, on the MCP server, for every caller; the grants themselves are kept by an McpToolGrantProvider another add-on contributes, and argument limits are evaluated by the tool's own McpToolGrantConstraintEvaluator.

Every provider answer is checked again here, so the provider can never widen a decision: owner, tool, expiry (strictly before), agent, interactivity and constraint. A grant is interactive-only unless it is explicitly unattended: it then covers a call only when the call comes from a chat conversation, so a grant chosen while the user watched never authorizes a run without them. No grant applies to a call of a retried answer: a retry repeats a question the user already saw answered, and its writes ask again.

  • Field Details

    • CARD_GRANT_DAYS

      public static final Set<Integer> CARD_GRANT_DAYS
      The validities, in days, an approval card may offer.
  • Constructor Details

    • McpToolGrantService

      public McpToolGrantService()
  • Method Details

    • getMaxDays

      public int getMaxDays()
      Returns:
      the longest validity, in days, of a user's standing approval: the card offers only the durations within it
    • isGrantStoreAvailable

      public boolean isGrantStoreAvailable()
      Returns:
      true when an add-on installed exactly one grant store; with none (or an ambiguous configuration) no grant ever applies
    • findApplicableGrant

      public McpToolGrant findApplicableGrant(McpToolGrantRequest request, Map<String,Object> arguments)
      Finds the standing approval that covers a call, the user's own grants first, then the platform policies.
      Parameters:
      request - the call as the server resolved it
      arguments - the call arguments as the tool receives them
      Returns:
      the grant to apply, or null when the call must be approved on a card
    • recordUse

      public void recordUse(McpToolGrant grant, McpToolGrantRequest request)
      Records one use of a grant in its store. A failure is logged and ignored: the run is traced and logged by the caller whatever the counter says.
      Parameters:
      grant - the grant that applied
      request - the call it applied to
    • allowsStandingApproval

      public boolean allowsStandingApproval(String toolName, Map<String,Object> arguments)
      Tells whether the tool lets a standing approval cover this call at all, from its own evaluators; a tool without evaluator always does, and every evaluator of the tool must agree: one refusing or failing is a veto.
      Parameters:
      toolName - the MCP tool name
      arguments - the call arguments as the tool receives them
      Returns:
      true when a standing approval may cover the call
    • proposeConstraint

      public McpToolGrantConstraint proposeConstraint(String toolName, Map<String,Object> arguments)
      Derives the argument limit an approval card may offer, from the tool's own evaluator. A tool claimed by several evaluators is offered none, since no single one can state a limit the others would accept.
      Parameters:
      toolName - the MCP tool name
      arguments - the call arguments as the tool receives them
      Returns:
      the constraint, or null when the tool has no evaluator or several, or the call offers none
    • parseChoice

      public McpToolGrantChoice parseChoice(String scope, String days, String constrained)
      Reads the "Always allow" part of an approval answer. Each value must be one the card offers; anything else makes the whole choice invalid.
      Parameters:
      scope - AGENT or TOOL
      days - one of CARD_GRANT_DAYS
      constrained - CONSTRAINED or ANY
      Returns:
      the choice, or null when a value is not one the card offers
    • createGrant

      public McpToolGrant createGrant(McpToolGrantRequest request, McpToolGrantChoice choice, McpToolGrantConstraint offeredConstraint)
      Builds and stores the grant the user chose on a card. Every field comes from the pending call and the offered constraint; the choice only selects among them. A card grant is always a user grant and never unattended.
      Parameters:
      request - the pending call the card was shown for
      choice - the checked choice
      offeredConstraint - the constraint the card offered, may be null
      Returns:
      the stored grant
      Throws:
      IllegalArgumentException - when the choice doesn't fit the call (an agent scope without a known agent, a constrained grant with no offered constraint)
      IllegalStateException - when no grant store is installed