NAME

MCP::Primitive - Primitive base class

SYNOPSIS

package MyMCPPrimitive;
use Mojo::Base 'MCP::Primitive';

1;

DESCRIPTION

MCP::Primitive is a base class for MCP (Model Context Protocol) primitives such as MCP::Tool, MCP::Prompt, and MCP::Resource.

ATTRIBUTES

MCP::Primitive implements the following attributes.

cache_scope

my $scope  = $primitive->cache_scope;
$primitive = $primitive->cache_scope('private');

Cache scope advertised for results derived from this primitive, either public for results shared by every caller, or private for results a gateway may only cache per caller. Defaults to public, and is forced to private whenever "scopes" is not empty.

cache_ttl

my $ttl    = $primitive->cache_ttl;
$primitive = $primitive->cache_ttl(60_000);

How long results derived from this primitive may be cached, in milliseconds. Defaults to 0, which means results must be revalidated on every request.

scopes

my $scopes = $primitive->scopes;
$primitive = $primitive->scopes(['mcp:read', 'mcp:write']);

OAuth scopes required to list or call this primitive, as an array reference; all of them must be granted. This is a local authorization policy layered on the HTTP transport's "auth" in MCP::Server::Transport::HTTP hook, not wire-level MCP metadata, and is only enforced for requests that supply scopes (so it has no effect over stdio). Defaults to no required scopes.

METHODS

MCP::Primitive inherits all methods from Mojo::Base and implements the following new ones.

context

my $context = $primitive->context;

Returns the MCP::Server::Context for the current request. Capture this before an async boundary to keep using its notification methods from later callbacks.

# Get controller for requests using the HTTP transport
my $c = $primitive->context->controller;

input_required

my $result = $primitive->input_required($input_requests);
my $result = $primitive->input_required($input_requests, $state);
my $result = $primitive->input_required(undef, $state);

Returns an input_required result, asking the client to gather information and call again. At least one of the two arguments is required.

return $tool->input_required({
  confirm => {
    method => 'elicitation/create',
    params => {
      message         => 'Really deploy to production?',
      requestedSchema => {type => 'object', properties => {ok => {type => 'boolean'}}}
    }
  }
}, {target => $args->{target}});

Input requests are keyed by names of your choosing, which the client mirrors back in "input_responses" in MCP::Server::Context. Only ask for capabilities the client declared in "client_capabilities" in MCP::Server::Context.

The optional state is any Perl data structure, and is sealed with "seal_state" in MCP::Server::Context before it travels through the client, so a retry can pick up where the first call left off without the server having to remember anything. Read it back with "request_state" in MCP::Server::Context, which returns undef for state that cannot be trusted; treat that like a first call and ask again.

SEE ALSO

MCP, https://mojolicious.org, https://modelcontextprotocol.io.