Skip to content

Conversation

aperez
Copy link
Member

@aperez aperez commented Oct 9, 2025

Currently AFAICT we don't have a way to get the MCP server socket after it started. So this change introduces a new protocol-server subcommand that allows us to query the location of a running server:

(lldb) protocol-server start MCP listen://localhost:0
MCP server started with connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server get MCP
MCP server connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server stop MCP
(lldb) protocol-server get MCP
error: MCP server is not running

@llvmbot
Copy link
Member

llvmbot commented Oct 9, 2025

@llvm/pr-subscribers-lldb

Author: Alexandre Perez (aperez)

Changes

Currently AFAICT we don't have a way to get the MCP server socket after it started. So this change introduces a new protocol-server subcommand that allows us to query the location of a running server:

(lldb) protocol-server start MCP listen://localhost:0
MCP server started with connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server get MCP
MCP server connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server stop MCP
(lldb) protocol-server get MCP
error: MCP server is not running

Full diff: https://github.com/llvm/llvm-project/pull/162752.diff

3 Files Affected:

  • (modified) lldb/source/Commands/CommandObjectProtocolServer.cpp (+44-1)
  • (modified) lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp (+1)
  • (modified) lldb/test/API/commands/protocol/TestMCPUnixSocket.py (+13)
diff --git a/lldb/source/Commands/CommandObjectProtocolServer.cpp b/lldb/source/Commands/CommandObjectProtocolServer.cpp
index c5ab9e9f05bec..ff9d38c84ed2d 100644
--- a/lldb/source/Commands/CommandObjectProtocolServer.cpp
+++ b/lldb/source/Commands/CommandObjectProtocolServer.cpp
@@ -131,15 +131,58 @@ class CommandObjectProtocolServerStop : public CommandObjectParsed {
   }
 };
 
+class CommandObjectProtocolServerGet : public CommandObjectParsed {
+public:
+  CommandObjectProtocolServerGet(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "protocol-server get",
+                            "get protocol server connection information",
+                            "protocol-server get <protocol>") {
+    AddSimpleArgumentList(lldb::eArgTypeProtocol, eArgRepeatPlain);
+  }
+
+  ~CommandObjectProtocolServerGet() override = default;
+
+protected:
+  void DoExecute(Args &args, CommandReturnObject &result) override {
+    if (args.GetArgumentCount() < 1) {
+      result.AppendError("no protocol specified");
+      return;
+    }
+
+    llvm::StringRef protocol = args.GetArgumentAtIndex(0);
+    ProtocolServer *server = ProtocolServer::GetOrCreate(protocol);
+    if (!server) {
+      result.AppendErrorWithFormatv(
+          "unsupported protocol: {0}. Supported protocols are: {1}", protocol,
+          llvm::join(ProtocolServer::GetSupportedProtocols(), ", "));
+      return;
+    }
+
+    Socket *socket = server->GetSocket();
+    if (!socket) {
+      result.AppendErrorWithFormatv("{0} server is not running", protocol);
+      return;
+    }
+
+    std::string address =
+        llvm::join(socket->GetListeningConnectionURI(), ", ");
+    result.AppendMessageWithFormatv(
+        "{0} server connection listeners: {1}", protocol, address);
+    result.SetStatus(eReturnStatusSuccessFinishNoResult);
+  }
+};
+
 CommandObjectProtocolServer::CommandObjectProtocolServer(
     CommandInterpreter &interpreter)
     : CommandObjectMultiword(interpreter, "protocol-server",
-                             "Start and stop a protocol server.",
+                             "Start, stop, and query protocol servers.",
                              "protocol-server") {
   LoadSubCommand("start", CommandObjectSP(new CommandObjectProtocolServerStart(
                               interpreter)));
   LoadSubCommand("stop", CommandObjectSP(
                              new CommandObjectProtocolServerStop(interpreter)));
+  LoadSubCommand("get", CommandObjectSP(
+                            new CommandObjectProtocolServerGet(interpreter)));
 }
 
 CommandObjectProtocolServer::~CommandObjectProtocolServer() = default;
diff --git a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
index 33bdd5eec3644..390cf3eeb16a5 100644
--- a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
+++ b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
@@ -144,6 +144,7 @@ llvm::Error ProtocolServerMCP::Stop() {
 
   m_server.reset(nullptr);
   m_server_info_handle.Remove();
+  m_listener.reset();
 
   return llvm::Error::success();
 }
diff --git a/lldb/test/API/commands/protocol/TestMCPUnixSocket.py b/lldb/test/API/commands/protocol/TestMCPUnixSocket.py
index ea9255cc60ef5..9edb97eb791b9 100644
--- a/lldb/test/API/commands/protocol/TestMCPUnixSocket.py
+++ b/lldb/test/API/commands/protocol/TestMCPUnixSocket.py
@@ -32,3 +32,16 @@ def test_unix_socket(self):
             startstr="MCP server started with connection listeners:",
             substrs=[f"unix-connect://{socket_file}"],
         )
+
+        self.expect(
+            "protocol-server get MCP",
+            startstr="MCP server connection listeners:",
+            substrs=[f"unix-connect://{socket_file}"],
+        )
+
+        self.runCmd("protocol-server stop MCP", check=False)
+        self.expect(
+            "protocol-server get MCP",
+            error=True,
+            substrs=["MCP server is not running"],
+        )

Copy link

github-actions bot commented Oct 9, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks useful, LGTM

@splhack
Copy link
Contributor

splhack commented Oct 10, 2025

Nice!

Is it possible to add --json option or Python API as follow up? So that Python script could get the status reliably without worrying about stdout format change.

@aperez aperez merged commit 6ed18d8 into llvm:main Oct 10, 2025
10 checks passed
@aperez
Copy link
Member Author

aperez commented Oct 10, 2025

@splhack I can put up a PR with a --json option as follow up.

@aperez aperez deleted the protocol_server_get branch October 10, 2025 16:56
DharuniRAcharya pushed a commit to DharuniRAcharya/llvm-project that referenced this pull request Oct 13, 2025
…62752)

Currently AFAICT we don't have a way to get the MCP server socket after
it started. So this change introduces a new `protocol-server` subcommand
that allows us to query the location of a running server:

```
(lldb) protocol-server start MCP listen://localhost:0
MCP server started with connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server get MCP
MCP server connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server stop MCP
(lldb) protocol-server get MCP
error: MCP server is not running
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants