/* * Copyright (C) 2025 Mcp-Vala Project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Mcp-Vala Project */ /** * MCP protocol types and data structures. * * This namespace contains all the protocol-specific types defined by the MCP specification, * including server information, capabilities, and other core protocol data structures. */ namespace Mcp.Types.Protocol { /** * Server information as defined by the MCP protocol. */ public class ServerInfo : GLib.Object { /** * The name of the server. */ public string name { get; set; } /** * The version of the server. */ public string version { get; set; } /** * Optional description of the server. */ public string? description { get; set; } /** * Optional website URL for the server. */ public string? website_url { get; set; } /** * Creates a new ServerInfo. * * @param name Server name * @param version Server version */ public ServerInfo (string name, string version) { this.name = name; this.version = version; } /** * Serializes ServerInfo to GLib.Variant. * * @return A GLib.Variant representing this ServerInfo */ public Variant to_variant () { var builder = Mcp.Types.VariantUtils.new_dict_builder (); builder.add ("{sv}", "name", new Variant.string (name)); builder.add ("{sv}", "version", new Variant.string (version)); Mcp.Types.VariantUtils.add_string_if_not_null (builder, "description", description); Mcp.Types.VariantUtils.add_string_if_not_null (builder, "website_url", website_url); return builder.end (); } /** * Creates a ServerInfo from GLib.Variant. * * @param variant The GLib.Variant to deserialize * @return The deserialized ServerInfo * @throws Error If deserialization fails */ public ServerInfo.from_variant (Variant variant) throws Error { if (!variant.is_of_type (VariantType.VARDICT)) { throw new Mcp.Core.McpError.PARSE_ERROR ("ServerInfo must be a dictionary"); } if (variant.lookup_value ("name", null) == null) { throw new Mcp.Core.McpError.INVALID_REQUEST ("Missing name in ServerInfo"); } if (variant.lookup_value ("version", null) == null) { throw new Mcp.Core.McpError.INVALID_REQUEST ("Missing version in ServerInfo"); } this.name = variant.lookup_value ("name", VariantType.STRING).get_string (); this.version = variant.lookup_value ("version", VariantType.STRING).get_string (); if (variant.lookup_value ("description", null) != null) { this.description = variant.lookup_value ("description", VariantType.STRING).get_string (); } if (variant.lookup_value ("website_url", null) != null) { this.website_url = variant.lookup_value ("website_url", VariantType.STRING).get_string (); } } } /** * Server capabilities as defined by the MCP protocol. */ public class ServerCapabilities : GLib.Object { /** * Whether logging is supported. */ public bool logging { get; set; default = false; } /** * Whether completions are supported. */ public bool completions { get; set; default = false; } /** * Optional prompts capabilities. */ public PromptsCapabilities? prompts { get; set; } /** * Optional resources capabilities. */ public ResourcesCapabilities? resources { get; set; } /** * Optional tools capabilities. */ public ToolsCapabilities? tools { get; set; } /** * Creates a new ServerCapabilities. */ public ServerCapabilities () { } /** * Serializes ServerCapabilities to GLib.Variant. * * @return A GLib.Variant representing this ServerCapabilities */ public Variant to_variant () { var builder = Mcp.Types.VariantUtils.new_dict_builder (); if (logging) { builder.add ("{sv}", "logging", new Variant.boolean (logging)); } if (completions) { builder.add ("{sv}", "completions", new Variant.boolean (completions)); } Mcp.Types.VariantUtils.add_variant_if_not_null (builder, "prompts", prompts != null ? prompts.to_variant () : null); Mcp.Types.VariantUtils.add_variant_if_not_null (builder, "resources", resources != null ? resources.to_variant () : null); Mcp.Types.VariantUtils.add_variant_if_not_null (builder, "tools", tools != null ? tools.to_variant () : null); return builder.end (); } /** * Creates a ServerCapabilities from GLib.Variant. * * @param variant The GLib.Variant to deserialize * @return The deserialized ServerCapabilities * @throws Error If deserialization fails */ public ServerCapabilities.from_variant (Variant variant) throws Error { if (!variant.is_of_type (VariantType.VARDICT)) { throw new Mcp.Core.McpError.PARSE_ERROR ("ServerCapabilities must be a dictionary"); } if (variant.lookup_value ("logging", null) != null) { this.logging = variant.lookup_value ("logging", VariantType.BOOLEAN).get_boolean (); } if (variant.lookup_value ("completions", null) != null) { this.completions = variant.lookup_value ("completions", VariantType.BOOLEAN).get_boolean (); } if (variant.lookup_value ("prompts", null) != null) { this.prompts = new PromptsCapabilities.from_variant (variant.lookup_value ("prompts", VariantType.VARDICT)); } if (variant.lookup_value ("resources", null) != null) { this.resources = new ResourcesCapabilities.from_variant (variant.lookup_value ("resources", VariantType.VARDICT)); } if (variant.lookup_value ("tools", null) != null) { this.tools = new ToolsCapabilities.from_variant (variant.lookup_value ("tools", VariantType.VARDICT)); } } } /** * Prompts capabilities. */ public class PromptsCapabilities : GLib.Object { /** * Whether the list of prompts can change. */ public bool list_changed { get; set; default = false; } /** * Creates a new PromptsCapabilities. */ public PromptsCapabilities () { } /** * Serializes PromptsCapabilities to GLib.Variant. * * @return A GLib.Variant representing this PromptsCapabilities */ public Variant to_variant () { var builder = Mcp.Types.VariantUtils.new_dict_builder (); builder.add ("{sv}", "listChanged", new Variant.boolean (list_changed)); return builder.end (); } /** * Creates a PromptsCapabilities from GLib.Variant. * * @param variant The GLib.Variant to deserialize * @return The deserialized PromptsCapabilities * @throws Error If deserialization fails */ public PromptsCapabilities.from_variant (Variant variant) throws Error { if (!variant.is_of_type (VariantType.VARDICT)) { throw new Mcp.Core.McpError.PARSE_ERROR ("PromptsCapabilities must be a dictionary"); } if (variant.lookup_value ("listChanged", null) != null) { this.list_changed = variant.lookup_value ("listChanged", VariantType.BOOLEAN).get_boolean (); } } } /** * Resources capabilities. */ public class ResourcesCapabilities : GLib.Object { /** * Whether subscription is supported. */ public bool subscribe { get; set; default = false; } /** * Whether the list of resources can change. */ public bool list_changed { get; set; default = false; } /** * Creates a new ResourcesCapabilities. */ public ResourcesCapabilities () { } /** * Serializes ResourcesCapabilities to GLib.Variant. * * @return A GLib.Variant representing this ResourcesCapabilities */ public Variant to_variant () { var builder = Mcp.Types.VariantUtils.new_dict_builder (); builder.add ("{sv}", "subscribe", new Variant.boolean (subscribe)); builder.add ("{sv}", "listChanged", new Variant.boolean (list_changed)); return builder.end (); } /** * Creates a ResourcesCapabilities from GLib.Variant. * * @param variant The GLib.Variant to deserialize * @return The deserialized ResourcesCapabilities * @throws Error If deserialization fails */ public ResourcesCapabilities.from_variant (Variant variant) throws Error { if (!variant.is_of_type (VariantType.VARDICT)) { throw new Mcp.Core.McpError.PARSE_ERROR ("ResourcesCapabilities must be a dictionary"); } if (variant.lookup_value ("subscribe", null) != null) { this.subscribe = variant.lookup_value ("subscribe", VariantType.BOOLEAN).get_boolean (); } if (variant.lookup_value ("listChanged", null) != null) { this.list_changed = variant.lookup_value ("listChanged", VariantType.BOOLEAN).get_boolean (); } } } /** * Tools capabilities. */ public class ToolsCapabilities : GLib.Object { /** * Whether the list of tools can change. */ public bool list_changed { get; set; default = false; } /** * Creates a new ToolsCapabilities. */ public ToolsCapabilities () { } /** * Serializes ToolsCapabilities to GLib.Variant. * * @return A GLib.Variant representing this ToolsCapabilities */ public Variant to_variant () { var builder = Mcp.Types.VariantUtils.new_dict_builder (); builder.add ("{sv}", "listChanged", new Variant.boolean (list_changed)); return builder.end (); } /** * Creates a ToolsCapabilities from GLib.Variant. * * @param variant The GLib.Variant to deserialize * @return The deserialized ToolsCapabilities * @throws Error If deserialization fails */ public ToolsCapabilities.from_variant (Variant variant) throws Error { if (!variant.is_of_type (VariantType.VARDICT)) { throw new Mcp.Core.McpError.PARSE_ERROR ("ToolsCapabilities must be a dictionary"); } if (variant.lookup_value ("listChanged", null) != null) { this.list_changed = variant.lookup_value ("listChanged", VariantType.BOOLEAN).get_boolean (); } } } }