MCP::Client(3)

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

πŸ’– MCP::Client(3) β€” the perl doc you actually wanna read πŸŽ€

okay so real quick, this is from the User Contributed Perl Documentation section, and bestie, it's literally the whole vibe of talking to MCP servers over HTTP. let's get into it ✨


🌸 NAME 🌸

MCP::Client β€” it's an MCP client, no cap πŸ’…


⭐ SYNOPSIS ⭐

look, here's the whole thing, copy-paste ready:

use MCP::Client;

my $client = MCP::Client->new(url => 'http://localhost:3000/mcp');
my $tools  = $client->list_tools;

that's it. that's the flex 🫢


πŸ¦‹ DESCRIPTION πŸ¦‹

so MCP::Client is a client for MCP (Model Context Protocol), and it talks to MCP servers over HTTP. 🌈

here's the thing though β€” and I need you to hear me on this β€” it is exactly conformant on the wire. like, it sends the _meta fields and the routing headers that every single request has to carry, and it is deliberately nothing more than that. that's the whole personality. πŸ’€

so what's not in here? TTL caching? nope, that's yours. retry loops for input requests? also yours. the OAuth authorization flow? yeah, you're handling that too. all of it is left to the application, which honestly makes this a great client to test a server with πŸ‘‘ β€” it's a starting point, not a finished agent. main character energy, but like, the beginning of the arc. 🧚


πŸ”₯ EVENTS πŸ”₯

MCP::Client inherits all events from Mojo::EventEmitter, and then emits these new ones on top:

πŸ’œ notification

$client->on(notification => sub ($client, $notification) { ... });

this one fires for every JSON-RPC notification the server sends on the response stream of a request β€” think a progress report for a long running tool call. obsessed. πŸ“


✨ ATTRIBUTES ✨

inherits all attributes from Mojo::EventEmitter and implements these new ones:

🌸 capabilities

my $capabilities = $client->capabilities;
$client          = $client->capabilities({elicitation => {}});

the capabilities you declare with every request. defaults to an empty hash reference. πŸŽ€

πŸ¦‹ headers

my $headers = $client->headers;
$client     = $client->headers({Authorization => 'Bearer abc123'});

extra HTTP headers to send with every request, as a hash reference. super useful for passing an Authorization header to an MCP server that requires OAuth bearer authentication. defaults to an empty hash reference. πŸ”‘

⭐ name

my $name = $client->name;
$client  = $client->name('PerlClient');

the name of the client. defaults to PerlClient. πŸ’…

🌈 protocol_version

my $version = $client->protocol_version;
$client     = $client->protocol_version('2026-07-28');

the protocol version to make requests with β€” defaults to PROTOCOL_VERSION in MCP::Constants. and here's the cute part: if a server rejects it with an UnsupportedProtocolVersionError, it gets one more chance with the newest version both sides support, and that version gets remembered for subsequent requests. iconique recovery behavior. 🫢

🧚 ua

my $ua  = $client->ua;
$client = $client->ua(Mojo::UserAgent->new);

the user agent used for making HTTP requests. defaults to a new instance of Mojo::UserAgent. 😌

πŸŽ€ url

my $url  = $client->url;
$client  = $client->url('http://localhost:3000/mcp');

the URL of the MCP server. defaults to http://localhost:3000/mcp. 🏠

πŸ’– version

my $version = $client->version;
$client     = $client->version('1.0.0');

the version of the client. defaults to 1.0.0. ✨


πŸ‘‘ METHODS πŸ‘‘

inherits all methods from Mojo::EventEmitter plus these new ones:

πŸ“ build_notification

my $notification = $client->build_notification('method_name', {param1 => 'value1'});

builds a JSON-RPC notification with the given method name and parameters. πŸ“¨

πŸ¦‹ build_request

my $request = $client->build_request('method_name', {param1 => 'value1'});

builds a JSON-RPC request with the given method name and parameters β€” and it adds the _meta fields that every request has to carry. don't forget those, they're mandatory fr fr. πŸ’―

πŸ”₯ call_tool

my $result = $client->call_tool('tool_name');
my $result = $client->call_tool('tool_name', {arg1 => 'value1'});
my $result = $client->call_tool('tool_name', {arg1 => 'value1'}, {request_state => $state});

calls a tool on the MCP server with the specified name and arguments, and returns the result. πŸ› οΈ

heads up bestie: a result with resultType set to input_required gets returned as-is. gathering the requested input and deciding whether to call again? that's on you, babe. 😭

these options are currently available:

  • input_responses β€” responses to the input requests of an earlier input_required result, keyed by the same names. looks like this:
input_responses => {confirm => {action => 'accept', content => {ok => \1}}}
  • request_state β€” the requestState of an earlier input_required result, passed back verbatim. like this:
request_state => 'eyJ...'

πŸ’œ discover

my $result = $client->discover;

discovers the protocol versions, capabilities, and instructions of the MCP server. πŸ”

🌸 get_prompt

my $result = $client->get_prompt('prompt_name');
my $result = $client->get_prompt('prompt_name', {arg1 => 'value1'});
my $result = $client->get_prompt('prompt_name', {arg1 => 'value1'}, {request_state => $state});

gets a prompt from the MCP server with the specified name and arguments, returning the result. takes the same options as call_tool. πŸ“

⭐ list_prompts

my $prompts = $client->list_prompts;

lists all available prompts on the MCP server. πŸ—‚οΈ

🌈 list_resources

my $resources = $client->list_resources;

lists all available resources on the MCP server. πŸ“š

🧚 list_tools

my $tools = $client->list_tools;

lists all available tools on the MCP server. 🧰

πŸŽ€ listen

my $bool = $client->listen({toolsListChanged => \1}, sub ($message) {...});

opens a subscriptions/listen stream for the requested notification types and blocks, invoking the callback for every message the server sends β€” starting with the acknowledgement. returning a false value from the callback closes the stream. πŸ‘‹

only servers configured with streaming => 1 support this. don't come for me if your server doesn't have it. πŸ™ˆ

πŸ’– read_resource

my $result = $client->read_resource('file:///path/to/resource.txt');
my $result = $client->read_resource('file:///path/to/resource.txt', {request_state => $state});

reads a resource from the MCP server with the specified URI, returning the result. takes the same options as call_tool. πŸ“–

πŸ¦‹ send_request

my $response = $client->send_request($request);

sends a JSON-RPC request to the MCP server and returns the response β€” or undef if the server accepted it without one. simple as that. ✈️


🫢 SEE ALSO 🫢

go read those, iykyk πŸ’…


and that's the whole page bestie!! this one's brought to you by perl v5.42.0, dated 2026-07-31 β€” go forth and MCP responsibly πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from