Module 7: Testing, Debugging, and Integration

Configure MCP Servers in Claude Code

Configure MCP Servers in Claude Code

Capsule description

This is the moment of truth. You've built MCP servers, tested them, added logging to them. But none of that matters until Claude Code can use them. A perfectly implemented MCP server that isn't connected to Claude Code is a program nobody uses.

Configuring Claude Code for MCP servers involves settings files, scopes (user vs project), permissions, and verification. Each step is verifiable — you're not going to "hope it works." You're going to confirm at each step that Claude Code sees your server, can list its tools, and can invoke them.

This capsule guides you step by step. By the end, your MCP server will be connected to Claude Code and working in your real workflows.


Anatomy of MCP configuration in Claude Code

Where it's configured

Claude Code looks for MCP configuration in two places:

MCP configuration:
├── User scope (global)
│   └── ~/.claude/settings.json
│       → Applies to ALL your projects
│       → Ideal for servers you always use (filesystem, GitHub, etc.)
│
└── Project scope (per project)
    └── .claude/settings.json (in the project's root)
        → Applies ONLY to this project
        → Ideal for project-specific servers
        → Can be versioned in git (shared with the team)

Configuration format

The MCP configuration lives inside the mcpServers field of the settings file:

{
  "mcpServers": {
    "server-name": {
      "command": "node",
      "args": ["path/to/server/dist/index.js"],
      "env": {
        "VARIABLE": "value"
      }
    }
  }
}

The fields:

FieldRequiredDescription
command✅Executable that starts the server (node, python, npx)
args✅Array of arguments for the command
env❌Environment variables for the server's process
cwd❌Working directory to run the server

Configure a TypeScript MCP server

Step 1: Compile your server

Make sure your server is compiled and works:

cd ~/projects/my-mcp-server
npm run build
node dist/index.js < /dev/null  # Verify that it starts without errors

Step 2: Add to Claude Code (user scope)

Use the Claude Code CLI to add your server:

claude mcp add file-utils node ~/projects/my-mcp-server/dist/index.js

This command modifies ~/.claude/settings.json automatically:

{
  "mcpServers": {
    "file-utils": {
      "command": "node",
      "args": ["/Users/your-user/projects/my-mcp-server/dist/index.js"]
    }
  }
}

Step 3: Verify the connection

Open Claude Code and verify:

claude
# Inside Claude Code, run:
/mcp

The /mcp command shows all the connected MCP servers and their status:

MCP Servers:
  file-utils: connected
    Tools: read_file, list_files
    Resources: status://server

If you see connected and your tools/resources listed, the configuration is correct.

Step 4: Test a tool

Ask Claude Code to use one of your tools:

You: "Read the file ~/projects/my-mcp-server/README.md"

Claude Code: [Invokes read_file with filePath: "...README.md"]
The file's content is:
# My MCP Server
...

If Claude Code invokes the tool and returns the correct result, the integration works end-to-end.


Configure a Python MCP server

Step 1: Verify the server

cd ~/projects/my-mcp-server-python
python server.py  # Verify that it starts without errors (Ctrl+C to exit)

Step 2: Add to Claude Code

claude mcp add python-utils python ~/projects/my-mcp-server-python/server.py

Result in settings:

{
  "mcpServers": {
    "python-utils": {
      "command": "python",
      "args": ["/Users/your-user/projects/my-mcp-server-python/server.py"]
    }
  }
}

With a virtual environment

If your Python server uses a virtual environment:

claude mcp add python-utils \
  ~/projects/my-mcp-server-python/.venv/bin/python \
  ~/projects/my-mcp-server-python/server.py

Or by editing the settings manually:

{
  "mcpServers": {
    "python-utils": {
      "command": "/Users/your-user/projects/my-mcp-server-python/.venv/bin/python",
      "args": ["server.py"],
      "cwd": "/Users/your-user/projects/my-mcp-server-python"
    }
  }
}

Configure servers with environment variables

Many MCP servers need API keys or other configurations:

{
  "mcpServers": {
    "github-server": {
      "command": "node",
      "args": ["/path/to/github-server/dist/index.js"],
      "env": {
        "GITHUB_TOKEN": "ghp_your_token_here"
      }
    }
  }
}

Security warning: If you put tokens in the project's .claude/settings.json, don't commit that file without first verifying that it doesn't contain secrets. Use system environment variables or a .env file when possible.

Alternative: use system variables

{
  "mcpServers": {
    "github-server": {
      "command": "node",
      "args": ["/path/to/github-server/dist/index.js"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}

Then configure the variable in your shell:

export GITHUB_TOKEN="ghp_your_token_here"

Configure multiple servers

Claude Code can connect to multiple MCP servers simultaneously:

{
  "mcpServers": {
    "file-utils": {
      "command": "node",
      "args": ["/path/to/file-utils/dist/index.js"]
    },
    "python-utils": {
      "command": "python",
      "args": ["/path/to/python-utils/server.py"]
    },
    "github-server": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}

How Claude Code handles multiple servers

When you have multiple servers:

Claude Code receives a request from the user
├── Lists tools from ALL the connected servers
├── Decides which tool to use based on the description
├── Invokes the tool from the corresponding server
└── Returns the result to the user

Example:
  "Read the README and search for open issues in GitHub"
  ├── read_file → file-utils server
  └── search_issues → github-server

Claude Code handles the orchestration automatically. You only configure the servers; Claude decides which to use based on the tools' descriptions.

Server names

The names must be unique and descriptive:

// ✅ Clear names
"file-utils": { ... }
"github-integration": { ... }
"project-database": { ... }

// ❌ Confusing names
"server1": { ... }
"my-server": { ... }
"test": { ... }

Project scope: per-project configuration

When to use project scope

Use project scope when:

  • The server is specific to a project (e.g., accesses the project's database)
  • You want to share the configuration with the team (versioned in git)
  • The server uses paths relative to the project

Create a project configuration

mkdir -p .claude

Create .claude/settings.json:

{
  "mcpServers": {
    "project-db": {
      "command": "node",
      "args": ["./tools/db-server/dist/index.js"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      }
    }
  }
}

Priority: project vs user

If the same server is configured in both scopes, Claude Code uses the project scope configuration (more specific):

Configuration resolution:
├── Project scope (.claude/settings.json) → high priority
└── User scope (~/.claude/settings.json)  → low priority

If "file-utils" exists in both:
→ The project scope configuration is used

Permissions and security

How permissions work

When Claude Code wants to invoke a tool from your MCP server, it asks you for confirmation the first time:

Claude Code: I want to use the "read_file" tool from the "file-utils" server.
             Allow? [y/n/always]

  y       → Allow this time
  n       → Deny
  always  → Always allow for this tool

Configure persistent permissions

If you select "always," the configuration is saved. You can also manage permissions with the CLI:

# See current permissions
claude mcp list

# See the details of a specific server
claude mcp get file-utils

Security considerations

Security rules for MCP servers:
├── Don't expose destructive tools without confirmation
│   (delete_file, drop_database, etc.)
├── Don't include secrets in versioned settings
├── Use absolute paths to avoid ambiguities
├── Limit the server's access scope
│   (only the necessary directories/APIs)
└── Review the permissions periodically

Complete step-by-step verification

After configuring a server, follow this checklist:

1. Does the server start?

# TypeScript
node dist/index.js < /dev/null 2>&1
# Should finish without errors (exit code 0)

# Python
python server.py < /dev/null 2>&1

2. Does Claude Code see it?

claude
# Inside Claude Code:
/mcp

Look for your server in the list. The status should be connected.

3. Are the tools listed?

In the /mcp output, verify that your tools appear with their correct names.

4. Does a tool work?

Ask Claude Code to use a specific tool:

"Use the list_files tool to list the files in the current directory"

5. Are errors handled?

Ask Claude Code for something that should fail:

"Use read_file to read /file/that/doesnt/exist"

Verify that Claude Code shows a descriptive error, not a crash.

Checklist summary

□ Server compiles and starts without errors
□ Settings configured (user or project scope)
□ /mcp shows the server as "connected"
□ Tools appear in the /mcp list
□ At least one tool works correctly
□ Errors are handled with descriptive messages
□ Environment variables configured (if applicable)
□ Permissions accepted for the tools

Managing servers with the CLI

Useful commands

# Add a server
claude mcp add <name> <command> [args...]

# List configured servers
claude mcp list

# See a server's details
claude mcp get <name>

# Remove a server
claude mcp remove <name>

# Add with a specific scope
claude mcp add --scope user <name> <command> [args...]
claude mcp add --scope project <name> <command> [args...]

Example: complete flow with the CLI

# 1. Add your server
claude mcp add file-utils node ~/mcp-servers/file-utils/dist/index.js

# 2. Verify that it was added
claude mcp list
# → file-utils: node /Users/your-user/mcp-servers/file-utils/dist/index.js

# 3. Open Claude Code and verify
claude
# → /mcp
# → file-utils: connected

# 4. If you need to change the configuration, edit directly:
# ~/.claude/settings.json

# 5. If you need to remove it:
claude mcp remove file-utils

Exercises

Exercise 1: Configure your server in user scope (Easy)

Take the MCP server you built in module 4 or 5. Configure it in Claude Code using claude mcp add. Verify with /mcp that it appears as connected.

See solution
# For TypeScript
cd ~/projects/my-mcp-server-ts
npm run build
claude mcp add my-server-ts node ~/projects/my-mcp-server-ts/dist/index.js

# For Python
claude mcp add my-server-py python ~/projects/my-mcp-server-py/server.py

# Verify
claude
# /mcp → should show your server as "connected"

Exercise 2: Configure project scope (Easy)

Create a project scope configuration in one of your projects. The server should use paths relative to the project.

See solution
cd ~/projects/my-project
mkdir -p .claude

Create .claude/settings.json:

{
  "mcpServers": {
    "project-tools": {
      "command": "node",
      "args": ["./mcp-server/dist/index.js"]
    }
  }
}

Exercise 3: Multiple servers (Medium)

Configure two different MCP servers (e.g., one in TypeScript and one in Python) in Claude Code. Verify that both appear in /mcp and that you can use tools from both in the same conversation.

See solution
claude mcp add file-utils-ts node ~/mcp-servers/file-utils/dist/index.js
claude mcp add api-utils-py python ~/mcp-servers/api-utils/server.py
claude mcp list
# → file-utils-ts, api-utils-py

# In Claude Code:
# /mcp → both as "connected"
# Test: "List the files in the current directory and then check the API's status"

Exercise 4: Server with environment variables (Medium)

Configure an MCP server that requires an environment variable (e.g., an API token). Configure it using system variables, not hardcoded in the settings file.

See solution
# 1. Configure the variable in your shell
echo 'export MY_API_TOKEN="secure_token_here"' >> ~/.zshrc
source ~/.zshrc

# 2. Add the server with env
claude mcp add my-api-server node ~/mcp-servers/api-server/dist/index.js

# 3. Edit ~/.claude/settings.json to add env
{
  "mcpServers": {
    "my-api-server": {
      "command": "node",
      "args": ["/Users/your-user/mcp-servers/api-server/dist/index.js"],
      "env": {
        "API_TOKEN": "${MY_API_TOKEN}"
      }
    }
  }
}

Exercise 5: Complete verification (Hard)

Run the complete verification checklist with one of your servers. Document the result of each step. If any step fails, diagnose and resolve the problem before continuing.

See solution
Verification checklist — file-utils server:

1. Does the server start?
   $ node dist/index.js < /dev/null 2>&1
   → Result: exit code 0 ✅

2. Does Claude Code see it?
   /mcp → file-utils: connected ✅

3. Are the tools listed?
   → read_file, list_files ✅

4. Does a tool work?
   "List the files in ~/projects"
   → Returns a list of files ✅

5. Are errors handled?
   "Read /nonexistent/file"
   → "Error: ENOENT: no such file or directory" ✅

6. Environment variables: N/A (not required)
7. Permissions: accepted ✅

Result: 7/7 steps successful

Configuration troubleshooting

"Server appears as 'disconnected' in /mcp"

Probable cause: The server crashes on startup.

Solution:

# Run the server manually to see the error
node dist/index.js < /dev/null 2>&1

# Common errors:
# - "Cannot find module" → npm run build
# - "ENOENT" → incorrect path in settings
# - "SyntaxError" → error in the code

"Tool doesn't appear in the /mcp list"

Probable cause: The tool isn't registered before the server is ready.

Solution: Verify that the tool is registered in the correct scope of your server (before connect()).

"/mcp doesn't show any server"

Probable cause: The settings file isn't in the correct location or has invalid JSON.

Solution:

# Verify that the file exists
cat ~/.claude/settings.json

# Validate the JSON
python -c "import json; json.load(open('$HOME/.claude/settings.json'))"

Summary

In this capsule you learned:

  • Two configuration scopes: user (~/.claude/settings.json) for global servers, project (.claude/settings.json) for specific servers
  • The configuration format uses command, args, env, and optionally cwd
  • claude mcp add is the fastest way to configure a server
  • /mcp in Claude Code shows you the status of all the connected servers
  • Environment variables are configured in the env field, preferably with ${VAR} instead of hardcoded values
  • Multiple servers work simultaneously — Claude Code orchestrates automatically which to use
  • The 8-step verification checklist confirms that everything works end-to-end
  • Permissions are managed interactively the first time and can be persisted

This is the step that makes all the work from modules 4-6 useful. Your MCP server is no longer just a program — it's a tool Claude Code uses natively.


Additional resources

  1. Claude Code MCP Documentation — Official documentation of MCP in Claude Code
  2. Claude Code CLI Reference — CLI reference including claude mcp
  3. MCP Servers Registry — Official servers for configuration reference
  4. Claude Code Settings — Documentation of settings files

Next capsule: Troubleshooting and Common Errors — a complete guide to the most frequent errors and how to resolve them, plus a mini-project that integrates everything learned in this module.