Class: Cuboid::MCP::Server

Inherits:
Object show all
Defined in:
lib/cuboid/mcp/server.rb

Overview

Cuboid’s MCP-server framework. Mirrors ‘Cuboid::Rest::Server`: application gems register tool handlers via `mcp_service_for(name, handler)` on their `Cuboid::Application` subclass; this server mounts one MCP transport per (instance, service) pair under `/instances/:instance/<service>` and proxies tool calls to the resolved engine instance via RPC.

Spawnable as ‘:mcp` via Cuboid::Processes::Manager (see `lib/cuboid/processes/executables/mcp.rb`).

Defined Under Namespace

Classes: Dispatcher

Class Method Summary collapse

Class Method Details

.rack_app(options = {}) ⇒ Object

Build (without booting) the Rack app — exposed for tests (Rack::Test against ‘rack_app({})`) and for embedders that want to mount MCP under a larger Rack tree.



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/cuboid/mcp/server.rb', line 72

def rack_app( options = {} )
    dispatcher = Dispatcher.new(
        name:      options[:name],
        version:   options[:version],
        stateless: options.fetch( :stateless, false )
    )

    Rack::Builder.new do
        use Cuboid::MCP::Auth
        run dispatcher
    end.to_app
end

.run!(options) ⇒ Object

Boot the MCP server.

Parameters:

Options Hash (options):

  • :bind (String)

    IP/host to bind

  • :port (Integer)

    Port to listen on

  • :name (String)

    MCP server name advertised to clients

  • :version (String)

    MCP server version advertised to clients

  • :tls (Hash)

    Optional TLS — same shape as Rest::Server

  • :stateless (Boolean)

    Streamable HTTP stateless mode



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/cuboid/mcp/server.rb', line 44

def run!( options )
    puma = Puma::Server.new( rack_app( options ) )

    ssl = configure_listener( puma, options )

    # Configure the Live registry so its `url_for(token)` can
    # synthesise the loopback URL the engine subprocess will
    # POST live events to. Done after listener configuration so
    # we know the resolved scheme.
    Live.configure(
        bind: options[:bind],
        port: options[:port],
        tls:  ssl
    )

    puts "MCP server listening on " \
         "http#{'s' if ssl}://#{options[:bind]}:#{options[:port]}/mcp"

    begin
        puma.run.join
    rescue Interrupt
        puma.stop( true )
    end
end