MCP-серверы¶
Что это такое?
Ознакомьтесь с базовой информацией, чтобы узнать подробности: MCP-серверы (Model Context Protocol).
Koda CLI выступает в роли MCP-клиента: подключается к MCP-серверам, обнаруживает их инструменты и делает их доступными агенту.
Серверы можно настраивать через файл settings.json или добавлять подкомандой koda mcp.
Быстрый пример¶
{
"mcpServers": {
"Notion": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "..."
}
}
}
}
Эквивалент через подкоманду:
Транспорт¶
Транспорт определяет способ связи Koda CLI с MCP-сервером и выбирается автоматически по используемому полю в конфигурации:
| Транспорт | Поле | Когда использовать |
|---|---|---|
stdio |
command |
локальный процесс, общение через потоки |
sse |
url |
удалённый сервер по протоколу Server-Sent Events |
http |
httpUrl |
удалённый сервер по протоколу Streamable HTTP |
Транспорт stdio подходит для локальных серверов: для него указываются command и при необходимости args и env.
Для удалённых серверов предпочтителен http (Streamable HTTP) — современный и рекомендованный способ.
Транспорт sse — более старый механизм: он всё ещё поддерживается, но для новых серверов следует выбирать http.
Для sse и http указывается URL эндпоинта и опционально headers.
Подробное описание полей конфигурации — в разделе «Поля конфигурации».
Добавление через koda mcp¶
Подкоманда koda mcp управляет серверами из терминала — без ручного редактирования settings.json.
Полный справочник опций — на странице аргументов CLI.
koda mcp add¶
Добавляет или обновляет сервер в настройках.
# stdio-сервер (по умолчанию)
koda mcp add local-tools node ./mcp-server.js --scope project
# SSE-сервер с заголовком
koda mcp add remote --transport sse \
--header "Authorization: Bearer ${MCP_TOKEN}" \
https://example.com/sse
# HTTP-сервер с ограничением инструментов и доверием
koda mcp add gated --transport http \
--include-tools list,read --trust \
https://example.com/mcp
Ключевые опции:
| Опция | Алиас | Назначение |
|---|---|---|
--scope |
-s |
user — глобально, project — для текущего проекта |
--transport |
-t |
stdio (по умолчанию), sse, http |
--env |
-e |
переменные окружения в формате KEY=value (только stdio) |
--header |
-H |
HTTP-заголовки для sse и http |
--timeout |
таймаут подключения в миллисекундах | |
--trust |
доверять серверу: пропускать подтверждения вызовов инструментов | |
--description |
текстовое описание сервера | |
--include-tools |
разрешить только перечисленные инструменты | |
--exclude-tools |
скрыть перечисленные инструменты от модели |
koda mcp remove¶
Удаляет сервер из настроек.
koda mcp list¶
Показывает настроенные серверы и их статус после реальной попытки подключения:
✓ Connected— сервер ответил на ping;✗ Disconnected— подключиться не удалось;… Connecting— подключение ещё выполняется.
Управление внутри сессии¶
В интерактивном режиме доступны слеш-команды:
| Команда | Назначение |
|---|---|
/mcp |
показать серверы, инструменты и prompts (алиас /mcp list) |
/mcp list |
то же самое, с подсказками |
/mcp desc |
показать описания серверов и инструментов |
/mcp schema |
показать схемы параметров инструментов |
/mcp nodesc |
скрыть описания |
/mcp auth <server> |
OAuth-аутентификация для сервера |
/mcp refresh |
переобнаружить серверы и инструменты |
Ctrl + T переключает отображение описаний инструментов.
Статусы серверов в выводе /mcp:
- 🟢 Ready — подключён, инструменты доступны;
- 🔄 Starting — подключение выполняется;
- 🔴 Disconnected — ошибка подключения.
Конфигурация серверов¶
Серверы описываются в settings.json внутри объекта mcpServers.
Ключ — имя сервера, значение — его конфигурация.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"trust": false,
"includeTools": ["read_file"],
"excludeTools": []
},
"remote-api": {
"httpUrl": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer ${MCP_TOKEN}"
},
"timeout": 10000
}
}
}
Поля конфигурации¶
| Поле | Транспорт | Назначение |
|---|---|---|
command |
stdio | исполняемая команда запуска сервера |
args |
stdio | массив аргументов команды |
env |
stdio | переменные окружения процесса сервера |
url |
sse | URL SSE-эндпоинта |
httpUrl |
http | URL Streamable HTTP-эндпоинта |
headers |
sse, http | HTTP-заголовки запросов |
timeout |
все | таймаут подключения в миллисекундах |
trust |
все | true — доверять всем инструментам без подтверждения |
description |
все | описание сервера для отображения в /mcp |
includeTools |
все | allowlist инструментов: разрешить только перечисленные |
excludeTools |
все | denylist инструментов: скрыть перечисленные от модели |
Области настроек¶
| Область | Путь | Назначение |
|---|---|---|
| User | ~/.kodacli/settings.json |
глобальные настройки |
| Workspace | <workspace>/.kodacli/settings.json |
настройки проекта |
Параметр mcpServers объединяется между областями: серверы из workspace добавляются к серверам из user.
Подробнее — на странице настроек.
Вызов инструментов MCP¶
Агент автоматически использует инструменты MCP, когда они подходят для задачи.
По умолчанию CLI запрашивает подтверждение перед каждым вызовом инструмента.
Чтобы пропускать подтверждения для доверенного сервера, установите "trust": true или используйте --trust при добавлении.
Подтверждениями также управляет флаг --approval-mode:
default— запрашивать подтверждение;auto_edit— автоматически подтверждать инструменты редактирования;yolo— автоматически подтверждать все инструменты.
OAuth-аутентификация¶
Некоторые MCP-серверы (например, Atlassian, Google) требуют OAuth. Если сервер поддерживает динамическое обнаружение OAuth, CLI определит это автоматически.
Команда запускает процесс аутентификации, после чего переобнаруживает инструменты сервера.
Без аргумента /mcp auth выводит список серверов с поддержкой OAuth.
Фильтрация серверов¶
Чтобы ограничить набор серверов, которые могут использоваться:
| Способ | Где | Назначение |
|---|---|---|
allowMCPServers |
settings | allowlist: разрешить только перечисленные серверы |
excludeMCPServers |
settings | denylist: исключить перечисленные серверы |
--allowed-mcp-server-names |
CLI-флаг | переопределяет обе настройки при запуске |
Серверы, не попавшие в allowlist, помечаются как заблокированные и отображаются со статусом 🔴 Blocked в /mcp.
Рекомендации безопасности¶
-
Доверяйте только проверенным серверам:
- Используйте официальные серверы.
- Проверяйте код кастомных серверов.
-
Ограничивайте доступ:
Не давайте доступ ко всей файловой системе — указывайте только нужные директории.
-
Используйте переменные окружения:
-
Требуйте подтверждение:
- Для операций записи.
- Для удаления данных.
- Для выполнения команд.
- Не устанавливайте
"trust": trueдля непроверенных серверов.
Предостережение
Прежде чем использовать сторонний сервер MCP, убедитесь, что вы доверяете его источнику и понимаете инструменты, которые он предоставляет. Вы используете сторонние серверы на свой страх и риск.
Создание собственного MCP-сервера¶
MCP-сервер можно написать на любом языке, например:
- TypeScript/JavaScript — официальная библиотека
@modelcontextprotocol/sdk; - Python — официальная библиотека
mcp; - Go — через
github.com/mark3labs/mcp-go; - Любой другой — через стандартные потоки или HTTP.
Сервер должен реализовать:
- Инициализация — handshake с клиентом;
- Список инструментов — что может делать сервер;
- Вызов инструментов — выполнение функций;
- Ресурсы (опционально) — данные для чтения;
- Промпты (опционально) — шаблоны текста.
Используйте официальную библиотеку mcp:
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:
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 }) => {
const temperature = Math.floor(Math.random() * 30) + 10;
return {
content: [
{
type: "text",
text: `Температура в городе ${city}: ${temperature}°C`,
},
],
};
}
);
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch(console.error);
Подключение:
Используйте библиотеку github.com/mark3labs/mcp-go:
package main
import (
"context"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
func main() {
s := server.NewMCPServer(
"File System MCP",
"1.0.0",
server.WithToolCapabilities(true),
)
s.AddTool(mcp.NewTool(
"read_file",
mcp.WithDescription("Читает содержимое файла"),
mcp.WithString("path", mcp.Required(), mcp.Description("Путь к файлу")),
), readFileHandler)
server.ServeStdio(s)
}
func readFileHandler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
path := req.Params.Arguments["path"].(string)
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.TextContent{Text: "Содержимое файла: " + path},
},
}, nil
}
Подключение: