Learn Claude Code: MCP Mastery Managing MCP in Teams

Managing MCP in Teams

Advanced 🕐 11 min Lesson 10 of 12
What you'll learn
  • Use .mcp.json as the authoritative team MCP configuration and keep credentials out of version control using environment variable expansion and headersHelper
  • Manage workspace trust in team contexts from initial onboarding through pre-approving servers in CI environments
  • Monitor MCP usage with OpenTelemetry and use scope precedence to let individuals override team defaults without modifying shared configuration

The team MCP coordination problem

When you add an MCP server for yourself, one command is enough. When you want every developer on your team to have the same servers — with the right configurations, pointing at the right environments, connecting to the right credentials — the question becomes: how do you distribute that configuration without copying commands into a wiki page that goes stale in six months?

The answer is .mcp.json in version control. It is the MCP equivalent of a lockfile or a Docker Compose configuration: a single source of truth for which servers the project uses, checked into the repository, applied automatically when anyone opens the project in Claude Code.

.mcp.json as the team's shared configuration

A project-scope .mcp.json at the repository root defines the team's MCP environment. When a developer clones the repository and starts Claude Code, Claude Code reads the file and prompts them to approve the listed servers. After approval, the servers connect and are available in every session in that project.

The file format is simple: an mcpServers object where each key is the server name and each value is the transport-specific configuration:

{"mcpServers": {"github": {"type": "http", "url": "https://api.githubcopilot.com/mcp/"}, "db": {"type": "stdio", "command": "npx", "args": ["-y", "@bytebase/dbhub", "--dsn", "${DB_DSN}"]}}}

This configuration gives every team member GitHub and database access with a single file commit. The DB_DSN variable expands from each developer's environment, keeping the connection string out of the repository.

Keeping secrets out of version control

The project-scope .mcp.json is committed to the repository, which means credentials should never appear directly in it. Three patterns handle per-user authentication:

  • Environment variable expansion: Use ${VAR} to read API keys and tokens from each developer's shell environment. Each developer sets their own variables; the file contains no secrets.
  • OAuth: For services that support it, OAuth stores credentials per-user in the system keychain. The .mcp.json entry has only the URL.
  • headersHelper: For SSO, Kerberos, or short-lived tokens, headersHelper runs a command at connection time that generates fresh credentials. The command can live in the shared configuration while each developer's environment provides the authentication context.

Workspace trust in team workflows

New developers cloning a repository see the workspace trust dialog on their first session. They must approve the listed servers before those servers connect. This is intentional — the trust dialog is the mechanism that prevents malicious configurations from executing silently on a fresh clone.

The approval status is stored per-developer in their ~/.claude.json, not in the repository. One developer approving does not approve for others. To streamline onboarding, set enableAllProjectMcpServers: true in a developer's user settings to pre-approve all project-scope servers without the per-server dialog. This is appropriate for CI environments and developers who have reviewed the team's .mcp.json policy.

To reset approval choices and re-evaluate the current .mcp.json — useful when the file changes significantly — run claude mcp reset-project-choices.

Scope precedence as an individual override mechanism

A developer who needs a different version of a team server — a staging endpoint instead of production, a local build instead of the published package — adds a local-scope entry with the same name. Local scope takes precedence over project scope, so Claude Code uses the local definition in that developer's sessions without changing the shared configuration.

This is the right pattern for individual variation. Each developer's local overrides live in their ~/.claude.json, invisible to teammates, and disappear when the developer removes them. The shared .mcp.json stays clean.

Monitoring MCP usage with OpenTelemetry

When OpenTelemetry export is configured, Claude Code can record which MCP servers and tools are invoked across your team. Set OTEL_LOG_TOOL_DETAILS=1 alongside an OpenTelemetry exporter endpoint to include MCP server and tool names in the tool events that Claude Code exports. Aggregate these in your collector to answer questions like: which servers does the team actually use? Which tools are called most frequently? Which servers are configured but never invoked?

This data informs decisions about which servers belong in the shared .mcp.json, which can be moved to user scope, and which should be cleaned up.

Sharing Claude Code as a server for CI

In CI pipelines and automation workflows, claude mcp serve exposes Claude Code's own built-in tools — View, Edit, LS, and others — to any MCP-compatible client. This makes Claude Code's file access and editing capabilities available to orchestration systems or other AI tools that speak the MCP protocol, without requiring a full Claude Code session.

Key takeaways
  • Project-scope .mcp.json in the repository root is the right home for team MCP configuration — check it in so every developer gets the same servers after accepting the workspace trust dialog
  • Keep secrets out of .mcp.json using ${VAR} expansion for per-user environment variables, OAuth for services that support it, and headersHelper for SSO or short-lived credentials
  • The workspace trust dialog gates project-scope server approval for each developer individually — use enableAllProjectMcpServers in user settings to pre-approve all project servers for CI environments
  • Local-scope entries override project-scope entries of the same name — developers who need a staging endpoint or custom build add a local override without touching the shared configuration
  • Set OTEL_LOG_TOOL_DETAILS=1 alongside an OpenTelemetry exporter to record which servers and tools your team actually invokes — use this to keep the shared .mcp.json accurate and lean