# Свои модельные серверы

> Запускайте агентов Claude Code, Codex CLI или OpenCode в nsq на своём модельном сервере — llama.cpp, Ollama, LM Studio, vLLM, SGLang, Unsloth Studio или любом API, совместимом с OpenAI или Anthropic.

Source: https://docs.neurosquad.ai/ru/cli/providers

Кроме [OpenRouter](https://docs.neurosquad.ai/ru/cli/openrouter), агент может работать на вашем собственном сервере: локальном —
**llama.cpp**, **Ollama**, **LM Studio**, **vLLM**, **SGLang**, **Unsloth Studio** — или на любом
удалённом API, который говорит на API **OpenAI** (chat completions или responses) или на Messages API
**Anthropic**. Для каждого агента отдельно, не трогая собственные настройки и логины CLI.

## Добавьте сервер

```sh
nsq provider add lmstudio --url http://localhost:1234
nsq provider add box --url http://192.168.1.20:8000 --ask-key     # спросит ключ, не показывая его
echo "$KEY" | nsq provider add work --url https://llm.example.com/v1 --key-stdin
```

`add` проверяет сервер, прежде чем что-то сохранить: запрашивает список моделей (`GET /v1/models`) и
выясняет, какие эндпоинты у сервера есть — OpenAI `POST /v1/chat/completions`, OpenAI
`POST /v1/responses`, Anthropic `POST /v1/messages`. API выбирать не нужно: сервер предлагается тому
CLI, для которого есть нужный ему эндпоинт, и `add` печатает, каким именно:

```text
added lmstudio: localhost:1234 — 12 models, endpoints: chat, responses, messages (9 ms)
  Claude Code  yes
  Codex        yes
  OpenCode     yes (chat completions)
```

Адрес можно вставить с `/v1` или без (и даже целиком `…/v1/chat/completions`); у сервера по
вложенному пути путь сохраняется (`https://api.example.com/anthropic`). Без схемы локальный адрес
получает `http://`, а любой другой — `https://`.

```sh
nsq provider list                    # адрес, эндпоинты, модели, сохранён ли ключ
nsq provider models lmstudio [qwen]  # модели сервера сейчас (и окно контекста, с которым он их отдаёт)
nsq provider test lmstudio           # проверить снова: новые модели, обновлённый сервер
nsq provider test lmstudio --ask-key # …с новым ключом (--clear-key его забывает)
nsq provider remove lmstudio
```

## Запустите на нём агента

```sh
nsq run claude   --provider lmstudio --model qwen/qwen3-coder-30b
nsq run codex    --provider ollama   --model qwen3-coder:30b
nsq run opencode --provider vllm     --model Qwen/Qwen3-Coder-30B-A3B-Instruct
nsq set api-fix  --provider lmstudio --model qwen/qwen3-coder-30b   # перевести существующего агента
nsq set api-fix  --provider none --model none                       # обратно к логину самого CLI
```

Модель — id из списка самого сервера. Если у сервера одна модель, `--model` не нужен. Переведённый
агент перезапускается в той же сессии, как только освободится, — разговор сохраняется.

В дашборде: `c` (новый агент) → **Provider** — `←` `→` перебирают
_собственный логин_, _OpenRouter_ и каждый ваш сервер, подходящий выбранному CLI (неподходящие
показаны с причиной), — а `F2` показывает модели этого сервера. `m` на агенте
показывает модели его сервера. `P` открывает экран провайдеров: `a` добавляет
сервер (`F2` подставляет адреса по умолчанию из таблицы ниже, поле ключа скрыто),
`t` проверяет сервер снова, `Enter` показывает его модели, `x` удаляет.

## Какой CLI какой API использует

| CLI | Использует |
| --- | --- |
| Claude Code | Только Anthropic Messages (`/v1/messages`) — сервер без него не предлагается |
| Codex | OpenAI Responses (`/v1/responses`); на сервере только с chat completions nsq запускает локальный шлюз, который переводит Responses ⇄ chat completions (ключ остаётся у nsq, Codex его не видит) |
| OpenCode | OpenAI chat completions (`@ai-sdk/openai-compatible`) или Anthropic Messages API, если у сервера нет chat-эндпоинта (`@ai-sdk/anthropic`) |

Сервер, у которого есть только `/v1/responses`, тоже принимается; его предлагают только Codex.

## Серверы

Что каждый сервер отдаёт сегодня — по его собственной документации (проверено в октябре 2026); для
вашей версии всё решает проверка подключения:

| Сервер | Адрес по умолчанию | Chat completions | Responses | Anthropic messages | Окно контекста в списке моделей | Ключ по умолчанию |
| --- | --- | --- | --- | --- | --- | --- |
| llama.cpp (`llama-server`) | `http://127.0.0.1:8080` (`:9931` начиная со сборки b11521, октябрь 2026) | да | да | да | `meta.n_ctx` | нет (`--api-key`) |
| Ollama | `http://localhost:11434` | да | да (0.13.3+) | да (0.14.0+) | не указано | нет |
| LM Studio | `http://localhost:1234` | да | да (0.3.29+) | да (0.4.1+) | не указано | нет (необязательные API-токены, 0.4.0+) |
| vLLM (`vllm serve`) | `http://localhost:8000` | да | да (0.10.0+) | да (0.11.1+) | `max_model_len` | нет (`--api-key`) |
| SGLang | `http://localhost:30000` | да | да | да (0.5.9+) | `max_model_len` | нет (`--api-key`) |
| Unsloth Studio | `http://localhost:8888` | да | да | да | `context_length` | **да** (`sk-unsloth-…`) |

То есть с актуальной версией любого из них все три CLI работают напрямую. Проверено от начала до
конца с настоящими CLI на llama.cpp (`llama-server` b11524): Claude Code — на `/v1/messages`,
Codex — на `/v1/responses` и через шлюз на `/v1/chat/completions`, OpenCode — на
`/v1/chat/completions`. Для вызовов инструментов llama.cpp нужен `--jinja`.

**Окно контекста.** Если список моделей сервера сообщает, с каким контекстом он отдаёт модель, об
этом узнаёт каждый CLI — Claude Code (`CLAUDE_CODE_MAX_CONTEXT_TOKENS`), Codex
(`model_context_window`, сжатие на 85 %), OpenCode (`limit.context` модели), — так что длинная сессия
сжимается до того, как окно сервера заполнится, а не падает. Агентные CLI шлют длинные промпты (у
одного Claude Code — заметно больше 10 000 токенов): запускайте сервер с достаточно большим
контекстом (`llama-server -c 32768`, `OLLAMA_CONTEXT_LENGTH` у Ollama, настройка длины контекста в LM
Studio).

## Что происходит с ключом

- Ключ необязателен (локальным серверам он не нужен). Его спрашивают без отображения (`--ask-key`)
или читают из stdin (`--key-stdin`) — **никогда** не аргументом командной строки, который может
прочитать любой процесс на машине; `--key <значение>` отклоняется.
- Он хранится в хранилище секретов ОС (диспетчер учётных данных Windows, Связка ключей macOS,
Secret Service в Linux). Если хранилища нет, задайте вместо этого `NSQ_PROVIDER_KEY_<NAME>`
(например, `NSQ_PROVIDER_KEY_LMSTUDIO`) там, где стартует демон.
- Агент получает его только через своё окружение при запуске — никогда в argv, логах или файлах
nsq (`providers.json` хранит адрес, эндпоинты и список моделей, без секретов). Codex за шлюзом
получает вместо ключа отдельные учётные данные шлюза для этого агента.
- Обычный `http://` принимается только для этой машины и локальной сети (в сети — с
предупреждением: промпты, ваш код и ключ идут незашифрованными). Всё остальное — только
`https://`. Редиректам nsq не следует никогда — ключ ушёл бы туда, куда они указывают.
- Заголовок атрибуции OpenRouter вашим серверам не отправляется никогда.
- Если сервер удалён или у него больше нет нужного CLI эндпоинта, агент не запускается — он никогда
не откатывается на собственный логин CLI (это отправило бы ваш код в облако).
- Claude Code: адрес сервера и модель задаются ещё и в собственном слое настроек агента, а
`CLAUDE_CODE_USE_BEDROCK` / `_VERTEX` / `_FOUNDRY` выключаются — так что `ANTHROPIC_BASE_URL`,
`ANTHROPIC_AUTH_TOKEN` или облачный бэкенд в вашем окружении или `~/.claude/settings.json` не
уводят агента в другое место. Остальная конфигурация самих CLI (профиль Codex, плагины OpenCode)
— ваша, nsq её не проверяет.

## Стоимость

nsq не знает, сколько берёт ваш сервер: запросы к нему показываются в `nsq cost` и в дашборде как
**no price** («без цены»), никогда не $0 — даже если модель названа так же, как платная. Это касается и прежних запросов
агента, сделанных до перехода на сервер (nsq не может знать, какой сервер на них ответил).
