Перейти к содержанию

MCP-серверы

v0.4.0

Что это такое?

Ознакомьтесь с этой секцией документации, чтобы узнать подробности: Базовая информация — MCP-серверы

Вот базовый пример, от которого можно отталкиваться:

~/.koda/config.yaml
mcpServers:
  - name: "Notion"
    command: "npx"
    args: ["-y", "@notionhq/notion-mcp-server"]
    env:
      NOTION_TOKEN: "..."

Подробности о конфигурации можно найти здесь: mcpServers.

Способы подключения

Способ подключения к серверу задаётся свойством type. Если оно не указано, используется stdio.

Тип Куда подключается Обязательные поля Аутентификация Когда использовать
stdio локальный процесс на вашей машине command env сервер запускается локально через стандартные потоки
sse удалённый сервер url apiKey сервер отдаёт только Server-Sent Events
streamable-http удалённый сервер url apiKey предпочтительный способ для новых удалённых серверов
websocket удалённый сервер url нет сервер принимает соединения по WebSocket

Для sse и streamable-http свойство apiKey добавляет к запросам заголовок Authorization: Bearer <значение>. Произвольные HTTP-заголовки в config.yaml не настраиваются: если сервер требует нестандартный заголовок, проверьте, поддерживает ли он apiKey, или подключите его через прокси.

Полный справочник полей — в mcpServers, готовые настройки популярных серверов — в примерах подключения.

stdio: локальный процесс

v0.4.0

Koda запускает сервер как дочерний процесс и общается с ним через стандартные потоки ввода и вывода. Нужное ПО должно быть установлено в системе.

~/.koda/config.yaml
mcpServers:
  - name: SQLite
    type: stdio          # можно не указывать — это значение по умолчанию
    command: npx
    args: ["-y", "mcp-sqlite", "/path/to/your/database.db"]
    env:
      LOG_LEVEL: "info"
    cwd: "/path/to/workdir"

Здесь command и args запускают сервер, env добавляет ему переменные окружения, а cwd задаёт рабочую директорию процесса.

Рабочая директория процесса

v0.9.4

Свойство cwd задаёт рабочую директорию запускаемого процесса и доступно начиная с версии v0.9.4.

sse: Server-Sent Events

v0.9.4

Koda подключается к готовому серверу по адресу url и получает события из постоянного потока. Этот способ появился раньше остальных сетевых и поддерживается для совместимости.

~/.koda/config.yaml
mcpServers:
  - name: "VSCode"
    type: sse
    url: http://127.0.0.1:64000/sse
    apiKey: "${MCP_TOKEN}"

streamable-http: Streamable HTTP

v0.9.4

Koda обменивается с сервером обычными HTTP-запросами и при необходимости получает ответ потоком. Для удалённых серверов выбирайте этот способ, если сервер его поддерживает.

~/.koda/config.yaml
mcpServers:
  - name: "Idea"
    type: streamable-http
    url: http://127.0.0.1:64442/stream
    apiKey: "${MCP_TOKEN}"
    toolCallTimeout: 300000

websocket: WebSocket

Koda устанавливает долгосрочное двунаправленное соединение с сервером. Адрес указывается в формате ws:// или wss://.

~/.koda/config.yaml
mcpServers:
  - name: "Realtime"
    type: websocket
    url: wss://mcp.example.com/ws

Ограничение WebSocket

Для этого транспорта задаётся только адрес сервера. apiKey и другие заголовки к такому соединению не применяются, поэтому подключайте так только те серверы, которым доверяете. Добавьте сервер в конфигурацию вручную — в диалоге добавления этого способа нет.

Как выбрать способ

  • Сервер запускается командой на вашей машине — stdio.
  • Сервер доступен по HTTP-адресу и работает как обычный MCP-эндпоинт — streamable-http.
  • Сервер отдаёт только SSE-поток — sse.
  • Сервер принимает WebSocket-соединения — websocket.

Адрес сервера обычно указан в его документации, там же приведены нужные args и переменные окружения.

Аутентификация удалённого сервера

v0.9.4

Свойство apiKey для sse и streamable-http добавляет к запросам заголовок Authorization: Bearer <значение>. Не храните токен в файле конфигурации в открытом виде — ссылайтесь на переменную окружения:

~/.koda/config.yaml
mcpServers:
  - name: Private API
    type: streamable-http
    url: https://example.com/mcp
    apiKey: "${MCP_TOKEN}"

Таймауты

v0.9.0

Свойство На что влияет По умолчанию
connectionTimeout ожидание подключения к серверу 20000 мс
toolCallTimeout ожидание одного вызова инструмента 120000 мс

Оба задаются в миллисекундах и подходят для любого транспорта. Медленный локальный сервер, которому нужно время на запуск, спасает connectionTimeout; долгую работу инструментов увеличивает toolCallTimeout.

Таймаут вызова инструмента

v1.2.6

Свойство toolCallTimeout задаёт, сколько Koda ждёт ответа одного вызова инструмента MCP. По умолчанию — 120000 миллисекунд; увеличьте значение, если сервер отвечает дольше.

Добавление через интерфейс

v0.9.4

  1. Откройте Настройки
  2. Перейдите на вкладку MCP
  3. Нажмите Добавить MCP сервер
  4. Выберите тип транспорта: stdio, sse или streamable-http
  5. Заполните поля — имя, команду с аргументами либо URL и API-ключ

Диалог сохраняет сервер в тот же файл конфигурации, поэтому после сохранения свойства можно уточнить вручную — например, добавить cwd или таймауты. Способ websocket доступен только через файл конфигурации.

Проверка статуса серверов

Через интерфейс:

  1. Откройте Настройки
  2. Перейдите на вкладку MCP
  3. Просмотрите список серверов:
    • 🟢 Connected — подключён
    • 🟡 Connecting — идёт подключение
    • ⚪ Not Connected — не подключён
    • 🔴 Error — ошибка подключения

Просмотр доступных инструментов

  1. Откройте чат
  2. Переключитесь на Агент
  3. Нажмите Инструменты
  4. Найдите инструменты MCP по названию сервера

Пример:

GitHub MCP:
  - github_create_issue
  - github_get_pull_request
  - github_search_repositories

SQLite MCP:
  - query_database
  - list_tables
  - describe_table

Вызов инструментов MCP

Агент автоматически использует инструменты MCP:

Пример 1: Работа с GitHub

Вы: Создай issue для баг репорта
Агент: [использует github_create_issue]

Пример 2: Работа с БД

Вы: Покажи последние 10 заказов
Агент: [использует query_database]

Пример 3: Работа с файлами

Вы: Прочитай конфиг из /etc/config
Агент: [использует filesystem_read]

По умолчанию один вызов инструмента MCP ограничен 120 секундами. Если сервер отвечает дольше, увеличьте таймаут свойством toolCallTimeout (в миллисекундах) — см. таймауты и mcpServers.

Политики инструментов MCP

Для инструментов MCP можно настроить политики:

  1. Откройте Инструменты в режиме Агент
  2. Найдите инструмент MCP
  3. Выберите политику:
    • ✅ Автоматически
    • ⚠️ С подтверждением
    • ❌ Выключен

Политика по умолчанию — Автоматически: она действует сразу после загрузки конфигурации, открывать настройки для этого не нужно. Заданные вами ограничения сохраняются и имеют приоритет над значением по умолчанию.

Рекомендации безопасности

  1. Доверяйте только проверенным серверам:
    • Используйте официальные серверы
    • Проверяйте код кастомных серверов
  2. Ограничивайте доступ:
    # Не давайте доступ ко всей файловой системе
    args:
      - "/home/user/projects/myproject"  # ✅ Хорошо
      - "/"                              # ❌ Плохо
    
  3. Используйте переменные окружения:
    env:
      API_KEY: ${API_KEY}  # Используйте переменные окружения
    
  4. Требуйте подтверждения:
    • Для операций записи
    • Для удаления данных
    • Для выполнения команд

Не рекомендуется:

  • Передавать секреты в логах
  • Давать доступ к системным файлам
  • Выполнять произвольные команды
  • Подключаться к недоверенным серверам

Допустимо:

  • Читать данные из БД
  • Вызывать API сервисов
  • Работать с файлами проекта
  • Использовать официальные серверы

Создание собственного MCP-сервера

MCP-сервер можно написать на любом языке, например:

  • TypeScript/JavaScript — официальная библиотека
  • Python — официальная библиотека
  • Java/Kotlin — через HTTP или WebSocket
  • Go — через stdio
  • Любой другой — через стандартные потоки

Сервер должен реализовать:

  1. Инициализация — handshake с клиентом
  2. Список инструментов — что может делать сервер
  3. Вызов инструментов — выполнение функций
  4. Ресурсы (опционально) — данные для чтения
  5. Промпты (опционально) — шаблоны текста

Готовый сервер подключается тем же способом, что и сторонний, — см. способы подключения. Ниже приведены примеры на популярных языках программирования.

Для создания MCP-сервера на Python используйте официальную библиотеку mcp:

# server.py
from mcp.server.fastmcp import FastMCP
import sqlite3

mcp = FastMCP("SQLite MCP")

@mcp.tool()
def query_database(sql: str) -> list[dict]:
    """Выполняет SQL-запрос к базе данных и возвращает результаты."""
    conn = sqlite3.connect("example.db")
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    cursor.execute(sql)
    results = [dict(row) for row in cursor.fetchall()]
    conn.close()
    return results

@mcp.resource("db://tables")
def list_tables() -> list[str]:
    """Возвращает список таблиц в базе данных."""
    conn = sqlite3.connect("example.db")
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
    tables = [row[0] for row in cursor.fetchall()]
    conn.close()
    return tables

if __name__ == "__main__":
    mcp.run()

Конфигурация:

name: Python SQLite MCP
command: python
args:
  - "/path/to/server.py"

Используйте пакет @modelcontextprotocol/sdk для создания сервера на Node.js:

// server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "Weather MCP",
  version: "1.0.0",
});

server.tool(
  "getWeather",
  "Получает текущую погоду для указанного города",
  {
    city: z.string().describe("Название города"),
  },
  async ({ city }) => {
    // Логика получения погоды (например, через API)
    const temperature = Math.floor(Math.random() * 30) + 10;
    return {
      content: [
        {
          type: "text",
          text: `Температура в городе ${city}: ${temperature}°C`,
        },
      ],
    };
  }
);

server.resource(
  "config",
  "config://settings",
  async () => ({
    content: [
      {
        type: "text",
        text: JSON.stringify({ apiKey: "xxx", timeout: 5000 }),
      },
    ],
  })
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

main().catch(console.error);

Конфигурация:

name: TypeScript Weather MCP
command: npx
args:
  - "tsx"
  - "/path/to/server.ts"

Для Go используйте библиотеку github.com/mark3labs/mcp-go:

// main.go
package main

import (
    "fmt"
    "github.com/mark3labs/mcp-go/mcp"
    "github.com/mark3labs/mcp-go/server"
)

func main() {
    s := server.NewMCPServer(
        "File System MCP",
        "1.0.0",
        server.WithResourceCapabilities(true, true),
        server.WithToolCapabilities(true),
    )

    // Добавляем инструмент
    s.AddTool(mcp.NewTool(
        "read_file",
        mcp.WithDescription("Читает содержимое файла"),
        mcp.WithString("path", mcp.Required(), mcp.Description("Путь к файлу")),
    ), readFileHandler)

    // Добавляем ресурс
    s.AddResource(mcp.Resource{
        URI:      "file:///etc/config",
        Name:     "System Config",
        Template: mcp.NewResourceTemplate("file://{path}"),
    }, readResourceHandler)

    server.ServeStdio(s)
}

func readFileHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    path := request.Arguments["path"].(string)
    // Логика чтения файла
    content := "Содержимое файла..."
    return &mcp.CallToolResult{
        Content: []mcp.Content{
            mcp.TextContent{Text: content},
        },
    }, nil
}

func readResourceHandler(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
    return []mcp.ResourceContents{
        {Text: "Конфигурация системы...", URI: request.Params.URI},
    }, nil
}

Конфигурация:

name: Go File System MCP
command: go
args:
  - "run"
  - "/path/to/main.go"