upstash/context7 · error
Pass the Context7 deployment root, without /mcp or /api
Error message
Pass the Context7 deployment root, without /mcp or /api
What it means
Thrown by normalizeDeploymentBaseUrl when the URL path already ends in /mcp or /api. The CLI derives endpoint URLs itself (getMcpUrl appends /mcp), so passing a full endpoint URL would yield doubled paths like /mcp/mcp; the user must pass the deployment root instead.
Solutions
- Drop the trailing /mcp or /api and pass the deployment root: 'https://host'.
- If you copied the URL from an MCP client, use the server's base origin instead.
- Omit the argument to use the hosted default.
Example fix
// before ctx7 setup --url https://my-onprem.internal/mcp // after ctx7 setup --url https://my-onprem.internal
Defensive patterns
Strategy: validation
Validate before calling
function isDeploymentRoot(raw: string): boolean {
try {
const p = new URL(raw).pathname.replace(/\/+$/, '');
return !p.endsWith('/mcp') && !p.endsWith('/api');
} catch { return false; }
} Try / catch
try {
const dep = resolveSetupDeployment(input);
} catch (e) {
if ((e as Error).message.includes('without /mcp or /api')) {
console.error('Pass the deployment root, e.g. https://host — the CLI appends /mcp itself.');
}
} Prevention
- Treat the setup URL as an origin, not an endpoint.
- Don't copy endpoint URLs from MCP client configs into deployment setup.
- Remember the CLI composes ${baseUrl}/mcp itself.
When it happens
Trigger: normalizeDeploymentBaseUrl receives a URL whose pathname ends with '/mcp' or '/api', e.g. 'https://host/mcp' or 'https://host/api', after trailing slashes are stripped.
Common situations: Copying the MCP endpoint URL shown in an MCP client config into the setup command; copying an API docs URL instead of the deployment origin.
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
- Context7 base URL must use http:// or https://
- invalid_url
- Context7 base URL must not contain credentials
AI-assisted analysis of upstash/context7@4416fb855b (2026-09-16).
Data as JSON: /api/errors/6f4845baa9b1b569.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/setup/deployment.ts:34
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);
return baseUrl === DEFAULT_CONTEXT7_BASE_URL
? { kind: "hosted", baseUrl: DEFAULT_CONTEXT7_BASE_URL }
: { kind: "custom", baseUrl };
}
export function getMcpUrl(deployment: SetupDeployment, auth: AuthOptions): string {
if (deployment.kind === "hosted") {
return auth.mode === "oauth"
? `${HOSTED_MCP_BASE_URL}/mcp/oauth`
: `${HOSTED_MCP_BASE_URL}/mcp`;
}
return `${deployment.baseUrl}/mcp`;View on GitHub (pinned to 4416fb855b)