10#include "llvm/Support/ErrorHandling.h"
11#include "llvm/Support/JSON.h"
17static bool mapRaw(
const json::Value &Params, StringLiteral Prop,
18 std::optional<json::Value> &V, json::Path P) {
19 const auto *O = Params.getAsObject();
21 P.report(
"expected object");
24 const json::Value *E = O->get(Prop);
31 if (
const int64_t *I = std::get_if<int64_t>(&
Id))
32 return json::Value(*I);
33 if (
const std::string *S = std::get_if<std::string>(&
Id))
34 return json::Value(*S);
35 llvm_unreachable(
"unexpected type in protocol::Id");
38static bool mapId(
const llvm::json::Value &V, StringLiteral Prop,
Id &
Id,
40 const auto *O = V.getAsObject();
42 P.report(
"expected object");
46 const auto *E = O->get(Prop);
48 P.field(Prop).report(
"not found");
52 if (
auto S = E->getAsString()) {
57 if (
auto I = E->getAsInteger()) {
62 P.report(
"expected string or number");
70 Result.insert({
"params", R.
params});
75 llvm::json::ObjectMapper O(V, P);
76 return O &&
mapId(V,
"id", R.
id, P) && O.map(
"method", R.
method) &&
85 llvm::json::Object Result{{
"code", E.
code}, {
"message", E.
message}};
87 Result.insert({
"data", *E.
data});
91bool fromJSON(
const llvm::json::Value &V,
Error &E, llvm::json::Path P) {
92 llvm::json::ObjectMapper O(V, P);
93 return O && O.map(
"code", E.
code) && O.map(
"message", E.
message) &&
102 llvm::json::Object Result{{
"jsonrpc",
"2.0"}, {
"id",
toJSON(R.
id)}};
105 Result.insert({
"error", *
error});
106 if (
const json::Value *result = std::get_if<json::Value>(&R.
result))
107 Result.insert({
"result", *result});
112 const json::Object *E = V.getAsObject();
114 P.report(
"expected object");
118 const json::Value *result = E->get(
"result");
119 const json::Value *raw_error = E->get(
"error");
121 if (result && raw_error) {
122 P.report(
"'result' and 'error' fields are mutually exclusive");
126 if (!result && !raw_error) {
127 P.report(
"'result' or 'error' fields are required'");
132 R.
result = std::move(*result);
140 return mapId(V,
"id", R.
id, P);
148 llvm::json::Object Result{{
"jsonrpc",
"2.0"}, {
"method", N.method}};
150 Result.insert({
"params", N.params});
155 llvm::json::ObjectMapper O(V, P);
156 if (!O || !O.map(
"method", N.method))
158 auto *Obj = V.getAsObject();
161 if (
auto *Params = Obj->get(
"params"))
171 llvm::json::ObjectMapper O(V, P);
172 return O && O.map(
"uri", R.
uri) && O.map(
"name", R.
name) &&
174 O.mapOptional(
"mimeType", R.
mimeType);
178 llvm::json::Object Result{{
"uri", R.
uri}, {
"name", R.
name}};
182 Result.insert({
"mimeType", R.
mimeType});
187 llvm::json::Object Result{{
"uri", RC.
uri}, {
"text", RC.
text}};
189 Result.insert({
"mimeType", RC.
mimeType});
194 llvm::json::Path P) {
195 llvm::json::ObjectMapper O(V, P);
196 return O && O.map(
"uri", RC.
uri) && O.map(
"text", RC.
text) &&
197 O.mapOptional(
"mimeType", RC.
mimeType);
201 return llvm::json::Object{{
"contents", RR.
contents}};
205 llvm::json::Path P) {
206 llvm::json::ObjectMapper O(V, P);
207 return O && O.map(
"contents", RR.
contents);
211 return llvm::json::Object{{
"type",
"text"}, {
"text", TC.
text}};
215 llvm::json::ObjectMapper O(V, P);
216 return O && O.map(
"text", TC.
text);
220 llvm::json::Object Result{{
"name", TD.
name}};
229 llvm::json::Path P) {
231 llvm::json::ObjectMapper O(V, P);
232 if (!O || !O.map(
"name", TD.
name) ||
239 return std::visit([](
auto &M) {
return toJSON(M); }, M);
243 const auto *O = V.getAsObject();
245 P.report(
"expected object");
249 if (
const json::Value *V = O->get(
"jsonrpc")) {
250 if (V->getAsString().value_or(
"") !=
"2.0") {
251 P.report(
"unsupported JSON RPC version");
255 P.report(
"not a valid JSON RPC message");
268 if (O->get(
"method")) {
276 if (O->get(
"result") || O->get(
"error")) {
284 P.report(
"unrecognized message type");
289 json::Object result{{
"name", I.
name}, {
"version", I.
version}};
291 if (!I.
title.empty())
292 result.insert({
"title", I.
title});
298 json::ObjectMapper O(V, P);
299 return O && O.map(
"name", I.
name) && O.mapOptional(
"title", I.
title) &&
300 O.mapOptional(
"version", I.
version);
310 json::Object result{};
313 result.insert({
"tools", json::Object{{
"listChanged",
true}}});
316 json::Object resources;
318 resources.insert({
"listChanged",
true});
320 resources.insert({
"subscribe",
true});
321 result.insert({
"resources", std::move(resources)});
325 result.insert({
"completions", json::Object{}});
328 result.insert({
"logging", json::Object{}});
334 const json::Object *O = V.getAsObject();
336 P.report(
"expected object");
340 if (O->find(
"tools") != O->end())
355 json::ObjectMapper O(V, P);
373 json::ObjectMapper O(V, P);
381 return json::Object{{
"tools", R.
tools}};
385 json::ObjectMapper O(V, P);
386 return O && O.map(
"tools", R.
tools);
390 json::Object result{{
"content", R.
content}};
393 result.insert({
"isError", R.
isError});
401 json::ObjectMapper O(V, P);
402 return O && O.map(
"content", R.
content) &&
403 O.mapOptional(
"isError", R.
isError) &&
408 json::Object result{{
"name", R.
name}};
411 result.insert({
"arguments", *R.
arguments});
417 json::ObjectMapper O(V, P);
422 return json::Object{{
"uri", R.
uri}};
426 json::ObjectMapper O(V, P);
427 return O && O.map(
"uri", R.
uri);
431 return json::Object{{
"resources", R.
resources}};
435 json::ObjectMapper O(V, P);
436 return O && O.map(
"resources", R.
resources);
441bool fromJSON(
const json::Value &V,
Void &R, json::Path P) {
return true; }
static llvm::raw_ostream & error(Stream &strm)
std::variant< Request, Response, Notification > Message
A general message as defined by the JSON-RPC 2.0 spec.
std::monostate Void
Special case parameter or result that has no value.
std::variant< int64_t, std::string > Id
A Request or Response 'id'.
llvm::json::Value toJSON(const Request &)
bool operator==(const Request &, const Request &)
static bool mapRaw(const json::Value &Params, StringLiteral Prop, std::optional< json::Value > &V, json::Path P)
static bool mapId(const llvm::json::Value &V, StringLiteral Prop, Id &Id, llvm::json::Path P)
bool fromJSON(const llvm::json::Value &, Request &, llvm::json::Path)
Capabilities a client may support.
std::string message
A short description of the error.
std::optional< llvm::json::Value > data
Additional information about the error.
int64_t code
The error type that occurred.
Describes the name and version of an MCP implementation, with an optional title for UI representation...
std::string title
Intended for UI and end-user contexts — optimized to be human-readable and easily understood,...
std::string name
Intended for programmatic or logical use, but used as a display name in past specs or fallback (if ti...
Implementation clientInfo
std::string protocolVersion
The latest version of the Model Context Protocol that the client supports.
ClientCapabilities capabilities
After receiving an initialize request from the client, the server sends this response.
std::string protocolVersion
The version of the Model Context Protocol that the server wants to use.
std::string instructions
Instructions describing how to use the server and its features.
ServerCapabilities capabilities
Implementation serverInfo
The server’s response to a resources/list request from the client.
std::vector< Resource > resources
A notification which does not expect a response.
std::optional< llvm::json::Value > params
The notification's params.
std::string method
The method to be invoked.
Sent from the client to the server, to read a specific resource URI.
std::string uri
The URI of the resource to read.
The server's response to a resources/read request from the client.
std::vector< TextResourceContents > contents
A request that expects a response.
std::optional< llvm::json::Value > params
The method's params.
std::string method
The method to be invoked.
A known resource that the server is capable of reading.
std::string description
A description of what this resource represents.
std::string uri
The URI of this resource.
std::string mimeType
The MIME type of this resource, if known.
std::string name
A human-readable name for this resource.
A response to a request, either an error or a result.
std::variant< Error, llvm::json::Value > result
The result of the request, either an Error or the JSON value of the response.
Capabilities that a server may support.
bool supportsCompletions
Utilities.
bool supportsResourcesList
bool supportsResourcesSubscribe
Text provided to or from an LLM.
std::string text
The text content of the message.
The contents of a specific resource or sub-resource.
std::string text
The text of the item.
std::string uri
The URI of this resource.
std::string mimeType
The MIME type of this resource, if known.