20namespace mcp::protocol {
140inline Json capability_raw_object(
const Json& raw) {
141 return raw.is_object() ? raw : Json::object();
144inline Json capability_member_object(
const Json&
object,
145 const std::string& key) {
146 if (
object.is_object() &&
object.contains(key) &&
147 object.at(key).is_object()) {
148 return object.at(key);
150 return Json::object();
157 Json tasks = capability_raw_object(capabilities.
raw);
158 if (capabilities.
list) {
159 tasks[
"list"] = capability_member_object(tasks,
"list");
161 if (capabilities.
cancel) {
162 tasks[
"cancel"] = capability_member_object(tasks,
"cancel");
165 Json requests = capability_member_object(tasks,
"requests");
167 Json tools = capability_member_object(requests,
"tools");
168 tools[
"call"] = capability_member_object(tools,
"call");
169 requests[
"tools"] = std::move(tools);
172 Json sampling = capability_member_object(requests,
"sampling");
173 sampling[
"createMessage"] =
174 capability_member_object(sampling,
"createMessage");
175 requests[
"sampling"] = std::move(sampling);
178 Json elicitation = capability_member_object(requests,
"elicitation");
179 elicitation[
"create"] = capability_member_object(elicitation,
"create");
180 requests[
"elicitation"] = std::move(elicitation);
182 if (!requests.empty()) {
183 tasks[
"requests"] = std::move(requests);
192 return json.is_object() || (json.is_boolean() && json.get<
bool>());
200 if (!tasks.is_object()) {
201 return task_capabilities;
203 task_capabilities.
raw = tasks;
205 if (tasks.contains(
"list")) {
208 if (tasks.contains(
"cancel")) {
211 if (tasks.contains(
"requests") && tasks.at(
"requests").is_object()) {
212 const auto& requests = tasks.at(
"requests");
213 if (requests.contains(
"tools") && requests.at(
"tools").is_object()) {
214 const auto& tools = requests.at(
"tools");
215 if (tools.contains(
"call")) {
220 if (requests.contains(
"sampling") && requests.at(
"sampling").is_object()) {
221 const auto& sampling = requests.at(
"sampling");
222 if (sampling.contains(
"createMessage")) {
227 if (requests.contains(
"elicitation") &&
228 requests.at(
"elicitation").is_object()) {
229 const auto& elicitation = requests.at(
"elicitation");
230 if (elicitation.contains(
"create")) {
236 return task_capabilities;
239inline bool task_capability_member_valid(
const Json& json) {
240 return json.is_object() || json.is_boolean();
243inline bool task_capabilities_are_valid(
const Json& tasks) {
244 if (!tasks.is_object()) {
247 if (tasks.contains(
"list") &&
248 !task_capability_member_valid(tasks.at(
"list"))) {
251 if (tasks.contains(
"cancel") &&
252 !task_capability_member_valid(tasks.at(
"cancel"))) {
255 if (!tasks.contains(
"requests")) {
258 if (!tasks.at(
"requests").is_object()) {
261 const auto& requests = tasks.at(
"requests");
262 if (requests.contains(
"tools")) {
263 if (!requests.at(
"tools").is_object()) {
266 const auto& tools = requests.at(
"tools");
267 if (tools.contains(
"call") &&
268 !task_capability_member_valid(tools.at(
"call"))) {
272 if (requests.contains(
"sampling")) {
273 if (!requests.at(
"sampling").is_object()) {
276 const auto& sampling = requests.at(
"sampling");
277 if (sampling.contains(
"createMessage") &&
278 !task_capability_member_valid(sampling.at(
"createMessage"))) {
282 if (requests.contains(
"elicitation")) {
283 if (!requests.at(
"elicitation").is_object()) {
286 const auto& elicitation = requests.at(
"elicitation");
287 if (elicitation.contains(
"create") &&
288 !task_capability_member_valid(elicitation.at(
"create"))) {
304 std::optional<TaskCapabilities>
tasks;
322 bool context =
false) {
330 std::optional<bool> schema_validation = std::nullopt) {
344 capabilities_.
tasks = std::move(value);
349 ensure_tasks().
list = value;
354 ensure_tasks().
cancel = value;
379 capabilities_.
extensions[std::move(name)] = std::move(value);
387 if (!capabilities_.
tasks.has_value()) {
390 return *capabilities_.
tasks;
406 Json json = Json::object();
408 Json roots = capability_raw_object(capabilities.
roots.
raw);
414 json[
"roots"] = std::move(roots);
419 sampling[
"tools"] = capability_member_object(sampling,
"tools");
422 sampling[
"context"] = capability_member_object(sampling,
"context");
425 json[
"sampling"] = std::move(sampling);
430 Json form = capability_member_object(elicitation,
"form");
432 form[
"schemaValidation"] =
435 elicitation[
"form"] = std::move(form);
438 elicitation[
"url"] = capability_member_object(elicitation,
"url");
441 json[
"elicitation"] = std::move(elicitation);
450 if (capabilities.
tasks.has_value()) {
452 json[
"tasks"] = std::move(tasks);
470 std::optional<TaskCapabilities>
tasks;
488 bool subscribe =
false) {
515 capabilities_.
tasks = std::move(value);
520 ensure_tasks().
list = value;
525 ensure_tasks().
cancel = value;
550 capabilities_.
extensions[std::move(name)] = std::move(value);
558 if (!capabilities_.
tasks.has_value()) {
561 return *capabilities_.
tasks;
577 Json json = Json::object();
579 Json tools = capability_raw_object(capabilities.
tools.
raw);
585 json[
"tools"] = std::move(tools);
598 json[
"resources"] = std::move(resources);
607 json[
"prompts"] = std::move(prompts);
612 json[
"logging"] = capability_raw_object(capabilities.
logging.
raw);
617 json[
"completions"] = capability_raw_object(capabilities.
completions.
raw);
619 if (capabilities.
tasks.has_value()) {
621 json[
"tasks"] = std::move(tasks);
638 if (!json.is_object()) {
643 if (json.contains(
"roots")) {
644 if (!json.at(
"roots").is_object()) {
648 const auto& roots = json.at(
"roots");
650 if (roots.contains(
"listChanged")) {
651 if (!roots.at(
"listChanged").is_boolean()) {
658 if (json.contains(
"sampling")) {
659 if (!json.at(
"sampling").is_object()) {
663 const auto& sampling = json.at(
"sampling");
665 if (sampling.contains(
"tools")) {
666 if (!sampling.at(
"tools").is_object()) {
671 if (sampling.contains(
"context")) {
672 if (!sampling.at(
"context").is_object()) {
678 if (json.contains(
"elicitation")) {
679 const auto& elicitation = json.at(
"elicitation");
680 if (!elicitation.is_object()) {
685 if (elicitation.contains(
"form")) {
686 if (!elicitation.at(
"form").is_object()) {
690 const auto& form = elicitation.at(
"form");
691 if (form.contains(
"schemaValidation")) {
692 if (!form.at(
"schemaValidation").is_boolean()) {
696 form.at(
"schemaValidation").get<
bool>();
699 if (elicitation.contains(
"url")) {
700 if (!elicitation.at(
"url").is_object()) {
706 if (json.contains(
"tasks")) {
707 if (!task_capabilities_are_valid(json.at(
"tasks"))) {
712 if (json.contains(
"experimental")) {
713 if (!json.at(
"experimental").is_object()) {
718 if (json.contains(
"extensions")) {
719 if (!json.at(
"extensions").is_object()) {
722 capabilities.
extensions = json.at(
"extensions");
732 if (!json.is_object()) {
737 if (json.contains(
"tools")) {
738 if (!json.at(
"tools").is_object()) {
742 const auto& tools = json.at(
"tools");
744 if (tools.contains(
"listChanged")) {
745 if (!tools.at(
"listChanged").is_boolean()) {
753 if (json.contains(
"resources")) {
754 if (!json.at(
"resources").is_object()) {
758 const auto& resources = json.at(
"resources");
760 if (resources.contains(
"listChanged")) {
761 if (!resources.at(
"listChanged").is_boolean()) {
765 resources.at(
"listChanged").get<
bool>();
768 if (resources.contains(
"subscribe")) {
769 if (!resources.at(
"subscribe").is_boolean()) {
777 if (json.contains(
"prompts")) {
778 if (!json.at(
"prompts").is_object()) {
782 const auto& prompts = json.at(
"prompts");
784 if (prompts.contains(
"listChanged")) {
785 if (!prompts.at(
"listChanged").is_boolean()) {
793 if (json.contains(
"logging")) {
794 if (!json.at(
"logging").is_object()) {
798 capabilities.
logging.
raw = json.at(
"logging");
800 if (json.contains(
"completions")) {
801 if (!json.at(
"completions").is_object()) {
807 if (json.contains(
"tasks")) {
808 if (!task_capabilities_are_valid(json.at(
"tasks"))) {
813 if (json.contains(
"experimental")) {
814 if (!json.at(
"experimental").is_object()) {
819 if (json.contains(
"extensions")) {
820 if (!json.at(
"extensions").is_object()) {
823 capabilities.
extensions = json.at(
"extensions");
std::optional< ServerCapabilities > server_capabilities_from_json(const Json &json)
Parses server capabilities from an initialize result.
Definition capabilities.hpp:730
Json server_capabilities_to_json(const ServerCapabilities &capabilities)
Serializes server capabilities to the MCP initialize result shape.
Definition capabilities.hpp:575
Json client_capabilities_to_json(const ClientCapabilities &capabilities)
Serializes client capabilities to the MCP initialize payload shape.
Definition capabilities.hpp:404
ServerCapabilitiesBuilder server_capabilities()
Starts a fluent server capability builder.
Definition capabilities.hpp:568
ClientCapabilitiesBuilder client_capabilities()
Starts a fluent client capability builder.
Definition capabilities.hpp:397
TaskCapabilities task_capabilities_from_json(const Json &tasks)
Parses task capabilities from an MCP capability object.
Definition capabilities.hpp:198
Json task_capabilities_to_json(const TaskCapabilities &capabilities)
Serializes task capability flags using object presence semantics.
Definition capabilities.hpp:156
bool capability_member_enabled(const Json &json)
Interprets either modern object presence or legacy boolean presence.
Definition capabilities.hpp:191
std::optional< ClientCapabilities > client_capabilities_from_json(const Json &json)
Parses client capabilities from an initialize request.
Definition capabilities.hpp:636
Fluent builder for client initialize capabilities.
Definition capabilities.hpp:312
Fluent builder for server initialize result capabilities.
Definition capabilities.hpp:478
Shared JSON, JSON-RPC, error, cancellation, and progress model types.
nlohmann::json Json
JSON value type used by all protocol DTOs.
Definition types.hpp:28
Capabilities advertised by an MCP client during initialization.
Definition capabilities.hpp:296
std::optional< TaskCapabilities > tasks
Optional task support. Omitted when the client does not advertise tasks.
Definition capabilities.hpp:304
RootCapabilities roots
Roots feature support.
Definition capabilities.hpp:298
SamplingCapabilities sampling
Sampling feature support.
Definition capabilities.hpp:300
std::optional< Json > experimental
Experimental capability bag preserved as raw JSON.
Definition capabilities.hpp:306
ElicitationCapabilities elicitation
Elicitation feature support.
Definition capabilities.hpp:302
Json extensions
Vendor or SDK extension capability bag.
Definition capabilities.hpp:308
Server capability flags for completion requests.
Definition capabilities.hpp:84
bool enabled
Whether completion/complete is supported.
Definition capabilities.hpp:86
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:88
Client capability flags for elicitation.
Definition capabilities.hpp:104
bool url
Whether URL-based elicitation requests are supported.
Definition capabilities.hpp:112
bool present
Whether the elicitation capability family was explicitly advertised.
Definition capabilities.hpp:106
bool form
Whether form-based elicitation/create requests are supported.
Definition capabilities.hpp:108
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:114
std::optional< bool > form_schema_validation
Whether form elicitation can validate schemas locally.
Definition capabilities.hpp:110
bool enabled() const noexcept
Returns true when any elicitation mode is supported.
Definition capabilities.hpp:118
Server capability flags for logging.
Definition capabilities.hpp:63
bool enabled
Whether logging/setLevel and logging message notifications are supported.
Definition capabilities.hpp:66
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:68
Server capability flags for prompts.
Definition capabilities.hpp:51
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:59
bool list_changed
Whether notifications/prompts/list_changed may be emitted.
Definition capabilities.hpp:55
bool enabled
Whether the server supports prompt listing or retrieval.
Definition capabilities.hpp:53
bool list_changed_present
Whether listChanged was explicitly present on the wire.
Definition capabilities.hpp:57
Server capability flags for resources.
Definition capabilities.hpp:35
bool enabled
Whether the server supports resource listing or reading.
Definition capabilities.hpp:37
bool subscribe_present
Whether subscribe was explicitly present on the wire.
Definition capabilities.hpp:45
bool list_changed
Whether notifications/resources/list_changed may be emitted.
Definition capabilities.hpp:39
bool list_changed_present
Whether listChanged was explicitly present on the wire.
Definition capabilities.hpp:41
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:47
bool subscribe
Whether the server supports resource subscribe/unsubscribe methods.
Definition capabilities.hpp:43
Client capability flags for roots.
Definition capabilities.hpp:92
bool enabled
Whether the client supports roots/list.
Definition capabilities.hpp:94
bool list_changed_present
Whether listChanged was explicitly present on the wire.
Definition capabilities.hpp:98
bool list_changed
Whether notifications/roots/list_changed may be emitted.
Definition capabilities.hpp:96
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:100
Client capability flags for sampling requests from the server.
Definition capabilities.hpp:72
bool enabled
Whether the client accepts sampling/createMessage requests.
Definition capabilities.hpp:74
bool tools
Whether sampling requests may use tool-related context.
Definition capabilities.hpp:76
bool context
Whether sampling requests may use broader context.
Definition capabilities.hpp:78
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:80
Capabilities advertised by an MCP server in the initialize result.
Definition capabilities.hpp:458
LoggingCapabilities logging
Logging feature support.
Definition capabilities.hpp:466
ToolCapabilities tools
Tool feature support.
Definition capabilities.hpp:460
ResourceCapabilities resources
Resource feature support.
Definition capabilities.hpp:462
CompletionCapabilities completions
Completion feature support.
Definition capabilities.hpp:468
Json extensions
Vendor or SDK extension capability bag.
Definition capabilities.hpp:474
PromptCapabilities prompts
Prompt feature support.
Definition capabilities.hpp:464
std::optional< Json > experimental
Experimental capability bag preserved as raw JSON.
Definition capabilities.hpp:472
std::optional< TaskCapabilities > tasks
Optional task support. Omitted when the server does not advertise tasks.
Definition capabilities.hpp:470
Capability flags for asynchronous task support.
Definition capabilities.hpp:125
bool sampling_create_message
Whether sampling/createMessage requests may include task parameters.
Definition capabilities.hpp:133
bool tools_call
Whether tools/call requests may include task parameters.
Definition capabilities.hpp:131
Json raw
Raw capability object preserved for future fields.
Definition capabilities.hpp:137
bool cancel
Whether tasks/cancel is supported.
Definition capabilities.hpp:129
bool elicitation_create
Whether elicitation/create requests may include task parameters.
Definition capabilities.hpp:135
bool list
Whether tasks/list is supported.
Definition capabilities.hpp:127
Asynchronous task status and task-management payloads.