Domain 2: Tool Design & MCP Integration (18%)Lesson 11 of 30

2.4 Integrating MCP Servers

2.4.1 Where Do an Agent's Tools Come From?

So far we've talked about tools abstractly. But in real projects, where do they come from? Many come from MCP servers — external programs that expose a bundle of tools (and other capabilities) to Claude through a shared standard called the Model Context Protocol. Task Statement 2.4 is about connecting these servers to Claude Code and your agents: where the configuration lives, how to keep secrets safe, and when to build your own server versus using an existing one.

Think of MCP like a universal power adapter. Before a shared standard, every integration was custom wiring — connect Claude to GitHub one way, to your database another way, to Slack a third way. MCP is the standard socket: a server speaks MCP, Claude speaks MCP, and they plug together. Connect a GitHub MCP server and Claude can read issues and open PRs; connect a Postgres MCP server and it can query your database — all through the same connection mechanism.

The headline benefit: once a server is connected, ALL of its tools are discovered automatically and become available to the agent at the same time. You don't wire up each tool individually — you connect the server, and its whole toolset shows up. This lesson is about doing that connection well, especially around scope and secrets.

MCP: one standard socket for many toolsClaude (MCP client)discovers tools on connectGitHub serverPostgres serverSlack server

MCP is a shared standard: any MCP server plugs into Claude the same way, and all of a connected server's tools are discovered at once.

ℹ️

The one idea to hold onto

MCP is a universal standard for connecting external tools to Claude. Connect an MCP server once and ALL its tools are discovered automatically and become available together — no per-tool wiring.

2.4.2 Where the Configuration Lives: Scope

The most exam-relevant decision is WHERE you configure a server, because that determines who else gets it. The exam frames this as two scopes (and current Claude Code adds a third — worth knowing both).

PROJECT scope lives in a file called .mcp.json at the project's root. Because it's a file in the repository, you check it into version control, and then everyone on the team automatically gets the same servers when they clone or pull. This is the right home for shared team tooling — the database server everyone needs, the issue tracker the whole team uses. USER scope lives in your personal config (~/.claude.json) and is private to you across all your projects — the right home for personal or experimental servers you don't want to impose on teammates.

This mirrors the CLAUDE.md hierarchy you'll meet in Domain 3.1: project-level = shared via git; user-level = personal, not shared. The signature exam scenario: a teammate isn't getting a server everyone should have — because it was configured in someone's USER scope (private) instead of PROJECT scope (.mcp.json, shared). The fix is to move it to project scope and commit it. (Current Claude Code also has a 'local' scope — private to you in one project — but project-vs-user is the distinction the exam tests.)

ScopeLives inShared with team?Use for
Project`.mcp.json` (repo root)Yes — via version controlShared team tooling
User`~/.claude.json`No — private to youPersonal / experimental servers

Project scope (.mcp.json, committed) shares servers with the whole team; user scope (~/.claude.json) keeps them personal. The classic bug: shared tooling stuck in user scope.

2.4.2 — Key Concept

Project-scoped MCP servers live in .mcp.json (committed to version control, shared with the team); user-scoped servers live in ~/.claude.json (personal). If teammates lack a server everyone needs, it was put in user scope — move it to project scope.

2.4.3 Keeping Secrets Out of Version Control

Project scope creates a tension: you want to SHARE the server config via git, but servers usually need secrets — API keys, tokens — and you absolutely must NOT commit secrets to a repository. How do you share the configuration without sharing the password?

The answer is environment variable expansion. In .mcp.json you write a placeholder like ${GITHUB_TOKEN} instead of the actual token. When Claude Code loads the config, it expands that placeholder using the environment variable on each person's machine. So the committed file says 'use whatever GITHUB_TOKEN is set here,' and each developer supplies their own token via their environment — the secret never enters the repository. You can also provide a fallback with ${VAR:-default}.

jsonEnvironment variable expansion in .mcp.json: ${GITHUB_TOKEN} is filled from each machine's environment, so the shared, committed config never contains the actual secret.
{
  "mcpServers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
    }
  }
}

2.4.3 — Key Concept

Use environment variable expansion (${VAR}, or ${VAR:-default}) in .mcp.json so a shared, version-controlled config references secrets like ${GITHUB_TOKEN} without ever committing the actual values — each machine supplies its own.

2.4.4 Resources, and When to Build vs Use

MCP servers expose more than just tools (actions). They can also expose RESOURCES — read-only content catalogs the agent can browse, like a list of issue summaries, a documentation hierarchy, or a database schema. The value is subtle but important: a resource lets the agent SEE what's available without making exploratory tool calls to find out. Instead of the agent calling list_issues, then get_issue, then get_issue again just to discover what exists, it can glance at a resource catalog. Tools are for DOING things; resources are for KNOWING what's there.

Finally, a judgment call the exam rewards: should you BUILD a custom MCP server or USE an existing one? The guidance is clear — for standard integrations (Jira, GitHub, Slack, Postgres), use the existing community server; reserve building a custom server for team-specific or proprietary workflows that no off-the-shelf server covers. Building custom for a standard integration is wasted effort and ongoing maintenance. One more tip: enhance your MCP tool descriptions (echoing Lesson 2.1) so the agent prefers them over built-in tools where the MCP tool is genuinely more capable.

SituationChoose
Standard integration (Jira, GitHub, Slack)Use the existing community MCP server
Team-specific / proprietary workflowBuild a custom MCP server
Agent makes many exploratory calls to discover dataExpose a resource (content catalog)
Agent prefers built-in Grep over your better MCP toolEnhance the MCP tool's description

Use existing servers for standard integrations; build custom only for proprietary needs. Expose resources to cut exploratory calls; strengthen descriptions so capable MCP tools get chosen.

ℹ️

2.4.4 — Key Concept

MCP resources expose read-only content catalogs (issue summaries, doc hierarchies, schemas) so the agent can see what's available without exploratory calls. Use existing community servers for standard integrations; build custom only for team-specific/proprietary workflows.

2.4.5 The Exam Traps

The 2.4 traps cluster around scope (sharing vs private), secret handling, and the build-vs-use decision. Keep the project/user split and the 'use existing servers' default in mind.

  • Wrong scope for team tooling. ✗ Putting a server the whole team needs in user scope (~/.claude.json). ✓ Project scope (.mcp.json), committed to version control.
  • Committing secrets. ✗ Hard-coding an API key in .mcp.json. ✓ Use ${VAR} environment variable expansion so the secret stays out of the repo.
  • Building when you should reuse. ✗ Writing a custom MCP server for a standard integration like Jira. ✓ Use the existing community server; build custom only for proprietary needs.
  • Sparse tool descriptions. ✗ Leaving MCP tools thinly described so the agent prefers built-in tools. ✓ Enhance the descriptions (Lesson 2.1) so capable MCP tools get selected.
⚠️

2.4.5 — Exam Trap

✗ Team config in user scope (teammates don't get it). ✗ Committing credentials instead of using ${VAR} expansion. ✗ Building a custom server for a standard integration. ✗ Sparse MCP tool descriptions. ✓ Project scope (.mcp.json) for shared tooling, env-var expansion for secrets, existing servers for standard integrations, and strong descriptions.

2.4.6 Put It Together: Wire Up MCP Servers

You now understand what MCP servers are, the project-vs-user scope decision, environment variable expansion for secrets, resources, and the build-vs-use call. The exercise puts a shared server into version control safely and proves the scope behaviour.

2.4.6 — Build Exercise (45 min)

(1) Configure a shared MCP server in a project-scoped .mcp.json using ${VAR} expansion for its auth token; confirm the committed file contains no secret. (2) Configure a personal/experimental server in user scope (~/.claude.json) and verify both are available at once. (3) Reproduce the classic bug: put a server everyone needs in user scope, confirm a teammate (or a second project) doesn't get it, then move it to project scope and confirm it now loads. (4) Expose a content catalog as a resource and observe the agent using it instead of exploratory tool calls.

MCP servers supply many of an agent's tools. The final lesson of Domain 2, 2.5, turns to the tools that are always there in Claude Code — the built-in Read, Write, Edit, Bash, Grep, and Glob — and how to choose between them efficiently.

ℹ️

Where this shows up on the exam

2.4 questions involve a teammate missing a server (scope), secrets in config (env-var expansion), or build-vs-use. Anchor on 'project scope shares, user scope is private', 'never commit secrets — use ${VAR}', and 'use existing servers for standard integrations'.

Key Takeaways

  • MCP is a universal standard for connecting external tools to Claude; connect a server once and ALL its tools are discovered automatically and available together.
  • Project scope (.mcp.json at the repo root) is committed to version control and shared with the whole team; user scope (~/.claude.json) is private to you across your projects.
  • Classic bug: a server the whole team needs configured in user scope — teammates don't get it; the fix is to move it to project scope and commit it.
  • Use environment variable expansion (${VAR}, ${VAR:-default}) in .mcp.json so a shared, committed config references secrets like ${GITHUB_TOKEN} without ever committing the actual values.
  • MCP resources expose read-only content catalogs (issue summaries, doc hierarchies, schemas) so the agent can see what's available without making exploratory tool calls.
  • Build-vs-use: use existing community servers for standard integrations (Jira/GitHub/Slack/Postgres); build a custom server only for team-specific or proprietary workflows.
  • Enhance MCP tool descriptions (Lesson 2.1) so the agent prefers a capable MCP tool over a built-in one where appropriate.

Check Your Understanding

Test what you learned in this lesson.

Q1.You want a custom /review-supporting MCP server to be available to every developer automatically when they clone or pull the repository. Where should it be configured?

Q2.How do you share a project-scoped MCP server config via git without committing its API key?

Q3.Your team needs to integrate with Jira, a standard tool with an existing community MCP server. What's the right approach?

Q4.An agent keeps making many exploratory tool calls just to discover what data exists (listing issues, then fetching each). What MCP feature reduces this?

Practice This Lesson