{"record":{"id":"2baf7c9ec5f07af8","repo":"charmbracelet/crush","slug":"unsupported-mcp-type-s","errorCode":null,"errorMessage":"unsupported mcp type: %s","messagePattern":"unsupported mcp type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/mcp/init.go","lineNumber":1193,"sourceCode":"\n\t\t\t// Normalize trailing slash for PRM discovery compatibility.\n\t\t\tnormalizedURL := strings.TrimSuffix(url, \"/\")\n\t\t\thandler, oauthErr := mcpoauth.NewHandler(name, normalizedURL, m.OAuthToken, preregistered, tokenSaver, mcpoauth.IsInteractive(ctx), m.OAuthCallbackPort)\n\t\t\tif oauthErr != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"failed to create OAuth handler for mcp %q: %w\", name, oauthErr)\n\t\t\t}\n\t\t\toauthHandler = handler\n\t\t\tauthURLs.Set(name, handler)\n\t\t\ttransport = newOAuthRoundTripper(handler, transport)\n\t\t}\n\n\t\tclient := &http.Client{Transport: transport}\n\t\treturn &mcp.SSEClientTransport{\n\t\t\tEndpoint:   url,\n\t\t\tHTTPClient: client,\n\t\t}, oauthHandler, nil\n\tdefault:\n\t\treturn nil, nil, fmt.Errorf(\"unsupported mcp type: %s\", m.Type)\n\t}\n}\n\ntype headerRoundTripper struct {\n\theaders map[string]string\n}\n\nfunc (rt headerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {\n\tfor k, v := range rt.headers {\n\t\treq.Header.Set(k, v)\n\t}\n\treturn http.DefaultTransport.RoundTrip(req)\n}\n\n// oauthRoundTripper wraps an HTTP transport with OAuth bearer token\n// injection and 401-triggered authorization. Used for SSE transports\n// that don't support the SDK's OAuthHandler natively. Based on Bruno\n// Krugel's implementation from PR #3396.","sourceCodeStart":1175,"sourceCodeEnd":1211,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/mcp/init.go#L1175-L1211","documentation":"The transport factory switches on the configured MCP server type (http/stdio/sse). Any type value outside the known set falls to the default branch and aborts client creation. This is a config-validation guard against typo'd or unsupported `type` fields.","triggerScenarios":"`mcp.<name>.type` set to something other than http, stdio, or sse — e.g. \"streamable\", \"websocket\", \"SSE\" if the config parser is case-sensitive, or a JSON config with a stale type name from an older schema.","commonSituations":"Copying an MCP config from Claude Code or another tool that uses different type names (\"sse\" vs \"http\" semantics, \"streamable-http\"); manual edit typos; migrating configs across Crush versions where type names changed.","solutions":["Change the type to one of the supported values: \"http\" (streamable), \"sse\", or \"stdio\"","If the server speaks streamable HTTP, use type \"http\" instead of \"streamable\" or \"streamable-http\"","Check the Crush docs for the current MCP config schema and update older configs","Validate your crushrc/crush.json against an example MCP block to catch typos"],"exampleFix":"// before (crushrc)\nmcp fs {\n  type \"streamable-http\"\n  url \"http://localhost:3000/mcp\"\n}\n// after\nmcp fs {\n  type \"http\"\n  url \"http://localhost:3000/mcp\"\n}","handlingStrategy":"validation","validationCode":"// validate the type field before writing config\nvalid := map[string]bool{\"http\": true, \"sse\": true, \"stdio\": true}\nif !valid[mcpType] {\n    return fmt.Errorf(\"mcp type %q not supported; use http, sse, or stdio\", mcpType)\n}","typeGuard":"func isKnownMCPType(t string) bool {\n    switch t { case \"http\", \"sse\", \"stdio\": return true }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Copy MCP type names only from current Crush docs, not from other tools' configs","Use lowercase type strings exactly as documented","Add a config lint step that checks known type values"],"tags":["mcp","config","validation"],"backgroundTag":"unsupported-config-value","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}