upstash/context7 · error
Context7 base URL must use http:// or https://
Error message
Context7 base URL must use http:// or https://
What it means
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.
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.
Example fix
// before ctx7 setup --url ws://my-onprem.internal // after ctx7 setup --url https://my-onprem.internal
Defensive patterns
Strategy: validation
Validate before calling
function hasHttpScheme(raw: string): boolean {
try {
const p = new URL(raw).protocol;
return p === 'http:' || p === 'https:';
} catch { return false; }
} Try / catch
try {
const dep = resolveSetupDeployment(input);
} catch (e) {
if ((e as Error).message.includes('http:// or https://')) {
console.error('Use an https:// URL; ws:// endpoints are derived automatically.');
}
} Prevention
- 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.
When it happens
Trigger: normalizeDeploymentBaseUrl receives a parseable URL whose url.protocol is not http: or https: — e.g. 'ftp://host', 'ws://host', 'file:///path'.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Context7 base URL must not contain a query string or…
- Invalid Context7 base URL
- invalid_url
- Pass the Context7 deployment root, without /mcp or /api
- Context7 base URL must not contain credentials
AI-assisted analysis of upstash/context7@4416fb855b (2026-09-16).
Data as JSON: /api/errors/c9791c98d7b4efff.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/setup/deployment.ts:22
const HOSTED_MCP_BASE_URL = "https://mcp.context7.com";
export type SetupDeployment =
| { kind: "hosted"; baseUrl: typeof DEFAULT_CONTEXT7_BASE_URL }
| { kind: "custom"; baseUrl: string };
export type CustomSetupDeployment = Extract<SetupDeployment, { kind: "custom" }>;
export function normalizeDeploymentBaseUrl(input?: string): string {
const raw = input?.trim() || DEFAULT_CONTEXT7_BASE_URL;
let url: URL;
try {
url = new URL(raw);
} catch {
throw new Error(`Invalid Context7 base URL: ${raw}`);
}
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error("Context7 base URL must use http:// or https://");
}
if (url.username || url.password) {
throw new Error("Context7 base URL must not contain credentials");
}
if (url.search || url.hash) {
throw new Error("Context7 base URL must not contain a query string or fragment");
}
url.pathname = url.pathname.replace(/\/+$/, "") || "/";
const normalized = url.toString().replace(/\/$/, "");
if (url.pathname.endsWith("/mcp") || url.pathname.endsWith("/api")) {
throw new Error("Pass the Context7 deployment root, without /mcp or /api");
}
return normalized;
}
export function resolveSetupDeployment(input?: string): SetupDeployment {
const baseUrl = normalizeDeploymentBaseUrl(input);View on GitHub (pinned to 4416fb855b)