MCP (Model Context Protocol) servers extend Claude's capabilities by connecting it to external systems - databases, APIs, development tools, issue trackers. Configuring them correctly determines whether your team shares a consistent toolset or descends into configuration chaos.
The Scoping Hierarchy
MCP server configuration lives at two levels, and mixing them up is where most setup problems start.
Project-level: .mcp.json
Lives in the project repository root. Version-controlled. Shared with every team member who clones or pulls the repository. Use this for servers that the entire team needs - your Jira integration, your GitHub tools, your internal API connectors.
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"jira": {
"command": "npx",
"args": ["-y", "@community/mcp-server-jira"],
"env": {
"JIRA_URL": "${JIRA_URL}",
"JIRA_TOKEN": "${JIRA_TOKEN}"
}
}
}
}
User-level: ~/.claude.json
Lives in the user's home directory. Personal. NOT version-controlled. NOT shared with teammates. Use this for experimental servers, personal integrations, or servers you're testing before proposing them to the team.
Key principle: all tools from all configured servers (both project-level and user-level) are discovered at connection time and available simultaneously. There's no manual activation step - if a server is configured and reachable, its tools appear in the agent's toolkit.
Environment Variable Expansion
The .mcp.json file supports ${VARIABLE_NAME} syntax for environment variable expansion. This is how you keep credentials out of version control whilst still sharing server configuration with your team.
{
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}",
"DATABASE_URL": "${DATABASE_URL}"
}
}
Each developer sets their own tokens locally (in their shell profile, .env file, or secrets manager). The .mcp.json file references the variable names, not the values. This means:
- The configuration file is safe to commit to version control
- Each developer authenticates with their own credentials
- Token rotation does not require config file changes
- No secrets leak through repository history
MCP Resources
MCP resources expose content catalogues to agents without requiring exploratory tool calls. Instead of calling a tool to discover what data exists, the agent gets that information upfront.
Examples of what to expose as resources:
- Issue summaries - a list of current Jira issues with titles and statuses
- Documentation hierarchies - a table of contents for your internal docs
- Database schemas - table names, column types, and relationships
The payoff is fewer wasted calls. Without resources, an agent might call list_tables, then describe_table for every table, burning tool calls just to get its bearings. With a database schema resource, it knows immediately.
Resources show agents what data is available. Tools let them act on it.
The Build-vs-Use Decision
This decision comes up constantly, in the exam and in real work. Your team needs to integrate with an external system: build a custom MCP server, or use an existing community one?
Use community servers for standard integrations:
- Jira, GitHub, Slack, Linear, Notion - these all have maintained community MCP servers
- They cover standard use cases, are tested by the community, and receive updates
- Using them saves development time and maintenance burden
Build custom servers only when:
- Your team has specific workflows that community servers cannot handle
- You need custom business logic embedded in the tool layer
- You require integration with proprietary internal systems that have no community server
The exam consistently favours the pragmatic choice. "Evaluate community servers first" is always correct when a standard integration is involved. "Build custom" is only correct when the scenario explicitly describes team-specific requirements that community servers cannot meet.
Enhancing MCP Tool Descriptions
Here's a subtle one: when an MCP tool has a sparse description, the agent may prefer built-in tools (like Grep) even when the MCP tool is more capable. The model simply has better context about built-in tools - their descriptions are rich and detailed.
The fix: enhance your MCP tool descriptions to explain capabilities and outputs in detail. Instead of:
search_codebase: "Searches code"
Write:
search_codebase: "Performs semantic code search across the
entire repository using AST-aware indexing. Returns matching
functions, classes, and methods with full context including
file path, line numbers, and surrounding code. More accurate
than text-based grep for finding code by intent rather than
exact string match. Use this instead of Grep when searching
for code by what it does rather than what it contains."
The enhanced description gives the model enough context to prefer the MCP tool when it's genuinely more capable than the built-in alternative.
Key Concept
Project-level .mcp.json is version-controlled and shared with the team. User-level ~/.claude.json is personal and not shared. Use ${ENV_VAR} syntax to keep credentials out of version control.