MCPcopy Create free account
hub / github.com/diillson/chatcli / Describe

Method Describe

cli/tools_catalog_adapter.go:46–82  ·  view source on GitHub ↗

Describe implements plugins.ToolCatalogAdapter.

(name string)

Source from the content-addressed store, hash-verified

44
45// Describe implements plugins.ToolCatalogAdapter.
46func (a *toolCatalogPluginAdapter) Describe(name string) (string, error) {
47 if a.cli.pluginManager == nil {
48 return "", fmt.Errorf("plugin manager unavailable in this session")
49 }
50 want := strings.TrimSpace(name)
51 want = strings.TrimPrefix(want, "@")
52
53 // MCP names are routed by their canonical mcp_ prefix. Matching is
54 // case-insensitive on our side; the stored name keeps the server's casing.
55 mcpToolset := a.visibleMCPTools()
56 if bare, ok := cutMCPPrefix(want); ok {
57 if tool, ok := findMCPTool(mcpToolset, bare); ok {
58 return renderMCPToolBlock(tool), nil
59 }
60 }
61
62 ps := a.cli.pluginManager.GetPlugins()
63 names := make([]string, 0, len(ps)+len(mcpToolset))
64 for _, p := range ps {
65 if strings.EqualFold(p.Name(), "@"+want) {
66 return renderToolBlock(p, false), nil
67 }
68 names = append(names, p.Name())
69 }
70
71 // Bare-name fallback: models routinely drop the mcp_ prefix ("describe
72 // read_file"). Only reached when no plugin matched, so a shadowing
73 // builtin still wins.
74 if tool, ok := findMCPTool(mcpToolset, want); ok {
75 return renderMCPToolBlock(tool), nil
76 }
77 for _, t := range mcpToolset {
78 names = append(names, "mcp_"+t.Name)
79 }
80 sort.Strings(names)
81 return "", fmt.Errorf("unknown tool %q — available: %s", name, strings.Join(names, ", "))
82}
83
84// List implements plugins.ToolCatalogAdapter.
85func (a *toolCatalogPluginAdapter) List() (string, error) {

Calls 8

visibleMCPToolsMethod · 0.95
cutMCPPrefixFunction · 0.85
findMCPToolFunction · 0.85
renderMCPToolBlockFunction · 0.85
renderToolBlockFunction · 0.85
ErrorfMethod · 0.80
NameMethod · 0.65
GetPluginsMethod · 0.45

Tested by 2