different-ai/openwork · error
An enterprise MCP OAuth redirect URI cannot contain credenti
Error message
An enterprise MCP OAuth redirect URI cannot contain credentials or a fragment.
What it means
validateRedirectUri in packages/enterprise-mcp-client/src/enterprise-mcp-client.ts throws when the redirect URI contains embedded userinfo credentials (username/password) or a fragment. Both are invalid for OAuth redirect URIs per RFC 9700 (fragments never reach the server; credentials in URLs leak secrets) and would break exact-match registration at the authorization server.
Source
Thrown at packages/enterprise-mcp-client/src/enterprise-mcp-client.ts:121
const url = new URL(parsed.serverUrl)
if (url.protocol !== "https:" && url.protocol !== "http:") {
throw new Error("An enterprise MCP server URL must use HTTP or HTTPS.")
}
if (url.username || url.password) {
throw new Error("An enterprise MCP server URL cannot contain embedded credentials.")
}
if (url.hash) throw new Error("An enterprise MCP server URL cannot contain a fragment.")
return url
}
function validateRedirectUri(redirectUri: string): string {
const parsed = redirectUriSchema.parse(redirectUri)
const url = new URL(parsed)
if (url.protocol !== "https:" && url.protocol !== "http:") {
throw new Error("An enterprise MCP OAuth redirect URI must use HTTP or HTTPS.")
}
if (url.username || url.password || url.hash) {
throw new Error("An enterprise MCP OAuth redirect URI cannot contain credentials or a fragment.")
}
return parsed
}
function configurationValue<T>(parse: () => T): T {
try {
return parse()
} catch (error) {
throw new EnterpriseMcpClientError({
operationPhase: "configuration",
requestPhase: null,
cause: error,
})
}
}
async function closeWithinDeadline(close: () => Promise<void>, timeoutMs: number): Promise<void> {
let timer: ReturnType<typeof setTimeout> | undefinedView on GitHub (pinned to 2b7df46e8a)
Solutions
- Remove any user:pass@ userinfo and #fragment from the redirect URI.
- Register a clean https:// (or http://127.0.0.1 loopback) callback with the authorization server and use exactly that string.
- Validate the redirect URI shape before constructing the client.
Example fix
// before redirectUri: "https://admin:secret@mcp.example.com/callback#oauth" // after redirectUri: "https://mcp.example.com/callback"
Defensive patterns
Strategy: validation
Validate before calling
function assertCleanRedirectUri(redirectUri: string) {
const u = new URL(redirectUri)
if (u.username || u.password || u.hash) {
throw new Error("redirectUri must not contain credentials or a fragment")
}
} Prevention
- Keep redirect URIs to scheme://host/path with no userinfo and no '#'
- Verify the registered callback in the authorization-server admin console matches byte-for-byte
- Avoid copying URLs from browsers (they often include anchors)
When it happens
Trigger: Passing a redirect URI like "https://user:pass@example.com/cb" or "https://example.com/cb#frag" to the client's redirect URI configuration.
Common situations: Reusing a URL copied from a browser (with an anchor) as the redirect; template config values like https://USER:PASS@host/cb that were never substituted out; confusion between the server URL rules and redirect URI rules.
Related errors
- An enterprise MCP OAuth redirect URI must use HTTP or HTTPS.
- `${t("providers.no_oauth_prefix")} ${resolved}. ${t("provide
- `${t("providers.not_oauth_flow_prefix")} ${resolved}.`
- t("providers.oauth_method_required")
- OpenWork-managed OAuth requires a remote MCP URL.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/b5e8e223841f9cf2.
Report an issue: GitHub.