OAuth, without API keys.
Updated October 10, 2026
DialMCP uses OAuth for the remote MCP connection. Your client opens the sign-in in a browser, so there is no API key to create, paste, rotate, or leak into a prompt. You add one URL, https://mcp.dialmcp.com/mcp, and the client works out the rest. That URL is documented on the hosted MCP server endpoint page.
This page describes DialMCP’s own flow: what the client discovers, how it registers, what tokens it gets, and what to do when sign-in breaks. For the per-client steps, see client setup. For how MCP authorization works in general, with the spec’s requirements revision by revision, read MCP authorization and OAuth for remote servers.
First connection
- Add
https://mcp.dialmcp.com/mcpto a client that supports remote MCP. - The client opens your browser. Enter a US or Canadian mobile number and type the SMS code.
- First time only: enter the first name the assistant should use on calls.
- Review the consent screen, click Allow, and return to your client.
The screens and their exact error messages are listed on client setup. The rest of this page is what happens underneath.
Step 1: discovery
A client that connects without a token gets a 401. The WWW-Authenticate header points to DialMCP’s protected resource metadata (RFC 9728):
HTTP/2 401
www-authenticate: Bearer realm="OAuth",
error="invalid_token",
error_description="Missing or invalid access token",
resource_metadata="https://mcp.dialmcp.com/.well-known/oauth-protected-resource/mcp"That document names the resource and its authorization server. Both the path-aware URL above and the root URL /.well-known/oauth-protected-resource return it, so clients that skip the header and probe the well-known URLs find it too:
{
"resource": "https://mcp.dialmcp.com/mcp",
"authorization_servers": ["https://mcp.dialmcp.com"],
"bearer_methods_supported": ["header"],
"resource_name": "dialmcp"
}The client then reads the authorization server metadata (RFC 8414) at https://mcp.dialmcp.com/.well-known/oauth-authorization-server. The fields that matter:
issuer:https://mcp.dialmcp.comauthorization_endpoint:/authorizetoken_endpoint:/tokenregistration_endpoint:/registergrant_types_supported:authorization_code,refresh_tokencode_challenge_methods_supported:plain,S256token_endpoint_auth_methods_supported:client_secret_basic,client_secret_post,none
There is no OpenID Connect discovery document (/.well-known/openid-configuration returns 404). DialMCP is not an identity provider, so clients use the RFC 8414 path.
Step 2: client registration
DialMCP registers clients with Dynamic Client Registration (RFC 7591) at /register. The client posts its name and redirect URIs and gets back a client_id. Confidential clients also get a secret. You never see any of this. It is why the browser page can say “Claude wants to place phone calls on your behalf”: the name comes from the registration.
The metadata does not advertise Client ID Metadata Documents (CIMD), which the current MCP spec prefers over DCR. Clients that support both handle this automatically. Claude, for example, uses CIMD only when the server advertises it and otherwise falls back to DCR. You do not need to pick a registration option or bring your own OAuth client.
A registration request without at least one redirect URI is rejected with invalid_client_metadata.
Step 3: the authorization request
The client opens /authorize in your browser with a PKCE challenge, its redirect_uri, and a state value. DialMCP checks two things before showing any page:
- The client is registered. If not, the page says “Unknown client”.
- The redirect URI exactly matches one the client registered, when the client sends one. Anything else is refused.
DialMCP accepts both PKCE methods it advertises. The MCP spec requires clients to use S256 when they can. Claude, for example, sends S256 on every authorization request. Spec-following clients also send a resource parameter set to https://mcp.dialmcp.com/mcp. DialMCP does not inspect it: there is a single protected resource, and its tokens are only checked on the /mcp endpoint.
The sign-in pages then run phone, code, name (new accounts only) and consent. Progress between pages is carried in a signed, expiring value rather than a server session. That means:
- The whole browser flow must finish within 10 minutes of opening it.
- Steps cannot be skipped: each page only accepts progress signed for that step. An expired, altered or wrong-step submission shows “This sign-in link expired or was tampered with.”
- Five wrong SMS codes lock the flow. Restart from the client to get a fresh code.
- Code sends are rate-limited per phone number and per IP address.
When you click Allow, DialMCP redirects back to the client with an authorization code and your original state. When you click Deny, it redirects with error=access_denied.
Step 4: tokens
The client exchanges the code at /token, along with its PKCE verifier. The authorization code is single-use and expires 10 minutes after it is issued. The response contains:
- An access token valid for 1 hour (
expires_in: 3600). The client sends it on every MCP request asAuthorization: Bearer …. Tokens are never accepted in the query string. - A refresh token. Before the hour is up, or after a
401, the client trades it at/tokenfor a new access token and a new refresh token. Rotation is built in, but the token you just used keeps working until the next refresh, so a retry after a dropped response does not strand you.
Tokens are opaque strings, not JWTs. Each one holds an internal account ID and grant ID plus a random secret. Your name and phone number are not in the token; they are stored with the grant on DialMCP’s side.
What you are authorizing
DialMCP does not use OAuth scopes. The metadata has no scopes_supported, and the consent screen is all-or-nothing. It tells you the client will be able to:
- place phone calls as your verified number, and
- view call status, transcripts and recordings.
It also reminds you that every call opens with an AI disclosure and is recorded. Once you allow access, the MCP server knows your account ID, the name you gave, and your verified phone number. It uses them to set the caller ID, say whose behalf the call is on, and show you only your own calls. The tool reference explains what each of the four tools does with that identity.
Your caller ID
The number you verify becomes the caller ID on calls you authorize. DialMCP does not spoof a number or hide behind a random caller ID, and recipients can call you back directly.
That is why verification is stricter for new accounts. On sign-up, the SMS code confirms both that you have the phone and that the number can be presented as your caller ID. Later sign-ins on the same number use an ordinary one-time code. The same number in a second client signs in to the same account, so call history and rate limits are shared across clients.
Re-authenticating and disconnecting
- Re-authenticate when a client keeps reporting that it needs sign-in, for example after you clear its stored credentials. Use the client’s own control:
/mcpin Claude Code,codex mcp login dialmcpin Codex. Each client’s re-auth step is on client setup. - Disconnect by removing DialMCP from the client. The client discards its tokens, so it can no longer place calls. This does not revoke the grant on DialMCP’s side.
Troubleshooting at the protocol level
Most people never need this. It is for client developers and for anyone reading client logs.
401witherror="invalid_token": no token, or the access token expired. A healthy client refreshes and retries once. If it keeps getting 401s, its refresh token is gone, so re-authenticate.- “Unknown client” in the browser: the client is using a
client_idDialMCP does not have. This usually happens with a stale saved registration. Remove the server from the client and add it again so it re-registers. - A plain “Internal error” (HTTP 500) right after the browser opens: usually the client sent a
redirect_uriit did not register. That is a client bug or a mixed-up saved registration. Re-adding the server fixes the second case. invalid_grantfrom/token: the authorization code was already used or is older than 10 minutes, the PKCE verifier did not match, or the refresh token is no longer valid. Restart the sign-in.invalid_clientfrom/token: the request had noclient_idor one DialMCP does not have (for example a stale registration), or a confidential client sent a missing or wrong secret.access_deniedin the redirect: someone clicked Deny. Reconnect when you want to allow it.- Static bearer tokens: do not configure one, for example Codex’s
bearer_token_env_varor a hand-writtenAuthorizationheader. DialMCP only accepts tokens issued through this flow.
Remote connection versus stdio bridge
OAuth is used for the hosted remote endpoint. The stdio bridge exists for clients that only support local MCP servers. It runs locally and goes through the same browser sign-in for the hosted service, so you still verify your phone and still get your own caller ID. The how to build an MCP server guide shows how browser-based OAuth works for any remote server. If you are containerizing your own Streamable HTTP server, put OAuth in front of the published URL. The Docker notes are on deploy an MCP server with Docker.
What OAuth does not change
Signing in does not bypass the service’s safety controls. Calls are still subject to AI disclosure, destination-local calling hours, concurrency and frequency limits, blocked number ranges, objective screening, and permanent opt-outs. See Safety for details.
FAQ
Do I need an API key or client secret?
No. The client registers itself and gets its credentials automatically. You only sign in with your phone in the browser.
How long does a sign-in last?
Access tokens last one hour, and the client refreshes them in the background with a rotating refresh token. You sign in again only when the client loses its stored credentials or you remove and re-add the server.
Does DialMCP use OAuth scopes?
No. Consent covers placing calls as your verified number and viewing your call status, transcripts and recordings. There is no narrower grant.
Why does the sign-in ask for a phone number instead of an email?
Your verified number is the caller ID on every call you authorize. The phone is the account.
https://mcp.dialmcp.com/mcp. It is the same URL as the hosted MCP endpoint, the connector README, the client setup examples, and the MCP server configuration examples. The resource value in the metadata is that exact string, path included.Once connected, learn the tool lifecycle and the JSON-RPC commands the client sends, or return to the docs home.