Detailed changes
@@ -154,7 +154,8 @@
"stdio",
"sse",
"stdio",
- "sse"
+ "sse",
+ "http"
],
"title": "Type",
"description": "Type of MCP connection",
@@ -176,7 +177,6 @@
},
"type": "object",
"required": [
- "command",
"type"
]
},
@@ -253,13 +253,8 @@
"required": [
"id",
"name",
- "cost_per_1m_out_cached",
"context_window",
- "default_max_tokens",
- "can_reason",
- "reasoning_effort",
- "has_reasoning_effort",
- "supports_attachments"
+ "default_max_tokens"
]
},
"Options": {
@@ -4,5 +4,12 @@
"go": {
"command": "gopls"
}
+ },
+ "mcp": {
+ "context7": {
+ "command": "",
+ "url": "https://mcp.context7.com/mcp",
+ "type": "http"
+ }
}
}
@@ -25,7 +25,7 @@ require (
github.com/go-logfmt/logfmt v0.6.0
github.com/google/uuid v1.6.0
github.com/invopop/jsonschema v0.13.0
- github.com/mark3labs/mcp-go v0.17.0
+ github.com/mark3labs/mcp-go v0.32.0
github.com/muesli/termenv v0.16.0
github.com/ncruces/go-sqlite3 v0.25.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
@@ -40,6 +40,8 @@ require (
mvdan.cc/sh/v3 v3.11.0
)
+require github.com/spf13/cast v1.7.1 // indirect
+
require (
cloud.google.com/go v0.116.0 // indirect
cloud.google.com/go/auth v0.13.0 // indirect
@@ -116,6 +116,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
@@ -165,8 +167,8 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/mark3labs/mcp-go v0.17.0 h1:5Ps6T7qXr7De/2QTqs9h6BKeZ/qdeUeGrgM5lPzi930=
-github.com/mark3labs/mcp-go v0.17.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE=
+github.com/mark3labs/mcp-go v0.32.0 h1:fgwmbfL2gbd67obg57OfV2Dnrhs1HtSdlY/i5fn7MU8=
+github.com/mark3labs/mcp-go v0.32.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
@@ -224,6 +226,8 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=
github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
+github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
+github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
@@ -124,13 +124,14 @@ type MCPType string
const (
MCPStdio MCPType = "stdio"
MCPSse MCPType = "sse"
+ MCPHttp MCPType = "http"
)
type MCP struct {
- Command string `json:"command" jsonschema:"title=Command,description=Command to execute for stdio MCP servers"`
+ Command string `json:"command,omitempty" jsonschema:"title=Command,description=Command to execute for stdio MCP servers"`
Env []string `json:"env,omitempty" jsonschema:"title=Environment,description=Environment variables for the MCP server"`
Args []string `json:"args,omitempty" jsonschema:"title=Arguments,description=Command line arguments for the MCP server"`
- Type MCPType `json:"type" jsonschema:"title=Type,description=Type of MCP connection,enum=stdio,enum=sse,default=stdio"`
+ Type MCPType `json:"type" jsonschema:"title=Type,description=Type of MCP connection,enum=stdio,enum=sse,enum=http,default=stdio"`
URL string `json:"url,omitempty" jsonschema:"title=URL,description=URL for SSE MCP servers"`
// TODO: maybe make it possible to get the value from the env
Headers map[string]string `json:"headers,omitempty" jsonschema:"title=Headers,description=HTTP headers for SSE MCP servers"`
@@ -1407,8 +1408,8 @@ func (c *Config) validateMCPs(errors *ValidationErrors) {
fieldPrefix := fmt.Sprintf("mcp.%s", mcpName)
// Validate MCP type
- if mcpConfig.Type != MCPStdio && mcpConfig.Type != MCPSse {
- errors.Add(fieldPrefix+".type", fmt.Sprintf("invalid MCP type: %s (must be 'stdio' or 'sse')", mcpConfig.Type))
+ if mcpConfig.Type != MCPStdio && mcpConfig.Type != MCPSse && mcpConfig.Type != MCPHttp {
+ errors.Add(fieldPrefix+".type", fmt.Sprintf("invalid MCP type: %s (must be 'stdio' or 'sse' or 'http')", mcpConfig.Type))
}
// Validate based on type
@@ -12,6 +12,7 @@ import (
"github.com/charmbracelet/crush/internal/version"
"github.com/mark3labs/mcp-go/client"
+ "github.com/mark3labs/mcp-go/client/transport"
"github.com/mark3labs/mcp-go/mcp"
)
@@ -118,6 +119,15 @@ func (b *mcpTool) Run(ctx context.Context, params tools.ToolCall) (tools.ToolRes
return tools.NewTextErrorResponse(err.Error()), nil
}
return runTool(ctx, c, b.tool.Name, params.Input)
+ case config.MCPHttp:
+ c, err := client.NewStreamableHttpClient(
+ b.mcpConfig.URL,
+ transport.WithHTTPHeaders(b.mcpConfig.Headers),
+ )
+ if err != nil {
+ return tools.NewTextErrorResponse(err.Error()), nil
+ }
+ return runTool(ctx, c, b.tool.Name, params.Input)
case config.MCPSse:
c, err := client.NewSSEMCPClient(
b.mcpConfig.URL,
@@ -187,6 +197,16 @@ func GetMcpTools(ctx context.Context, permissions permission.Service) []tools.Ba
continue
}
+ mcpTools = append(mcpTools, getTools(ctx, name, m, permissions, c)...)
+ case config.MCPHttp:
+ c, err := client.NewStreamableHttpClient(
+ m.URL,
+ transport.WithHTTPHeaders(m.Headers),
+ )
+ if err != nil {
+ logging.Error("error creating mcp client", "error", err)
+ continue
+ }
mcpTools = append(mcpTools, getTools(ctx, name, m, permissions, c)...)
case config.MCPSse:
c, err := client.NewSSEMCPClient(