Skip to content

Commit a4f0684

Browse files
committed
feat(mcp): add search ch functionality to MCP tools panel #371
1 parent e956d02 commit a4f0684

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

core/src/main/kotlin/cc/unitmesh/devti/mcp/editor/McpPreviewEditor.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.UserDataHolderBase
2222
import com.intellij.openapi.vfs.VirtualFile
2323
import com.intellij.psi.PsiManager
2424
import com.intellij.ui.JBColor
25+
import com.intellij.ui.SearchTextField
2526
import com.intellij.ui.components.JBLabel
2627
import com.intellij.ui.components.JBScrollPane
2728
import com.intellij.ui.components.JBTextField
@@ -41,6 +42,8 @@ import java.awt.FlowLayout
4142
import java.beans.PropertyChangeListener
4243
import javax.swing.*
4344
import javax.swing.border.CompoundBorder
45+
import javax.swing.event.DocumentEvent
46+
import javax.swing.event.DocumentListener
4447

4548
open class McpPreviewEditor(
4649
val project: Project,
@@ -59,6 +62,7 @@ open class McpPreviewEditor(
5962
private lateinit var resultPanel: McpResultPanel
6063
private val config = McpLlmConfig()
6164
private val borderColor = JBColor(0xE5E7EB, 0x3C3F41) // Equivalent to Tailwind gray-200
65+
private lateinit var searchField: SearchTextField
6266

6367
init {
6468
createUI()
@@ -79,12 +83,24 @@ open class McpPreviewEditor(
7983
private fun createUI() {
8084
val headerPanel = panel {
8185
row {
82-
val label = JBLabel("MCP Preview - Tools Panel").apply {
86+
val label = JBLabel("MCP Tools").apply {
8387
font = JBUI.Fonts.label(14.0f).asBold()
88+
border = JBUI.Borders.emptyLeft(8)
8489
isOpaque = true
8590
}
8691

8792
cell(label).align(Align.FILL).resizableColumn()
93+
94+
searchField = SearchTextField().apply {
95+
textEditor.emptyText.text = "Search tools..."
96+
textEditor.document.addDocumentListener(object : DocumentListener {
97+
override fun insertUpdate(e: DocumentEvent) = filterTools()
98+
override fun removeUpdate(e: DocumentEvent) = filterTools()
99+
override fun changedUpdate(e: DocumentEvent) = filterTools()
100+
})
101+
}
102+
103+
cell(searchField).align(Align.FILL).resizableColumn()
88104
}
89105
}.apply {
90106
border = BorderFactory.createMatteBorder(0, 0, 1, 0, borderColor)
@@ -197,6 +213,11 @@ open class McpPreviewEditor(
197213
mainPanel.add(bottomPanel, BorderLayout.SOUTH)
198214
}
199215

216+
private fun filterTools() {
217+
val searchText = searchField.text.trim()
218+
toolListPanel.filterTools(searchText)
219+
}
220+
200221
private fun showConfigDialog() {
201222
val dialog = McpLlmConfigDialog(project, config, allTools)
202223

core/src/main/kotlin/cc/unitmesh/devti/mcp/ui/McpToolListPanel.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import javax.swing.SwingUtilities
2323
class McpToolListPanel(private val project: Project) : JPanel() {
2424
private val mcpServerManager = CustomMcpServerManager.instance(project)
2525
private val allTools = mutableMapOf<String, List<Tool>>()
26+
private var currentFilteredTools = mutableMapOf<String, List<Tool>>()
2627
private var loadingJob: Job? = null
2728
private val serverLoadingStatus = mutableMapOf<String, Boolean>()
2829
private val serverPanels = mutableMapOf<String, JPanel>()
@@ -41,6 +42,7 @@ class McpToolListPanel(private val project: Project) : JPanel() {
4142
serverLoadingStatus.clear()
4243
serverPanels.clear()
4344
allTools.clear()
45+
currentFilteredTools.clear()
4446

4547
SwingUtilities.invokeLater {
4648
removeAll()
@@ -69,6 +71,7 @@ class McpToolListPanel(private val project: Project) : JPanel() {
6971
try {
7072
val tools = mcpServerManager.collectServerInfo(serverName, serverConfig)
7173
allTools[serverName] = tools
74+
currentFilteredTools[serverName] = tools
7275
onToolsLoaded(allTools)
7376

7477
SwingUtilities.invokeLater {
@@ -85,6 +88,30 @@ class McpToolListPanel(private val project: Project) : JPanel() {
8588
}
8689
}
8790

91+
fun filterTools(searchText: String) {
92+
if (searchText.isEmpty()) {
93+
// If search text is empty, restore all tools
94+
currentFilteredTools = allTools.toMutableMap()
95+
} else {
96+
// Filter tools based on search text
97+
currentFilteredTools = allTools.mapValues { (_, tools) ->
98+
tools.filter { tool ->
99+
tool.name.contains(searchText, ignoreCase = true) ||
100+
tool.description?.contains(searchText, ignoreCase = true) == true
101+
}
102+
}.toMutableMap()
103+
}
104+
105+
// Update UI with filtered tools
106+
SwingUtilities.invokeLater {
107+
currentFilteredTools.forEach { (serverName, tools) ->
108+
updateServerSection(serverName, tools)
109+
}
110+
revalidate()
111+
repaint()
112+
}
113+
}
114+
88115
private fun createServerSection(serverName: String) {
89116
val serverPanel = JPanel(BorderLayout()).apply {
90117
background = UIUtil.getPanelBackground()

0 commit comments

Comments
 (0)