Curriculum › Tool Design & MCP Integration · 18% of the exam

Integrating MCP servers

What you’ll be able to do

  • Configure shared MCP servers in project-scoped .mcp.json, using environment variable expansion for tokens
  • Configure personal or experimental MCP servers in user-scoped ~/.claude.json
  • Write MCP tool descriptions detailed enough that the agent prefers them over built-in tools like Grep when they are more capable
  • Expose content catalogs as MCP resources to cut exploratory tool calls
  • Choose a community MCP server for standard integrations and build custom servers only for team-specific workflows

What you need to know

Two scopes: project and user

Claude Code reads MCP server configuration from two places, and which one you use decides who gets the server:

  • Project scope, .mcp.json in the repository. It is committed with the code, so everyone who clones the project gets the same servers. Use it for shared team tooling such as the issue tracker, the team's internal docs server, or the database the project works against.
  • User scope, ~/.claude.json in your home directory. Only you get these servers, in every project. Use it for personal or experimental servers you're trying out, which teammates shouldn't have to install or trust.

The common mistakes go both ways. A shared server configured only in one engineer's ~/.claude.json works for them and is missing for everyone else. An experimental server added to .mcp.json is pushed on the whole team before anyone has agreed to it.

Keep secrets out of the repository with ${VAR}

Because .mcp.json is committed, it must not contain credentials. Claude Code expands environment variables in it, so the file refers to a token by name and each developer (or CI) provides the value in their own environment:

before — a real token committed to the repo
{ "mcpServers": { "github": { "command": "...", "env": { "GITHUB_TOKEN": "ghp_a1b2c3..." } } } }
after — shared config, secret supplied by each environment
{ "mcpServers": { "github": { "command": "...", "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" } } } }

The team shares one configuration, and nobody commits a secret. Gitignoring .mcp.json or moving the server into everyone's user config would also keep the token out of git, but it gives up the shared configuration that was the point of project scope.

All servers’ tools are available at once

When the agent connects, it discovers the tools from every configured MCP server, project and user scope together, and all of them are available at the same time alongside the built-in tools. That has a consequence: MCP tools compete for selection with each other and with built-ins like Grep, Read, and Glob.

A common failure is an agent that keeps using Grep to search code even though an MCP tool would do much better, for example one that searches a cross-repository index and returns symbols with their call sites. If the MCP tool's description just says "Searches code", the model has no reason to prefer it over the familiar built-in. Expand the description to say what it covers, what it returns, and when it beats a plain text search ("searches all 40 service repositories, not only the open checkout; returns definitions and call sites; use for 'where is X used' across services"). As 2.1 explains, the description is what the model chooses from.

Resources show what exists without exploring

Tools are for actions. MCP resources expose content the agent can read, which makes them a good fit for catalogs: a list of issue summaries, a documentation hierarchy, a database schema. Without a catalog, an agent finds out what's available by exploring: listing, searching, opening things to see what they are, with each step costing a tool call and context. With the catalog exposed as a resource, the agent can see what exists up front and go straight to the item it needs.

Community servers first, custom servers for your own workflows

For standard integrations such as Jira, GitHub, or common databases, an existing community MCP server is usually the right choice. Someone else has already built and maintained the tool definitions, and you only configure it. Build a custom server when the workflow is specific to your team, for example an internal deployment process or a proprietary data model that no general-purpose server covers. Writing your own Jira server spends effort on a solved problem.

Key concept

Shared servers go in .mcp.json with ${VAR} references for secrets. Personal and experimental ones go in ~/.claude.json. Every configured server’s tools are live at once, so describe MCP tools well enough to win selection, expose catalogs as resources, and use community servers for standard integrations.

When a scenario involves "it works on my machine" MCP setups, leaked tokens, or an agent ignoring a better MCP tool, check scope, variable expansion, and tool descriptions, in that order.

Practice scenario

ScenarioA developer productivity team wants every engineer's Claude Code to use the company Jira and an internal code-index server. One engineer has both configured in their own ~/.claude.json with tokens pasted in, plus an experimental diagram server. Teammates don't have the servers at all, and even where the code-index server is set up, the agent mostly uses Grep and spends many calls exploring the repository layout.
Work it through, then open this

Move Jira and the code-index server into the project’s .mcp.json, with tokens referenced as ${JIRA_TOKEN}-style variables that each engineer sets locally. Use a community Jira server rather than writing one. The experimental diagram server stays in that engineer’s ~/.claude.json. To get the agent using the code index, expand that server’s tool descriptions to state what the index covers and returns compared with a text search. Exposing the repository and service catalog as an MCP resource lets the agent see the layout without exploratory calls.

Build exercise — Set up a team MCP configuration

Intermediate · 30 min

What you’ll learn

  • Splitting servers between project and user scope
  • Using environment variable expansion for credentials
  • Making MCP tools and resources easy for the agent to use
  1. List the MCP servers you use and label each as shared team tooling or personal/experimental. Put the shared ones in the project’s .mcp.json and the rest in ~/.claude.json, and check both sets are available in one session.

    • Why: Scope decides who gets a server. Tools from both scopes are discovered together at connection time.
    • You should see: Teammates getting the shared servers from the repository, your experimental server only on your machine, and all of them listed together in your session.
  2. Replace every literal credential in .mcp.json with a ${VAR} reference and set the variables in your environment.

    • Why: The file is committed. Expansion keeps the configuration shared and the secrets out of git.
    • You should see: A diff with no secrets in it, and the servers still connecting.
  3. Pick one MCP tool the agent tends to bypass for a built-in tool and rewrite its description to explain capabilities and outputs. If the server has a browsable catalog, expose it as a resource.

    • Why: The model chooses from descriptions, and a resource catalog replaces exploratory calls.
    • You should see: The agent picking the MCP tool for requests it fits, and fewer list or search calls spent finding out what exists.

Exam traps

Committing a literal token in .mcp.json instead of using environment variable expansion

The file is shared through version control. Reference the secret as ${VAR} and let each environment provide it.

Putting a server the whole team needs in ~/.claude.json, where teammates never get it

User scope is personal. Shared tooling belongs in the project’s .mcp.json.

Adding a personal experimental server to the project’s .mcp.json

That pushes an untested server on everyone. Keep experiments in ~/.claude.json.

Leaving MCP tool descriptions thin, so the agent falls back to built-in Grep

All tools compete for selection. A more capable MCP tool needs a description that says why it is better.

Making the agent discover available content through repeated exploratory tool calls instead of a resource catalog

MCP resources expose catalogs such as issue summaries, doc hierarchies, and schemas so the agent can see what exists directly.

Building a custom MCP server for a standard integration like Jira that a community server already covers

Use existing community servers for standard systems, and keep custom servers for team-specific workflows.

Sources

Quick check

A team's .mcp.json, committed to the repository, configures a GitHub MCP server with an engineer's personal access token written directly in the file. What is the best fix?