7 "charm.land/lipgloss/v2"
8 "github.com/charmbracelet/crush/internal/agent/tools/mcp"
9 "github.com/charmbracelet/crush/internal/ui/common"
10 "github.com/charmbracelet/crush/internal/ui/styles"
13// mcpInfo renders the MCP status section showing active MCP clients and their
15func (m *UI) mcpInfo(width, maxItems int, isSection bool) string {
16 var mcps []mcp.ClientInfo
19 for _, state := range m.mcpStates {
20 mcps = append(mcps, state)
23 title := t.Subtle.Render("MCPs")
25 title = common.Section(t, title, width)
27 list := t.Subtle.Render("None")
29 list = mcpList(t, mcps, width, maxItems)
32 return lipgloss.NewStyle().Width(width).Render(fmt.Sprintf("%s\n\n%s", title, list))
35// mcpCounts formats tool and prompt counts for display.
36func mcpCounts(t *styles.Styles, counts mcp.Counts) string {
39 parts = append(parts, t.Subtle.Render(fmt.Sprintf("%d tools", counts.Tools)))
41 if counts.Prompts > 0 {
42 parts = append(parts, t.Subtle.Render(fmt.Sprintf("%d prompts", counts.Prompts)))
44 return strings.Join(parts, " ")
47// mcpList renders a list of MCP clients with their status and counts,
48// truncating to maxItems if needed.
49func mcpList(t *styles.Styles, mcps []mcp.ClientInfo, width, maxItems int) string {
50 var renderedMcps []string
52 for _, m := range mcps {
55 var description string
56 var extraContent string
59 case mcp.StateStarting:
60 icon = t.ItemBusyIcon.String()
61 description = t.Subtle.Render("starting...")
62 case mcp.StateConnected:
63 icon = t.ItemOnlineIcon.String()
64 extraContent = mcpCounts(t, m.Counts)
66 icon = t.ItemErrorIcon.String()
67 description = t.Subtle.Render("error")
69 description = t.Subtle.Render(fmt.Sprintf("error: %s", m.Error.Error()))
71 case mcp.StateDisabled:
72 icon = t.ItemOfflineIcon.Foreground(t.Muted.GetBackground()).String()
73 description = t.Subtle.Render("disabled")
75 icon = t.ItemOfflineIcon.String()
78 renderedMcps = append(renderedMcps, common.Status(t, common.StatusOpts{
81 Description: description,
82 ExtraContent: extraContent,
86 if len(renderedMcps) > maxItems {
87 visibleItems := renderedMcps[:maxItems-1]
88 remaining := len(renderedMcps) - maxItems
89 visibleItems = append(visibleItems, t.Subtle.Render(fmt.Sprintf("…and %d more", remaining)))
90 return lipgloss.JoinVertical(lipgloss.Left, visibleItems...)
92 return lipgloss.JoinVertical(lipgloss.Left, renderedMcps...)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list