{"slug": "sign-in-to-a-remote-mcp-server-in-claude-code-mcp-and-claude-mcp-login", "title": "Sign in to a remote MCP server in Claude Code: /mcp and claude mcp login", "summary": "A developer has documented how to authenticate remote MCP servers in Claude Code, which requires a browser-based OAuth sign-in before hosted servers like Sentry, Linear and Notion become usable. Servers are added with `claude mcp add --transport http <name> <url>` and then authorized either through the `/mcp` panel or the shell command `claude mcp login <name>`, with tokens stored securely and refreshed automatically. The guide also covers `--callback-port` for fixed redirect URIs, passing a pre-registered client ID and secret, and headless sign-in over SSH using `--no-browser`.", "body_md": "*Originally published at [https://aicoding-guide.com](https://aicoding-guide.com/en/posts/claude-code-mcp-http-oauth/).*\n\nHosted MCP servers like Sentry, Linear and Notion are not usable the moment you register their URL. They need a browser sign-in first, and `claude mcp list` shows them as `! Needs authentication` until you do it.\n\nIn short: add the server with `claude mcp add --transport http <name> <url>`, then either run `/mcp` in a session and choose `Authenticate` on that server, or run `claude mcp login <name>` from your shell. Tokens are stored securely and refreshed automatically.\n\nThis article is part of a series. For every way to register a server, see [Adding MCP servers to Claude Code](https://aicoding-guide.com/en/posts/claude-code-mcp-servers-setup/).\n\n**Key point**\n\nWhat you will learn\n\n- The two ways to sign in:\n`/mcp` and `claude mcp login`\n`--callback-port` for a fixed redirect URI, and how to pass a pre-registered client ID- What to do when a token expires or the browser never opens\n\nRegister the server over the HTTP transport. The docs use Sentry as the example.\n\n```\nclaude mcp add --transport http sentry https://mcp.sentry.dev/mcp\n```\n\nRight after adding, `claude mcp list` shows `! Needs authentication`. That is expected; the sign-in clears it.\n\nStart a session, run `/mcp`, select the server from the list, press Enter and choose `Authenticate`. Your browser opens the service's sign-in page, where you approve the connection. Back in Claude Code the server's status changes to connected.\n\nClaude Code marks a remote server as needing authentication when it answers with `401 Unauthorized` or `403 Forbidden`. There is also a startup notice listing servers that need sign-in, so you do not have to open `/mcp` to find them (v2.1.193 or later).\n\n**Glossary**\n\n**Dynamic Client Registration**: an OAuth mechanism where the client registers itself with the authorization server instead of you registering an app by hand. When a server supports it, passing the URL to `claude mcp add` is all the setup the sign-in needs.\n\nTo sign in without opening a session, use `claude mcp login`.\n\n```\nclaude mcp login sentry\n```\n\nTo clear stored credentials later, run `claude mcp logout <name>`.\n\nOver SSH, or on Linux without a display server, the command detects that no local browser is available and prints the authorization URL rather than trying to open one. Open that URL on your own machine, then paste the full redirect URL from the address bar back at the prompt. The paste step needs an interactive terminal, so connect with `ssh -t`. Pass `--no-browser` to force the URL prompt even when a browser is detected.\n\n```\nclaude mcp login sentry --no-browser\n```\n\nNon-interactive runs (`claude -p`, the Agent SDK) have no `/mcp` panel, so Claude Code cannot run the OAuth flow there. As of v2.1.196, with tool search enabled, it tells Claude that the server's tools are unavailable until you authorize it, so Claude can name the server instead of acting as though it were not configured. Do the sign-in itself from an interactive session or with `claude mcp login`.\n\nIf a server does not support Dynamic Client Registration, you get an error such as \"Incompatible auth server: does not support dynamic client registration\". Register an OAuth app through the service's developer portal and pass the credentials yourself.\n\nServers that require a registered redirect URI expect the form `http://localhost:PORT/callback`. Pick a port, register it, and pass the same port to `--callback-port`: by default Claude Code picks a random free port, which will never match.\n\n| Flag / key | What it does | \n|---|---|\n| `--callback-port <port>` | Fixes the callback port. Usable on its own | \n| `--client-id <id>` | The client ID of your registered OAuth app | \n| `--client-secret` | Prompts for the secret with masked input | \n| `MCP_CLIENT_SECRET` | Supplies the secret through the environment, skipping the prompt | \n\n```\nclaude mcp add --transport http \\\n  --client-id your-client-id --client-secret --callback-port 8080 \\\n  my-server https://mcp.example.com/mcp\n```\n\nIn JSON, the same settings live in an `oauth` object. The secret stays out of the JSON and is passed with the separate `--client-secret` flag.\n\n```\nclaude mcp add-json my-server \\\n  '{\"type\":\"http\",\"url\":\"https://mcp.example.com/mcp\",\"oauth\":{\"clientId\":\"your-client-id\",\"callbackPort\":8080}}' \\\n  --client-secret\n```\n\n`oauth` also takes `scopes`, which pins the scopes requested during authorization (a single space-separated string, matching RFC 6749), and `authServerMetadataUrl`, which overrides metadata discovery.\n\n```\n{\n  \"mcpServers\": {\n    \"slack\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.slack.com/mcp\",\n      \"oauth\": {\n        \"scopes\": \"channels:read chat:write search:read\"\n      }\n    }\n  }\n}\n```\n\n`oauth.scopes` takes precedence over `authServerMetadataUrl` and over whatever the server advertises at `/.well-known`. If the authorization server advertises `offline_access`, Claude Code appends it so the token can be refreshed without another browser sign-in.\n\n**The secret can only be set when you add the server**\n\nThe client secret is stored in your system keychain (macOS) or a credentials file, never in your config. You can set it only at add time: when you authenticate with `claude mcp login` or from `/mcp`, Claude Code uses the stored secret and neither prompts for one nor reads `MCP_CLIENT_SECRET`. To change it, run `claude mcp remove <name>` and add the server again with `--client-secret` and the same `--scope`. Use `claude mcp get <name>` to check whether credentials are configured.\n\nWhich file each scope writes to is covered in [claude mcp add scopes: local, project and user](https://aicoding-guide.com/en/posts/claude-code-mcp-scope/), and passing a static token through a header in [Passing tokens from environment variables in .mcp.json](https://aicoding-guide.com/en/posts/claude-code-mcp-json-env/).\n\nWhen a request to a server you already signed in to returns `401`, Claude Code refreshes the stored token, reconnects and retries the request once. It flags the server in `/mcp` only if that retry also fails.\n\nWhen the server rejects the stored refresh token, a notice pointing at `/mcp` appears immediately. Open `/mcp` and choose **Re-authenticate** on that server.\n\n| Symptom | What to do | \n|---|---|\n| The browser does not open | Copy the URL shown in the terminal and open it manually | \n| The redirect fails with a connection error after you authenticate | Paste the full callback URL from the address bar into the URL prompt Claude Code shows | \n| A server with a configured `Authorization` header returns 401 or 403 | It will not fall back to OAuth; the connection is reported as failed. Check the token, or remove the header | \n| A tool call fails with 403 `insufficient_scope` | Add the scope the server names to `oauth.scopes` , then authenticate again from`/mcp` | \n\nThat last row catches people out: Claude Code requests the scopes you pinned, not the scope the server asked for, so signing in again without adding it gives you a token that still lacks it.\n\nOne gap worth naming: **the on-disk location of OAuth access and refresh tokens could not be confirmed in the official documentation**. It says only that tokens are \"stored securely and refreshed automatically\", and names the keychain or a credentials file for the client secret alone.\n\n`claude mcp add --transport http <name> <url>`, then sign in from `/mcp` → `Authenticate` or with `claude mcp login <name>`\n`claude mcp logout <name>` or \"Clear authentication\" in the `claude mcp login --no-browser` prints the URL and takes the redirect URL back`--client-id` and `--callback-port`, plus `--client-secret` if the app has one`oauth.scopes` first", "url": "https://wpnews.pro/news/sign-in-to-a-remote-mcp-server-in-claude-code-mcp-and-claude-mcp-login", "canonical_source": "https://dev.to/aicoding-guide/sign-in-to-a-remote-mcp-server-in-claude-code-mcp-and-claude-mcp-login-43i7", "published_at": "2026-09-27 19:21:56+00:00", "updated_at": "2026-09-27 20:01:08.089858+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "developer-tools", "ai-tools"], "entities": ["Claude Code", "Anthropic", "Sentry", "Linear", "Notion", "Model Context Protocol"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/sign-in-to-a-remote-mcp-server-in-claude-code-mcp-and-claude-mcp-login", "markdown": "https://wpnews.pro/news/sign-in-to-a-remote-mcp-server-in-claude-code-mcp-and-claude-mcp-login.md", "text": "https://wpnews.pro/news/sign-in-to-a-remote-mcp-server-in-claude-code-mcp-and-claude-mcp-login.txt", "jsonld": "https://wpnews.pro/news/sign-in-to-a-remote-mcp-server-in-claude-code-mcp-and-claude-mcp-login.jsonld"}}