MCP-серверы¶
v0.4.0
Что это такое?
Ознакомьтесь с этой секцией документации, чтобы узнать подробности: Базовая информация — MCP-серверы
Вот базовый пример, от которого можно отталкиваться:
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 запускает сервер как дочерний процесс и общается с ним через стандартные потоки ввода и вывода. Нужное ПО должно быть установлено в системе.
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 и получает события из постоянного потока.
Этот способ появился раньше остальных сетевых и поддерживается для совместимости.
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-запросами и при необходимости получает ответ потоком. Для удалённых серверов выбирайте этот способ, если сервер его поддерживает.
mcpServers:
- name: "Idea"
type: streamable-http
url: http://127.0.0.1:64442/stream
apiKey: "${MCP_TOKEN}"
toolCallTimeout: 300000
websocket: WebSocket¶
Koda устанавливает долгосрочное двунаправленное соединение с сервером.
Адрес указывается в формате ws:// или wss://.
Ограничение WebSocket
Для этого транспорта задаётся только адрес сервера.
apiKey и другие заголовки к такому соединению не применяются, поэтому подключайте так только те серверы, которым доверяете.
Добавьте сервер в конфигурацию вручную — в диалоге добавления этого способа нет.
Как выбрать способ¶
- Сервер запускается командой на вашей машине —
stdio. - Сервер доступен по HTTP-адресу и работает как обычный MCP-эндпоинт —
streamable-http. - Сервер отдаёт только SSE-поток —
sse. - Сервер принимает WebSocket-соединения —
websocket.
Адрес сервера обычно указан в его документации, там же приведены нужные args и переменные окружения.
Аутентификация удалённого сервера¶
v0.9.4
Свойство apiKey для sse и streamable-http добавляет к запросам заголовок Authorization: Bearer <значение>.
Не храните токен в файле конфигурации в открытом виде — ссылайтесь на переменную окружения:
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
- Откройте Настройки
- Перейдите на вкладку MCP
- Нажмите Добавить MCP сервер
- Выберите тип транспорта: stdio, sse или streamable-http
- Заполните поля — имя, команду с аргументами либо URL и API-ключ
Диалог сохраняет сервер в тот же файл конфигурации, поэтому после сохранения свойства можно уточнить вручную — например, добавить cwd или таймауты.
Способ websocket доступен только через файл конфигурации.
Проверка статуса серверов¶
Через интерфейс:
- Откройте Настройки
- Перейдите на вкладку MCP
- Просмотрите список серверов:
- 🟢 Connected — подключён
- 🟡 Connecting — идёт подключение
- ⚪ Not Connected — не подключён
- 🔴 Error — ошибка подключения
Просмотр доступных инструментов¶
- Откройте чат
- Переключитесь на Агент
- Нажмите Инструменты
- Найдите инструменты 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
Пример 2: Работа с БД
Пример 3: Работа с файлами
По умолчанию один вызов инструмента MCP ограничен 120 секундами.
Если сервер отвечает дольше, увеличьте таймаут свойством toolCallTimeout (в миллисекундах) — см. таймауты и mcpServers.
Политики инструментов MCP¶
Для инструментов MCP можно настроить политики:
- Откройте Инструменты в режиме Агент
- Найдите инструмент MCP
- Выберите политику:
- ✅ Автоматически
- ⚠️ С подтверждением
- ❌ Выключен
Политика по умолчанию — Автоматически: она действует сразу после загрузки конфигурации, открывать настройки для этого не нужно. Заданные вами ограничения сохраняются и имеют приоритет над значением по умолчанию.
Рекомендации безопасности¶
- Доверяйте только проверенным серверам:
- Используйте официальные серверы
- Проверяйте код кастомных серверов
- Ограничивайте доступ:
- Используйте переменные окружения:
- Требуйте подтверждения:
- Для операций записи
- Для удаления данных
- Для выполнения команд
Не рекомендуется:
- Передавать секреты в логах
- Давать доступ к системным файлам
- Выполнять произвольные команды
- Подключаться к недоверенным серверам
Допустимо:
- Читать данные из БД
- Вызывать API сервисов
- Работать с файлами проекта
- Использовать официальные серверы
Создание собственного MCP-сервера¶
MCP-сервер можно написать на любом языке, например:
- TypeScript/JavaScript — официальная библиотека
- Python — официальная библиотека
- Java/Kotlin — через HTTP или WebSocket
- Go — через stdio
- Любой другой — через стандартные потоки
Сервер должен реализовать:
- Инициализация — handshake с клиентом
- Список инструментов — что может делать сервер
- Вызов инструментов — выполнение функций
- Ресурсы (опционально) — данные для чтения
- Промпты (опционально) — шаблоны текста
Готовый сервер подключается тем же способом, что и сторонний, — см. способы подключения. Ниже приведены примеры на популярных языках программирования.
Для создания 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()
Конфигурация:
Используйте пакет @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);
Конфигурация:
Для 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
}
Конфигурация: