NAME
Langertha::Raider::MCP::HTTP - Internal JSON-RPC over MCP's streamable HTTP transport
VERSION
version 0.504
SYNOPSIS
# Internal to Langertha-Raider -- no API promise.
my $wire = Langertha::Raider::MCP::HTTP->new(
loop => $loop,
url => 'https://mcp.example.com/mcp',
headers => { Authorization => 'Bearer ...' },
);
my $init = await $wire->request_f( 'initialize', { ... } );
$wire->protocol_version( $init->{protocolVersion} );
await $wire->notify_f( 'notifications/initialized' );
await $wire->stop_f;
DESCRIPTION
Internal module. Its interface may change without notice.
The streamable HTTP transport of MCP (revisions 2025-03-26 and later, ADR 0029 §10): every message is a POST of one JSON-RPC message to "url" with Accept: application/json, text/event-stream; the answer is either a JSON body or an event stream (text/event-stream) whose data: lines carry JSON-RPC messages until the response to the request arrives. The Mcp-Session-Id a server hands out with the initialize response is sent with every later request, and so is MCP-Protocol-Version once "protocol_version" is set. "stop_f" ends the session with a DELETE. Requests the server sends inside an event stream are answered with a POST (ping with an empty result, everything else "Method not found"); notifications are ignored. No standalone GET stream is opened.
Written for raider because the installed Net::Async::MCP::Transport::HTTP speaks only the 2026-07-28 revision: it never sends Mcp-Session-Id and always sends MCP-Protocol-Version: 2026-07-28, which servers of the earlier revisions refuse.
loop
The IO::Async::Loop. Required.
url
The endpoint. Required.
headers
Headers sent with every request (Authorization, ...). Default none.
protocol_version
The negotiated revision; once set, sent as MCP-Protocol-Version.
on_notification
sub { my ( $method, $params ) = @_; ... }, called for a notification in the event stream of a request's answer (there is no standalone stream). Optional.
session_id
The Mcp-Session-Id the server handed out, or undef.
start
Nothing to start: the first request connects. For the interface it shares with Langertha::Raider::MCP::Stdio.
stderr_tail
Empty: a remote server has no stderr here.
request_f
my $result = await $wire->request_f( $method, \%params );
Sends a request; done with its result, failed with MCP error CODE: MESSAGE (category mcp) for a JSON-RPC error, with HTTP STATUS ... for an HTTP error, or when the module a connection needs does not load (Langertha::Raider::ConnectCheck).
notify_f
await $wire->notify_f( 'notifications/initialized' );
Sends a notification; done whatever the server answers (202 is what it should).
notify
"notify_f" without waiting.
stop_f
Ends the session: cancels what is in flight, then a DELETE with the session id (when there is one; answer ignored, at most 2 seconds).
SEE ALSO
SUPPORT
Issues
Please report bugs and feature requests at https://github.com/Getty/langertha-raider/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.