Class ::nsmcp::Protocol

::nsmcp::Protocol[i] create ... \
           [ -authorizer:required authorizer:required ] \
           [ -registry:required registry:required ] \
           [ -versions (default "2025-03-26 2025-06-18 2025-11-25") ]

Defined in /usr/local/ns/tcl/nsmcp/protocol.tcl

Class Relations

  • class: ::nx::Class[i]
  • superclass: ::nsmcp::Object[i]
::nx::Class create ::nsmcp::Protocol \
     -superclass ::nsmcp::Object

Methods (to be applied on instances)

  • dispatch (scripted, public)

     <instance of nsmcp::Protocol[i]> dispatch context method params

    Dispatch an authenticated MCP protocol method. Handle initialization and tool operations using the configured registry and request authorizer.

    Parameters:
    context (required)
    Authenticated request context carrying the principal, grants and selected server.
    method (required)
    MCP protocol method or HTTP method, depending on the adapter.
    params (required)
    Rooted typed JSON-RPC parameters.
    Returns:
    The rooted JSON protocol result or notification result.

    Testcases:
    No testcase defined.
    switch -- $method {
        initialize {
            set requested [:parameter $params protocolVersion string]
            :parameter $params capabilities object
            set client [list {} object [:parameter $params clientInfo object]]
            :parameter $client name string
            :parameter $client version string
            set version [expr {[:supports $requested] ? $requested : [lindex ${:versions} end]}]
            return [list {} object [list protocolVersion string $version  capabilities object {tools object {listChanged boolean false}}  serverInfo object {name string nsmcp version string 0.1}]]
        }
        ping {
            return {{} object {}}
        }
        tools/list {
            if {![catch {
                ns_json triples gettype -path cursor -- $params
            }]} {
                return -code error -errorcode {NSMCP RPC -32602} "Pagination is not available"
            }
            return [${:registry} list $context ${:authorizer}]
        }
        tools/call {
            set name [:parameter $params name string]
            set arguments {{} object {}}
            if {![catch {
                ns_json triples gettype -path arguments -- $params
            }]} {
                set arguments [list {} object [:parameter $params arguments object]]
            }
            return [${:registry} call $context ${:authorizer} $name $arguments]
        }
        default {
            return -code error -errorcode {NSMCP RPC -32601} "Method not found"
        }
    }
  • error (scripted, public)

     <instance of nsmcp::Protocol[i]> error id code message

    Encode a JSON-RPC error response. Preserve the typed request identifier while constructing the standard error envelope.

    Parameters:
    id (required)
    Typed request or retained evidence identifier.
    code (required)
    JSON-RPC error code.
    message (required)
    Diagnostic message text.
    Returns:
    Serialized JSON for the error response.

    Testcases:
    No testcase defined.
    return [ns_json value -- [list {} object [list jsonrpc string 2.0  id [lindex $id 1] [lindex $id 2]  error object [list code number $code message string $message]]]]
  • handle (scripted, public)

     <instance of nsmcp::Protocol[i]> handle context body

    Parse and handle one JSON-RPC request body. Enforce JSON structure and size bounds, then encode protocol errors or dispatch results.

    Parameters:
    context (required)
    Authenticated request context carrying the principal, grants and selected server.
    body (required)
    Serialized HTTP or JSON-RPC request body.
    Returns:
    The serialized protocol response.

    Testcases:
    No testcase defined.
    set null {{} null {}}
    if {[catch {
        ns_json parse -maxdepth 32 -maxstring 65536 -maxcontainer 256  -validatenumbers -output triples -- $body
    } request]} {
        return [dict create status 400 body [:error $null -32700 "Parse error"]]
    }
    set id $null
    set hasId 0
    if {[catch {
        :uniqueMembers $request
        if {[lindex $request 1] ne "object"} {
            error "expected object"
        }
        set hasId [expr {![catch {
            ns_json triples gettype -path id -- $request
        } idType]}]
        if {$hasId} {
            set id [list {} $idType [:parameter $request id {string number}]]
        }
        if {[:parameter $request jsonrpc string] ne "2.0"} {
            error "invalid JSON-RPC version"
        }
        set method [:parameter $request method string]
        set params {{} object {}}
        if {![catch {
            ns_json triples gettype -path params -- $request
        }]} {
            set params [list {} object [:parameter $request params object]]
        }
    }]} {
        return [dict create status 400 body [:error $null -32600 "Invalid request"]]
    }
    if {!$hasId} {
        # Notifications cannot invoke tools. No asynchronous work is supported.
        return [dict create status 202 body {}]
    }
    if {[catch {
        :dispatch $context $method $params
    } result options]} {
        set code -32603
        set message "Internal error"
        set ec [dict get $options -errorcode]
        if {[lrange $ec 0 1] eq {NSMCP RPC}} {
            set code [lindex $ec 2]
            set message $result
        }
        return [dict create status 200 body [:error $id $code $message]]
    }
    return [dict create status 200 body [ns_json value -- [list {} object  [list jsonrpc string 2.0 id [lindex $id 1] [lindex $id 2]  result object [lindex $result 2]]]]]
  • supports (scripted, public)

     <instance of nsmcp::Protocol[i]> supports version

    Check whether an MCP protocol version is supported. Compare the requested version with the configured version list.

    Parameters:
    version (required)
    Requested MCP protocol-version string.
    Returns:
    True for a supported version, otherwise false.

    Testcases:
    No testcase defined.
    return [expr {$version in ${:versions}}]