[Lldb-commits] [lldb] [lldb] Add lldb-mcp scaffolding (PR #155708)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Wed Aug 27 16:04:29 PDT 2025
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/155708
>From 9c2db2349ffd5fdcbbb5ceebf2a72979dd2a2e88 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Wed, 27 Aug 2025 15:15:48 -0700
Subject: [PATCH 1/2] [lldb] Add lldb-mcp scaffolding
Add the scaffolding for a new tool lldb-mcp. This utility is meant to
replace netcat and acts a proxy between the LLM and one or more LLDB
instances. In its current form, the utility is a trivial MCP server
without any tools or resources.
---
lldb/tools/CMakeLists.txt | 1 +
lldb/tools/lldb-mcp/CMakeLists.txt | 33 +++++++++
lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in | 21 ++++++
lldb/tools/lldb-mcp/lldb-mcp.cpp | 80 ++++++++++++++++++++++
4 files changed, 135 insertions(+)
create mode 100644 lldb/tools/lldb-mcp/CMakeLists.txt
create mode 100644 lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in
create mode 100644 lldb/tools/lldb-mcp/lldb-mcp.cpp
diff --git a/lldb/tools/CMakeLists.txt b/lldb/tools/CMakeLists.txt
index e2f039527ad75..4a0d2f695481d 100644
--- a/lldb/tools/CMakeLists.txt
+++ b/lldb/tools/CMakeLists.txt
@@ -10,6 +10,7 @@ add_subdirectory(lldb-fuzzer EXCLUDE_FROM_ALL)
add_lldb_tool_subdirectory(lldb-instr)
add_lldb_tool_subdirectory(lldb-dap)
+add_lldb_tool_subdirectory(lldb-mcp)
if (LLDB_BUILD_LLDBRPC)
add_lldb_tool_subdirectory(lldb-rpc-gen)
endif()
diff --git a/lldb/tools/lldb-mcp/CMakeLists.txt b/lldb/tools/lldb-mcp/CMakeLists.txt
new file mode 100644
index 0000000000000..7fe3301ab3081
--- /dev/null
+++ b/lldb/tools/lldb-mcp/CMakeLists.txt
@@ -0,0 +1,33 @@
+add_lldb_tool(lldb-mcp
+ lldb-mcp.cpp
+
+ LINK_COMPONENTS
+ Option
+ Support
+ LINK_LIBS
+ liblldb
+ lldbHost
+ lldbProtocolMCP
+ )
+
+if(APPLE)
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lldb-mcp-Info.plist.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lldb-mcp-Info.plist
+ )
+ target_link_options(lldb-mcp
+ PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_BINARY_DIR}/lldb-mcp-Info.plist)
+endif()
+
+if(LLDB_BUILD_FRAMEWORK)
+ # In the build-tree, we know the exact path to the framework directory.
+ # The installed framework can be in different locations.
+ lldb_setup_rpaths(lldb-mcp
+ BUILD_RPATH
+ "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}"
+ INSTALL_RPATH
+ "@loader_path/../../../SharedFrameworks"
+ "@loader_path/../../System/Library/PrivateFrameworks"
+ "@loader_path/../../Library/PrivateFrameworks"
+ )
+endif()
diff --git a/lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in b/lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in
new file mode 100644
index 0000000000000..7d01d3145d929
--- /dev/null
+++ b/lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.lldb-dap</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>lldb-dap</string>
+ <key>CFBundleVersion</key>
+ <string>${LLDB_VERSION}</string>
+ <key>SecTaskAccess</key>
+ <array>
+ <string>allowed</string>
+ <string>debug</string>
+ </array>
+</dict>
+</plist>
diff --git a/lldb/tools/lldb-mcp/lldb-mcp.cpp b/lldb/tools/lldb-mcp/lldb-mcp.cpp
new file mode 100644
index 0000000000000..3769b9a7408eb
--- /dev/null
+++ b/lldb/tools/lldb-mcp/lldb-mcp.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Config.h"
+#include "lldb/Host/File.h"
+#include "lldb/Host/MainLoop.h"
+#include "lldb/Host/MainLoopBase.h"
+#include "lldb/Protocol/MCP/Protocol.h"
+#include "lldb/Protocol/MCP/Server.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/WithColor.h"
+
+using namespace lldb_protocol::mcp;
+
+using lldb_private::File;
+using lldb_private::MainLoop;
+using lldb_private::MainLoopBase;
+using lldb_private::NativeFile;
+
+static constexpr llvm::StringLiteral kName = "lldb-mcp";
+static constexpr llvm::StringLiteral kVersion = "0.1.0";
+
+int main(int argc, char *argv[]) {
+ llvm::InitLLVM IL(argc, argv, /*InstallPipeSignalExitHandler=*/false);
+#if !defined(__APPLE__)
+ llvm::setBugReportMsg("PLEASE submit a bug report to " LLDB_BUG_REPORT_URL
+ " and include the crash backtrace.\n");
+#else
+ llvm::setBugReportMsg("PLEASE submit a bug report to " LLDB_BUG_REPORT_URL
+ " and include the crash report from "
+ "~/Library/Logs/DiagnosticReports/.\n");
+#endif
+
+#if defined(_WIN32)
+ // Windows opens stdout and stdin in text mode which converts \n to 13,10
+ // while the value is just 10 on Darwin/Linux. Setting the file mode to
+ // binary fixes this.
+ int result = _setmode(fileno(stdout), _O_BINARY);
+ assert(result);
+ result = _setmode(fileno(stdin), _O_BINARY);
+ UNUSED_IF_ASSERT_DISABLED(result);
+ assert(result);
+#endif
+
+ lldb::IOObjectSP input = std::make_shared<NativeFile>(
+ fileno(stdin), File::eOpenOptionReadOnly, NativeFile::Unowned);
+
+ lldb::IOObjectSP output = std::make_shared<NativeFile>(
+ fileno(stdout), File::eOpenOptionReadOnly, NativeFile::Unowned);
+
+ constexpr llvm::StringLiteral client_name = "stdio";
+ static MainLoop loop;
+
+ llvm::sys::SetInterruptFunction([]() {
+ loop.AddPendingCallback(
+ [](MainLoopBase &loop) { loop.RequestTermination(); });
+ });
+
+ auto transport_up = std::make_unique<lldb_protocol::mcp::MCPTransport>(
+ input, output, std::string(client_name),
+ [&](llvm::StringRef message) { llvm::errs() << message << '\n'; });
+
+ auto instance_up = std::make_unique<lldb_protocol::mcp::Server>(
+ std::string(kName), std::string(kVersion), std::move(transport_up), loop);
+
+ if (llvm::Error error = instance_up->Run()) {
+ llvm::logAllUnhandledErrors(std::move(error), llvm::WithColor::error(),
+ "DAP session error: ");
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
>From edbb8a9abc49ab3280bbffae5316d1c8f022605c Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Wed, 27 Aug 2025 16:04:16 -0700
Subject: [PATCH 2/2] Fix copy/paste errors
---
lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in | 4 ++--
lldb/tools/lldb-mcp/lldb-mcp.cpp | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in b/lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in
index 7d01d3145d929..4dc3ddd912808 100644
--- a/lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in
+++ b/lldb/tools/lldb-mcp/lldb-mcp-Info.plist.in
@@ -5,11 +5,11 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
- <string>com.apple.lldb-dap</string>
+ <string>com.apple.lldb-mcp</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
- <string>lldb-dap</string>
+ <string>lldb-mcp</string>
<key>CFBundleVersion</key>
<string>${LLDB_VERSION}</string>
<key>SecTaskAccess</key>
diff --git a/lldb/tools/lldb-mcp/lldb-mcp.cpp b/lldb/tools/lldb-mcp/lldb-mcp.cpp
index 3769b9a7408eb..42daabbe4da2f 100644
--- a/lldb/tools/lldb-mcp/lldb-mcp.cpp
+++ b/lldb/tools/lldb-mcp/lldb-mcp.cpp
@@ -53,7 +53,7 @@ int main(int argc, char *argv[]) {
fileno(stdin), File::eOpenOptionReadOnly, NativeFile::Unowned);
lldb::IOObjectSP output = std::make_shared<NativeFile>(
- fileno(stdout), File::eOpenOptionReadOnly, NativeFile::Unowned);
+ fileno(stdout), File::eOpenOptionWriteOnly, NativeFile::Unowned);
constexpr llvm::StringLiteral client_name = "stdio";
static MainLoop loop;
@@ -72,7 +72,7 @@ int main(int argc, char *argv[]) {
if (llvm::Error error = instance_up->Run()) {
llvm::logAllUnhandledErrors(std::move(error), llvm::WithColor::error(),
- "DAP session error: ");
+ "MCP error: ");
return EXIT_FAILURE;
}
More information about the lldb-commits
mailing list