learn-mcp-with-phoebe / Builder session 4 of 8
Learn MCP with Phoebe · Builder track · Session 4 of 8

Connect to real hosts

Your server works in the Inspector. Tonight it works everywhere. You will wire daybreak-mcp into Claude Code with a checked-in .mcp.json, then into Claude Desktop with a config file - and ask "how did March look?" in a real chat and watch it call your tool and answer $150. The payoff of the whole track lands here: one server, three hosts, zero code changes. The only new skill is configuration, and the only new judgement is scope.

🟡 Medium Practitioners: DE · DS · AI engineers · builders Python · spec 2025-11-25 45 min
0-3 · Welcome 3-20 · Claude Code + scopes 20-34 · Desktop + beyond 34-45 · Reference servers + Q&A
Part 0

The same server, three hosts

You wrote daybreak-mcp once. A host is any AI app that speaks MCP - Claude Code, Claude Desktop, Cursor, VS Code. Each connects to your server by configuration, not code: point it at the command that launches your server, and the same handshake and tools/list you have been reading all track runs automatically. Nothing in server.py changes. That interoperability is the entire promise of MCP, and tonight you cash it in.

Live - presented in session Self-study - read after class ▶ Live MCP wire - step through real messages Official sources covered
★ What you walk out with today Daybreak wired into Claude Code via a project-scope .mcp.json and into Claude Desktop via claude_desktop_config.json, a clear rule for which of the three scopes to use when, the tool-naming convention that tells you a server landed (mcp__daybreak__query_sales), and a reference server running alongside your own in the same host.
Part 1 · covers Claude Code MCP docs, official "Connect to local MCP servers"

Claude Code: .mcp.json and scopes 8 min live

Claude Code configures MCP servers at three scopes, and the scope decides who sees the server and where the config lives. Precedence runs local > project > user: if the same server name is defined at more than one scope, the more specific one wins. Get the scope right and you never fight config again.

local just you, just this project private to your machine use to: experiment project .mcp.json in the repo root checked in, whole team gets it use to: share with a team user every project you open your personal toolbox use to: everywhere-you tools Precedence when a name collides local project user - the leftmost defined wins The 2026-07-28 revision keeps scopes; it changes the wire beneath them, not where your config lives.
🔍 Click to zoom - three scopes, one precedence rule
LiveScope decision guide4 min▶

The rule is about audience, not difficulty. Ask "who should have this server?" and the scope falls out:

  • Experimenting alone? Use local. Private to you and this project, gone when you clean up. Nothing leaks into a repo.
  • Team repo where everyone needs it? Use project. The .mcp.json is checked into the repo root, so every teammate who clones gets Daybreak with no setup.
  • A tool you want in every project? Use user. Your personal toolbox - a reference filesystem server, say - available everywhere you work.

Here is the project-scope config. It lives at the repo root as .mcp.json and gets committed:

.mcp.json · project scope, checked into the repo root{ "mcpServers": { "daybreak": { "command": "uv", "args": ["run", "python", "server.py"], "env": { "DAYBREAK_DB": "${DAYBREAK_DB:-./daybreak.db}" } } } }
  • command + args - exactly how to launch your stdio server; the host runs it as a subprocess.
  • env supports variable expansion: ${VAR} and ${VAR:-default} pull from the environment, so secrets and paths never get hard-coded into the checked-in file.
LiveVerifying a server landed4 min▶

Two ways to confirm Claude Code actually loaded your server. First, run /mcp in the session - it lists connected servers and their status. Second, look at how the tools are named:

the host renames your tools by servermcp__daybreak__query_sales mcp__daybreak__top_products mcp__daybreak__subscription_status # pattern: mcp__<server-name>__<tool-name>
  • mcp__daybreak__query_sales - the host prefixes every tool with mcp__ and the server name from your config. Seeing this prefix is proof the server connected and its tools are namespaced.
  • The server name comes from the JSON key ("daybreak"), not from FastMCP("daybreak-mcp") - name the key deliberately, because it shows up in every tool name.
  • If /mcp shows the server failed, the command in your config threw - run it by hand in the terminal to see the error, exactly like the Inspector failures in b2.
Same handshake, no model in b2 When Claude Code launches your server it runs the exact initialize handshake you stepped through in b1 - just automatically, with a real model on the other end this time.
Part 2 · covers official "Connect to local MCP servers", DLAI "Configuring Servers for Claude Desktop"

Claude Desktop and beyond 7 min live

Claude Desktop uses a single config file, claude_desktop_config.json, with the same mcpServers shape you just wrote - command and args. Edit it, restart Desktop, and your server appears. This is the payoff moment: the identical server.py now runs in a second host, and you changed zero lines of Python.

LiveDesktop config walkthrough4 min▶

Open Desktop's settings, go to Developer, click Edit Config, and add Daybreak. The file lives at:

where the file livesmacOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json
claude_desktop_config.json · add Daybreak{ "mcpServers": { "daybreak": { "command": "uv", "args": [ "run", "--directory", "/Users/you/daybreak-mcp", "python", "server.py" ] } } }
  • Absolute paths. Desktop does not launch from your project folder, so pass --directory with the full path - a relative path is the number-one Desktop failure.
  • Restart to load. Desktop reads this file only at startup. Fully quit and reopen - not just close the window - for the server to appear.
  • Same shape as .mcp.json under the hood: mcpServers, command, args, optional env. Learn it once.
Self-studyVS Code, Cursor, and the rest3 min read▶

The host list keeps growing, and they all consume the same server. You do not relearn MCP per host - you learn where each keeps its config:

  • VS Code (via GitHub Copilot) and Cursor both support MCP servers through their own settings, using the same command/args/env idea.
  • The pattern is universal: a host needs the launch command and, for remote servers, a URL. That is the whole contract.
  • This is why interoperability is the point. You wrote Daybreak once in b2 and b3; every host above runs it unchanged. Adding a host is config, never code.
Part 3 · covers official reference servers, DLAI "Connecting to Reference Servers"

Reference servers 6 min live

You are not the only server in the host. The MCP project ships official reference servers - filesystem, git/github, memory, and more - that you can install alongside Daybreak. A host with several servers is the normal case, and the tool-name prefix is what keeps them straight.

one host Claude Code / Desktop daybreak (yours) filesystem (reference) github (reference) memory (reference) The mcp__<server>__<tool> prefix keeps two servers' tools apart - daybreak's query_sales never collides with anyone's.
🔍 Click to zoom - one host, many servers, all named apart
LivePairing your server with reference servers4 min▶

Add a reference server next to Daybreak in the same config. The filesystem server is the classic pairing - now the model can read a file and query your sales in one conversation:

.mcp.json · two servers, one host{ "mcpServers": { "daybreak": { "command": "uv", "args": ["run", "python", "server.py"] }, "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/reports"] } } }

Reload, and /mcp lists both. The tools are namespaced - mcp__daybreak__query_sales and mcp__filesystem__read_file - so nothing collides. Now watch the handshake that every one of these servers runs when the host starts it:

Demo 1 of 2

Wire Daybreak into Claude Code ★ 12 min · everyone connects

Do it live. Four moves from a checked-in config to a real answer about March in a real chat.

Write .mcp.json at your repo root with the project-scope config from Part 1. Commit it - that is what "project scope" means.

Reload Claude Code in that directory and run /mcp. Confirm daybreak is connected.

Ask, in plain English: "How did March look?" The model finds mcp__daybreak__query_sales, fills month=2026-03, and calls it.

Read the answer. It reports completed revenue $150.00 with one refund - your server, your data, a real host, no code changes.

Demo 2 of 2

Same server, Claude Desktop ★ 8 min · connect

Now the second host, to feel the payoff: identical server, different config file, one restart.

Edit config. Desktop settings -> Developer -> Edit Config. Add the daybreak block from Part 2, with the absolute --directory path.

Restart Desktop fully - quit and reopen, not just close the window. It reads the config only at startup.

Verify. Open the connectors indicator and confirm daybreak lists its three tools.

Ask "how did March look?" again. Same $150 answer, second host, still zero changes to server.py.

Homework

Try it yourself - this week ◐ 25-35 min total

Source material

Official sources covered

This session teaches the working core of the host-connection docs across the official sources, on the running project. Certificates and videos stay official. This page covers:

✓code.claude.com - Claude Code MCP docslocal/project/user scopes, precedence, .mcp.json shape, env-var expansion, /mcp, tool naming
✓modelcontextprotocol.io - "Connect to local MCP servers"claude_desktop_config.json, mcpServers, restart-to-load, reference servers
✓DeepLearning.AI "MCP" - "Configuring Servers for Claude Desktop"Desktop config end to end + connecting to reference servers
◐github.com/modelcontextprotocol/servers - reference server catalogfilesystem/github/memory named and paired; full catalog linked
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · The same server name is defined at local and user scope. Which wins?

Precedence is local > project > user: the most specific scope wins. A local definition overrides both project and user for that server name.

2 · Where does a project-scope .mcp.json live, and what happens to it?

Project scope means .mcp.json sits at the repo root and is committed. Every teammate who clones the repo gets the server with no extra setup - that is the point of the scope.

3 · You edited claude_desktop_config.json but the server does not appear. Most likely fix?

Claude Desktop loads MCP config at launch. After editing the file you must fully quit and reopen the app (not just close the window) for the new server to load. A relative path is the other common culprit.

Builder session 4 cheat sheet · pin this

Three scopeslocal (just you, this project) · project (.mcp.json in repo root, checked in) · user (all your projects).
Precedencelocal > project > user. Most specific wins when a server name collides.
.mcp.json shapemcpServers -> name -> command, args, env. env supports ${VAR} and ${VAR:-default} expansion.
Verify it landedRun /mcp for status; tools appear as mcp__daybreak__query_sales (server name from the JSON key).
Claude Desktopclaude_desktop_config.json, same mcpServers shape. Use absolute --directory. Restart fully to load.
Other hostsVS Code, Cursor - same command/args idea. Adding a host is config, never code.
Reference serversOfficial filesystem/github/memory run alongside yours; the mcp__ prefix keeps tools from colliding.
The payoffOne server, three hosts, zero code changes. Ask "how did March look?" -> query_sales -> $150.