Catalyst-Plugin-MCP

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

        protocol_versions => ['2025-06-18'],          # newest-first
        server_info       => { name => 'myapp', version => '1.0' },
    },
);
```

## Security

**This plugin ships no authentication and no `Origin` validation, and
`mcp_dispatch` does not add any.** A `tools/call` runs your provider's code, so
an endpoint mounted as in the synopsis above executes tools for anyone who can
POST to it. Guarding it is the application's job:

- **Authenticate the endpoint.** The MCP Streamable HTTP transport says servers
  SHOULD authenticate connections. Put your own authentication (a Catalyst
  authentication plugin, an `auto` action, or middleware) in front of
  `mcp_dispatch`. Consider also what a provider is allowed to reach: the engine
  does not scope tools or resources to a user.
- **Validate the `Origin` header.** The transport says servers MUST validate
  `Origin`, to stop a browser on another site from driving your endpoint via DNS
  rebinding. Check it against an allow-list and reject anything else before
  dispatching.

Binding to localhost rather than `0.0.0.0` is worth it for a local server, but
it is not a substitute for either of the above. See the `SECURITY` section in
`Catalyst::Plugin::MCP` for detail.

## Author

Mike Whitaker <mike@altrion.org>

lib/Catalyst/Plugin/MCP.pm  view on Meta::CPAN


=head1 SYNOPSIS

    package MyApp;
    use Catalyst qw/
        +Catalyst::Plugin::JSONRPC::Server
        +Catalyst::Plugin::MCP
    /;
    __PACKAGE__->setup;

    # in a controller action mounted at your MCP endpoint
    sub mcp :Path('/mcp') :Args(0) {
        my ( $self, $c ) = @_;
        $c->mcp_register_provider( $c->model('MCP::Resources') );
        $c->mcp_register_provider( $c->model('MCP::Tools') );
        $c->mcp_dispatch;
    }

=head1 REQUIRED PLUGINS

This plugin builds on L<Catalyst::Plugin::JSONRPC::Server> and calls its

lib/Catalyst/Plugin/MCP.pm  view on Meta::CPAN


Advertised at C<initialize>. Defaults to a generic name and this plugin's
version, so set it to your own.

=back

=head1 SECURITY

B<This plugin ships no authentication and no C<Origin> validation, and
C<mcp_dispatch> does not add any.> A C<tools/call> runs your provider's code,
so an endpoint mounted as in the SYNOPSIS executes tools for anyone who can
POST to it. Guarding it is the application's job, and both of these are on you:

=over

=item Authenticate the endpoint

The MCP Streamable HTTP transport says servers SHOULD authenticate connections.
Put your own authentication (a Catalyst authentication plugin, an C<auto>
action, or middleware) in front of C<mcp_dispatch>, and let the request reach it
only once it is authorised. Consider also what a provider is allowed to reach:
the engine does not scope tools or resources to a user.

=item Validate the C<Origin> header

The transport says servers MUST validate C<Origin> on incoming connections, to
stop a browser on another site from driving your endpoint via DNS rebinding.
Check it against an allow-list and reject anything else before dispatching.

=back

Binding to localhost rather than C<0.0.0.0> is worth it for a local server, but
it is not a substitute for either of the above.

=head1 EXAMPLES

A runnable example lives in F<examples/>: a small Catalyst app loading



( run in 0.603 second using v1.01-cache-2.11-cpan-92ad3014f07 )