1010#include " Resource.h"
1111#include " Tool.h"
1212#include " lldb/Core/PluginManager.h"
13- #include " lldb/Protocol/MCP/MCPError .h"
14- #include " lldb/Protocol/MCP/Tool .h"
13+ #include " lldb/Host/FileSystem .h"
14+ #include " lldb/Protocol/MCP/Server .h"
1515#include " lldb/Utility/LLDBLog.h"
1616#include " lldb/Utility/Log.h"
1717#include " llvm/ADT/StringExtras.h"
18+ #include " llvm/Support/Error.h"
1819#include " llvm/Support/Threading.h"
1920#include < thread>
20- #include < variant>
2121
2222using namespace lldb_private ;
2323using namespace lldb_private ::mcp;
@@ -104,6 +104,43 @@ llvm::Error ProtocolServerMCP::Start(ProtocolServer::Connection connection) {
104104 if (llvm::Error error = handles.takeError ())
105105 return error;
106106
107+ auto listening_uris = m_listener->GetListeningConnectionURI ();
108+ if (listening_uris.empty ())
109+ return createStringError (" Failed to list listening connections" );
110+ std::string address =
111+ llvm::join (m_listener->GetListeningConnectionURI (), " , " );
112+
113+ llvm::SmallString<128 > user_home_dir;
114+ FileSystem::Instance ().GetHomeDirectory (user_home_dir);
115+ FileSpec mcp_registry_dir = FileSpec (user_home_dir.c_str ());
116+ mcp_registry_dir.AppendPathComponent (" .lldb" );
117+ mcp_registry_dir.AppendPathComponent (" mcp" );
118+
119+ Status error (llvm::sys::fs::create_directory (mcp_registry_dir.GetPath ()));
120+ if (error.Fail ())
121+ return error.takeError ();
122+
123+ m_mcp_registry_entry_path = mcp_registry_dir.CopyByAppendingPathComponent (
124+ formatv (" lldb-{0}.json" , getpid ()).str ());
125+
126+ const File::OpenOptions flags = File::eOpenOptionWriteOnly |
127+ File::eOpenOptionCanCreate |
128+ File::eOpenOptionTruncate;
129+ llvm::Expected<lldb::FileUP> file =
130+ FileSystem::Instance ().Open (m_mcp_registry_entry_path, flags,
131+ lldb::eFilePermissionsFileDefault, false );
132+ if (!file)
133+ return file.takeError ();
134+
135+ ServerMetadata metadata;
136+ metadata.connection_uri = listening_uris[0 ];
137+ metadata.pid = getpid ();
138+
139+ std::string buf = formatv (" {0}" , toJSON (metadata)).str ();
140+ size_t num_bytes = buf.size ();
141+ if (llvm::Error error = (*file)->Write (buf.data (), num_bytes).takeError ())
142+ return error;
143+
107144 m_running = true ;
108145 m_listen_handlers = std::move (*handles);
109146 m_loop_thread = std::thread ([=] {
@@ -122,6 +159,10 @@ llvm::Error ProtocolServerMCP::Stop() {
122159 m_running = false ;
123160 }
124161
162+ if (!m_mcp_registry_entry_path.GetPath ().empty ())
163+ FileSystem::Instance ().RemoveFile (m_mcp_registry_entry_path);
164+ m_mcp_registry_entry_path.Clear ();
165+
125166 // Stop the main loop.
126167 m_loop.AddPendingCallback (
127168 [](lldb_private::MainLoopBase &loop) { loop.RequestTermination (); });
0 commit comments