16#include "llvm/ADT/StringExtras.h"
17#include "llvm/Support/Error.h"
18#include "llvm/Support/Threading.h"
28static constexpr
llvm::StringLiteral
kName =
"lldb-mcp";
47 return std::make_unique<ProtocolServerMCP>();
58 "MCP initialization complete");
61 std::make_unique<CommandTool>(
"command",
"Run an lldb command."));
62 server.
AddTool(std::make_unique<DebuggerListTool>(
63 "debugger_list",
"List debugger instances with their debugger_id."));
69 std::string client_name = llvm::formatv(
"client_{0}", ++
m_client_count);
70 LLDB_LOG(log,
"New MCP client connected: {0}", client_name);
73 auto transport_up = std::make_unique<lldb_protocol::mcp::Transport>(
74 io_sp, io_sp, [client_name](llvm::StringRef message) {
78 auto instance_up = std::make_unique<lldb_protocol::mcp::Server>(
81 [client_name](llvm::StringRef message) {
86 [
this, transport_ptr]() {
m_instances.erase(transport_ptr); });
88 llvm::Expected<MainLoop::ReadHandleUP> handle =
89 transport_up->RegisterMessageHandler(
m_loop, *instance_up);
91 LLDB_LOG_ERROR(log, handle.takeError(),
"Failed to run MCP server: {0}");
95 std::make_tuple<ServerUP, ReadHandleUP, TransportUP>(
96 std::move(instance_up), std::move(*handle), std::move(transport_up));
100 std::lock_guard<std::mutex> guard(
m_mutex);
103 return llvm::createStringError(
"the MCP server is already running");
116 this, std::placeholders::_1));
117 if (llvm::Error
error = handles.takeError())
120 auto listening_uris =
m_listener->GetListeningConnectionURI();
121 if (listening_uris.empty())
123 std::string address =
124 llvm::join(
m_listener->GetListeningConnectionURI(),
", ");
129 return handle.takeError();
135 llvm::set_thread_name(
"protocol-server.mcp");
139 return llvm::Error::success();
144 std::lock_guard<std::mutex> guard(
m_mutex);
151 m_loop.AddPendingCallback(
162 return llvm::Error::success();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
static constexpr llvm::StringLiteral kName
static constexpr llvm::StringLiteral kVersion
static llvm::Error createStringError(const char *format, Args &&...args)
virtual void RequestTermination()
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
static llvm::Error Terminate()
static std::unique_ptr< Socket > Create(const SocketProtocol protocol, Status &error)
bool Fail() const
Test for error condition.
std::unique_ptr< Socket > m_listener
virtual void Extend(lldb_protocol::mcp::Server &server) const
std::thread m_loop_thread
virtual llvm::Error Start(ProtocolServer::Connection connection) override
static lldb::ProtocolServerUP CreateInstance()
virtual llvm::Error Stop() override
void AcceptCallback(std::unique_ptr< Socket > socket)
static llvm::StringRef GetPluginNameStatic()
lldb_protocol::mcp::ServerInfoHandle m_server_info_handle
std::map< lldb_protocol::mcp::MCPTransport *, std::tuple< ServerUP, ReadHandleUP, TransportUP > > m_instances
static llvm::StringRef GetPluginDescriptionStatic()
virtual ~ProtocolServerMCP() override
lldb_private::MainLoop m_loop
std::vector< ReadHandleUP > m_listen_handlers
void AddTool(std::unique_ptr< Tool > tool)
void AddResourceProvider(std::unique_ptr< ResourceProvider > resource_provider)
void AddNotificationHandler(llvm::StringRef method, NotificationHandler handler)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
lldb_private::Transport< Request, Response, Notification > MCPTransport
Generic transport that uses the MCP protocol.
std::shared_ptr< lldb_private::IOObject > IOObjectSP
std::unique_ptr< lldb_private::ProtocolServer > ProtocolServerUP
Socket::SocketProtocol protocol
A notification which does not expect a response.
Information about this instance of lldb's MCP server for lldb-mcp to use to coordinate connecting an ...
static llvm::Expected< ServerInfoHandle > Write(const ServerInfo &)
Writes the server info into a unique file in ~/.lldb.