https://github.com/JDevlieghere created 
https://github.com/llvm/llvm-project/pull/155708

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.

>From 9c2db2349ffd5fdcbbb5ceebf2a72979dd2a2e88 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jo...@devlieghere.com>
Date: Wed, 27 Aug 2025 15:15:48 -0700
Subject: [PATCH] [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;
+}

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to