DEV Community

Nicolas Dabene
Nicolas Dabene

Posted on • Originally published at nicolas-dabene.fr

How to Connect MCP Server to Claude?

Connecting Your MCP Server to Claude Desktop: The Definitive Integration Guide

After meticulously crafting an MCP server, developing powerful tools, establishing automatic discovery, and fortifying it with robust security, the grand finale awaits. Today marks the pivotal step: integrating your custom server with Claude Desktop. Prepare to witness Claude leveraging your unique toolset in real-time, bringing your development journey full circle. This is where your vision truly comes alive.

Unlocking AI Synergy: Your MCP Server Meets Claude

Relive the excitement of seeing your AI assistant come to life. The thrill of watching Claude naturally interact with a tool you've built, after countless hours of coding and testing, is unparalleled. That breakthrough moment is precisely what we'll achieve together in this concluding installment.

This guide will walk you through setting up Claude Desktop for seamless interaction with your MCP server, rigorously testing your custom tools, troubleshooting common hurdles, and exploring powerful advanced applications. Ultimately, you'll empower yourself with a bespoke AI capable of securely managing your files, data, and systems.

Essential Preparations

To ensure a smooth setup process, please confirm you have the following in place:

  • Claude Desktop: Download and install it from claude.ai/download if you haven't already.
  • Functional MCP Server: All previous parts of this series (1-5) must be completed, and your server should be operational.
  • Node.js and npm: Required to run your server environment.
  • Claude Account: Both free and Pro accounts are compatible.

Visualizing the Connection Architecture

Prior to diving into configuration, let's conceptualize the communication flow between Claude Desktop and your custom server:

┌─────────────────┐
│  Claude Desktop │
│   (Interface)   │
└────────┬────────┘
         │
         │ Reads configuration
         ↓
┌─────────────────┐
│  Configuration  │
│  claude_desktop │
│   _config.json  │
└────────┬────────┘
         │
         │ Launches automatically
         ↓
┌─────────────────┐
│  Your Server    │
│      MCP        │
│  (Node.js/TS)   │
└────────┬────────┘
         │
         │ Accesses your resources
         ↓
┌─────────────────┐
│   Files /       │
│   Data /        │
│   Systems       │
└─────────────────┘
Enter fullscreen mode Exit fullscreen mode

Essentially, Claude Desktop references a specific configuration file. This file then triggers the background execution of your MCP server, facilitating communication through standard input/output (stdio). Remarkably, this direct integration bypasses the need for your server to operate as an HTTP server!

Modifying the Server for Stdio Communication

Our server previously relied on Express and HTTP for communication. However, integrating with Claude Desktop necessitates a version designed for stdio communication. Begin by creating src/mcp-stdio.ts with the following content:

// src/mcp-stdio.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js';
import { toolRegistry } from './mcp/registry';
import { MCP_PROTOCOL_VERSION, SERVER_INFO } from './mcp/protocol';
import { ParameterValidator, ValidationError, PathValidator } from './security/validator';

/**
 * MCP server for Claude Desktop (stdio)
 */
class MCPStdioServer {
  private server: Server;
  private pathValidator: PathValidator;

  constructor() {
    // Initialize path validator
    this.pathValidator = new PathValidator([
      process.cwd(),
      process.env.HOME || '/home',
    ]);

    // Create MCP server
    this.server = new Server(
      {
        name: SERVER_INFO.name,
        version: SERVER_INFO.version,
      },
      {
        capabilities: {
          tools: {},
        },
      }
    );

    this.setupHandlers();
  }

  /**
   * MCP handlers configuration
   */
  private setupHandlers() {
    // Handler to list tools
    this.server.setRequestHandler(
      ListToolsRequestSchema,
      async () => {
        const tools = toolRegistry.getAllDescriptions();

        return {
          tools: tools.map(tool => ({
            name: tool.name,
            description: tool.description,
            inputSchema: tool.input_schema,
          })),
        };
      }
    );

    // Handler to execute a tool
    this.server.setRequestHandler(
      CallToolRequestSchema,
      async (request) => {
        const { name, arguments: args } = request.params;

        try {
          // Get tool description
          const toolDescription = toolRegistry.getDescription(name);

          if (!toolDescription) {
            return {
              content: [
                {
                  type: 'text',
                  text: JSON.stringify({
                    success: false,
                    error: `Tool '${name}' not found`,
                  }),
                },
              ],
            };
          }

          // Validate parameters
          ParameterValidator.validate(args || {}, toolDescription.input_schema);

          // Specific path validation for file tools
          if (name === 'readFile' || name === 'listFiles' || name === 'searchFiles') {
            const pathParam = args.file_path || args.directory_path;
            if (pathParam) {
              args.validated_path = this.pathValidator.validatePath(pathParam);
            }
          }

          // Execute tool
          console.error(`[MCP] Execution: ${name}`);
          const result = await toolRegistry.execute(name, args);

          // Format response
          return {
            content: [
              {
                type: 'text',
                text: result.success ? result.content || 'Operation successful' : `Error: ${result.error}`,
              },
            ],
          };

        } catch (error: any) {
          console.error(`[MCP] Error:`, error);

          if (error instanceof ValidationError) {
            return {
              content: [
                {
                  type: 'text',
                  text: `Validation error: ${error.message}`,
                },
              ],
              isError: true,
            };
          }

          return {
            content: [
              {
                type: 'text',
                text: `Error: ${error.message}`,
              },
            ],
            isError: true,
          };
        }
      }
    );
  }

  /**
   * Start the server
   */
  async start() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);

    console.error('[MCP] Server started and connected via stdio');
    console.error(`[MCP] Available tools: ${toolRegistry.count()}`);
  }
}

// Server startup
const server = new MCPStdioServer();
server.start().catch((error) => {
  console.error('[MCP] Fatal error:', error);
  process.exit(1);
});
Enter fullscreen mode Exit fullscreen mode

Crucial Note: Observe how console.error() is employed for logging messages. This is because stdout is exclusively dedicated to MCP communication, requiring all diagnostic output to be directed to stderr.

Next, install the essential MCP SDK:

npm install @modelcontextprotocol/sdk
Enter fullscreen mode Exit fullscreen mode

Proceed to compile your TypeScript project:

npx tsc
Enter fullscreen mode Exit fullscreen mode

Verify that the compilation completes without errors. The resulting executable will be located at dist/mcp-stdio.js.

Claude Desktop Configuration

Claude Desktop retrieves its operational configuration from a predefined location, which varies by operating system:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Either create a new file or modify an existing one at this location, populating it with the following configuration details:

{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": [
        "/absolute/path/to/your/project/dist/mcp-stdio.js"
      ],
      "env": {
        "NODE_ENV": "production"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Remember to update /absolute/path/to/your/project with the actual, full path to your server's project directory.

For effortless retrieval of your project's absolute path, use these commands:

cd /your/project/mcp-server
pwd
# Copy the result and append /dist/mcp-stdio.js
Enter fullscreen mode Exit fullscreen mode

Here’s a full configuration example for clarity:

{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": [
        "/Users/nicolas/Dev/mcp-server/dist/mcp-stdio.js"
      ],
      "env": {
        "NODE_ENV": "production",
        "PATH": "/usr/local/bin:/usr/bin:/bin"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Pro Tip: Include the PATH environment variable in your configuration if you encounter "command not found" errors during execution.

Initiating Claude Desktop

Follow these steps to launch Claude and verify the connection:

  1. Completely close Claude Desktop if it's currently running.
  2. Restart Claude Desktop.
  3. Open Developer Tools (on macOS: View → Developer → Toggle Developer Tools).
  4. Look at the console to observe connection logs.

Upon successful integration, your console should display messages similar to these:

[MCP] Server started and connected via stdio
[MCP] Available tools: 3
Enter fullscreen mode Exit fullscreen mode

Confirming Tool Accessibility

Within Claude Desktop, initiate a fresh conversation and prompt it with:

What tools do you have available?
Enter fullscreen mode Exit fullscreen mode

Claude's response should resemble the following:

I have several tools to interact with the file system:

  1. readFile: Allows reading the content of a text file
  2. listFiles: Lists files and folders in a directory
  3. searchFiles: Searches for files by name

What would you like me to do?

Should Claude fail to recognize your tools, please refer to the troubleshooting guidance in the "Debugging: Common Problems" section.

Initial Test: File Read Operation

Let’s set up a simple test file within your project directory:

echo "This is a test of the MCP server with Claude Desktop!" > test-claude.txt
Enter fullscreen mode Exit fullscreen mode

Then, engage Claude with this query:

Read the test-claude.txt file in the current directory and tell me what it contains.
Enter fullscreen mode Exit fullscreen mode

Claude will intelligently perform the following actions:

  1. Understand it needs to use the readFile tool.
  2. Request your permission to proceed.
  3. Execute the tool.
  4. Display the file's content.

Observe a typical conversation flow:

You: Read the test-claude.txt file

Claude: I’ll read the test-claude.txt file for you.

[Permission request appears]

[You click “Authorize”]

Claude: The file contains: “This is a test of the MCP server with Claude Desktop!”

Isn't that incredible? You've just witnessed Claude executing your very own code and tools, live!

Advanced Capabilities: Listing and Searching

Let's explore more sophisticated interactions. Try asking Claude:

List all TypeScript files in the src folder
Enter fullscreen mode Exit fullscreen mode

Claude will then:

  1. Utilize listFiles to enumerate the contents of src/.
  2. Filter for .ts files within its response.
  3. Present you with an organized list.

Alternatively, challenge Claude with:

Find all files that contain "security" in their name
Enter fullscreen mode Exit fullscreen mode

Claude will efficiently employ searchFiles with the appropriate parameter to fulfill your request.

Security Validation: Witnessing Protection

Now, let’s actively observe our implemented security measures. Pose this risky command to Claude:

Read the file ../../../../etc/passwd
Enter fullscreen mode Exit fullscreen mode

Claude will attempt to invoke the readFile tool with this unauthorized path. However, your robust PathValidator will successfully intercept and prevent the request. You will receive an error message akin to this:

I couldn’t read this file. The error indicates: “Paths with “..” are not allowed (path traversal)”

Excellent! Your security safeguards are fully operational, even when interacting with Claude.

Unlocking Advanced Scenarios with MCP

With your MCP server successfully linked to Claude, let's delve into some practical and powerful applications:

1. Code Analysis

Prompt Claude: "Examine every TypeScript file within the src/tools directory and provide a total line count for the entire codebase."

Claude's workflow: It will enumerate files in src/tools, read the content of each .ts file, tally the lines, and then present you with a comprehensive report.

2. Automatic Documentation

Ask Claude: "Generate a README.md file that comprehensively documents all tools located in src/tools, including their respective parameters."

Claude's workflow: It will identify the files, process each tool, extract critical details, and then construct a well-formatted README document.

3. Search and Summary

Instruct Claude: "Locate all files referencing the term 'validation' and summarize the implementation approach for validation logic."

Claude's workflow: It will scan for pertinent files, ingest their content, analyze the underlying code, and then synthesize the findings into a concise summary.

4. Assisted Refactoring

Request from Claude: "Review the src/tools/readFile.ts file and suggest potential performance enhancements."

Claude's workflow: It will access and read the file, apply its inherent code analysis expertise, and then recommend actionable optimization strategies.

Troubleshooting Guide: Resolving Common Issues

Issue 1: Claude Fails to Detect Tools

Symptom: Claude replies with a message like, "I don't have tools available for that specific request."

Potential Fixes:

  1. Configuration Verification:

    • macOS: Inspect your claude_desktop_config.json file.

      cat ~/Library/Application\ Support/Claude/claude_desktop_config.json
      
-   Ensure the specified path is accurate and the file exists.
Enter fullscreen mode Exit fullscreen mode
    ```bash
    ls /path/to/your/project/dist/mcp-stdio.js
    ```
Enter fullscreen mode Exit fullscreen mode
  1. Compilation Status:

    • Navigate to your project directory and confirm successful compilation.

      cd your-project
      npx tsc
      ls dist/mcp-stdio.js # This file must be present
      
  2. Manual Server Test:

    • Execute your compiled server directly. It should remain active without immediate termination.

      node dist/mcp-stdio.js
      # Input some text and press Enter; the server should not crash
      
  3. Examine Claude Desktop Developer Tools:

    • Open the developer console within Claude Desktop (View → Developer → Toggle Developer Tools).
    • Look for any error messages highlighted in red.
    • Search for log entries prefixed with [MCP].

Issue 2: 'Command Not Found' Error

Symptom: The Developer Tools display an error similar to: "Error: spawn node ENOENT."

Resolution: Explicitly define the full path to your node executable within the configuration file, and consider adding the PATH environment variable:

{
  "mcpServers": {
    "filesystem": {
      "command": "/usr/local/bin/node",
      "args": ["/absolute/path/dist/mcp-stdio.js"],
      "env": {
        "PATH": "/usr/local/bin:/usr/bin:/bin"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

To locate the correct node executable path on your system, use the which command:

which node
Enter fullscreen mode Exit fullscreen mode

Issue 3: Instant Server Crash

Symptom: Logs indicate the MCP server initiates, but then immediately terminates.

Diagnostic Steps:

  1. Standalone Server Execution:

    • Run your compiled server independently. It should stay operational if you input something and press Enter.

      node dist/mcp-stdio.js
      # Input some text and press Enter; the server should remain active
      
  2. Dependency Verification:

    • Ensure all project dependencies are correctly installed.

      npm install
      npm list @modelcontextprotocol/sdk
      
  3. Examine Standard Error (stderr):

    • Redirect stderr output to a log file for detailed error analysis.

      node dist/mcp-stdio.js 2>error.log
      # Review error.log for specific failure messages
      

Conclusion

A hearty congratulations! You've reached the culmination of this comprehensive six-part series, successfully constructing a robust Model Context Protocol (MCP) server from its fundamental building blocks to a fully integrated system:

Part 1: Grasping the core MCP principles and architectural design.
Part 2: Setting up a professional TypeScript development environment.
Part 3: Crafting your initial functional MCP tools.
Part 4: Implementing an intelligent automatic tool discovery mechanism.
Part 5: Fortifying your server with four distinct layers of security.
Part 6: Establishing a seamless connection with Claude Desktop – you are here!

At this juncture, you are equipped with:

  • A high-caliber, production-ready MCP server.
  • A suite of secure and easily expandable custom tools.
  • Full, operational integration with Claude Desktop.
  • The expertise to independently develop and deploy your own AI-powered functionalities.

What's Next for Your MCP Journey?

The potential with MCP is truly limitless. Consider these exciting avenues:

  • Streamline repetitive tasks by empowering Claude with automation.
  • Develop highly specialized AI assistants tailored to specific domains.
  • Embed Claude's capabilities directly into your organizational workflows.
  • Contribute your innovative tools to the broader developer community.

The codebase you've meticulously developed is not just functional; it's secure, resilient, and inherently maintainable. It serves as an exceptional launchpad for endeavors far more ambitious than you might imagine. I am genuinely eager to discover the incredible projects you'll bring to life!


Authored by Nicolas Dabène – a PHP & PrestaShop Expert with over 15 years of experience in software architecture and AI integration. Originally published December 17, 2025.

Explore the full MCP series:


Thank you immensely for embarking on this MCP journey with me! Your creations are what truly bring this protocol to life – please don't hesitate to share your projects; I'd genuinely love to see what you build.

For more in-depth tutorials, practical coding tips, and discussions on AI and software architecture, make sure to subscribe to my YouTube channel and connect with me on LinkedIn!

Top comments (0)