Class ::nsmcp::Protocol (public)
::nx::Class ::nsmcp::Protocol
Defined in /usr/local/ns/tcl/nsmcp/lib/protocol.tcl
- Testcases:
- No testcase defined.
Source code: :property registry:required :property authorizer:required :property {versions {2025-03-26 2025-06-18 2025-11-25}} :public method supports {version} {return [expr {$version in ${:versions}}]} :method parameter {object key types} { # Protocol validation, not a JSON implementation. Native access preserves # JSON types; getvalue -output triples returns the selected member's data. if {[catch {ns_json triples gettype -path [list $key] -- $object} type] || $type ni $types} { return -code error -errorcode {NSMCP RPC -32602} "Missing or invalid parameter: $key" } return [ns_json triples getvalue -output triples -path [list $key] -- $object] } :method uniqueMembers {value} { lassign $value name type members if {$type ni {object array}} return set seen {} foreach {name type data} $members { if {[dict exists $seen $name]} {error "duplicate JSON member"} dict set seen $name 1 :uniqueMembers [list {} $type $data] } } :public method error {id code message} { 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]]]] } :public method dispatch {context method params} { 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" } } } :public method handle {context body} { 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]]]]] }XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)