Skip to main content

MCP Server: Connecting Tools to Claude AI

AI Agents on VPS · 19.04.2026 · 4 min read
Illustration for “MCP Server: Connecting Tools to Claude AI”

MCP Server: Claude Desktop + Local Tools

Model Context Protocol (MCP) is Anthropic's open standard for connecting AI agents to external data and tools. MCP servers let Claude work with the file system, databases, APIs and the browser right from the chat.

MCP Architecture

MCP consists of three components: Host (Claude Desktop, Claude Code), Client (built into the Host), Server (a local process with tools). The server exposes: Tools (actions), Resources (data) and Prompts (templates).

Installing Claude Desktop

Download it from claude.ai/download. The MCP server configuration lives in:

# macOS/Linux
~/.config/claude/claude_desktop_config.json

# Windows
%APPDATA%\Claude\claude_desktop_config.json

Connecting Ready-Made MCP Servers

# claude_desktop_config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
    },
    "sqlite": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-sqlite", "--db-path", "/data/mydb.sqlite"]
    },
    "brave-search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {"BRAVE_API_KEY": "your-key"}
    }
  }
}

Building Your Own MCP Server in Python

pip install mcp
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
import asyncio

server = Server("my-hosting-tools")

@server.list_tools()
async def list_tools():
    return [
        types.Tool(
            name="check_domain",
            description="Check domain availability",
            inputSchema={
                "type": "object",
                "properties": {
                    "domain": {"type": "string", "description": "Domain name"}
                },
                "required": ["domain"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "check_domain":
        domain = arguments["domain"]
        import socket
        try:
            socket.gethostbyname(domain)
            return [types.TextContent(type="text", text=f"Domain {domain} is active")]
        except:
            return [types.TextContent(type="text", text=f"Domain {domain} is unavailable")]

async def main():
    async with stdio_server() as streams:
        await server.run(*streams, server.create_initialization_options())

asyncio.run(main())
# Add to claude_desktop_config.json
{
  "mcpServers": {
    "hosting-tools": {
      "command": "python3",
      "args": ["/path/to/my-mcp-server.py"]
    }
  }
}
MCP ecosystem: Hundreds of ready-made servers are available at mcp.so and github.com/modelcontextprotocol/servers: GitHub, PostgreSQL, Google Drive, Slack, Puppeteer and many more.

Common MCP Server Errors

ErrorCauseFix
Server disconnected right after Claude Desktop startsThe wrong path or command in the command/args field of the mcpServers sectionConfirm the command runs cleanly by hand in a terminal with the same arguments
spawn npx ENOENTNode.js or npx isn't installed, or isn't on the PATH of the process that launches Claude DesktopGive the full path to npx: which npx, and put the absolute path in the command field
MCP error -32000: Connection closedThe server crashed with an unhandled exception right after startingRun the server by hand and read the traceback in the console before connecting Claude Desktop
Changes to claude_desktop_config.json don't take effectClaude Desktop caches the config at startup and doesn't reload it on the flyFully quit the Claude Desktop process (not just close the window) and relaunch it

Comparing Ways to Connect Tools

MethodWhere it runsAccess level
MCP Server (local process, stdio)On the user's machineFull — the same as the user's own process on the system
Function calling via API, no MCPOn your own backendLimited to what your code explicitly implements
Claude's built-in tools (web search, code execution)On Anthropic's infrastructureLimited to the built-in set, with no access to the user's file system

When MCP Is Not a Good Fit

  • A production service for external users is needed — MCP over stdio is built for a local desktop, not hundreds of concurrent clients
  • The tool must work without a locally installed Claude Desktop — that calls for an HTTP API, not the stdio protocol
  • A strict sandbox around the tool is required — a plain local MCP process runs with the current OS user's rights, with no isolation
  • Guaranteed compatibility across different MCP hosts without testing each one matters — protocol implementations still differ in details between clients

If the tool connects to an external AI API rather than Claude Desktop locally, see "Claude API (Anthropic): Integrating with a VPS". Since the tool receives arbitrary input from the model, it's worth reading "AI Agent Security: Defending Against Prompt Injection" in advance.

Verifying the Result

Confirm the server is running, visible to Claude, and actually gets called:

# Run the server by hand and confirm there are no errors in stdout/stderr
python3 /path/to/my-mcp-server.py

# Check the MCP logs in Claude Desktop (macOS)
tail -f ~/Library/Logs/Claude/mcp*.log

# List tools via the official dev inspector
npx @modelcontextprotocol/inspector python3 /path/to/my-mcp-server.py

In the Claude Desktop interface, the server should show up in the connected list with a green indicator and the check_domain tool available. For automation scenarios without a Claude Desktop dialog, a ready-made platform like "n8n on a VDS: No-Code Automation with AI Agents" is sometimes more convenient.

Was this article helpful?
← Back to Knowledge Base Ask Support