{"record":{"id":"c9791c98d7b4efff","repo":"upstash/context7","slug":"context7-base-url-must-use-http-or-https","errorCode":null,"errorMessage":"Context7 base URL must use http:// or https://","messagePattern":"Context7 base URL must use http:// or https://","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/setup/deployment.ts","lineNumber":22,"sourceCode":"const HOSTED_MCP_BASE_URL = \"https://mcp.context7.com\";\n\nexport type SetupDeployment =\n  | { kind: \"hosted\"; baseUrl: typeof DEFAULT_CONTEXT7_BASE_URL }\n  | { kind: \"custom\"; baseUrl: string };\nexport type CustomSetupDeployment = Extract<SetupDeployment, { kind: \"custom\" }>;\n\nexport function normalizeDeploymentBaseUrl(input?: string): string {\n  const raw = input?.trim() || DEFAULT_CONTEXT7_BASE_URL;\n  let url: URL;\n\n  try {\n    url = new URL(raw);\n  } catch {\n    throw new Error(`Invalid Context7 base URL: ${raw}`);\n  }\n\n  if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n    throw new Error(\"Context7 base URL must use http:// or https://\");\n  }\n  if (url.username || url.password) {\n    throw new Error(\"Context7 base URL must not contain credentials\");\n  }\n  if (url.search || url.hash) {\n    throw new Error(\"Context7 base URL must not contain a query string or fragment\");\n  }\n\n  url.pathname = url.pathname.replace(/\\/+$/, \"\") || \"/\";\n  const normalized = url.toString().replace(/\\/$/, \"\");\n  if (url.pathname.endsWith(\"/mcp\") || url.pathname.endsWith(\"/api\")) {\n    throw new Error(\"Pass the Context7 deployment root, without /mcp or /api\");\n  }\n  return normalized;\n}\n\nexport function resolveSetupDeployment(input?: string): SetupDeployment {\n  const baseUrl = normalizeDeploymentBaseUrl(input);","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/upstash/context7/blob/4416fb855b8f752be735e34f943b5d0762701aad/packages/cli/src/setup/deployment.ts#L4-L40","documentation":"Thrown by normalizeDeploymentBaseUrl when the parsed URL uses a protocol other than http: or https:. The CLI only supports HTTP(S) for Context7 deployment base URLs; schemes like ftp:, ws:, or file: are rejected.","triggerScenarios":"normalizeDeploymentBaseUrl receives a parseable URL whose url.protocol is not http: or https: — e.g. 'ftp://host', 'ws://host', 'file:///path'.","commonSituations":"Copying a WebSocket endpoint URL (ws://) from MCP client config instead of the deployment root; using a file:// path for a local deployment; guessing a scheme.","solutions":["Change the scheme to https:// (or http:// only for trusted internal networks).","If the deployment exposes ws:// MCP endpoints, still pass the http(s) root — the CLI appends /mcp itself.","Omit the argument to use the hosted default URL."],"exampleFix":"// before\nctx7 setup --url ws://my-onprem.internal\n\n// after\nctx7 setup --url https://my-onprem.internal","handlingStrategy":"validation","validationCode":"function hasHttpScheme(raw: string): boolean {\n  try {\n    const p = new URL(raw).protocol;\n    return p === 'http:' || p === 'https:';\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const dep = resolveSetupDeployment(input);\n} catch (e) {\n  if ((e as Error).message.includes('http:// or https://')) {\n    console.error('Use an https:// URL; ws:// endpoints are derived automatically.');\n  }\n}","preventionTips":["Don't copy ws:// or wss:// MCP URLs into setup; pass the http(s) origin.","Never use file:// paths for remote deployments.","Default to https:// for all external hosts."],"tags":["url","protocol","validation","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"4416fb855b8f752be735e34f943b5d0762701aad","analyzedAt":"2026-09-16T20:28:07.148Z","contentChangedAt":"2026-09-16T20:28:07.148Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}