Detailed changes
@@ -28,12 +28,6 @@ type FetchPermissionsParams struct {
Timeout int `json:"timeout,omitempty"`
}
-type fetchTool struct {
- client *http.Client
- permissions permission.Service
- workingDir string
-}
-
const FetchToolName = "fetch"
//go:embed fetch.md
@@ -12,13 +12,15 @@ import (
// GetMCPTools gets all the currently available MCP tools.
func GetMCPTools(permissions permission.Service, wd string) []*Tool {
var result []*Tool
- for name, tool := range mcp.Tools() {
- result = append(result, &Tool{
- mcpName: name,
- tool: tool,
- permissions: permissions,
- workingDir: wd,
- })
+ for mcpName, tools := range mcp.Tools() {
+ for _, tool := range tools {
+ result = append(result, &Tool{
+ mcpName: mcpName,
+ tool: tool,
+ permissions: permissions,
+ workingDir: wd,
+ })
+ }
}
return result
}
@@ -74,7 +76,7 @@ func (m *Tool) Info() fantasy.ToolInfo {
}
return fantasy.ToolInfo{
- Name: fmt.Sprintf("mcp_%s_%s", m.mcpName, m.tool.Name),
+ Name: m.Name(),
Description: m.tool.Description,
Parameters: parameters,
Required: required,
@@ -58,12 +58,12 @@ func (s State) String() string {
}
// EventType represents the type of MCP event
-type EventType string
+type EventType uint
const (
- EventStateChanged EventType = "state_changed"
- EventToolsListChanged EventType = "tools_list_changed"
- EventPromptsListChanged EventType = "prompts_list_changed"
+ EventStateChanged EventType = iota
+ EventToolsListChanged
+ EventPromptsListChanged
)
// Event represents an event in the MCP system
@@ -11,13 +11,10 @@ import (
type Prompt = mcp.Prompt
-var (
- allPrompts = csync.NewMap[string, *Prompt]()
- clientPrompts = csync.NewMap[string, []*Prompt]()
-)
+var allPrompts = csync.NewMap[string, []*Prompt]()
// Prompts returns all available MCP prompts.
-func Prompts() iter.Seq2[string, *Prompt] {
+func Prompts() iter.Seq2[string, []*Prompt] {
return allPrompts.Seq2()
}
@@ -65,10 +62,8 @@ func RefreshPrompts(ctx context.Context, name string) {
updatePrompts(name, prompts)
prev, _ := states.Get(name)
- updateState(name, StateConnected, nil, session, Counts{
- Prompts: len(prompts),
- Tools: prev.Counts.Tools,
- })
+ prev.Counts.Prompts = len(prompts)
+ updateState(name, StateConnected, nil, session, prev.Counts)
}
func getPrompts(ctx context.Context, c *mcp.ClientSession) ([]*Prompt, error) {
@@ -85,14 +80,8 @@ func getPrompts(ctx context.Context, c *mcp.ClientSession) ([]*Prompt, error) {
// updatePrompts updates the global mcpPrompts and mcpClient2Prompts maps
func updatePrompts(mcpName string, prompts []*Prompt) {
if len(prompts) == 0 {
- clientPrompts.Del(mcpName)
- } else {
- clientPrompts.Set(mcpName, prompts)
- }
- for mcpName, prompts := range clientPrompts.Seq2() {
- for _, p := range prompts {
- key := mcpName + ":" + p.Name
- allPrompts.Set(key, p)
- }
+ allPrompts.Del(mcpName)
+ return
}
+ allPrompts.Set(mcpName, prompts)
}
@@ -14,13 +14,10 @@ import (
type Tool = mcp.Tool
-var (
- allTools = csync.NewMap[string, *Tool]()
- clientTools = csync.NewMap[string, []*Tool]()
-)
+var allTools = csync.NewMap[string, []*Tool]()
// Tools returns all available MCP tools.
-func Tools() iter.Seq2[string, *Tool] {
+func Tools() iter.Seq2[string, []*Tool] {
return allTools.Seq2()
}
@@ -72,10 +69,8 @@ func RefreshTools(ctx context.Context, name string) {
updateTools(name, tools)
prev, _ := states.Get(name)
- updateState(name, StateConnected, nil, session, Counts{
- Tools: len(tools),
- Prompts: prev.Counts.Prompts,
- })
+ prev.Counts.Tools = len(tools)
+ updateState(name, StateConnected, nil, session, prev.Counts)
}
func getTools(ctx context.Context, session *mcp.ClientSession) ([]*Tool, error) {
@@ -89,16 +84,10 @@ func getTools(ctx context.Context, session *mcp.ClientSession) ([]*Tool, error)
return result.Tools, nil
}
-// updateTools updates the global mcpTools and mcpClient2Tools maps
func updateTools(name string, tools []*Tool) {
if len(tools) == 0 {
- clientTools.Del(name)
- } else {
- clientTools.Set(name, tools)
- }
- for name, tools := range clientTools.Seq2() {
- for _, t := range tools {
- allTools.Set(name, t)
- }
+ allTools.Del(name)
+ return
}
+ allTools.Set(name, tools)
}
@@ -1,10 +1,10 @@
package commands
import (
+ "cmp"
"context"
"fmt"
"io/fs"
- "log/slog"
"os"
"path/filepath"
"regexp"
@@ -223,32 +223,30 @@ type CommandRunCustomMsg struct {
func loadMCPPrompts() []Command {
var commands []Command
- for key, prompt := range mcp.Prompts() {
- clientName, promptName, ok := strings.Cut(key, ":")
- if !ok {
- slog.Warn("prompt not found", "key", key)
- continue
+ for mcpName, prompts := range mcp.Prompts() {
+ for _, prompt := range prompts {
+ key := mcpName + ":" + prompt.Name
+ commands = append(commands, Command{
+ ID: key,
+ Title: cmp.Or(prompt.Title, prompt.Name),
+ Description: prompt.Description,
+ Handler: createMCPPromptHandler(mcpName, prompt.Name, prompt),
+ })
}
- commands = append(commands, Command{
- ID: key,
- Title: clientName + ":" + promptName,
- Description: prompt.Description,
- Handler: createMCPPromptHandler(clientName, promptName, prompt),
- })
}
return commands
}
-func createMCPPromptHandler(clientName, promptName string, prompt *mcp.Prompt) func(Command) tea.Cmd {
+func createMCPPromptHandler(mcpName, promptName string, prompt *mcp.Prompt) func(Command) tea.Cmd {
return func(cmd Command) tea.Cmd {
if len(prompt.Arguments) == 0 {
- return execMCPPrompt(clientName, promptName, nil)
+ return execMCPPrompt(mcpName, promptName, nil)
}
return util.CmdHandler(ShowMCPPromptArgumentsDialogMsg{
Prompt: prompt,
OnSubmit: func(args map[string]string) tea.Cmd {
- return execMCPPrompt(clientName, promptName, args)
+ return execMCPPrompt(mcpName, promptName, args)
},
})
}