What You Will Do
You have built an MCP server, added tools and resources, and tested everything with the Inspector. Now you will connect your server to Claude Desktop so you can use your tools in a real AI conversation.
When this is done, you will be able to type something like "Echo the phrase 'it works!'" in Claude Desktop and watch it call your echo tool, or ask Claude to calculate something and see it use your calculate tool.
Prerequisite: You need Claude Desktop installed. If you do not have it yet, download it from claude.ai/download. The free plan works for this.
Step 1: Find Your Config File
Claude Desktop stores its MCP server configuration in a JSON file. The location depends on your operating system:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Windows:
%APPDATA%\Claude\claude_desktop_config.json
(Usually: C:\Users\YourName\AppData\Roaming\Claude\claude_desktop_config.json)
Linux:
~/.config/Claude/claude_desktop_config.jsonIf the file does not exist, create it. If it exists but is empty, that is fine — you will add content in the next step.
On macOS, you can open it quickly from the terminal:
# macOS — open in your default editor
open ~/Library/Application\ Support/Claude/claude_desktop_config.json
# Or create it if it doesn't exist
mkdir -p ~/Library/Application\ Support/Claude
touch ~/Library/Application\ Support/Claude/claude_desktop_config.jsonOn Windows, you can open it from the command prompt or PowerShell:
# Windows — open in notepad
notepad %APPDATA%\Claude\claude_desktop_config.jsonStep 2: Add Your Server to the Config
Open the config file in your editor and add the following. Replace the path with the absolute path to your project's built file:
{
"mcpServers": {
"my-first-server": {
"command": "node",
"args": ["/absolute/path/to/my-first-mcp-server/build/index.js"]
}
}
}Important: The path must be absolute, not relative. Here are examples for each OS:
macOS / Linux:
"args": ["/Users/yourname/projects/my-first-mcp-server/build/index.js"]
Windows:
"args": ["C:\\Users\\yourname\\projects\\my-first-mcp-server\\build\\index.js"]To find your absolute path, run this from your project directory:
# macOS / Linux
pwd
# Windows (PowerShell)
(Get-Location).PathThen append /build/index.js to the result.
If you already have servers configured: Add your new server inside the existing
mcpServersobject. Each key is a unique server name. Do not replace the entire file — just add a new entry:
{
"mcpServers": {
"existing-server": {
"command": "...",
"args": ["..."]
},
"my-first-server": {
"command": "node",
"args": ["/absolute/path/to/my-first-mcp-server/build/index.js"]
}
}
}Understanding the Config Structure
Each server entry in mcpServers has this shape:
"server-name": {
"command": "node", // The executable to run
"args": ["path/to/file.js"], // Arguments passed to the command
"env": { // Optional: environment variables
"API_KEY": "your-key"
}
}- command — The program to execute. For TypeScript/JavaScript servers, this is
node. For Python servers, it would bepythonorpython3. For servers installed via npm, it might benpx. - args — An array of arguments passed to the command. For your server, this is the path to the compiled JavaScript file. If your server takes command-line flags, add them here too.
- env — Optional. Environment variables set for the server process. Useful for API keys, configuration flags, or database URLs. These are not visible to other servers or to Claude Desktop itself.
When Claude Desktop starts, it reads this config, launches each server as a child process using the command and args, and connects to it via stdio. The exact same mechanism you tested with the Inspector.
Step 3: Restart Claude Desktop
Claude Desktop reads the config file at startup. After editing the config, you must restart the application for changes to take effect.
Fully quit Claude Desktop (not just close the window):
- macOS: Right-click the dock icon and select Quit, or press
Cmd+Q. - Windows: Right-click the system tray icon and select Quit, or use Task Manager to end the process.
- Linux: Close the window and verify the process is gone with
ps aux | grep claude.
Then reopen Claude Desktop.
Common mistake: Closing the window is not the same as quitting. On macOS especially, the app stays running in the background. Make sure you fully quit and relaunch.
Step 4: Verify the Connection
After relaunching Claude Desktop, check that your server connected successfully:
- Open a new conversation in Claude Desktop.
- Look for a tools icon (it may look like a hammer, wrench, or plug icon) near the message input area. Click it.
- You should see your tools listed:
echo,calculate,format_date,random_fact, andplaceholder_image. - If you see them, the connection is working. Claude can now call your tools.
If you do not see the tools icon or your tools are not listed, skip ahead to the "When Your Server Does Not Show Up" section.
Step 5: Test in a Real Conversation
Now the fun part. Start a conversation with Claude and try these prompts:
Test 1: Echo
You: "Use the echo tool to echo 'Hello from Claude Desktop!'"
Expected: Claude calls the echo tool and shows you the result:
"Echo: Hello from Claude Desktop!"Test 2: Calculate
You: "What is 247 times 38?"
Expected: Claude uses the calculate tool with a=247, b=38, operation=multiply
and tells you the result: 9,386Test 3: Random Fact
You: "Tell me a random fun fact."
Expected: Claude calls the random_fact tool and shares the fact it receives.Test 4: Format Date
You: "How would you write today's date in French?"
Expected: Claude calls format_date with today's date and locale: "fr-FR".Test 5: System Info (via Resource)
You: "What system am I running on? Check the system info."
Expected: Claude reads the system://info resource and tells you your
hostname, OS, memory, and CPU count.Watch how Claude decides which tool to use. It reads the tool descriptions you wrote and matches them to the user's intent. The quality of your descriptions directly affects how well the AI uses your tools.
Observation: Claude may ask for confirmation before calling a tool. This is a safety feature. The AI shows you which tool it wants to call and with what parameters. Click "Allow" to proceed. You can also configure auto-approval for trusted servers.
When Your Server Does Not Show Up
If your tools do not appear in Claude Desktop after restarting, work through this checklist in order:
1. Verify the Config File Syntax
The config must be valid JSON. A single missing comma, extra comma, or mismatched bracket breaks it. Validate your JSON:
# macOS / Linux — check if the file is valid JSON
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | python3 -m json.tool
# If this prints formatted JSON, the syntax is correct.
# If it prints an error, fix the JSON.Common JSON mistakes:
- Trailing comma after the last entry in an object or array
- Using single quotes instead of double quotes
- Missing quotes around keys
- Unescaped backslashes in Windows paths (use
\\\\)
2. Verify the Path Exists
# Run the exact command Claude Desktop would run:
node /absolute/path/to/my-first-mcp-server/build/index.js
# If this hangs (waiting for input), your server starts correctly.
# If you see an error, fix it.
# Press Ctrl+C to stop.3. Verify You Fully Restarted
Closing the window is not enough on most systems. Fully quit and relaunch. On macOS, check the dock — if the app still has a dot under it, it is still running.
4. Check for Conflicting Config
If you have both a user-level and a project-level config, they might conflict. Start with only one config file active.
Checking Claude Desktop Logs
Claude Desktop writes log files that show MCP connection details, including error messages from servers that fail to start.
macOS:
~/Library/Logs/Claude/mcp*.log
# View the most recent log:
ls -lt ~/Library/Logs/Claude/mcp*.log | head -5
cat ~/Library/Logs/Claude/mcp-server-my-first-server.log
Windows:
%APPDATA%\Claude\logs\
# Look for files named mcp-server-*.log
Linux:
~/.config/Claude/logs/
# or check systemd journal if launched via systemdCommon log messages and what they mean:
"Server process exited with code 1"
→ Your server crashed on startup. Run the command manually to see the error.
"Failed to initialize: timeout"
→ Server started but didn't respond to the initialization handshake.
→ Usually caused by console.log() corrupting stdout.
"Error: Cannot find module '/wrong/path/build/index.js'"
→ The path in your config is wrong. Fix it.
"Connected to server my-first-server (5 tools, 3 resources)"
→ Success! Your server is connected and working.Passing Environment Variables
If your server needs API keys or other secrets, pass them via the env field in the config. This keeps secrets out of your source code:
{
"mcpServers": {
"my-api-server": {
"command": "node",
"args": ["/path/to/api-server/build/index.js"],
"env": {
"API_KEY": "sk-your-secret-key-here",
"API_BASE_URL": "https://api.example.com"
}
}
}
}Your server accesses these via process.env.API_KEY and process.env.API_BASE_URL. The variables are scoped to the server process — they do not leak to other servers or to Claude Desktop itself.
Security note: The config file contains your secrets in plaintext. Make sure the file has appropriate permissions and is not checked into version control. If you share your Claude Desktop config, redact the env values first.
Running Multiple Servers
Claude Desktop can connect to multiple MCP servers simultaneously. Each server runs as a separate process, and their tools and resources are combined in the UI:
{
"mcpServers": {
"my-first-server": {
"command": "node",
"args": ["/path/to/my-first-mcp-server/build/index.js"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token"
}
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/Documents"]
}
}
}In this example, Claude Desktop connects to three servers: your custom server, the official GitHub server, and the official filesystem server. Claude sees all their tools together and can use tools from different servers in the same conversation.
This is the power of MCP: each server is independently developed and independently configured, but Claude orchestrates them seamlessly.
Try It Yourself
Complete these tasks to confirm everything works end to end:
- Add your server to Claude Desktop using the steps above. Verify all your tools appear in the tools menu.
- Have a real conversation that uses at least three of your tools. For example:
Watch Claude call"What is 99 times 73? Also tell me a random fact. And what's today's date in German?"calculate,random_fact, andformat_datein sequence. - Test a resource. Ask Claude: "Check my system information and tell me how much free memory I have."
- Intentionally break something. Change your server config to point to a wrong path. Restart Claude Desktop. Check the logs to see the error message. Then fix it.
- Add a second MCP server. Try the official filesystem server:
Restart Claude Desktop and ask Claude to list files in /tmp."filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] }
Troubleshooting
Claude does not use my tools
Claude chooses tools based on their descriptions. If your description is vague, Claude might not connect your tool to the user's request. Try being more explicit in your prompt: "Use the echo tool to..."
Tool calls fail with permission errors
Claude Desktop may require you to approve tool calls. Look for a confirmation dialog asking if you want to allow the tool to run. Click "Allow" or "Always allow for this server."
Server crashes mid-conversation
If your server crashes (unhandled exception, out of memory), Claude Desktop will show an error for subsequent tool calls. Check the MCP logs for the crash message. Fix the bug, rebuild, and restart Claude Desktop.
Changes to server code not reflected
After changing your server code:
- Rebuild:
npm run build - Restart Claude Desktop (full quit and relaunch)
Claude Desktop launches your server fresh on startup. It does not hot-reload. Every code change requires a rebuild and restart cycle.
Config file syntax error silently ignored
If the JSON config is invalid, Claude Desktop might start without any MCP servers and not show a visible error. Always validate your JSON after editing:
python3 -c "import json; json.load(open('path/to/config'))"
# No output = valid JSON. Error message = fix the syntax.What You Accomplished
- Located the Claude Desktop configuration file on your OS
- Added your custom MCP server to the config
- Understood the config structure (command, args, env)
- Connected your server and verified tools appear in the UI
- Tested your tools in real AI conversations
- Learned to debug using Claude Desktop logs
- Configured environment variables for server secrets
Phase 2 Complete
You have finished the Hands-On Development phase. Starting from an empty directory, you:
- Built a working MCP server from scratch
- Added tools with complex inputs, HTTP requests, images, and error handling
- Added resources with static data, dynamic data, and URI templates
- Tested everything with MCP Inspector
- Connected your server to Claude Desktop and used it in real conversations
You now have a real, working MCP server that Claude can use. In the next phase, you will learn design patterns for building more robust, production-quality servers: security, error handling strategies, state management, and multi-server composition.