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

MCP-серверы

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

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

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

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

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

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

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

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

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

  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

Для инструментов 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
  • Любой другой — через стандартные потоки

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

  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"