Перейти к содержимому

Решение проблем

Типичные ошибки MCP серверов и их решения — коды ошибок, отладка, FAQ

MCP использует стандартные коды ошибок JSON-RPC 2.0 плюс специфичные для протокола.

КодНазваниеОписание
-32700Parse errorНевалидный JSON
-32600Invalid RequestЗапрос не соответствует JSON-RPC
-32601Method not foundМетод не существует
-32602Invalid paramsНеверные параметры
-32603Internal errorВнутренняя ошибка сервера
КодНазваниеОписание
-32000Connection closedСоединение закрыто (часто из-за stdout)
-32001Request timeoutТаймаут запроса
-32002Resource not foundРесурс не найден
-32003Tool not foundИнструмент не найден
-32004Prompt not foundПромпт не найден

Симптомы: Сервер запускается, но сразу отключается. В логах: “Connection closed unexpectedly”.

Причина: Вывод в stdout нарушает JSON-RPC протокол.

import sys
import logging
# ❌ НЕПРАВИЛЬНО
print("Debug message") # Ломает JSON-RPC!
# ✅ ПРАВИЛЬНО
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug("Debug message")
# Или напрямую
print("Debug message", file=sys.stderr)

Симптомы: {"error": {"code": -32002, "message": "Resource not found: xxx"}}

Причина: Клиент запрашивает ресурс, который не зарегистрирован на сервере.

  1. Проверьте, что ресурс зарегистрирован:
@mcp.resource("config://settings") # Точный URI
def get_settings():
return {"theme": "dark"}
  1. Проверьте URI — он должен точно совпадать:
# ❌ Зарегистрировано
@mcp.resource("config://settings")
# ❌ Запрашивается (не совпадает)
# "config://setting" — нет 's' в конце
# "config:/settings" — одна косая черта
# "settings" — нет схемы
# ✅ Правильный запрос
# "config://settings"
  1. Проверьте список ресурсов в MCP Inspector:
    • Откройте вкладку Resources
    • Убедитесь, что нужный ресурс есть в списке

Симптомы: {"error": {"code": -32003, "message": "Tool not found: xxx"}}

  1. Проверьте регистрацию инструмента:
@mcp.tool() # Декоратор обязателен
def my_tool(param: str) -> str:
"""Описание инструмента"""
return f"Result: {param}"
  1. Проверьте имя инструмента:
# Имя берётся из имени функции
@mcp.tool()
def calculate_sum(a: int, b: int) -> int: # Имя: "calculate_sum"
return a + b
# Или можно задать явно
@mcp.tool(name="sum") # Имя: "sum"
def calculate_sum(a: int, b: int) -> int:
return a + b
  1. Перезапустите сервер после изменений

Симптомы: Сервер запускается, но инструменты не появляются в списке.

  1. Проверьте конфигурацию

    Окно терминала
    # macOS
    cat ~/Library/Application\ Support/Claude/claude_desktop_config.json

    JSON должен быть валидным (проверьте запятые и кавычки).

  2. Проверьте пути Используйте абсолютные пути:

    {
    "mcpServers": {
    "my-server": {
    "command": "/usr/bin/python3",
    "args": ["/Users/me/project/server.py"]
    }
    }
    }
  3. Проверьте запуск вручную

    Окно терминала
    python /Users/me/project/server.py

    Если есть ошибки — исправьте их.

  4. Проверьте логи Claude

    Окно терминала
    # macOS
    tail -f ~/Library/Logs/Claude/mcp*.log
  5. Полностью перезапустите Claude

    • Закройте все окна
    • Cmd+Q (macOS) или завершите процесс
    • Запустите заново
// ❌ Неправильно: относительный путь
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["server.py"]
}
}
}
// ✅ Правильно: абсолютный путь
{
"mcpServers": {
"my-server": {
"command": "/usr/bin/python3",
"args": ["/Users/me/project/server.py"]
}
}
}
// ❌ Неправильно: лишняя запятая
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["server.py"], // <-- Лишняя запятая!
}
}
}
// ✅ Правильно
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["server.py"]
}
}
}

Error: connection refused
Error: password authentication failed
Error: database "xxx" does not exist

Решения:

import os
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("db-server")
# 1. Проверьте DATABASE_URL
DATABASE_URL = os.getenv("DATABASE_URL")
if not DATABASE_URL:
raise ValueError("DATABASE_URL не установлена")
# 2. Проверьте формат URL
# postgresql://user:password@host:port/database
# postgresql://postgres:secret@localhost:5432/mydb
# 3. Используйте connection pool
import asyncpg
pool = None
@mcp.tool()
async def query_db(sql: str) -> str:
global pool
if pool is None:
pool = await asyncpg.create_pool(DATABASE_URL)
async with pool.acquire() as conn:
result = await conn.fetch(sql)
return str(result)
Error: unable to open database file
Error: database is locked

Решения:

import sqlite3
import os
# 1. Проверьте путь к файлу
db_path = "/path/to/database.db"
if not os.path.exists(db_path):
raise FileNotFoundError(f"БД не найдена: {db_path}")
# 2. Используйте правильные флаги
conn = sqlite3.connect(
db_path,
check_same_thread=False, # Для многопоточности
timeout=30.0 # Таймаут блокировки
)
# 3. Для read-only доступа
conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)

Симптомы: ModuleNotFoundError: No module named 'mcp'

{
"mcpServers": {
"my-server": {
"command": "/path/to/venv/bin/python",
"args": ["/path/to/server.py"]
}
}
}

Или используйте uvx:

{
"mcpServers": {
"my-server": {
"command": "uvx",
"args": ["--from", "mcp", "mcp", "run", "server.py"]
}
}
}

Окно терминала
# Скомпилируйте TypeScript
npx tsc
# Или используйте ts-node
npm install -D ts-node typescript @types/node
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["ts-node", "/path/to/server.ts"]
}
}
}
tsconfig.json
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
"target": "ES2022"
}
}
package.json
{
"type": "module"
}

  • Инструменты работают медленно
  • Request timeout ошибки
  • Claude “зависает” при вызове tool
  1. Добавьте прогресс-уведомления:
@mcp.tool()
async def long_operation(data: str) -> str:
"""Долгая операция"""
# Уведомляем о прогрессе
await mcp.request_context.session.send_progress(
progress=0, total=100, message="Начинаю обработку..."
)
# Делаем работу
result = await process_data(data)
await mcp.request_context.session.send_progress(
progress=100, total=100, message="Готово!"
)
return result
  1. Используйте асинхронные операции:
import asyncio
import aiohttp
@mcp.tool()
async def fetch_data(url: str) -> str:
"""Получить данные из URL"""
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=30) as response:
return await response.text()
  1. Ограничьте размер ответа:
@mcp.tool()
def get_file(path: str) -> str:
"""Читает файл (макс 100KB)"""
MAX_SIZE = 100 * 1024
with open(path, 'r') as f:
content = f.read(MAX_SIZE)
if len(content) == MAX_SIZE:
content += "\n... (файл обрезан)"
return content

Окно терминала
npx @modelcontextprotocol/inspector python server.py
  1. Вкладка Tools — все инструменты должны быть в списке
  2. Вызовите tool — проверьте, что возвращается результат
  3. Вкладка Logs — смотрите JSON-RPC сообщения
Окно терминала
# Проверка initialize
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | python server.py
# Список tools
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | python server.py

Окно терминала
# Python
pip show mcp
# Node.js
npm list @modelcontextprotocol/sdk
Окно терминала
# Python
pip install --upgrade mcp
# Node.js
npm update @modelcontextprotocol/sdk

Можно ли использовать несколько серверов одновременно?

Заголовок раздела «Можно ли использовать несколько серверов одновременно?»

Да, добавьте несколько записей в mcpServers:

{
"mcpServers": {
"server1": { "command": "python", "args": ["server1.py"] },
"server2": { "command": "python", "args": ["server2.py"] }
}
}

Используйте переменные окружения:

{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["server.py"],
"env": {
"API_KEY": "xxx",
"DATABASE_URL": "postgresql://..."
}
}
}
}
КлиентЛоги
Claude Desktop (macOS)~/Library/Logs/Claude/mcp*.log
Claude Desktop (Windows)%APPDATA%\Claude\logs\
VS CodeView → Output → MCP
CursorDeveloper Tools → Console

Production Checklist

Чеклист — подготовка к production

Настройка клиентов

Клиенты — Claude, VS Code, Cursor