Skip to content

Commit e67ef3e

Browse files
authored
Merge pull request #11599 from swiftlang/lldb-mcp-backport-before-json
2 parents f3a4f1e + 642311b commit e67ef3e

File tree

25 files changed

+711
-540
lines changed

25 files changed

+711
-540
lines changed

lldb/source/Plugins/Protocol/MCP/MCPError.h renamed to lldb/include/lldb/Protocol/MCP/MCPError.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
//===-- MCPError.h --------------------------------------------------------===//
1+
//===----------------------------------------------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "Protocol.h"
9+
#ifndef LLDB_PROTOCOL_MCP_MCPERROR_H
10+
#define LLDB_PROTOCOL_MCP_MCPERROR_H
11+
12+
#include "lldb/Protocol/MCP/Protocol.h"
1013
#include "llvm/Support/Error.h"
11-
#include "llvm/Support/FormatVariadic.h"
1214
#include <string>
1315

14-
namespace lldb_private::mcp {
16+
namespace lldb_protocol::mcp {
1517

1618
class MCPError : public llvm::ErrorInfo<MCPError> {
1719
public:
@@ -24,7 +26,7 @@ class MCPError : public llvm::ErrorInfo<MCPError> {
2426

2527
const std::string &getMessage() const { return m_message; }
2628

27-
protocol::Error toProtcolError() const;
29+
lldb_protocol::mcp::Error toProtocolError() const;
2830

2931
static constexpr int64_t kResourceNotFound = -32002;
3032
static constexpr int64_t kInternalError = -32603;
@@ -47,4 +49,6 @@ class UnsupportedURI : public llvm::ErrorInfo<UnsupportedURI> {
4749
std::string m_uri;
4850
};
4951

50-
} // namespace lldb_private::mcp
52+
} // namespace lldb_protocol::mcp
53+
54+
#endif

lldb/source/Plugins/Protocol/MCP/Protocol.h renamed to lldb/include/lldb/Protocol/MCP/Protocol.h

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,62 +11,88 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14-
#ifndef LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOL_H
15-
#define LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOL_H
14+
#ifndef LLDB_PROTOCOL_MCP_PROTOCOL_H
15+
#define LLDB_PROTOCOL_MCP_PROTOCOL_H
1616

1717
#include "llvm/Support/JSON.h"
1818
#include <optional>
1919
#include <string>
2020
#include <variant>
2121

22-
namespace lldb_private::mcp::protocol {
22+
namespace lldb_protocol::mcp {
2323

24-
static llvm::StringLiteral kVersion = "2024-11-05";
24+
static llvm::StringLiteral kProtocolVersion = "2024-11-05";
25+
26+
/// A Request or Response 'id'.
27+
///
28+
/// NOTE: This differs from the JSON-RPC 2.0 spec. The MCP spec says this must
29+
/// be a string or number, excluding a json 'null' as a valid id.
30+
using Id = std::variant<int64_t, std::string>;
2531

2632
/// A request that expects a response.
2733
struct Request {
28-
uint64_t id = 0;
34+
/// The request id.
35+
Id id = 0;
36+
/// The method to be invoked.
2937
std::string method;
38+
/// The method's params.
3039
std::optional<llvm::json::Value> params;
3140
};
3241

3342
llvm::json::Value toJSON(const Request &);
3443
bool fromJSON(const llvm::json::Value &, Request &, llvm::json::Path);
44+
bool operator==(const Request &, const Request &);
3545

36-
struct ErrorInfo {
46+
struct Error {
47+
/// The error type that occurred.
3748
int64_t code = 0;
49+
/// A short description of the error. The message SHOULD be limited to a
50+
/// concise single sentence.
3851
std::string message;
39-
std::string data;
40-
};
41-
42-
llvm::json::Value toJSON(const ErrorInfo &);
43-
bool fromJSON(const llvm::json::Value &, ErrorInfo &, llvm::json::Path);
44-
45-
struct Error {
46-
uint64_t id = 0;
47-
ErrorInfo error;
52+
/// Additional information about the error. The value of this member is
53+
/// defined by the sender (e.g. detailed error information, nested errors
54+
/// etc.).
55+
std::optional<llvm::json::Value> data;
4856
};
4957

5058
llvm::json::Value toJSON(const Error &);
5159
bool fromJSON(const llvm::json::Value &, Error &, llvm::json::Path);
60+
bool operator==(const Error &, const Error &);
5261

62+
/// A response to a request, either an error or a result.
5363
struct Response {
54-
uint64_t id = 0;
55-
std::optional<llvm::json::Value> result;
56-
std::optional<ErrorInfo> error;
64+
/// The request id.
65+
Id id = 0;
66+
/// The result of the request, either an Error or the JSON value of the
67+
/// response.
68+
std::variant<Error, llvm::json::Value> result;
5769
};
5870

5971
llvm::json::Value toJSON(const Response &);
6072
bool fromJSON(const llvm::json::Value &, Response &, llvm::json::Path);
73+
bool operator==(const Response &, const Response &);
6174

6275
/// A notification which does not expect a response.
6376
struct Notification {
77+
/// The method to be invoked.
6478
std::string method;
79+
/// The notification's params.
6580
std::optional<llvm::json::Value> params;
6681
};
6782

6883
llvm::json::Value toJSON(const Notification &);
6984
bool fromJSON(const llvm::json::Value &, Notification &, llvm::json::Path);
85+
bool operator==(const Notification &, const Notification &);
86+
87+
/// A general message as defined by the JSON-RPC 2.0 spec.
88+
using Message = std::variant<Request, Response, Notification>;
89+
// With clang-cl and MSVC STL 202208, convertible can be false later if we do
90+
// not force it to be checked early here.
91+
static_assert(std::is_convertible_v<Message, Message>,
92+
"Message is not convertible to itself");
93+
94+
bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
95+
llvm::json::Value toJSON(const Message &);
7096

7197
struct ToolCapability {
7298
/// Whether this server supports notifications for changes to the tool list.
@@ -176,13 +202,8 @@ struct ToolDefinition {
176202
llvm::json::Value toJSON(const ToolDefinition &);
177203
bool fromJSON(const llvm::json::Value &, ToolDefinition &, llvm::json::Path);
178204

179-
using Message = std::variant<Request, Response, Notification, Error>;
180-
181-
bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
182-
llvm::json::Value toJSON(const Message &);
183-
184205
using ToolArguments = std::variant<std::monostate, llvm::json::Value>;
185206

186-
} // namespace lldb_private::mcp::protocol
207+
} // namespace lldb_protocol::mcp
187208

188209
#endif
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_PROTOCOL_MCP_RESOURCE_H
10+
#define LLDB_PROTOCOL_MCP_RESOURCE_H
11+
12+
#include "lldb/Protocol/MCP/Protocol.h"
13+
#include <vector>
14+
15+
namespace lldb_protocol::mcp {
16+
17+
class ResourceProvider {
18+
public:
19+
ResourceProvider() = default;
20+
virtual ~ResourceProvider() = default;
21+
22+
virtual std::vector<lldb_protocol::mcp::Resource> GetResources() const = 0;
23+
virtual llvm::Expected<lldb_protocol::mcp::ResourceResult>
24+
ReadResource(llvm::StringRef uri) const = 0;
25+
};
26+
27+
} // namespace lldb_protocol::mcp
28+
29+
#endif
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_PROTOCOL_MCP_SERVER_H
10+
#define LLDB_PROTOCOL_MCP_SERVER_H
11+
12+
#include "lldb/Protocol/MCP/Protocol.h"
13+
#include "lldb/Protocol/MCP/Resource.h"
14+
#include "lldb/Protocol/MCP/Tool.h"
15+
#include "llvm/ADT/StringMap.h"
16+
#include "llvm/Support/Error.h"
17+
#include <mutex>
18+
19+
namespace lldb_protocol::mcp {
20+
21+
class Server {
22+
public:
23+
Server(std::string name, std::string version);
24+
virtual ~Server() = default;
25+
26+
void AddTool(std::unique_ptr<Tool> tool);
27+
void AddResourceProvider(std::unique_ptr<ResourceProvider> resource_provider);
28+
29+
protected:
30+
virtual Capabilities GetCapabilities() = 0;
31+
32+
using RequestHandler =
33+
std::function<llvm::Expected<Response>(const Request &)>;
34+
using NotificationHandler = std::function<void(const Notification &)>;
35+
36+
void AddRequestHandlers();
37+
38+
void AddRequestHandler(llvm::StringRef method, RequestHandler handler);
39+
void AddNotificationHandler(llvm::StringRef method,
40+
NotificationHandler handler);
41+
42+
llvm::Expected<std::optional<Message>> HandleData(llvm::StringRef data);
43+
44+
llvm::Expected<Response> Handle(Request request);
45+
void Handle(Notification notification);
46+
47+
llvm::Expected<Response> InitializeHandler(const Request &);
48+
49+
llvm::Expected<Response> ToolsListHandler(const Request &);
50+
llvm::Expected<Response> ToolsCallHandler(const Request &);
51+
52+
llvm::Expected<Response> ResourcesListHandler(const Request &);
53+
llvm::Expected<Response> ResourcesReadHandler(const Request &);
54+
55+
std::mutex m_mutex;
56+
57+
private:
58+
const std::string m_name;
59+
const std::string m_version;
60+
61+
llvm::StringMap<std::unique_ptr<Tool>> m_tools;
62+
std::vector<std::unique_ptr<ResourceProvider>> m_resource_providers;
63+
64+
llvm::StringMap<RequestHandler> m_request_handlers;
65+
llvm::StringMap<NotificationHandler> m_notification_handlers;
66+
};
67+
68+
} // namespace lldb_protocol::mcp
69+
70+
#endif
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_PROTOCOL_MCP_TOOL_H
10+
#define LLDB_PROTOCOL_MCP_TOOL_H
11+
12+
#include "lldb/Protocol/MCP/Protocol.h"
13+
#include "llvm/Support/JSON.h"
14+
#include <string>
15+
16+
namespace lldb_protocol::mcp {
17+
18+
class Tool {
19+
public:
20+
Tool(std::string name, std::string description);
21+
virtual ~Tool() = default;
22+
23+
virtual llvm::Expected<lldb_protocol::mcp::TextResult>
24+
Call(const lldb_protocol::mcp::ToolArguments &args) = 0;
25+
26+
virtual std::optional<llvm::json::Value> GetSchema() const {
27+
return llvm::json::Object{{"type", "object"}};
28+
}
29+
30+
lldb_protocol::mcp::ToolDefinition GetDefinition() const;
31+
32+
const std::string &GetName() { return m_name; }
33+
34+
private:
35+
std::string m_name;
36+
std::string m_description;
37+
};
38+
39+
} // namespace lldb_protocol::mcp
40+
41+
#endif

lldb/source/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_subdirectory(Host)
1010
add_subdirectory(Initialization)
1111
add_subdirectory(Interpreter)
1212
add_subdirectory(Plugins)
13+
add_subdirectory(Protocol)
1314
add_subdirectory(Symbol)
1415
add_subdirectory(Target)
1516
add_subdirectory(Utility)
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
add_lldb_library(lldbPluginProtocolServerMCP PLUGIN
2-
MCPError.cpp
3-
Protocol.cpp
42
ProtocolServerMCP.cpp
53
Resource.cpp
64
Tool.cpp
@@ -10,5 +8,6 @@ add_lldb_library(lldbPluginProtocolServerMCP PLUGIN
108

119
LINK_LIBS
1210
lldbHost
11+
lldbProtocolMCP
1312
lldbUtility
1413
)

0 commit comments

Comments
 (0)