///|
/// Roots capability declared by an MCP client.
pub struct RootsCapability {
list_changed : Bool?
} derive(Debug, Eq)
///|
pub fn RootsCapability::RootsCapability(
list_changed? : Bool,
) -> RootsCapability {
{ list_changed, }
}
///|
pub impl ToJson for RootsCapability with fn to_json(self : RootsCapability) -> Json {
let fields : Map[String, Json] = Map([])
fields.set_opt("listChanged", self.list_changed.map(Json::boolean))
Json::object(fields)
}
///|
pub impl @json.FromJson for RootsCapability with fn from_json(
value : Json,
path : @json.JsonPath,
) -> RootsCapability raise {
guard value is Object(fields) else {
raise JsonDecodeError((path, "expected object"))
}
let list_changed = match fields.get("listChanged") {
Some(True) => Some(true)
Some(False) => Some(false)
Some(Null) | None => None
Some(_) =>
raise JsonDecodeError((path.add_key("listChanged"), "expected boolean"))
}
RootsCapability(list_changed?)
}
///|
pub fn RootsCapability::from_json(
value : Json,
path? : @json.JsonPath,
) -> RootsCapability raise McpError {
decode_json(value, path?)
}
///|
/// Sampling capability declared by an MCP client.
pub struct SamplingCapability {} derive(Debug, Eq)
///|
pub fn SamplingCapability::SamplingCapability() -> SamplingCapability {
SamplingCapability::{ }
}
///|
pub impl ToJson for SamplingCapability with fn to_json(
self : SamplingCapability,
) -> Json {
ignore(self)
Json::object(Map([]))
}
///|
pub impl @json.FromJson for SamplingCapability with fn from_json(
value : Json,
path : @json.JsonPath,
) -> SamplingCapability raise {
guard value is Object(_) else {
raise JsonDecodeError((path, "expected object"))
}
SamplingCapability()
}
///|
pub fn SamplingCapability::from_json(
value : Json,
path? : @json.JsonPath,
) -> SamplingCapability raise McpError {
decode_json(value, path?)
}
///|
/// Client support for server-initiated elicitation.
pub struct ElicitationCapability {
form : Json?
url : Json?
} derive(Debug, Eq)
///|
pub fn ElicitationCapability::ElicitationCapability(
form? : Json,
url? : Json,
) -> ElicitationCapability {
{ form: form.map(fn(f) { f.copy() }), url: url.map(fn(u) { u.copy() }) }
}
///|
fn ElicitationCapability::copy(
self : ElicitationCapability,
) -> ElicitationCapability {
ElicitationCapability(form?=self.form, url?=self.url)
}
///|
pub impl ToJson for ElicitationCapability with fn to_json(
self : ElicitationCapability,
) -> Json {
let fields : Map[String, Json] = Map([])
fields.set_opt("form", self.form.map(fn(f) { f.copy() }))
fields.set_opt("url", self.url.map(fn(u) { u.copy() }))
Json::object(fields)
}
///|
pub impl @json.FromJson for ElicitationCapability with fn from_json(
value : Json,
path : @json.JsonPath,
) -> ElicitationCapability raise {
guard value is Object(fields) else {
raise JsonDecodeError((path, "expected object"))
}
let form = match fields.get("form") {
Some(Object(_) as v) => Some(v)
Some(Null) | None => None
Some(_) => raise JsonDecodeError((path.add_key("form"), "expected object"))
}
let url = match fields.get("url") {
Some(Object(_) as v) => Some(v)
Some(Null) | None => None
Some(_) => raise JsonDecodeError((path.add_key("url"), "expected object"))
}
ElicitationCapability(form?, url?)
}
///|
pub fn ElicitationCapability::from_json(
value : Json,
path? : @json.JsonPath,
) -> ElicitationCapability raise McpError {
decode_json(value, path?)
}
///|
/// Capabilities declared by an MCP client.
pub struct ClientCapabilities {
roots : RootsCapability?
sampling : SamplingCapability?
elicitation : ElicitationCapability?
extensions : Map[String, Json]
experimental : Map[String, Json]
extra : Map[String, Json]
} derive(Debug, Eq)
///|
pub fn ClientCapabilities::ClientCapabilities(
roots? : RootsCapability,
sampling? : SamplingCapability,
elicitation? : ElicitationCapability,
extensions? : Map[String, Json] = {},
experimental? : Map[String, Json] = {},
extra? : Map[String, Json] = {},
) -> ClientCapabilities {
{
roots,
sampling,
elicitation,
extensions: extensions.copy_json(),
experimental: experimental.copy_json(),
extra: extra.copy_json(),
}
}
///|
pub fn ClientCapabilities::copy(
self : ClientCapabilities,
) -> ClientCapabilities {
ClientCapabilities(
roots?=self.roots,
sampling?=self.sampling,
elicitation?=self.elicitation.map(value => value.copy()),
extensions=self.extensions,
experimental=self.experimental,
extra=self.extra,
)
}
///|
pub fn ClientCapabilities::empty() -> ClientCapabilities {
ClientCapabilities()
}
///|
fn valid_extension_identifier(identifier : String) -> Bool {
let length = identifier.length()
if length < 3 || length > 255 {
return false
}
let mut slash_index = -1
for index in 0.. Bool {
let length = segment.length()
if length == 0 {
return false
}
for index in 0..= 'a' && char <= 'z') ||
(char >= '0' && char <= '9') ||
char == '-' ||
char == '.'
if !is_valid {
return false
}
}
true
}
///|
fn validate_extension_keys(
values : Map[String, Json],
path? : @json.JsonPath,
) -> Unit raise McpError {
for key, _ in values {
if !valid_extension_identifier(key) {
let p = match path {
Some(path) => path.add_key(key).to_string()
None => "extension '\{key}'"
}
raise InvalidParams("\{p}: not a valid extension identifier")
}
}
}
///|
fn validate_experimental_keys(
values : Map[String, Json],
path? : @json.JsonPath,
) -> Unit raise McpError {
for key, _ in values {
if valid_extension_identifier(key) {
let p = match path {
Some(path) => path.add_key(key).to_string()
None => "experimental '\{key}'"
}
raise InvalidParams("\{p}: must not use namespaced extension syntax")
}
if !valid_identifier_segment(key) {
let p = match path {
Some(path) => path.add_key(key).to_string()
None => "experimental '\{key}'"
}
raise InvalidParams("\{p}: not a valid experimental feature name")
}
}
}
///|
fn put_capability_map(
fields : Map[String, Json],
key : String,
values : Map[String, Json],
) -> Unit {
if !values.is_empty() {
fields[key] = Json::object(values.copy_json())
}
}
///|
pub impl ToJson for ClientCapabilities with fn to_json(
self : ClientCapabilities,
) -> Json {
let fields = self.extra.copy_json()
for key in ["roots", "sampling", "elicitation", "extensions", "experimental"] {
fields.remove(key)
}
if self.roots is Some(value) {
fields["roots"] = ToJson::to_json(value)
}
if self.sampling is Some(value) {
fields["sampling"] = ToJson::to_json(value)
}
if self.elicitation is Some(value) {
fields["elicitation"] = ToJson::to_json(value)
}
put_capability_map(fields, "extensions", self.extensions)
put_capability_map(fields, "experimental", self.experimental)
Json::object(fields)
}
///|
fn decode_capability_map(
fields : Map[String, Json],
key : String,
path : @json.JsonPath,
) -> Map[String, Json] raise @json.JsonDecodeError {
let subpath = path.add_key(key)
match fields.get(key) {
Some(Object(values)) => {
if key == "extensions" {
validate_extension_keys(values, path=subpath) catch {
error => raise @json.JsonDecodeError((subpath, error.message()))
}
} else if key == "experimental" {
validate_experimental_keys(values, path=subpath) catch {
error => raise @json.JsonDecodeError((subpath, error.message()))
}
}
values.copy_json()
}
Some(Null) | None => Map([])
Some(_) => raise @json.JsonDecodeError((subpath, "expected object"))
}
}
///|
pub impl @json.FromJson for ClientCapabilities with fn from_json(
value : Json,
path : @json.JsonPath,
) -> ClientCapabilities raise {
guard value is Object(fields) else {
raise JsonDecodeError((path, "expected object"))
}
let extra : Map[String, Json] = Map([])
for key, val in fields {
match key {
"roots" | "sampling" | "elicitation" | "extensions" | "experimental" => ()
_ => extra[key] = val
}
}
let roots : RootsCapability? = match fields {
{ "roots": v, .. } => Some(@json.from_json(v, path=path.add_key("roots")))
_ => None
}
let sampling : SamplingCapability? = match fields {
{ "sampling": v, .. } =>
Some(@json.from_json(v, path=path.add_key("sampling")))
_ => None
}
let elicitation : ElicitationCapability? = match fields {
{ "elicitation": v, .. } =>
Some(@json.from_json(v, path=path.add_key("elicitation")))
_ => None
}
let extensions = decode_capability_map(fields, "extensions", path)
let experimental = decode_capability_map(fields, "experimental", path)
ClientCapabilities(
roots?,
sampling?,
elicitation?,
extensions~,
experimental~,
extra~,
)
}
///|
pub fn ClientCapabilities::from_json(
value : Json,
path? : @json.JsonPath,
) -> ClientCapabilities raise McpError {
decode_json(value, path?)
}
///|
/// Tools capability declared by an MCP server.
pub struct ToolsCapability {
list_changed : Bool?
} derive(Debug, Eq)
///|
pub fn ToolsCapability::ToolsCapability(
list_changed? : Bool,
) -> ToolsCapability {
{ list_changed, }
}
///|
pub impl ToJson for ToolsCapability with fn to_json(self : ToolsCapability) -> Json {
let fields : Map[String, Json] = Map([])
fields.set_opt("listChanged", self.list_changed.map(Json::boolean))
Json::object(fields)
}
///|
pub impl @json.FromJson for ToolsCapability with fn from_json(
value : Json,
path : @json.JsonPath,
) -> ToolsCapability raise {
guard value is Object(fields) else {
raise JsonDecodeError((path, "expected object"))
}
let list_changed = match fields.get("listChanged") {
Some(True) => Some(true)
Some(False) => Some(false)
Some(Null) | None => None
Some(_) =>
raise JsonDecodeError((path.add_key("listChanged"), "expected boolean"))
}
ToolsCapability(list_changed?)
}
///|
pub fn ToolsCapability::from_json(
value : Json,
path? : @json.JsonPath,
) -> ToolsCapability raise McpError {
decode_json(value, path?)
}
///|
/// Prompts capability declared by an MCP server.
pub struct PromptsCapability {
list_changed : Bool?
} derive(Debug, Eq)
///|
pub fn PromptsCapability::PromptsCapability(
list_changed? : Bool,
) -> PromptsCapability {
{ list_changed, }
}
///|
pub impl ToJson for PromptsCapability with fn to_json(self : PromptsCapability) -> Json {
let fields : Map[String, Json] = Map([])
fields.set_opt("listChanged", self.list_changed.map(Json::boolean))
Json::object(fields)
}
///|
pub impl @json.FromJson for PromptsCapability with fn from_json(
value : Json,
path : @json.JsonPath,
) -> PromptsCapability raise {
guard value is Object(fields) else {
raise JsonDecodeError((path, "expected object"))
}
let list_changed = match fields.get("listChanged") {
Some(True) => Some(true)
Some(False) => Some(false)
Some(Null) | None => None
Some(_) =>
raise JsonDecodeError((path.add_key("listChanged"), "expected boolean"))
}
PromptsCapability(list_changed?)
}
///|
pub fn PromptsCapability::from_json(
value : Json,
path? : @json.JsonPath,
) -> PromptsCapability raise McpError {
decode_json(value, path?)
}
///|
/// Resources capability declared by an MCP server.
pub struct ResourcesCapability {
subscribe : Bool?
list_changed : Bool?
} derive(Debug, Eq)
///|
pub fn ResourcesCapability::ResourcesCapability(
subscribe? : Bool,
list_changed? : Bool,
) -> ResourcesCapability {
{ subscribe, list_changed }
}
///|
pub impl ToJson for ResourcesCapability with fn to_json(
self : ResourcesCapability,
) -> Json {
let fields : Map[String, Json] = Map([])
fields.set_opt("subscribe", self.subscribe.map(Json::boolean))
fields.set_opt("listChanged", self.list_changed.map(Json::boolean))
Json::object(fields)
}
///|
pub impl @json.FromJson for ResourcesCapability with fn from_json(
value : Json,
path : @json.JsonPath,
) -> ResourcesCapability raise {
guard value is Object(fields) else {
raise JsonDecodeError((path, "expected object"))
}
let subscribe = match fields.get("subscribe") {
Some(True) => Some(true)
Some(False) => Some(false)
Some(Null) | None => None
Some(_) =>
raise JsonDecodeError((path.add_key("subscribe"), "expected boolean"))
}
let list_changed = match fields.get("listChanged") {
Some(True) => Some(true)
Some(False) => Some(false)
Some(Null) | None => None
Some(_) =>
raise JsonDecodeError((path.add_key("listChanged"), "expected boolean"))
}
ResourcesCapability(subscribe?, list_changed?)
}
///|
pub fn ResourcesCapability::from_json(
value : Json,
path? : @json.JsonPath,
) -> ResourcesCapability raise McpError {
decode_json(value, path?)
}
///|
/// Logging capability declared by an MCP server.
pub struct LoggingCapability {} derive(Debug, Eq)
///|
pub fn LoggingCapability::LoggingCapability() -> LoggingCapability {
LoggingCapability::{ }
}
///|
pub impl ToJson for LoggingCapability with fn to_json(self : LoggingCapability) -> Json {
ignore(self)
Json::object(Map([]))
}
///|
pub impl @json.FromJson for LoggingCapability with fn from_json(
value : Json,
path : @json.JsonPath,
) -> LoggingCapability raise {
guard value is Object(_) else {
raise JsonDecodeError((path, "expected object"))
}
LoggingCapability()
}
///|
pub fn LoggingCapability::from_json(
value : Json,
path? : @json.JsonPath,
) -> LoggingCapability raise McpError {
decode_json(value, path?)
}
///|
/// Capabilities declared by an MCP server.
pub struct ServerCapabilities {
tools : ToolsCapability?
resources : ResourcesCapability?
prompts : PromptsCapability?
logging : LoggingCapability?
completions : Bool
extensions : Map[String, Json]
experimental : Map[String, Json]
extra : Map[String, Json]
} derive(Debug, Eq)
///|
pub fn ServerCapabilities::ServerCapabilities(
tools? : ToolsCapability,
resources? : ResourcesCapability,
prompts? : PromptsCapability,
logging? : LoggingCapability,
completions? : Bool = false,
extensions? : Map[String, Json] = {},
experimental? : Map[String, Json] = {},
extra? : Map[String, Json] = {},
) -> ServerCapabilities {
{
tools,
resources,
prompts,
logging,
completions,
extensions: extensions.copy_json(),
experimental: experimental.copy_json(),
extra: extra.copy_json(),
}
}
///|
fn ServerCapabilities::copy(self : ServerCapabilities) -> ServerCapabilities {
ServerCapabilities(
tools?=self.tools,
resources?=self.resources,
prompts?=self.prompts,
logging?=self.logging,
completions=self.completions,
extensions=self.extensions,
experimental=self.experimental,
extra=self.extra,
)
}
///|
pub fn ServerCapabilities::empty() -> ServerCapabilities {
ServerCapabilities()
}
///|
pub impl ToJson for ServerCapabilities with fn to_json(
self : ServerCapabilities,
) -> Json {
let fields = self.extra.copy_json()
for
key in [
"tools", "resources", "prompts", "logging", "completions", "extensions", "experimental",
] {
fields.remove(key)
}
if self.tools is Some(value) {
fields["tools"] = ToJson::to_json(value)
}
if self.resources is Some(value) {
fields["resources"] = ToJson::to_json(value)
}
if self.prompts is Some(value) {
fields["prompts"] = ToJson::to_json(value)
}
if self.logging is Some(value) {
fields["logging"] = ToJson::to_json(value)
}
if self.completions {
fields["completions"] = Json::object({})
}
put_capability_map(fields, "extensions", self.extensions)
put_capability_map(fields, "experimental", self.experimental)
Json::object(fields)
}
///|
pub impl @json.FromJson for ServerCapabilities with fn from_json(
value : Json,
path : @json.JsonPath,
) -> ServerCapabilities raise {
guard value is Object(fields) else {
raise JsonDecodeError((path, "expected object"))
}
let extra : Map[String, Json] = Map([])
for key, item in fields {
match key {
"tools"
| "resources"
| "prompts"
| "logging"
| "completions"
| "extensions"
| "experimental" => ()
_ => extra[key] = item
}
}
let tools : ToolsCapability? = match fields {
{ "tools": v, .. } => Some(@json.from_json(v, path=path.add_key("tools")))
_ => None
}
let resources : ResourcesCapability? = match fields {
{ "resources": v, .. } =>
Some(@json.from_json(v, path=path.add_key("resources")))
_ => None
}
let prompts : PromptsCapability? = match fields {
{ "prompts": v, .. } =>
Some(@json.from_json(v, path=path.add_key("prompts")))
_ => None
}
let logging : LoggingCapability? = match fields {
{ "logging": v, .. } =>
Some(@json.from_json(v, path=path.add_key("logging")))
_ => None
}
let completions = match fields.get("completions") {
Some(Object(_)) => true
Some(_) =>
raise JsonDecodeError((path.add_key("completions"), "expected object"))
None => false
}
let extensions = decode_capability_map(fields, "extensions", path)
let experimental = decode_capability_map(fields, "experimental", path)
ServerCapabilities(
tools?,
resources?,
prompts?,
logging?,
completions~,
extensions~,
experimental~,
extra~,
)
}
///|
pub fn ServerCapabilities::from_json(
value : Json,
path? : @json.JsonPath,
) -> ServerCapabilities raise McpError {
decode_json(value, path?)
}