NAME
App::MCP::CLI::Client - Transport-neutral MCP client used by all mcpcli sub-commands
VERSION
This module is distributed as part of App::MCP::CLI v0.0.1.
SYNOPSIS
use App::MCP::CLI::Client;
use App::MCP::CLI::Config qw(load_config resolve_server_cmd);
my ($cmd, $url, $env) = resolve_server_cmd(load_config(), 'my-server');
my $client = App::MCP::CLI::Client->new(
cmd => $cmd, # stdio transport, or
url => $url, # HTTP/SSE transport
env => $env,
timeout => 30,
);
$client->connect; # initialize + notifications/initialized
my $tools = $client->list_tools; # arrayref of tool descriptors
my $res = $client->call_tool('add_numbers', { a => 1, b => 2 });
print content_text($res->{result}) if $res->{result};
$client->close;
DESCRIPTION
App::MCP::CLI::Client hides the differences between the two transports supported by mcpcli behind one small API, so every sub-command gets the same behaviour:
Every wait for the server is bounded by a timeout (default 30 seconds).
If a stdio server exits unexpectedly, or an SSE stream is closed, a clear error is raised instead of a JSON parse failure.
Responses are matched to requests by
id. Notifications and log lines sent by the server in between are skipped, and server-initiatedpingrequests are answered.The
initializerequest is followed by thenotifications/initializednotification, as required by the2024-11-05lifecycle.
stdio: the server is started with IPC::Open2; messages are newline-delimited JSON.
HTTP/SSE (protocol revision 2024-11-05): a long-lived GET opens the event stream, the endpoint event announces where to POST, and each response is accepted either in the POST reply body or as a message event on the stream. https:// URLs need IO::Socket::SSL.
All errors are raised with die and a message ending in a newline.
METHODS
new( %args )
Arguments: cmd (arrayref) or url (string); optional env (hashref applied only to the spawned process), timeout (seconds, 0 disables), headers (hashref, SSE only) and client_name.
Set the environment variable MCPCLI_DEBUG to see every JSON-RPC message on STDERR.
is_sse
True when the client talks HTTP/SSE.
server_info
The serverInfo hashref reported by the server (after "connect").
connect
Starts the transport and performs the MCP handshake. Returns the client.
request( $method [, $params] )
Sends a JSON-RPC request and returns the full response hashref (which has either a result or an error key). Dies on timeout or transport failure.
notify( $method [, $params] )
Sends a JSON-RPC notification (no response is expected).
list_tools
Returns an arrayref of every tool the server advertises, following nextCursor pagination. Dies if the server answers with an error.
call_tool( $name, \%arguments )
Sends tools/call and returns the full response hashref.
content_text( $result )
Exported on request. Renders the content blocks of a tools/call result as text: text blocks are returned verbatim, other block types (image, audio, resources) become a short placeholder so that nothing is silently dropped. Falls back to pretty-printed structuredContent when there is no content.
close
Shuts the connection down. For stdio servers, stdin is closed first; a server that has not exited after two seconds is sent SIGTERM, then SIGKILL. Safe to call more than once.
SEE ALSO
AUTHOR
Mohammad Sajid Anwar, <mohammad.anwar at yahoo.com>
REPOSITORY
https://github.com/manwar/App-MCP-CLI
BUGS
Please report any bugs or feature requests through the web interface at https://github.com/manwar/App-MCP-CLI/issues.
LICENSE AND COPYRIGHT
Copyright (C) 2026 Mohammad Sajid Anwar.
This program is free software; you can redistribute it and / or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at: