{"record":{"id":"0dc608c8cfc4f0a8","repo":"can1357/oh-my-pi","slug":"this-server-proxies-oauth-through-mcp-remote-whic","errorCode":null,"errorMessage":"this server proxies OAuth through mcp-remote, which caches tokens machine-wide in ~/.mcp-auth (shared across every OMP profile). Clear ~/.mcp-auth to force a fresh login, or replace the proxy with ${httpHint} so OMP manages OAuth per profile.","messagePattern":"this server proxies OAuth through mcp-remote, which caches tokens machine-wide in ~/\\.mcp-auth \\(shared across every OMP profile\\)\\. Clear ~/\\.mcp-auth to force a fresh login, or replace the proxy with (.+?) so OMP manages OAuth per profile\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/modes/controllers/mcp-command-controller.ts","lineNumber":1210,"sourceCode":"\t\tconst next = { ...config } as MCPServerConfig & { auth?: MCPAuthConfig };\n\t\tdelete next.auth;\n\t\treturn next;\n\t}\n\n\tasync #resolveOAuthEndpointsFromServer(\n\t\tconfig: MCPServerConfig,\n\t\tauthChallenge?: MCPAuthChallenge,\n\t): Promise<OAuthEndpoints> {\n\t\t// Stdio servers manage credentials inside the child process; OMP's OAuth\n\t\t// flow only applies to http/sse transports. Without this guard the\n\t\t// unauthenticated preflight below spawns the child, which happily reuses\n\t\t// its own cached tokens (e.g. mcp-remote's machine-wide ~/.mcp-auth) and\n\t\t// produces the misleading \"reauthorization is not required\".\n\t\tif (config.type !== \"http\" && config.type !== \"sse\") {\n\t\t\tconst remoteUrl = config.args?.find(arg => /^https?:\\/\\//.test(arg));\n\t\t\tconst httpHint = `{ \"type\": \"http\", \"url\": ${JSON.stringify(remoteUrl ?? \"<remote url>\")} }`;\n\t\t\tconst usesMcpRemote = [config.command, ...(config.args ?? [])].some(part => part?.includes(\"mcp-remote\"));\n\t\t\tthrow new Error(\n\t\t\t\tusesMcpRemote\n\t\t\t\t\t? `this server proxies OAuth through mcp-remote, which caches tokens machine-wide in ~/.mcp-auth (shared across every OMP profile). Clear ~/.mcp-auth to force a fresh login, or replace the proxy with ${httpHint} so OMP manages OAuth per profile.`\n\t\t\t\t\t: `stdio servers manage their own credentials, so OMP has no OAuth to reauthorize. If the service supports OAuth over HTTP, configure it as ${httpHint} instead.`,\n\t\t\t);\n\t\t}\n\t\t// First test if server actually needs auth by connecting without OAuth\n\t\tlet connectionSucceeded = false;\n\t\tlet connectionError: Error | undefined;\n\t\ttry {\n\t\t\tawait this.#handleTestConnection(this.#stripOAuthAuth(config), { oauth: false });\n\t\t\tconnectionSucceeded = true;\n\t\t} catch (error) {\n\t\t\tconnectionError = error as Error;\n\t\t}\n\n\t\t// Server connected fine without auth. A tool-level challenge overrides\n\t\t// this: servers may allow the anonymous handshake yet protect individual\n\t\t// tool calls with `_meta[\"mcp/www_authenticate\"]`. Even without such a","sourceCodeStart":1192,"sourceCodeEnd":1228,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/modes/controllers/mcp-command-controller.ts#L1192-L1228","documentation":"Thrown by #resolveOAuthEndpointsFromServer when /mcp reauth is requested for a server whose transport is not http/sse (i.e. stdio). OMP's OAuth flow only works over HTTP transports; for stdio servers the child process manages its own credentials, so there is no OMP-side OAuth to refresh. When the command line contains mcp-remote, the message additionally warns that mcp-remote caches tokens machine-wide in ~/.mcp-auth, shared across all OMP profiles, and suggests switching to a direct http config.","triggerScenarios":"Running /mcp reauth <name> where the server config has type stdio (or any type other than http/sse) — either a plain stdio server, or one launched via `npx mcp-remote https://...`.","commonSituations":"Users copy a Claude Code / Cursor config that wraps a remote MCP server in mcp-remote for OAuth support, then try to re-authorize inside OMP; tokens appear 'stuck' because ~/.mcp-auth is machine-global and profile-independent.","solutions":["If it uses mcp-remote: delete ~/.mcp-auth to clear the shared token cache, then log in again.","Better: replace the mcp-remote proxy with a native http config — `{ \"type\": \"http\", \"url\": \"<the remote url>\" }` — so OMP manages OAuth per profile (run /mcp reauth again afterwards).","For plain stdio servers: re-authorize through the service's own CLI/tooling; OMP has no OAuth to manage. If the service supports OAuth over HTTP, reconfigure it as an http server."],"exampleFix":"// before (stdio via mcp-remote, shared token cache)\n{ \"type\": \"stdio\", \"command\": \"npx\", \"args\": [\"-y\", \"mcp-remote\", \"https://mcp.example.com/mcp\"] }\n// after (native http transport, OMP-managed OAuth per profile)\n{ \"type\": \"http\", \"url\": \"https://mcp.example.com/mcp\" }","handlingStrategy":"validation","validationCode":"const cfg = getServerConfig(name);\nif (cfg.type !== \"http\" && cfg.type !== \"sse\") {\n  throw new Error(`/mcp reauth only applies to http/sse servers; '${name}' is ${cfg.type}`);\n}","typeGuard":"function isRemoteMcpConfig(c: MCPServerConfig): c is MCPServerConfig & { type: \"http\" | \"sse\"; url: string } {\n  return (c.type === \"http\" || c.type === \"sse\") && \"url\" in c && typeof c.url === \"string\";\n}","tryCatchPattern":"try {\n  await reauthServer(name);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"mcp-remote\")) {\n    // stdio/mcp-remote target: switch config to native http and clear ~/.mcp-auth\n  } else throw err;\n}","preventionTips":["Prefer native { \"type\": \"http\", \"url\": ... } configs over the mcp-remote proxy whenever the service supports OAuth over HTTP.","Remember ~/.mcp-auth is machine-global — treat 'stuck' mcp-remote logins as a stale-cache problem and delete that directory.","Only run /mcp reauth against remote (http/sse) servers; stdio credentials belong to the child process."],"tags":["oauth","mcp","stdio","mcp-remote","config"],"backgroundTag":"oauth-unsupported-transport","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}