8 "github.com/charmbracelet/crush/internal/agent/tools/mcp"
9 "github.com/charmbracelet/crush/internal/permission"
12// GetMCPTools gets all the currently available MCP tools.
13func GetMCPTools(permissions permission.Service, wd string) []*Tool {
15 for mcpName, tools := range mcp.Tools() {
16 for _, tool := range tools {
17 result = append(result, &Tool{
20 permissions: permissions,
28// Tool is a tool from a MCP.
32 permissions permission.Service
34 providerOptions fantasy.ProviderOptions
37func (m *Tool) SetProviderOptions(opts fantasy.ProviderOptions) {
38 m.providerOptions = opts
41func (m *Tool) ProviderOptions() fantasy.ProviderOptions {
42 return m.providerOptions
45func (m *Tool) Name() string {
46 return fmt.Sprintf("mcp_%s_%s", m.mcpName, m.tool.Name)
49func (m *Tool) MCP() string {
53func (m *Tool) MCPToolName() string {
57func (m *Tool) Info() fantasy.ToolInfo {
58 parameters := make(map[string]any)
59 required := make([]string, 0)
61 if input, ok := m.tool.InputSchema.(map[string]any); ok {
62 if props, ok := input["properties"].(map[string]any); ok {
65 if req, ok := input["required"].([]any); ok {
66 // Convert []any -> []string when elements are strings
67 for _, v := range req {
68 if s, ok := v.(string); ok {
69 required = append(required, s)
72 } else if reqStr, ok := input["required"].([]string); ok {
73 // Handle case where it's already []string
78 return fantasy.ToolInfo{
80 Description: m.tool.Description,
81 Parameters: parameters,
86func (m *Tool) Run(ctx context.Context, params fantasy.ToolCall) (fantasy.ToolResponse, error) {
87 sessionID := GetSessionFromContext(ctx)
89 return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for creating a new file")
91 permissionDescription := fmt.Sprintf("execute %s with the following parameters:", m.Info().Name)
92 p := m.permissions.Request(
93 permission.CreatePermissionRequest{
95 ToolCallID: params.ID,
97 ToolName: m.Info().Name,
99 Description: permissionDescription,
100 Params: params.Input,
104 return fantasy.ToolResponse{}, permission.ErrorPermissionDenied
107 result, err := mcp.RunTool(ctx, m.mcpName, m.tool.Name, params.Input)
109 return fantasy.NewTextErrorResponse(err.Error()), nil
113 case "image", "media":
114 if !GetSupportsImagesFromContext(ctx) {
115 modelName := GetModelNameFromContext(ctx)
116 return fantasy.NewTextErrorResponse(fmt.Sprintf("This model (%s) does not support image data.", modelName)), nil
119 var response fantasy.ToolResponse
120 if result.Type == "image" {
121 response = fantasy.NewImageResponse(result.Data, result.MediaType)
123 response = fantasy.NewMediaResponse(result.Data, result.MediaType)
125 response.Content = result.Content
128 return fantasy.NewTextResponse(result.Content), nil
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