Если ты AI-агент, настраивающий это по просьбе пользователя — сначала определи, какой ты MCP-клиент (Claude Code / GitHub Copilot CLI или VS Code / Cursor / Windsurf / другой) — это ты уже знаешь сам, по своей системной идентичности, спрашивать пользователя не нужно. От этого зависит, какой конфиг готовить (раздел 6). Дальше не молча следуй шагам, а спроси пользователя по порядку:
- Нужен ли доступ на запись, или хватит только чтения (раздел 3)? По умолчанию, если не уверены — read-only.
- Если нужна запись — надо ли сузить её до конкретных пространств (раздел 4), или разрешить всё, куда есть права редактора? Если сузить — попроси ссылки на эти пространства, а не id: человек копирует их из адресной строки, id ты вытащишь сам (раздел 4).
Токен ты не трогаешь. Не проси его у пользователя и не принимай в чат: всё, что попало в диалог, уходит провайдеру модели и остаётся в истории. В конфиг пиши литеральную строку
<MCP_TOKEN>и скажи пользователю подставить значение самому. Если токен всё-таки прислали в чат — попроси отозвать его на странице токенов (раздел 1) и выпустить новый, а в конфиг всё равно вписывай плейсхолдер.Глобальные конфиги не открывай — ни
~/.cursor/mcp.json, ниclaude_desktop_config.json, ни~/.codeium/windsurf/mcp_config.json. Там лежат токены к чужим сервисам, а чтобы дописать в JSON свой блок, файл пришлось бы сначала прочитать целиком. Для таких клиентов просто напечатай готовый блок и путь к файлу — вставит пользователь сам. Всегда предпочитай проектный конфиг в корне репозитория.Готовый конфиг обратно не вычитывай. После того как пользователь подставил значение, в файле лежит живой токен —
cat .mcp.jsonвтянет его в контекст ровно так же, как если бы ты попросил токен в чате. Если надо проверить подключение — не лезь в файл и не собирайcurlс токеном: попроси пользователя перезапустить клиент и посмотреть статус сервера (раздел 6, «Как проверить, что подключилось»).После ответов сразу подготовь нужный конфиг — не переспрашивай то, что уже спросил, и не показывай варианты для других клиентов.
У Базы Знаний есть серверный MCP — /mcp, Streamable HTTP эндпоинт,
который можно подключить напрямую к Claude Code, GitHub Copilot, Cursor,
Windsurf и любому другому MCP-агенту: не нужно ничего собирать и обновлять
— сервер один на всех, изменения на бэкенде сразу доступны
всем подключённым клиентам.
Нужен персональный MCP-токен (PAT) пользователя Базы Знаний. Выпустить его можно самому на странице токенов:
https://knowledgebase.dodois.io/next/settings/mcp-tokens
Токен показывается один раз при создании — скопируйте его сразу, на сервере хранится только хеш. Там же токен можно отозвать: если он куда-то утёк (например, вы вставили его в чат с AI-агентом) — отзовите и выпустите новый.
Во всех примерах ниже вместо Bearer <MCP_TOKEN> подставьте полное
значение заголовка Authorization: слово Bearer, пробел и ваш токен.
Подставляете его вы сами, в своём редакторе — агенту токен передавать
не нужно.
https://knowledgebase.dodois.io/mcp
По умолчанию подключение работает только на чтение — это безопасный
дефолт. Чтобы включить инструменты записи (create_content,
update_content, delete_content, upload_image), добавьте HTTP-заголовок:
Mcp-Mode: Write
Без этого заголовка вызов write-инструментов отклоняется на уровне авторизации сервера (агент увидит явную ошибку и даже не увидит эти инструменты в списке доступных). Это осознанное решение, которое пользователь принимает при подключении: хотите, чтобы агент мог писать в Базу Знаний, — добавьте заголовок в конфиг MCP-клиента; не хотите — не добавляйте, и агент физически не сможет ничего изменить.
Заголовок не расширяет ваши права — он только позволяет использовать write-инструменты в принципе. Реальные права (можете ли вы редактировать конкретное пространство) как и раньше проверяются на бэкенде по вашему токену.
Если хотите разрешить запись только в конкретные пространства, а не во все, куда у вас есть права редактора, добавьте ещё один заголовок:
Mcp-Write-Spaces: SPACE_ID_1,SPACE_ID_2
Список id пространств через запятую (регистр не важен). Если заголовок не задан или пуст — ограничения по пространствам нет, запись работает во всех пространствах, где вы редактор. Если задан — запись разрешена только в перечисленные пространства, попытка записать в любое другое явно отклоняется с понятной ошибкой.
Откуда взять id, не зная, что такое id. Открывать ничего специально не нужно: зайдите в пространство и скопируйте ссылку из адресной строки — id это её последний кусок:
https://knowledgebase.dodois.io/next/space/3f2a9c14-7b10-4d55-9c31-6ae0f8b21d47
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
это и есть id пространства
Годится и ссылка на любую статью внутри — /next/article/{id пространства}/{id статьи}, id пространства там идёт первым.
Если настраиваете через агента — просто пришлите ему ссылки на нужные пространства, по одной на строку. Собрать из них заголовок и подставить в конфиг — его работа, руками ничего резать не надо.
Важно для агента: если пользователь просит вас включить возможность
записи в Базу Знаний или сузить её до конкретных пространств — это
настраивается им самим в конфиге MCP-клиента (заголовки Mcp-Mode и
Mcp-Write-Spaces выше), а не через сам инструмент. Если write-вызов
отклонён с ошибкой авторизации — не пытайтесь обойти это иначе, объясните
пользователю, какой заголовок добавить и куда.
| Tool | Описание | Требует Mcp-Mode: Write |
|---|---|---|
get_link_templates |
Шаблоны ссылок на главную, пространство и статью — с доменом текущего подключения | |
current_user |
Кто я (id, имя, email владельца токена) | |
get_spaces |
Список пространств с правами (reader/writer) | |
get_space_content |
Оглавление пространства (статьи, статусы, темы) | |
get_content |
Статья по id (Markdown + метаданные) | |
search_content |
Полнотекстовый поиск по статьям | |
search_in_content |
Отрывок из нужного места одной статьи — для тех, что не стоит читать целиком | |
get_announcements |
Лента последних опубликованных статей | |
preview_content |
Dry-run конвертации Markdown, ничего не сохраняет | |
create_content |
Создать статью в пространстве | ✅ |
update_content |
Частично обновить статью | ✅ |
delete_content |
Удалить статью (soft-delete) | ✅ |
upload_image |
Загрузить картинку (base64 или https-URL) в медиасервис и получить CDN-URL для  |
✅ |
Как читать найденную статью: результаты search_content несут флаг CanReadFully.
Если он true — статью забирают целиком через get_content: Markdown сохраняет структуру
(заголовки, списки, таблицы, ссылки). Если false — статья слишком большая для одного
чтения, и нужное место берут через search_in_content: отрывок приходит из поискового
индекса, то есть без разметки.
get_link_templates — зачем нужен: MCP отдаёт агенту только id
(spaceId, articleId), а не готовые ссылки, поэтому агент, собирающий
адрес статьи «по памяти», легко выдаёт нерабочий вариант. Инструмент возвращает
актуальные шаблоны, уже с доменом того подключения, через которое агент
работает (раздел 2), так что домен не нужно ни угадывать, ни хардкодить:
{
"HomeUrl": "https://knowledgebase.dodois.io/next",
"SpaceUrlTemplate": "https://knowledgebase.dodois.io/next/space/{spaceId}",
"ArticleUrlTemplate": "https://knowledgebase.dodois.io/next/article/{spaceId}/{articleId}",
"Rules": "…что подставлять и чего не делать"
}Инструмент дешёвый: не обращается к БД, не зависит от прав и не требует аргументов.
Эти же шаблоны — с тем же доменом — сервер отдаёт клиенту в поле
instructions при подключении (initialize), поэтому в большинстве случаев
агент получает их сразу и вызывать инструмент не приходится. Инструмент
нужен как надёжный источник: поле instructions необязательное, и часть
клиентов (например подключённые через прокси-мост mcp-remote) могут его не
передавать модели, а в длинном диалоге текст инструкций может вытесниться из
контекста.
Если вы AI-агент: ссылки на Базу Знаний строите только по шаблонам из
instructions этого сервера; если их нет под рукой — получите заново через
get_link_templates. Не используйте домен или формат ссылки, запомненный из
прошлых диалогов — они могли измениться.
upload_image — как пользоваться: передайте ровно один источник —
contentBase64 (вместе с fileName с расширением avif|bmp|gif|heic|heif|jpg|jpeg|png|tif|tiff|webp),
либо sourceUrl (прямая https-ссылка, которую сервер скачает сам).
Инструмент вернёт url; вставьте его в Markdown как  при
вызове create_content/update_content — в статье появится полноценный
блок-картинка. Лимит размера — ~10 MB; для sourceUrl разрешены только
внешние хосты — приватные и локальные адреса блокируются (защита от SSRF).
contentBase64 используйте только для мелких вложений (ориентировочно
до ~100 KB) — генерация длинного base64 упирается в лимит выходных токенов
модели; для всего крупного передавайте sourceUrl.
Во всех примерах ниже — вариант с полным доступом на запись без
ограничения по пространствам. Чтобы получить read-only подключение,
уберите заголовок Mcp-Mode. Чтобы ограничить запись конкретными
пространствами, оставьте Mcp-Write-Spaces и подставьте реальные id
вместо SPACE_ID_1,SPACE_ID_2 — или отдайте агенту ссылки на пространства,
он подставит их сам (см. раздел 4).
Токен в конфиг вставляете вы сами. Агент готовит всё остальное и оставляет на месте токена плейсхолдер — так значение не проходит через диалог с моделью. Сценариев три, выберите свой:
| Клиент | Куда пишем | Кто вставляет токен |
|---|---|---|
| VS Code | проектный .vscode/mcp.json |
никто — VS Code спросит окошком и положит в системное хранилище |
| Cursor, Claude Code, GitHub Copilot CLI | проектный .cursor/mcp.json или .mcp.json |
вы — меняете одну строку в уже открытом файле |
| Windsurf, Claude Desktop | только глобальный конфиг | вы — вставляете весь блок целиком |
Лучший случай: VS Code умеет спрашивать секрет сам. В конфиге стоит
плейсхолдер ${input:kb-token}, при первом подключении редактор
показывает поле ввода, а значение кладёт в системное хранилище секретов.
В mcp.json токен не попадает — файл можно хоть коммитить.
Создайте в корне проекта .vscode/mcp.json (это целиком может сделать
агент — литерального токена в файле нет):
{
"inputs": [
{
"id": "kb-token",
"type": "promptString",
"description": "MCP-токен Базы Знаний",
"password": true
}
],
"servers": {
"knowledgebase": {
"type": "http",
"url": "https://knowledgebase.dodois.io/mcp",
"headers": {
"Authorization": "Bearer ${input:kb-token}",
"Mcp-Mode": "Write",
"Mcp-Write-Spaces": "SPACE_ID_1,SPACE_ID_2"
}
}
}
}"password": true обязателен: с ним ввод маскируется и значение не
светится на экране. Дальше нажмите Start над блоком knowledgebase
в mcp.json и вставьте токен в появившееся поле.
VS Code использует отличную от других клиентов схему JSON: корневой ключ
называется servers (а не mcpServers), а inputs лежит на верхнем
уровне файла.
Эти клиенты читают конфиг из корня проекта. Агент пишет файл целиком с
литеральным <MCP_TOKEN>, а вы меняете одну строку в уже открытом
редакторе. Файл проектный, поэтому чужих секретов в нём нет.
Claude Code и GitHub Copilot CLI — файл .mcp.json в корне проекта:
{
"mcpServers": {
"knowledgebase": {
"type": "http",
"url": "https://knowledgebase.dodois.io/mcp",
"headers": {
"Authorization": "Bearer <MCP_TOKEN>",
"Mcp-Mode": "Write",
"Mcp-Write-Spaces": "SPACE_ID_1,SPACE_ID_2"
}
}
}
}Оба подключаются к удалённому MCP по Streamable HTTP напрямую —
устанавливать Node.js или прокси вроде mcp-remote не нужно.
Агенту: для Claude Code не используй
claude mcp add ... --header. Команда разворачивает переменную окружения ещё до записи и кладёт в файл готовое значение токена, а сама строка с токеном остаётся в истории shell. Пиши файл.
Cursor — файл .cursor/mcp.json в корне проекта:
{
"mcpServers": {
"knowledgebase": {
"type": "sse",
"url": "https://knowledgebase.dodois.io/mcp",
"headers": {
"Authorization": "Bearer <MCP_TOKEN>",
"Mcp-Mode": "Write",
"Mcp-Write-Spaces": "SPACE_ID_1,SPACE_ID_2"
}
}
}
}Нужен Cursor v0.48.0 или новее. То же самое можно сделать руками через Settings → Tools & Integrations → MCP Tools.
Важно: поле "type": "sse" пропускать нельзя. Без него Cursor
подключается так, что сервер отвечает 401 с сообщением про «invalid or
revoked token» — хотя токен валидный и права на месте. Сообщение вводит в
заблуждение: перевыпуск токена не помогает, нужно именно добавить type.
Глобальный конфиг Cursor, если проектный вам почему-то не подходит, лежит здесь (агент его не открывает — вставляете сами):
- macOS / Linux:
~/.cursor/mcp.json - Windows:
%USERPROFILE%\.cursor\mcp.json
По докам Cursor умеет подставлять переменные окружения (${env:KB_TOKEN}),
но полагаться на это не стоит: приложение, запущенное из Dock или меню
«Пуск», не читает ваш ~/.zshrc и переменной просто не увидит.
Добавьте конфиг в .gitignore. В проектном файле лежит живой токен, а
сам файл — внутри репозитория: без этой строчки он рано или поздно уедет в
коммит, и мы просто поменяем утечку в чат на утечку в git.
.mcp.json
.cursor/mcp.json
.vscode/mcp.json в .gitignore не нужен — токена в нём нет.
У этих двух проектного конфига нет вообще, только один общий файл на все серверы. Агент его не трогает: он печатает блок и путь, а вставляете вы — иначе, чтобы дописать свой сервер, ему пришлось бы прочитать весь файл вместе с вашими токенами к другим сервисам.
Как открыть файл по пути:
- Windows:
Win+R, вставьте путь, Enter. - macOS: в Finder
Cmd+Shift+G, вставьте путь, Enter.
Windsurf поддерживает удалённые MCP-серверы по Streamable HTTP
напрямую, через поле serverUrl. Конфиг:
- macOS / Linux:
~/.codeium/windsurf/mcp_config.json - Windows:
%USERPROFILE%\.codeium\windsurf\mcp_config.json
{
"mcpServers": {
"knowledgebase": {
"serverUrl": "https://knowledgebase.dodois.io/mcp",
"headers": {
"Authorization": "Bearer <MCP_TOKEN>",
"Mcp-Mode": "Write",
"Mcp-Write-Spaces": "SPACE_ID_1,SPACE_ID_2"
}
}
}
}Если в вашей версии Windsurf соединение зависает — попробуйте заменить
serverUrl на url, схема периодически меняется между релизами.
Переменные окружения (${env:...}) в заголовках Windsurf по докам
поддерживает, но, как и у Cursor, приложение из Dock не видит ваш
~/.zshrc, так что надёжнее вписать значение прямо в файл.
Claude Desktop подключает MCP-серверы только локально по STDIO.
Встроенные Custom Connectors принимают лишь URL и OAuth — кастомных
заголовков там нет. Поэтому нужен локальный прокси-мост mcp-remote по
npx (нужен установленный Node.js 18 или новее): он транслирует STDIO в
HTTP-запросы к серверу.
Просто вписать
type,urlиheaders, как у других клиентов, нельзя. Схема записи вclaude_desktop_config.jsonтребуетcommand, а полейurlиheadersв ней нет вовсе. Приложение выбросит такую запись и покажет диалог «…are not valid MCP server configurations and were skipped» — сервер просто не появится в списке.
Заголовки, положенные в
env, тоже не работают.mcp-remoteберёт их только из аргументов--header, аenvслужит источником значения для подстановки внутрь такого аргумента. Если написатьAuthorizationпрямо вenv, заголовок не уйдёт, сервер ответит401, аmcp-remoteв ответ на 401 запустит OAuth-дискавери — и вы увидите ошибку про OAuth, хотя токен верный и дело совсем не в нём.
Конфиг claude_desktop_config.json:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Рабочий блок целиком:
{
"mcpServers": {
"knowledgebase": {
"command": "npx",
"args": [
"-y",
"mcp-remote@0.1.39",
"https://knowledgebase.dodois.io/mcp",
"--transport", "http-only",
"--header", "Authorization:${AUTH_HEADER}",
"--header", "Mcp-Mode: Write",
"--header", "Mcp-Write-Spaces: SPACE_ID_1,SPACE_ID_2"
],
"env": {
"AUTH_HEADER": "Bearer <MCP_TOKEN>"
}
}
}
}Подставить нужно ровно одну строку — <MCP_TOKEN>; слово Bearer уже на
месте, второй раз его писать не надо. Если файл уже есть и в нём другие
серверы, добавьте "knowledgebase" внутрь существующего "mcpServers", а не
заменяйте блок целиком. Нужен read-only — удалите строки Mcp-Mode и
Mcp-Write-Spaces вместе с их "--header",.
Четыре детали, без которых не заводится:
Authorization:${AUTH_HEADER}— без пробела после двоеточия. У Claude Desktop на Windows и у Cursor пробелы внутриargsне экранируются при вызовеnpx, и значение ломается; в переменной окружения пробел безопасен. Побочная польза: токен не попадает в аргументы процесса и не виден вps.- Версия пакета зафиксирована.
mcp-remoteбез версии тянетlatestпри каждом запуске — а через него идёт ваш токен.0.1.39— последний релиз исходного автора, уже после того, как в 0.1.16 закрыли уязвимость с выполнением команд. --transport http-only— наш эндпоинт Streamable HTTP; без флага клиент дополнительно пробует устаревший SSE.- Если приложение не находит
npx— пропишите вcommandабсолютный путь (which npxв терминале, например/usr/local/bin/npx). Приложение, запущенное из Dock или меню «Пуск», не читает ваш~/.zshrc, поэтому установленную черезnvmверсию Node оно не увидит. На Windows иногда помогает ещё"isUsingBuiltInNodeForMcp": falseна верхнем уровне файла, рядом сmcpServers.
После правки выйдите из приложения полностью (Cmd+Q на macOS, выход из
трея на Windows) — просто закрыть окно недостаточно — и запустите заново.
Если видите ошибку про OAuth — почините конфиг и удалите кэш авторизации
mcp-remote, иначе он продолжит ходить в OAuth по старой памяти:
rm -rf ~/.mcp-auth (Windows — каталог %USERPROFILE%\.mcp-auth), затем
перезапустите Claude Desktop.
Осознайте компромисс.
mcp-remote— сторонний npm-пакет, не продукт Anthropic, и ваш токен идёт через него. Мы фиксируем версию, но для Claude Desktop всё равно разумно завести отдельный токен и по возможности read-only. Нормальное решение — OAuth, которого у сервера пока нет.
Любой клиент, поддерживающий Streamable HTTP MCP-транспорт с кастомными заголовками, подключается так же:
- URL:
https://knowledgebase.dodois.io/mcp - Заголовок
Authorization: Bearer <MCP_TOKEN>— обязателен - Заголовок
Mcp-Mode: Write— опционален, включает запись - Заголовок
Mcp-Write-Spaces— опционален, сужает запись до конкретных пространств (см. раздел 4)
Если у клиента есть проектный конфиг — используйте его, а не глобальный. Если клиент не умеет задавать кастомные HTTP-заголовки для удалённых серверов — подключение к этому MCP-серверу для вас недоступно, обратитесь в команду Базы Знаний.
Проверяет сам клиент — ни curl, ни чтения конфига для этого не нужно.
Перезапустите клиент (конфиг читается при старте) и посмотрите статус:
- Claude Code — команда
/mcpв сессии:knowledgebaseдолжен быть в списке как connected, с инструментами. - GitHub Copilot CLI — там же,
/mcpв сессии. - Cursor — Settings → Tools & Integrations → MCP Tools: у сервера зелёная точка и список инструментов.
- VS Code — прямо в
.vscode/mcp.jsonнад блоком сервера появляется строка со статусом и кнопками Start / Stop / Restart; по Start редактор и спросит токен. - Windsurf, Claude Desktop — перезапустить приложение и открыть список MCP-серверов в настройках.
Если сервер не поднялся — почти всегда дело в токене: он неверный, ещё не
подставлен вместо <MCP_TOKEN> или отозван (раздел 1). Подставьте заново
и перезапустите клиент ещё раз.
В GitHub Copilot CLI это почти всегда означает не проблему транспорта, а
неверный или ещё не выданный токен: сервер отвечает 401 Unauthorized,
после чего клиент вместо явной ошибки авторизации пытается запустить
OAuth-флоу (discovery .well-known/oauth-authorization-server), которого
у этого MCP-сервера нет — и зависает в состоянии needs-auth. Проверьте
~/.copilot/logs/ на строки HTTP 401 / OAuth authentication failed и
убедитесь, что токен действительно выпущен и не отозван (раздел 1), и что он правильно
подставлен в заголовок Authorization: Bearer <MCP_TOKEN>.
Доступ к конкретным пространствам (можете ли вы читать/редактировать) — тот же самый, что и везде в Базе Знаний, и не зависит от того, каким способом вы подключились. Заголовки выше только сужают то, что и так разрешено вашему аккаунту, но никогда не расширяют его.