25namespace mcp::protocol {
40 std::optional<std::int64_t>
size;
55 resource_.
uri = std::move(uri);
56 resource_.
name = std::move(name);
60 resource_.
title = std::move(value);
75 resource_.
size = value;
80 resource_.
icons.push_back(std::move(value));
90 resource_.
meta = std::move(value);
95 resource_.
extensions[std::move(name)] = std::move(value);
99 Resource build() {
return std::move(resource_); }
139 std::optional<std::int64_t>
size;
154 resource_template_.
uri_template = std::move(uri_template);
155 resource_template_.
name = std::move(name);
159 resource_template_.
title = std::move(value);
169 resource_template_.
mime_type = std::move(value);
174 resource_template_.
size = value;
179 resource_template_.
icons.push_back(std::move(value));
189 resource_template_.
meta = std::move(value);
194 resource_template_.
extensions[std::move(name)] = std::move(value);
206 std::string uri_template, std::string name) {
256 std::optional<std::string>
text;
258 std::optional<std::string>
blob;
267 static constexpr bool defined =
true;
268 static auto fields() {
269 return std::make_tuple(
276 {
"uri",
"mimeType",
"text",
"blob",
"_meta"}));
278 static std::vector<std::string> known_keys() {
279 return {
"uri",
"mimeType",
"text",
"blob",
"_meta"};
308 static constexpr bool defined =
true;
309 static auto fields() {
310 return std::make_tuple(
315 static std::vector<std::string> known_keys() {
return {
"uri"}; }
321 static_cast<int>(ErrorCode::InvalidRequest), std::move(message), {}};
325 const Json& json, std::string_view context) {
326 if (!json.is_number_integer()) {
327 return mcp::core::unexpected(
328 resource_json_error(std::string(context) +
" size must be an integer"));
330 const auto size = json.get<std::int64_t>();
331 if (size < 0 || size >
static_cast<std::int64_t
>(
332 std::numeric_limits<std::uint32_t>::max())) {
333 return mcp::core::unexpected(resource_json_error(
334 std::string(context) +
" size must be a uint32 value"));
341 Json json = Json::object();
342 if (!resource.title.empty()) {
343 json[
"title"] = resource.title;
345 json[
"uri"] = resource.uri;
346 json[
"name"] = resource.name;
347 if (!resource.description.empty()) {
348 json[
"description"] = resource.description;
350 if (!resource.mime_type.empty()) {
351 json[
"mimeType"] = resource.mime_type;
353 if (resource.size.has_value()) {
354 json[
"size"] = *resource.size;
356 if (!resource.icons.empty()) {
357 json[
"icons"] = Json::array();
358 for (
const auto& icon : resource.icons) {
362 if (!resource.annotations.empty()) {
363 json[
"annotations"] = resource.annotations;
365 if (resource.meta.has_value()) {
366 json[
"_meta"] = *resource.meta;
375 if (!json.is_object()) {
376 return mcp::core::unexpected(
379 if (json.contains(
"title")) {
380 if (!json.at(
"title").is_string()) {
381 return mcp::core::unexpected(
385 if (!json.contains(
"uri") || !json.at(
"uri").is_string()) {
386 return mcp::core::unexpected(
389 if (!json.contains(
"name") || !json.at(
"name").is_string()) {
390 return mcp::core::unexpected(
395 if (json.contains(
"title")) {
396 resource.title = json.at(
"title").get<std::string>();
398 resource.uri = json.at(
"uri").get<std::string>();
399 resource.name = json.at(
"name").get<std::string>();
400 if (json.contains(
"description")) {
401 if (!json.at(
"description").is_string()) {
402 return mcp::core::unexpected(
405 resource.description = json.at(
"description").get<std::string>();
407 if (json.contains(
"mimeType")) {
408 if (!json.at(
"mimeType").is_string()) {
409 return mcp::core::unexpected(
412 resource.mime_type = json.at(
"mimeType").get<std::string>();
414 if (json.contains(
"size")) {
415 const auto size = resource_size_from_json(json.at(
"size"),
"resource");
417 return mcp::core::unexpected(size.error());
419 resource.size = *size;
421 if (json.contains(
"icons")) {
422 if (!json.at(
"icons").is_array()) {
423 return mcp::core::unexpected(
426 for (
const auto& item : json.at(
"icons")) {
428 if (!icon.has_value()) {
429 return mcp::core::unexpected(
432 resource.icons.push_back(*icon);
435 if (json.contains(
"annotations")) {
436 if (!json.at(
"annotations").is_object()) {
437 return mcp::core::unexpected(
440 resource.annotations = json.at(
"annotations");
442 if (json.contains(
"_meta")) {
443 if (!json.at(
"_meta").is_object()) {
444 return mcp::core::unexpected(
447 resource.meta = json.at(
"_meta");
450 json, {
"title",
"uri",
"name",
"description",
"mimeType",
"size",
"icons",
451 "annotations",
"_meta"});
458 Json json = Json::object();
459 if (!resource_template.title.empty()) {
460 json[
"title"] = resource_template.title;
462 json[
"uriTemplate"] = resource_template.uri_template;
463 json[
"name"] = resource_template.name;
464 if (!resource_template.description.empty()) {
465 json[
"description"] = resource_template.description;
467 if (!resource_template.mime_type.empty()) {
468 json[
"mimeType"] = resource_template.mime_type;
470 if (resource_template.size.has_value()) {
471 json[
"size"] = *resource_template.size;
473 if (!resource_template.icons.empty()) {
474 json[
"icons"] = Json::array();
475 for (
const auto& icon : resource_template.icons) {
479 if (!resource_template.annotations.empty()) {
480 json[
"annotations"] = resource_template.annotations;
482 if (resource_template.meta.has_value()) {
483 json[
"_meta"] = *resource_template.meta;
493 if (!json.is_object()) {
494 return mcp::core::unexpected(
497 if (json.contains(
"title")) {
498 if (!json.at(
"title").is_string()) {
499 return mcp::core::unexpected(
503 if (!json.contains(
"uriTemplate") || !json.at(
"uriTemplate").is_string()) {
504 return mcp::core::unexpected(
507 if (!json.contains(
"name") || !json.at(
"name").is_string()) {
508 return mcp::core::unexpected(
513 if (json.contains(
"title")) {
514 resource_template.title = json.at(
"title").get<std::string>();
516 resource_template.uri_template = json.at(
"uriTemplate").get<std::string>();
517 resource_template.name = json.at(
"name").get<std::string>();
518 if (json.contains(
"description")) {
519 if (!json.at(
"description").is_string()) {
521 "resource template description must be a string"));
523 resource_template.description = json.at(
"description").get<std::string>();
525 if (json.contains(
"mimeType")) {
526 if (!json.at(
"mimeType").is_string()) {
527 return mcp::core::unexpected(
530 resource_template.mime_type = json.at(
"mimeType").get<std::string>();
532 if (json.contains(
"size")) {
534 resource_size_from_json(json.at(
"size"),
"resource template");
536 return mcp::core::unexpected(size.error());
538 resource_template.size = *size;
540 if (json.contains(
"icons")) {
541 if (!json.at(
"icons").is_array()) {
542 return mcp::core::unexpected(
545 for (
const auto& item : json.at(
"icons")) {
547 if (!icon.has_value()) {
548 return mcp::core::unexpected(
551 resource_template.icons.push_back(*icon);
554 if (json.contains(
"annotations")) {
555 if (!json.at(
"annotations").is_object()) {
557 "resource template annotations must be an object"));
559 resource_template.annotations = json.at(
"annotations");
561 if (json.contains(
"_meta")) {
562 if (!json.at(
"_meta").is_object()) {
563 return mcp::core::unexpected(
566 resource_template.meta = json.at(
"_meta");
569 json, {
"title",
"uriTemplate",
"name",
"description",
"mimeType",
"size",
570 "icons",
"annotations",
"_meta"});
571 return resource_template;
576 Json json = Json::object();
577 json[
"resources"] = Json::array();
578 for (
const auto& resource : result.
resources) {
584 if (result.
meta.has_value()) {
585 json[
"_meta"] = *result.
meta;
587 if (result.
ttl_ms.has_value()) {
588 json[
"ttlMs"] = *result.
ttl_ms;
601 if (!json.is_object()) {
602 return mcp::core::unexpected(
605 if (!json.contains(
"resources") || !json.at(
"resources").is_array()) {
607 "resources/list result requires a resources array"));
611 for (
const auto& item : json.at(
"resources")) {
614 return mcp::core::unexpected(resource.error());
618 if (json.contains(
"nextCursor")) {
619 if (!json.at(
"nextCursor").is_string()) {
620 return mcp::core::unexpected(
623 result.
next_cursor = json.at(
"nextCursor").get<std::string>();
625 if (json.contains(
"_meta")) {
626 if (!json.at(
"_meta").is_object()) {
627 return mcp::core::unexpected(
630 result.
meta = json.at(
"_meta");
640 Json json = Json::object();
641 json[
"resourceTemplates"] = Json::array();
643 json[
"resourceTemplates"].push_back(
649 if (result.
meta.has_value()) {
650 json[
"_meta"] = *result.
meta;
652 if (result.
ttl_ms.has_value()) {
653 json[
"ttlMs"] = *result.
ttl_ms;
666 if (!json.is_object()) {
668 "resources/templates/list result must be an object"));
670 if (!json.contains(
"resourceTemplates") ||
671 !json.at(
"resourceTemplates").is_array()) {
673 "resources/templates/list result requires a resourceTemplates array"));
677 for (
const auto& item : json.at(
"resourceTemplates")) {
679 if (!resource_template) {
680 return mcp::core::unexpected(resource_template.error());
684 if (json.contains(
"nextCursor")) {
685 if (!json.at(
"nextCursor").is_string()) {
687 "resources/templates/list nextCursor must be a string"));
689 result.
next_cursor = json.at(
"nextCursor").get<std::string>();
691 if (json.contains(
"_meta")) {
692 if (!json.at(
"_meta").is_object()) {
694 "resources/templates/list result _meta must be an object"));
696 result.
meta = json.at(
"_meta");
699 json, {
"resourceTemplates",
"nextCursor",
"_meta"});
706 if (params.
meta.has_value()) {
707 json[
"_meta"] = *params.
meta;
717 if (!json.is_object()) {
718 return mcp::core::unexpected(
721 if (!json.contains(
"uri") || !json.at(
"uri").is_string()) {
722 return mcp::core::unexpected(
726 params.
uri = json.at(
"uri").get<std::string>();
727 if (json.contains(
"_meta")) {
728 if (!json.at(
"_meta").is_object()) {
729 return mcp::core::unexpected(
732 params.
meta = json.at(
"_meta");
742 if (params.
meta.has_value()) {
743 json[
"_meta"] = *params.
meta;
753 if (!json.is_object()) {
754 return mcp::core::unexpected(
757 if (!json.contains(
"uri") || !json.at(
"uri").is_string()) {
758 return mcp::core::unexpected(
762 params.
uri = json.at(
"uri").get<std::string>();
763 if (json.contains(
"_meta")) {
764 if (!json.at(
"_meta").is_object()) {
765 return mcp::core::unexpected(
768 params.
meta = json.at(
"_meta");
797 auto result = reflect_from_json<ResourceContents>(json);
801 if (!result->text.has_value() && !result->blob.has_value()) {
802 return mcp::core::unexpected(
810 Json json = Json::object();
811 json[
"contents"] = Json::array();
812 for (
const auto& contents : result.
contents) {
815 if (result.
meta.has_value()) {
816 json[
"_meta"] = *result.
meta;
818 if (result.
ttl_ms.has_value()) {
819 json[
"ttlMs"] = *result.
ttl_ms;
832 if (!json.is_object()) {
833 return mcp::core::unexpected(
836 if (!json.contains(
"contents") || !json.at(
"contents").is_array()) {
837 return mcp::core::unexpected(
842 for (
const auto& item : json.at(
"contents")) {
845 return mcp::core::unexpected(contents.error());
847 result.
contents.push_back(*contents);
849 if (json.contains(
"_meta")) {
850 if (!json.at(
"_meta").is_object()) {
851 return mcp::core::unexpected(
854 result.
meta = json.at(
"_meta");
869 return reflect_from_json<ResourceUpdatedNotificationParams>(json);
Fluent builder for concrete resource descriptors.
Definition resource.hpp:52
Fluent builder for resource-template descriptors.
Definition resource.hpp:151
Shared JSON, JSON-RPC, error, cancellation, and progress model types.
void append_json_extensions(Json &json, const Json &extensions)
Flattens extension members into a JSON object without overwriting typed fields.
Definition types.hpp:358
nlohmann::json Json
JSON value type used by all protocol DTOs.
Definition types.hpp:28
Json collect_json_extensions(const Json &json, std::initializer_list< std::string_view > known_keys)
Collects unknown object members so typed DTOs can preserve future protocol fields and vendor extensio...
Definition types.hpp:320
C++17 tuple-reflection infrastructure for zero-boilerplate DTO serialization.
#define CXXMCP_REFLECT_CHECK(Struct, expected_count)
Validates that a Reflect<> specialization covers the expected number of fields.
Definition reflect.hpp:1008
constexpr FieldDescriptor< Struct, Field > field(const char *wire_name, Field Struct::*pointer)
Creates a FieldDescriptor with wire name and pointer-to-member.
Definition reflect.hpp:75
ExtensionsField< Struct > extensions_field(Json Struct::*pointer, std::vector< std::string > own_keys)
Creates an ExtensionsField descriptor.
Definition reflect.hpp:90
Json reflect_to_json(const T &obj)
Serializes a DTO to JSON using its Reflect<T> trait.
Definition reflect.hpp:701
ResourceBuilder resource_definition(std::string uri, std::string name)
Creates a fluent builder for advertised MCP resource metadata.
Definition resource.hpp:106
Json resource_contents_to_json(const ResourceContents &contents)
Serializes resource contents.
Definition resource.hpp:788
core::Result< ResourcesSubscribeParams > resources_subscribe_params_from_json(const Json &json)
Parses resources/subscribe params.
Definition resource.hpp:752
core::Result< ResourcesReadParams > resources_read_params_from_json(const Json &json)
Parses resources/read params.
Definition resource.hpp:715
core::Result< ResourcesUnsubscribeParams > resources_unsubscribe_params_from_json(const Json &json)
Parses resources/unsubscribe params.
Definition resource.hpp:783
Json resource_template_to_json(const ResourceTemplate &resource_template)
Serializes a resource template descriptor.
Definition resource.hpp:456
core::Result< ResourcesReadResult > resources_read_result_from_json(const Json &json)
Parses a resources/read result.
Definition resource.hpp:830
core::Result< ResourceUpdatedNotificationParams > resource_updated_notification_params_from_json(const Json &json)
Parses notifications/resources/updated params.
Definition resource.hpp:868
core::Result< ResourceContents > resource_contents_from_json(const Json &json)
Parses resource contents.
Definition resource.hpp:795
core::Result< ResourcesListResult > resources_list_result_from_json(const Json &json)
Parses a resources/list result.
Definition resource.hpp:599
core::Result< ResourceTemplatesListResult > resource_templates_list_result_from_json(const Json &json)
Parses a resources/templates/list result.
Definition resource.hpp:665
Json resources_read_params_to_json(const ResourcesReadParams ¶ms)
Serializes resources/read params.
Definition resource.hpp:704
Json resource_updated_notification_params_to_json(const ResourceUpdatedNotificationParams ¶ms)
Serializes notifications/resources/updated params.
Definition resource.hpp:861
core::Result< Resource > resource_from_json(const Json &json)
Parses a resource descriptor.
Definition resource.hpp:374
Json resources_read_result_to_json(const ResourcesReadResult &result)
Serializes a resources/read result.
Definition resource.hpp:809
core::Result< ResourceTemplate > resource_template_from_json(const Json &json)
Parses a resource template descriptor.
Definition resource.hpp:491
core::Error resource_json_error(std::string message)
Builds an InvalidRequest error for resource JSON validation failures.
Definition resource.hpp:319
Json resources_subscribe_params_to_json(const ResourcesSubscribeParams ¶ms)
Serializes resources/subscribe params.
Definition resource.hpp:739
ResourceTemplateBuilder resource_template_definition(std::string uri_template, std::string name)
Creates a fluent builder for advertised resource-template metadata.
Definition resource.hpp:205
Json resource_templates_list_result_to_json(const ResourceTemplatesListResult &result)
Serializes a resources/templates/list result.
Definition resource.hpp:638
Json resources_list_result_to_json(const ResourcesListResult &result)
Serializes a resources/list result.
Definition resource.hpp:575
Json resource_to_json(const Resource &resource)
Serializes a resource descriptor.
Definition resource.hpp:340
Json resources_unsubscribe_params_to_json(const ResourcesUnsubscribeParams ¶ms)
Serializes resources/unsubscribe params.
Definition resource.hpp:775
Shared result and error primitives used by the public cxxmcp SDK.
tl::expected< T, Error > Result
Alias for the SDK result type.
Definition result.hpp:64
Structured error returned by fallible SDK operations.
Definition result.hpp:35
Icon descriptor used by tools, resources, resource templates, and prompts.
Definition types.hpp:160
Primary template.
Definition reflect.hpp:199
One content part returned by resources/read.
Definition resource.hpp:250
std::optional< std::string > text
Text content when the resource is represented as UTF-8 text.
Definition resource.hpp:256
std::optional< std::string > blob
Base64-encoded binary content when the resource is not text.
Definition resource.hpp:258
std::string uri
URI of the resource content.
Definition resource.hpp:252
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:262
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:260
std::string mime_type
Optional MIME type of this content part.
Definition resource.hpp:254
URI template advertised by resources/templates/list.
Definition resource.hpp:127
Json annotations
Optional annotations for model or client presentation.
Definition resource.hpp:143
std::string mime_type
Optional MIME type expected for matching resources.
Definition resource.hpp:137
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:147
std::string description
Optional human-readable description.
Definition resource.hpp:135
std::vector< Icon > icons
Optional icon descriptors for client presentation.
Definition resource.hpp:141
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:145
std::optional< std::int64_t > size
Optional size hint in bytes when known.
Definition resource.hpp:139
std::string uri_template
URI template string that can be expanded into concrete resource URIs.
Definition resource.hpp:131
std::string title
Optional human-readable display title.
Definition resource.hpp:129
std::string name
Stable template name.
Definition resource.hpp:133
Result object for resources/templates/list.
Definition resource.hpp:211
std::vector< ResourceTemplate > resource_templates
Resource templates available to the caller.
Definition resource.hpp:213
std::optional< std::string > cache_scope
Cache scope hint: "public" or "private" (SEP-2549).
Definition resource.hpp:223
std::optional< std::string > next_cursor
Optional cursor for retrieving the next page.
Definition resource.hpp:215
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:219
std::optional< std::int64_t > ttl_ms
Cache time-to-live hint in milliseconds (SEP-2549).
Definition resource.hpp:221
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:217
Parameters for notifications/resources/updated.
Definition resource.hpp:299
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:303
std::string uri
URI of the resource that was updated.
Definition resource.hpp:301
Concrete resource advertised by resources/list.
Definition resource.hpp:28
std::string title
Optional human-readable display title.
Definition resource.hpp:30
std::string name
Stable resource name.
Definition resource.hpp:34
std::string uri
Stable URI used by resources/read and subscription methods.
Definition resource.hpp:32
std::string mime_type
Optional MIME type for the resource contents.
Definition resource.hpp:38
std::string description
Optional human-readable description.
Definition resource.hpp:36
Json annotations
Optional annotations for model or client presentation.
Definition resource.hpp:44
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:46
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:48
std::optional< std::int64_t > size
Optional size hint in bytes when known.
Definition resource.hpp:40
std::vector< Icon > icons
Optional icon descriptors for client presentation.
Definition resource.hpp:42
Result object for resources/list.
Definition resource.hpp:111
std::optional< std::string > next_cursor
Optional cursor for retrieving the next page.
Definition resource.hpp:115
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:117
std::vector< Resource > resources
Resources available to the caller.
Definition resource.hpp:113
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:119
std::optional< std::int64_t > ttl_ms
Cache time-to-live hint in milliseconds (SEP-2549).
Definition resource.hpp:121
std::optional< std::string > cache_scope
Cache scope hint: "public" or "private" (SEP-2549).
Definition resource.hpp:123
Parameters for resources/read.
Definition resource.hpp:227
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:231
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:233
std::string uri
URI of the resource to read.
Definition resource.hpp:229
Result object for resources/read.
Definition resource.hpp:285
std::optional< std::string > cache_scope
Cache scope hint: "public" or "private" (SEP-2549).
Definition resource.hpp:295
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:289
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:291
std::vector< ResourceContents > contents
One or more content parts for the requested URI.
Definition resource.hpp:287
std::optional< std::int64_t > ttl_ms
Cache time-to-live hint in milliseconds (SEP-2549).
Definition resource.hpp:293
Parameters for resources/subscribe.
Definition resource.hpp:237
std::optional< Json > meta
Optional _meta extension object preserved on the wire.
Definition resource.hpp:241
std::string uri
URI of the resource to subscribe to.
Definition resource.hpp:239
Json extensions
Unknown JSON members preserved for forward-compatible round trips.
Definition resource.hpp:243
Reflection specializations for DTOs defined in types.hpp.
Json icon_to_json(const Icon &icon)
Serializes a shared icon descriptor.
Definition types_reflect.hpp:109
std::optional< Icon > icon_from_json(const Json &json)
Parses a shared icon descriptor.
Definition types_reflect.hpp:114