Build Model Context Protocol servers in Perl
MCP server SDK for Perl, built on Mojolicious, with tool calling, prompts, resources, and HTTP or Stdio transports.
0.15Add to Favorites
Why it matters
Enable Perl developers to create MCP-compliant servers that expose tools, prompts, and resources to AI models through HTTP or stdio transports, with full support for notifications, progress tracking, and JSON Schema validation.
Outcomes
What it gets done
Define tools with JSON Schema validation and expose them via HTTP or stdio
Send progress notifications and logs on response streams during tool execution
Embed MCP endpoints into existing Mojolicious web applications with routing
Handle multi-round tool requests with integrity-protected state management
Source
Get it from source
Spark does not host a copy of it.
Open sourceReports
Agent outcome reports
No reports yet
Overview
Perl SDK
MCP Perl SDK brings Model Context Protocol support to Perl on the Mojolicious framework, supporting tool calling, prompts, and resources over Streamable HTTP and Stdio transports with JSON Schema-validated arguments and OAuth scopes per tool. Use it to build an MCP server in Perl, especially on Mojolicious. It is early-stage software with several planned features (pagination, resource templates, subscriptions) not yet implemented.
What it does
MCP Perl SDK (mojo-mcp) brings Model Context Protocol support to Perl, built on the Mojolicious real-time web framework. It implements protocol revision 2026-07-28 and covers tool calling, prompts, and resources over both Streamable HTTP and Stdio transports, as a stateless protocol with no handshake or session to keep alive.
When to use - and when NOT to
Use it when you're building an MCP server in Perl, especially if you already run (or want to run) it on Mojolicious - the to_action method mounts an MCP endpoint onto any Mojolicious route, reusing the app's own authentication. It's explicitly early-stage: the module and the MCP spec itself are both changing rapidly, and breaking changes are called out as likely. Several features aren't implemented yet - pagination, resource templates, completion, tasks, MCP Apps, and resource subscriptions - and the roots, sampling, and logging client features are deprecated in this protocol revision and not implemented at all.
Capabilities
- Tool calling, prompts, and resources, over Streamable HTTP or Stdio transport.
- Stateless protocol (no handshake, no session) with routing-header validation so gateways and servers can't disagree about what was called.
- JSON Schema 2020-12 validation of tool arguments.
- Progress and log notifications delivered on the response stream of the request they belong to, upgrading a plain JSON response to SSE only when there's something to send.
- Cancellation as a first-class signal, so long-running tools can stop early; multi-round tool requests with integrity-protected request state.
- Cache hints for discovery/list/read results, and list-changed notifications for tools, prompts, and resources (opt-in via a
streamingflag, since it requires per-process state incompatible with pre-forking servers). - OAuth scopes enforceable per tool, prompt, and resource; new OAuth clients should use client ID metadata documents rather than dynamic client registration, which is deprecated.
- Scales with a pre-forking web server and async tools using promises; includes an HTTP client for testing and can be embedded directly in Mojolicious web apps.
How to install
Requires Perl 5.20 or newer, installed from CPAN:
cpanm -n MCP
A Perlbrew environment is recommended. From there, the module's own tutorial builds a real server one feature at a time. A minimal Streamable HTTP server registers a tool with MCP::Server->new and mounts it with any '/mcp' => $server->to_action; inside a Mojolicious::Lite app; a Stdio version uses $server->to_stdio instead for local command-line testing.
Who it's for
Perl developers, especially those already using Mojolicious, who want to expose tools, prompts, and resources to MCP clients without adopting a different language's SDK.
Source README
MCP Perl SDK
Model Context Protocol support for Perl and the
Mojolicious real-time web framework.
Features
Please be aware that this module is still in development and will be changing rapidly. Additionally the MCP
specification is getting regular updates which we will implement. Breaking changes are very likely. The protocol
revision currently implemented is 2026-07-28.
- Tool calling, prompts and resources
- Streamable HTTP and Stdio transports
- Stateless protocol, with no handshake and no session to keep alive
- Routing header validation, so gateways and servers can never disagree about what was called
- JSON Schema 2020-12 validation of tool arguments
- Progress and log notifications on the response stream of the request they belong to
- Cancellation as a first-class signal, so long-running tools can stop early
- Multi-round tool requests with integrity-protected request state
- Cache hints for discovery, list and read results
- Notifications for list changes (tools, prompts, resources)
- OAuth scopes for tools, prompts and resources
- Scalable with pre-forking web server and async tools using promises
- HTTP client for testing
- Can be embedded in Mojolicious web apps
Not supported yet: pagination, resource templates, completion, tasks, MCP Apps, and resource subscriptions. The
roots, sampling and logging client features are deprecated in this revision and are not implemented. New OAuth
clients should use client ID metadata documents, since dynamic client registration is deprecated as well.
Installation
All you need is Perl 5.20 or newer. Just install from CPAN.
$ cpanm -n MCP
We recommend the use of a Perlbrew environment.
Then follow the tutorial, which builds a real server one feature at a
time.
Streamable HTTP Transport
Use the to_action method to add an MCP endpoint to any Mojolicious application.
use Mojolicious::Lite -signatures;
use MCP::Server;
my $server = MCP::Server->new;
$server->tool(
name => 'echo',
description => 'Echo the input text',
input_schema => {type => 'object', properties => {msg => {type => 'string'}}, required => ['msg']},
code => sub ($tool, $args) {
return "Echo: $args->{msg}";
}
);
any '/mcp' => $server->to_action;
app->start;
Authentication can be added by the web application, just like for any other route. OAuth scopes can be enforced per
tool, prompt and resource.
Notifications
Notifications that belong to a request, such as progress reports, are delivered on the response stream of that very
request, which is upgraded from a plain JSON response to SSE whenever there is something to deliver. No extra
configuration is required, and it works under a pre-forking web server.
use Mojolicious::Lite -signatures;
use MCP::Server;
my $server = MCP::Server->new;
$server->tool(
name => 'echo',
description => 'Echo the input text',
input_schema => {type => 'object', properties => {msg => {type => 'string'}}, required => ['msg']},
code => sub ($tool, $args) {
$tool->context->notify_progress(1, 2, "Echoing: $args->{msg}");
return "Echo: $args->{msg}";
}
);
any '/mcp' => $server->to_action;
app->start;
Notifications that do not belong to a request, such as list_changed, need a long-lived stream, which clients open
with a subscriptions/listen request. That does require per-process state and is not compatible with pre-forking
web servers, so it is opt-in with streaming.
any '/mcp' => $server->to_action({streaming => 1});
Stdio Transport
Build local command line applications and use the stdio transport for testing with the to_stdio method.
use Mojo::Base -strict, -signatures;
use MCP::Server;
my $server = MCP::Server->new;
$server->tool(
name => 'echo',
description => 'Echo the input text',
input_schema => {type => 'object', properties => {msg => {type => 'string'}}, required => ['msg']},
code => sub ($tool, $args) {
return "Echo: $args->{msg}";
}
);
$server->to_stdio;
Just run the script and type requests on the command line. Every request has to declare the protocol version it is
made with and the capabilities of the client making it.
$ perl examples/echo_stdio.pl
{"jsonrpc":"2.0","id":"1","method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}
{"jsonrpc":"2.0","id":"2","method":"tools/call","params":{"name":"echo","arguments":{"msg":"hello perl"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.