# Ошибки MCP: -32000 Connection closed, -32002 и другие

> Разбор ошибок MCP-серверов: -32000 Connection closed, -32002 Resource not found, -32003 Tool not found, инструменты не видны в Claude Desktop, тайм-ауты

Страница: https://mcpdoc.ru/reference/troubleshooting/
Указатель сайта: https://mcpdoc.ru/llms.txt

## Коды ошибок JSON-RPC

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

### Стандартные ошибки JSON-RPC

| Код | Название | Описание |
|-----|----------|----------|
| `-32700` | Parse error | Невалидный JSON |
| `-32600` | Invalid Request | Запрос не соответствует JSON-RPC |
| `-32601` | Method not found | Метод не существует |
| `-32602` | Invalid params | Неверные параметры |
| `-32603` | Internal error | Внутренняя ошибка сервера |

### Ошибки MCP

| Код | Название | Описание |
|-----|----------|----------|
| `-32000` | Connection closed | Соединение закрыто (часто из-за stdout) |
| `-32001` | Request timeout | Тайм-аут запроса |
| `-32002` | Resource not found | Ресурс не найден |
| `-32003` | Tool not found | Инструмент не найден |
| `-32004` | Prompt not found | Промпт не найден |

---

## Ошибка -32000: Connection closed

**Симптомы:** Сервер запускается, но сразу отключается. В журнале: "Connection closed unexpectedly".

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

### Решение

  **Python**

    ```python
    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)
    ```
  
  **TypeScript**

    ```typescript
    // ❌ НЕПРАВИЛЬНО
    console.log("Debug message");  // Идёт в stdout!

    // ✅ ПРАВИЛЬНО
    console.error("Debug message");  // Идёт в stderr

    // Или создайте helper
    function log(msg: string) {
      process.stderr.write(`[DEBUG] ${msg}\n`);
    }
    ```
  
  **Go**

    ```go
    import (
        "log"
        "os"
    )

    // ❌ НЕПРАВИЛЬНО
    fmt.Println("Debug message")

    // ✅ ПРАВИЛЬНО
    log.SetOutput(os.Stderr)
    log.Println("Debug message")
    ```
  

**stdout** = только JSON-RPC сообщения
**stderr** = журналы, отладка, ошибки

---

## Ошибка -32002: Resource not found

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

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

### Решение

1. Проверьте, что ресурс зарегистрирован:

```python
@mcp.resource("config://settings")  # Точный URI
def get_settings():
    return {"theme": "dark"}
```

2. Проверьте URI — он должен точно совпадать:

```python
# ❌ Зарегистрировано
@mcp.resource("config://settings")

# ❌ Запрашивается (не совпадает)
# "config://setting"  — нет 's' в конце
# "config:/settings"  — одна косая черта
# "settings"          — нет схемы

# ✅ Правильный запрос
# "config://settings"
```

3. Проверьте список ресурсов в MCP Inspector:
   - Откройте вкладку Resources
   - Убедитесь, что нужный ресурс есть в списке

---

## Ошибка -32003: Tool not found

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

### Решение

1. Проверьте регистрацию инструмента:

```python
@mcp.tool()  # Декоратор обязателен
def my_tool(param: str) -> str:
    """Описание инструмента"""
    return f"Result: {param}"
```

2. Проверьте имя инструмента:

```python
# Имя берётся из имени функции
@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
```

3. Перезапустите сервер после изменений

---

## Tools не видны в Claude Desktop

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

### Перечень проверок

1. **Проверьте конфигурацию**
   ```bash
   # macOS
   cat ~/Library/Application\ Support/Claude/claude_desktop_config.json
   ```
   JSON должен быть валидным (проверьте запятые и кавычки).

2. **Проверьте пути**
   Используйте абсолютные пути:
   ```json
   {
     "mcpServers": {
       "my-server": {
         "command": "/usr/bin/python3",
         "args": ["/Users/me/project/server.py"]
       }
     }
   }
   ```

3. **Проверьте запуск вручную**
   ```bash
   python /Users/me/project/server.py
   ```
   Если есть ошибки — исправьте их.

4. **Проверьте журналы Claude**
   ```bash
   # macOS
   tail -f ~/Library/Logs/Claude/mcp*.log
   ```

5. **Полностью перезапустите Claude**
   - Закройте все окна
   - Cmd+Q (macOS) или завершите процесс
   - Запустите заново

### Типичные ошибки конфигурации

```json
// ❌ Неправильно: относительный путь
{
  "mcpServers": {
    "my-server": {
      "command": "python",
      "args": ["server.py"]
    }
  }
}

// ✅ Правильно: абсолютный путь
{
  "mcpServers": {
    "my-server": {
      "command": "/usr/bin/python3",
      "args": ["/Users/me/project/server.py"]
    }
  }
}
```

```json
// ❌ Неправильно: лишняя запятая
{
  "mcpServers": {
    "my-server": {
      "command": "python",
      "args": ["server.py"],  // <-- Лишняя запятая!
    }
  }
}

// ✅ Правильно
{
  "mcpServers": {
    "my-server": {
      "command": "python",
      "args": ["server.py"]
    }
  }
}
```

---

## Ошибки подключения к базе данных

### PostgreSQL

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

**Решения:**

```python
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)
```

### SQLite

```
Error: unable to open database file
Error: database is locked
```

**Решения:**

```python
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)
```

---

## Ошибки с виртуальным окружением Python

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

### Решение

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

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

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

---

## Ошибки TypeScript

### "Cannot find module"

```bash
# Скомпилируйте TypeScript
npx tsc

# Или используйте ts-node
npm install -D ts-node typescript @types/node
```

```json
{
  "mcpServers": {
    "my-server": {
      "command": "npx",
      "args": ["ts-node", "/path/to/server.ts"]
    }
  }
}
```

### "Top-level await"

```json
// tsconfig.json
{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Node",
    "target": "ES2022"
  }
}
```

```json
// package.json
{
  "type": "module"
}
```

---

## Тайм-ауты и производительность

### Симптомы
- Инструменты работают медленно
- `Request timeout` ошибки
- Claude "зависает" при вызове tool

### Решения

1. **Добавьте прогресс-уведомления:**

```python
@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
```

2. **Используйте асинхронные операции:**

```python
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()
```

3. **Ограничьте размер ответа:**

```python
@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
```

---

## Отладка с MCP Inspector

### Запуск Inspector

```bash
npx @modelcontextprotocol/inspector python server.py
```

### Что проверять

1. **Вкладка Tools** — все инструменты должны быть в списке
2. **Вызовите tool** — проверьте, что возвращается результат
3. **Вкладка Logs** — смотрите JSON-RPC сообщения

### CLI режим для автоматизации

```bash
# Проверка 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
```

---

## Частые вопросы

### Как узнать версию MCP SDK?

```bash
# Python
pip show mcp

# Node.js
npm list @modelcontextprotocol/sdk
```

### Как обновить SDK?

```bash
# Python
pip install --upgrade mcp

# Node.js
npm update @modelcontextprotocol/sdk
```

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

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

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

### Как передать секреты?

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

```json
{
  "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 Code | View → Output → MCP |
| Cursor | Developer Tools → Console |

---

## Что читать дальше

  **MCP Inspector**

    [Инструменты разработчика](https://mcpdoc.ru/reference/tools/) — подробнее о Inspector
  
  **Перечень проверок перед запуском**

    [Перечень проверок](https://mcpdoc.ru/reference/checklist/) - подготовка к рабочей среде
  
  **Примеры кода**

    [Примеры](https://mcpdoc.ru/reference/examples/) - работающий код
  
  **Настройка клиентов**

    [Клиенты](https://mcpdoc.ru/reference/clients/) — Claude, VS Code, Cursor
