MCP::Tool(3)

πŸ“¦
version 0.150.0 Β· 2 versions
, in opensuse-leap 16.0

πŸ’– MCP::Tool β€” the tool container, bestie edition ✨

okay so this is MCP::Tool(3) from the User Contributed Perl Documentation section, and it's literally the little box where your tools live. buckle up πŸŽ€

✨ NAME ✨

MCP::Tool β€” tool container, no cap 🧰

🌸 SYNOPSIS 🌸

use MCP::Tool;

my $tool = MCP::Tool->new;

that's it. that's the whole vibe check. two lines and you're a main character πŸ’…

πŸ¦‹ DESCRIPTION πŸ¦‹

MCP::Tool is a container for tools to be called. and like, it does NOT play around with validation β€” arguments and structured content get checked with JSON::Schema::Tiny, which covers JSON Schema 2020-12, 2019-09, and draft-07. slay. but heads up bestie πŸ™ˆ: it only partially implements $id, $dynamicRef, and $dynamicAnchor. so don't come for it about those, it's doing its best.

πŸ‘‘ ATTRIBUTES πŸ‘‘

MCP::Tool implements the following attributes, and yes you can read AND write them. flexible icon behaviour ✨

πŸ“ annotations

my $annotations = $tool->annotations;
$tool           = $tool->annotations({title => '...'});

Optional annotations for the tool, which provide additional metadata about the tool behavior. optional!! like a little accessory, not a requirement πŸ’…

🧚 code

my $code = $tool->code;
$tool    = $tool->code(sub { ... });

Tool code. this is the actual literal thing your tool does. the main character, truly. πŸ”₯

🌈 description

my $description = $tool->description;
$tool           = $tool->description('A brief description of the tool');

Description of the tool. keep it cute, keep it brief πŸ’–

⭐ input_schema

my $schema = $tool->input_schema;
$tool      = $tool->input_schema({type => 'object', properties => {foo => {type => 'string'}}});

JSON schema for validating input arguments, and omg the dialect rules, pay attention bestie πŸ“:

  • Schemas without a $schema keyword are interpreted as JSON Schema 2020-12, which is the default dialect of the Model Context Protocol.
  • Schemas with one are interpreted as the dialect it names, which has to be one of 2020-12, 2019-09, or draft-07.
  • Any other dialect is an error. straight up. πŸ’€

Properties may carry an x-mcp-header keyword, naming the HTTP header a client has to mirror the argument in, for the benefit of gateways that route on headers alone. and there's a whole method for that, see header_params below 🫢

πŸ”₯ max_schema_depth

my $depth = $tool->max_schema_depth;
$tool     = $tool->max_schema_depth(10);

How many levels deep validation may descend into a schema before it's aborted β€” which bounds the work a deeply nested or recursive schema can cause. it's giving safety rails and honestly? we stan. defaults to 50 ✨

πŸ’œ name

my $name = $tool->name;
$tool    = $tool->name('my_tool');

Name of the tool. pick something iconic πŸŽ€

πŸŽ€ output_schema

my $schema = $tool->output_schema;
$tool      = $tool->output_schema({type => 'object', properties => {foo => {type => 'string'}}});

JSON schema for validating output results, interpreted with the same dialect rules as input_schema. same rules, different direction, iykyk 🌸


πŸ’… METHODS πŸ’…

MCP::Tool inherits all methods from MCP::Primitive and implements the following new ones. inherited + new = full stack of methods, periodt πŸ‘‘

🌸 audio_result

my $result = $tool->audio_result($bytes, $options, $is_error);

Returns an audio result in the expected format, optionally marking it as an error. πŸ”Š

These options are currently available:

  • mime_type β€” specifies the MIME type of the audio, defaults to audio/wav. example: mime_type => 'audio/wav'

πŸ¦‹ call

my $result = $tool->call($args, $context);

Calls the tool with the given arguments and context, returning a result. and here's the fun part: the result can be a promise or a direct value. either way, it's valid πŸ’–

⭐ header_params

my $params = $tool->header_params;

All properties of input_schema annotated with x-mcp-header, returned as an array reference of hash references with name, path and type keys. important detail bestie 🚨: only properties reachable from the schema root through a chain of properties keys are considered, since the protocol forbids x-mcp-header anywhere else. and the result is cached after the first call, so it's fast like that ✨

🧚 image_result

my $result = $tool->image_result($bytes, $options, $is_error);

Returns an image result in the expected format, optionally marking it as an error. πŸ–ΌοΈ

These options are currently available:

  • annotations β€” annotations for the image. example: annotations => {audience => ['user']}
  • mime_type β€” specifies the MIME type of the image, defaults to image/png. example: mime_type => 'image/png'
my $result = $tool->resource_link_result($uri, $options, $is_error);

Returns a resource link result in the expected format, optionally marking it as an error. πŸ”—

These options are currently available:

  • annotations β€” annotations for the resource link. example: annotations => {audience => ['user']}
  • description β€” description of the resource. example: description => 'A brief description of the resource'
  • mime_type β€” specifies the MIME type of the resource, defaults to text/plain. example: mime_type => 'text/x-perl'
  • name β€” name of the resource. example: name => 'Resource Name'
ok wait, real talk πŸ™ˆ β€” look at that mime_type one again. the example says text/x-perl but the default is text/plain. that's just how it is, don't @ me, i'm reporting the facts πŸ’…

🌈 structured_result

my $result = $tool->structured_result({foo => 'bar'}, $is_error);

Returns a structured result in the format of output_schema, optionally marking it as an error. and the plot twist 😭: data that does not match output_schema is turned into an error result instead. so it either slays or it fails, no in-between πŸ’€

πŸ’œ text_result

my $result = $tool->text_result('Some text', $is_error);

Returns a text result in the expected format, optionally marking it as an error. simple, clean, iconic ✨

πŸŽ€ validate_input

my $bool = $tool->validate_input($args);

Validates the input arguments against input_schema. and watch out, the boolean is backwards from what you'd expect 🚨: it returns true if validation failed. also, references are only resolved as JSON pointers into the schema itself, so a $ref to a remote schema is never fetched over the network and simply fails validation. no sneaky requests, we love a secure queen πŸ”₯

πŸ‘‘ validate_output

my $bool = $tool->validate_output($data);

Validates structured content against output_schema. returns true if validation failed, and false if the tool has no output schema. yes same backwards-energy as above, that's just the house style πŸ’…


🫢 SEE ALSO 🫢

go read those, they're literally so good πŸ’–


and that's the whole page bestie!! πŸŽ‰ this was MCP::Tool(3) from perl v5.42.0, dated 2026-07-31. mwah, go build something iconic πŸŒˆβœ¨πŸ¦‹

πŸ“¦ where this page comes from