cxxmcp 1.1.6
C++ MCP SDK
Loading...
Searching...
No Matches
schema.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 [caomengxuan666]
2
3#pragma once
4
7
8#include <string>
9#include <type_traits>
10#include <utility>
11#include <vector>
12
15
16namespace mcp::protocol {
17
20 public:
21 static Json any() { return Json::object(); }
22
23 static Json object() { return Json{{"type", "object"}}; }
24
25 static Json string() { return Json{{"type", "string"}}; }
26
27 static Json integer() { return Json{{"type", "integer"}}; }
28
29 static Json number() { return Json{{"type", "number"}}; }
30
31 static Json boolean() { return Json{{"type", "boolean"}}; }
32
33 static Json array(Json items) {
34 return Json{{"type", "array"}, {"items", std::move(items)}};
35 }
36
37 static Json string_enum(std::vector<std::string> values) {
38 return Json{{"type", "string"}, {"enum", std::move(values)}};
39 }
40};
41
43template <class T, class Enable = void>
45 static Json schema() { return JsonSchema::object(); }
46};
47
48template <>
50 static Json schema() { return JsonSchema::any(); }
51};
52
53template <>
54struct SchemaTraits<std::string> {
55 static Json schema() { return JsonSchema::string(); }
56};
57
58template <>
59struct SchemaTraits<bool> {
60 static Json schema() { return JsonSchema::boolean(); }
61};
62
63template <class T>
65 T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>>> {
66 static Json schema() { return JsonSchema::integer(); }
67};
68
69template <class T>
70struct SchemaTraits<T, std::enable_if_t<std::is_floating_point_v<T>>> {
71 static Json schema() { return JsonSchema::number(); }
72};
73
75template <class T>
76inline Json schema_for();
77
78template <class T>
79struct SchemaTraits<std::vector<T>> {
80 static Json schema() { return JsonSchema::array(schema_for<T>()); }
81};
82
83template <class T>
84struct SchemaTraits<std::optional<T>> {
85 static Json schema() { return schema_for<T>(); }
86};
87
89namespace detail {
90
91template <typename Struct, typename Field>
92inline void add_reflected_field_schema(
93 Json& properties, Json& required,
95 if constexpr (is_optional_v<Field>) {
96 properties[fd.wire_name] = schema_for<typename Field::value_type>();
97 } else {
98 properties[fd.wire_name] = schema_for<Field>();
99 required.push_back(fd.wire_name);
100 }
101}
102
103template <typename Struct>
104inline void add_reflected_field_schema(Json&, Json&,
105 const ExtensionsField<Struct>&) {}
106
107template <typename Struct, typename Field>
108inline void add_reflected_field_schema(
109 Json&, Json&, const DeserializeOnlyField<Struct, Field>&) {}
110
111template <class T>
112inline Json reflect_schema() {
113 Json properties = Json::object();
114 Json required = Json::array();
115
116 std::apply(
117 [&](const auto&... fds) {
118 (add_reflected_field_schema(properties, required, fds), ...);
119 },
120 Reflect<T>::fields());
121
122 Json result = {{"type", "object"}, {"properties", std::move(properties)}};
123 if (!required.empty()) {
124 result["required"] = std::move(required);
125 }
126 result["additionalProperties"] = false;
127 return result;
128}
129
130} // namespace detail
131
136template <class T>
137inline Json schema_for() {
138 using Decayed = std::decay_t<T>;
139 if constexpr (has_reflect_v<Decayed>) {
140 return detail::reflect_schema<Decayed>();
141 } else {
143 }
144}
145
148 public:
150 schema_["type"] = "object";
151 schema_["properties"] = Json::object();
152 }
153
154 ObjectSchemaBuilder& title(std::string value) {
155 schema_["title"] = std::move(value);
156 return *this;
157 }
158
159 ObjectSchemaBuilder& description(std::string value) {
160 schema_["description"] = std::move(value);
161 return *this;
162 }
163
164 ObjectSchemaBuilder& property(std::string name, Json schema) {
165 schema_["properties"][std::move(name)] = std::move(schema);
166 return *this;
167 }
168
169 ObjectSchemaBuilder& optional_property(std::string name, Json schema) {
170 return property(std::move(name), std::move(schema));
171 }
172
173 ObjectSchemaBuilder& required(std::string name) {
174 schema_["required"].push_back(std::move(name));
175 return *this;
176 }
177
178 ObjectSchemaBuilder& required_property(std::string name, Json schema) {
179 const auto required_name = name;
180 property(std::move(name), std::move(schema));
181 return required(required_name);
182 }
183
184 ObjectSchemaBuilder& additional_properties(bool value) {
185 schema_["additionalProperties"] = value;
186 return *this;
187 }
188
189 Json build() const& { return schema_; }
190
191 Json build() && { return std::move(schema_); }
192
193 private:
194 Json schema_ = Json::object();
195};
196
199
200} // namespace mcp::protocol
Primitive JSON Schema helpers used by public SDK builders.
Definition schema.hpp:19
Fluent object-schema builder for tool input and output schemas.
Definition schema.hpp:147
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
C++17 tuple-reflection infrastructure for zero-boilerplate DTO serialization.
Json schema_for()
Returns the JSON Schema advertised for a C++ type.
Definition schema.hpp:137
ObjectSchemaBuilder object_schema()
Creates a fluent object-schema builder.
Definition schema.hpp:198
Describes a single DTO field: its JSON wire name, pointer-to-member, and optional post-deserializatio...
Definition reflect.hpp:41
Type-to-schema customization point for typed SDK helpers.
Definition schema.hpp:44