✔ ConnectedReady. This is what you want after OAuth.
! Needs authenticationReachable. Sign in next. Expected for DialMCP before the browser flow.
! Connected · tools fetch failedTCP worked, tools/list did not. claude mcp get dialmcp has the error.
✘ Failed to connect / ✘ Connection errorURL did not respond, or a header you set was rejected.
⏸ Pending approval (run claude to approve)Project-scoped .mcp.json you have not trusted yet.

On some Windows consoles the glyphs render as and ×. Same statuses.

claude mcp get dialmcp prints the scope and the full URL. If /mcp later says the endpoint was not found, the error often shows the origin without the path. The get command is how you see /mcp is missing.

Finish OAuth

Close-up of a laptop keyboard with the D key in focus
Photo: Martin Vorel / Wikimedia Commons (CC BY-SA 4.0).

DialMCP, Sentry, Linear, Notion, and most hosted remotes sit behind OAuth. After add, claude mcp list showing ! Needs authentication is the happy path, not a bug.

Inside a session:

/mcp

Select dialmcp, press Enter, choose Authenticate. The browser opens. Sign in, verify a US or Canadian mobile number by SMS, approve, come back. The verified number is the caller ID on calls you authorize. There is no API key to paste.

From Claude Code v2.1.186 you can skip the panel:

claude mcp login dialmcp

claude mcp logout dialmcp clears stored credentials. If you are on SSH or a box with no display, claude mcp login dialmcp --no-browser prints the URL. Open it on a machine with a browser, then paste the full redirect URL back at the prompt (ssh -t so the paste works).

If the browser opens and the callback then fails, paste the full callback URL from the address bar into the prompt Claude Code shows. Tokens are stored and refreshed; a later 401 retries once after refresh before /mcp asks you to re-authenticate.

Then ask something that requires a tool. "What tools do you have from dialmcp?" is boring and useful. You want place_call, get_call, end_call, and list_calls. The first tool call asks for permission. Approve it. The label on that tool in the output is how you know the answer came from the MCP server, not a web search. Tool shapes: DialMCP tools.

A real first task is one call with a stated objective, not a test ping. Something like: call the dental office, ask whether they have an opening Thursday after 3, do not book. place_call returns a call ID immediately. Poll get_call until it finishes. That is asynchronous on purpose. Guardrails still apply: AI disclosure, destination-local hours, rate limits, blocked ranges. See Safety. DialMCP is for individual, objective-driven calls. Bulk, telemarketing, surveys, lead gen, debt collection, and political outreach are refused.

Pick a scope or the next repo looks empty

Default scope is local: private to you, active only in the project where you ran the command. Stored in ~/.claude.json under that project's path, not in ~/.claude/mcp.json or %APPDATA%\Claude\mcp.json. Claude Code does not read those paths. On Windows, ~/.claude.json is %USERPROFILE%\.claude.json. If CLAUDE_CONFIG_DIR is set, the file is .claude.json inside that directory instead.

ScopeFlagFileWho sees it
local (default)--scope local~/.claude.json (per project)You, this project
project--scope project.mcp.json at the repo rootAnyone who clones it
user--scope user~/.claude.json (top-level mcpServers)You, every project

A server's scope is fixed at add time. To move it, remove and re-add:

claude mcp remove dialmcp --scope local
claude mcp add --scope user --transport http dialmcp https://mcp.dialmcp.com/mcp

User scope is the right default for a personal remote like DialMCP that you want in every repo. Project scope is for the team copy. Commit .mcp.json. Teammates get an approval prompt the first time; that prompt exists so a cloned repo cannot launch processes without consent. claude mcp reset-project-choices clears those approvals if you rejected one by accident.

/mcp showing No MCP servers configured almost always means you added at local scope in a different directory. Re-add from this project, or use --scope user.

When the same name exists in more than one place, Claude Code connects once, using the whole entry from the highest-precedence source. Fields are not merged. Order: local, then project, then user, then plugins, then claude.ai connectors.

The `.mcp.json` type field

Hand-writing the project file is fine. This is the DialMCP shape:

{
  "mcpServers": {
    "dialmcp": {
      "type": "http",
      "url": "https://mcp.dialmcp.com/mcp"
    }
  }
}

type is required. A url with no type is read as stdio. Claude Code skips the server and reports that you need "type": "http" (or sse / ws). Before v2.1.202 the same mistake printed command: expected string, received undefined. That error looks like a missing npx binary. It is not. The entry was never a command.

Restart the session after editing .mcp.json. Claude Code reads it at startup. Malformed entries are skipped; /mcp shows the parse warning.

Do not copy this block into VS Code's mcp.json (root key is servers) or Cursor's .cursor/mcp.json (no type required the same way). The cheat sheet is configuration examples.

Local stdio, briefly

A local server is a subprocess. Everything after -- is the command Claude Code runs:

claude mcp add playwright -- npx -y @playwright/mcp@latest

No --transport flag; stdio is the default. Without --, Claude Code parses the server's flags as its own. The add command itself is the same in PowerShell and Command Prompt.

This is the right path for Playwright, a filesystem allowlist, Docker, a database socket. It is the wrong path for DialMCP. The hosted calling service is already on the internet. If a client truly cannot speak remote HTTP, the stdio bridge (npx -y dialmcp-connector) is a local shim that still talks to https://mcp.dialmcp.com/mcp after OAuth. It is not a second product.

MCP_TIMEOUT defaults to 30 seconds at startup. A first npx download can miss that. MCP_TIMEOUT=60000 claude raises it. That knob is for slow local starts, not for DialMCP.

claude.ai connectors inside Claude Code

If Claude Code's active login is a claude.ai subscription, connectors you added at claude.ai/customize/connectors show up in /mcp with a claude.ai marker. Team and Enterprise still need an Owner to add the URL first; members then Connect. Unused connectors collapse behind a "Show unused connectors" row.

They do not load when ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, apiKeyHelper, Bedrock, Google Cloud's Agent Platform, or CLAUDE_CODE_OAUTH_TOKEN from claude setup-token is the active credential. /status tells you which login is actually in force. A connector showing connected · session token rejected is a stale Claude Code login, not a broken DialMCP OAuth. /login again, then reconnect from /mcp.

A server you added with claude mcp add at the same URL hides the claude.ai copy. /mcp says so.

To copy Desktop local servers into Claude Code on macOS or WSL: claude mcp add-from-claude-desktop. That reads claude_desktop_config.json. It will not import a custom connector, and it will skip Desktop names that contain spaces.

Mistakes that look like a dead Claude Code MCP server

Added in the wrong directory. Local scope is per project. claude mcp list from ~/work/other will not show what you added in ~/work/this.

URL without type in .mcp.json. Skipped. Add "type": "http".

Bearer header on an OAuth server. Failed connection, no /mcp Authenticate option. Remove the header, claude mcp remove, re-add.

Wrong path on the URL. A 404 in /mcp says the endpoint was not found at the origin. claude mcp get shows whether you dropped /mcp. Many MCP endpoints only answer POST, so curl -I returning 404 or 405 still means the host is up.

Expecting Desktop JSON to feed Claude Code. It does not, except the explicit import command on macOS/WSL. The reverse is also false: .mcp.json is not claude_desktop_config.json.

API key field. DialMCP has none. See install.

Wrapping Claude Code as the server. Repos named claude-code-mcp that expose claude -p as tools are the inverse of this setup. They will not add DialMCP to your CLI.

Further reading

Need a phone-call MCP server, not another local process? DialMCP is already hosted at https://mcp.dialmcp.com/mcp. Add it with claude mcp add, finish OAuth, skip the deploy.

Claude Code client setup

FAQ

Is this the same as adding an MCP server to Claude?

No. Claude.ai and Claude Desktop use Connectors and, for local Desktop only, claude_desktop_config.json. Claude Code uses claude mcp add. The Claude article covers the other two.

Should I put DialMCP at project scope?

Only if the whole team should see the same remote. Most people want --scope user so every repo gets it without committing a personal OAuth client into git. Project-scoped remotes still need each person to Authenticate as themselves.

Can I start on stdio and skip HTTP?

Yes for tools that must run on your machine. No for DialMCP. Use HTTP, or the npx bridge if the host cannot speak remote MCP.

Why does `claude -p` not open OAuth?

Non-interactive runs have no /mcp panel. Authorize once from an interactive session or claude mcp login, then the print-mode run can use the stored token.

Where do I put the JSON?

Claude Code project file: .mcp.json with "type": "http". Not VS Code settings.json. Not Desktop's config file. Configuration examples is the file-path map.

Ready-to-paste snippets for Claude Code, Cursor, VS Code, Codex, and Desktop are on client setup. If you are building the server rather than connecting to one, start from how to build an MCP server or the stdio-to-remote tutorial.