@@ -3,6 +3,7 @@ package mcp
33import (
44 "context"
55 "iter"
6+ "log/slog"
67
78 "github.com/charmbracelet/crush/internal/csync"
89 "github.com/modelcontextprotocol/go-sdk/mcp"
@@ -11,25 +12,15 @@ import (
1112type Prompt = mcp.Prompt
1213
1314var (
14− allPrompts = csync.NewMap[string, *Prompt]()
15− client2Prompts = csync.NewMap[string, []*Prompt]()
15+ allPrompts = csync.NewMap[string, *Prompt]()
16+ clientPrompts = csync.NewMap[string, []*Prompt]()
1617)
1718
18−// GetPrompts returns all available MCP prompts.
19−func GetPrompts() iter.Seq2[string, *Prompt] {
19+// Prompts returns all available MCP prompts.
20+func Prompts() iter.Seq2[string, *Prompt] {
2021 return allPrompts.Seq2()
2122}
2223
23−// GetPrompt returns a specific MCP prompt by name.
24−func GetPrompt(name string) (*Prompt, bool) {
25− return allPrompts.Get(name)
26−}
27−
28−// GetPromptsByClient returns all prompts for a specific MCP client.
29−func GetPromptsByClient(clientName string) ([]*Prompt, bool) {
30− return client2Prompts.Get(clientName)
31−}
32−
3324// GetPromptMessages retrieves the content of an MCP prompt with the given arguments.
3425func GetPromptMessages(ctx context.Context, clientName, promptName string, args map[string]string) ([]string, error) {
3526 c, err := getOrRenewClient(ctx, clientName)
@@ -56,6 +47,30 @@ func GetPromptMessages(ctx context.Context, clientName, promptName string, args
5647 return messages, nil
5748}
5849
50+// RefreshPrompts gets the updated list of prompts from the MCP and updates the
51+// global state.
52+func RefreshPrompts(ctx context.Context, name string) {
53+ session, ok := sessions.Get(name)
54+ if !ok {
55+ slog.Warn("refresh prompts: no session", "name", name)
56+ return
57+ }
58+
59+ prompts, err := getPrompts(ctx, session)
60+ if err != nil {
61+ updateState(name, StateError, err, nil, Counts{})
62+ return
63+ }
64+
65+ updatePrompts(name, prompts)
66+
67+ prev, _ := states.Get(name)
68+ updateState(name, StateConnected, nil, session, Counts{
69+ Prompts: len(prompts),
70+ Tools: prev.Counts.Tools,
71+ })
72+}
73+
5974func getPrompts(ctx context.Context, c *mcp.ClientSession) ([]*Prompt, error) {
6075 if c.InitializeResult().Capabilities.Prompts == nil {
6176 return nil, nil
@@ -70,11 +85,11 @@ func getPrompts(ctx context.Context, c *mcp.ClientSession) ([]*Prompt, error) {
7085// updatePrompts updates the global mcpPrompts and mcpClient2Prompts maps
7186func updatePrompts(mcpName string, prompts []*Prompt) {
7287 if len(prompts) == 0 {
73− client2Prompts.Del(mcpName)
88+ clientPrompts.Del(mcpName)
7489 } else {
75− client2Prompts.Set(mcpName, prompts)
90+ clientPrompts.Set(mcpName, prompts)
7691 }
77− for mcpName, prompts := range client2Prompts.Seq2() {
92+ for mcpName, prompts := range clientPrompts.Seq2() {
7893 for _, p := range prompts {
7994 key := mcpName + ":" + p.Name
8095 allPrompts.Set(key, p)