Локальный OpenAI/Anthropic-compatible прокси для бесплатных web-аккаунтов GLM/Z.ai и Kimi
Ватермарка: t.me/forgetmeai
FreeGLMKimiAPI превращает web-чаты GLM/Z.ai, старый chatglm.cn и Kimi в локальный API, который понимают OpenAI SDK, Claude Code, OpenCode, OpenClaw, Hermes Agent и другие агентные клиенты.
По духу это похоже на FreeQwenApi / FreeDeepseekAPI, но проект сделан отдельно и дополнительно умеет эмулировать tool use для AI-агентов.
⚠️ Это не официальный API. Используй для личных экспериментов, локальных агентов и тестов. Не публикуй токены и не открывай сервис наружу безAPI_KEYS.
- Коротко: что это даёт
- Возможности
- Быстрый старт
- Модели
- Как добавить аккаунты
- Как получить токены
- Примеры запросов
- Tool use для агентов
- Диагностика
- Ограничения
- Полезные ссылки
| Было | Стало |
|---|---|
| Web-чат GLM/Z.ai или Kimi только в браузере | Локальный API на http://127.0.0.1:9766 |
| Нельзя просто подключить агентный клиент | Можно использовать OpenAI/Anthropic-compatible клиенты |
| У web-моделей нет нормального function calling | Прокси эмулирует tool_calls через prompt-протокол |
| Несколько аккаунтов приходится переключать руками | Есть auth.json, round-robin и cooldown после ошибок |
| Anti-bot у Z.ai ломает прямые запросы | Есть browser fallback и опциональный CloakBrowser |
POST /v1/chat/completions— чат в формате OpenAI, обычный и streaming.POST /v1/messages— минимальная прослойка Anthropic Messages API для Claude Code и похожих клиентов.GET /v1/models— список моделей.GET /health— проверка состояния.GET /sessions— просмотр закреплённых сессий.
- GLM / Z.ai через актуальный
chat.z.ai. - Старый GLM через
chatglm.cnиGLM_BACKEND=chatglm. - Kimi через gRPC-Web endpoint
kimi.com.
- Эмуляция OpenAI
tools/ function calling. - Парсинг
[function_calls], JSON, XML-подобного формата и старогоTOOL_CALL. - Ответы с
tool_calls, совместимые с OpenAI. - Закреплённые сессии по
user/ ID агента. - Локальные мок-тесты без живых токенов через
MOCK_PROVIDER=1.
auth.jsonс несколькими аккаунтами.- Round-robin между аккаунтами.
- Cooldown после ошибок провайдера.
- Admin API для добавления аккаунтов без рестарта.
git clone https://github.com/ForgetMeAI/FreeGLMKimiAPI.git
cd FreeGLMKimiAPI
npm install
cp .env.example .env
npm testЗапуск без реальных токенов, чтобы проверить API-обвязку:
MOCK_PROVIDER=1 PORT=9766 npm startПроверка:
curl http://127.0.0.1:9766/health
curl http://127.0.0.1:9766/v1/models
node scripts/smoke.jsglm-5glm-5-thinkingglm-5-searchglm-5-deepresearch
kimi-k2.5kimi-k2.5-thinkingkimi-k2.5-search
Провайдер выбирается по имени модели:
glm* → GLM / Z.ai
kimi* → Kimi
По умолчанию:
DEFAULT_PROVIDER=kimi
DEFAULT_MODEL=kimi-k2.5Токены — это секреты уровня пароля. Не коммить auth.json, не публикуй токены и не открывай сервис наружу без API_KEYS.
Создай auth.json рядом с проектом:
{
"accounts": [
{ "id": "zai1", "provider": "glm", "token": "PASTE_ZAI_TOKEN_HERE" },
{ "id": "glm-cn1", "provider": "glm", "backend": "chatglm", "refresh_token": "PASTE_CHATGLM_REFRESH_TOKEN_HERE" },
{ "id": "kimi1", "provider": "kimi", "token": "PASTE_KIMI_TOKEN_HERE" }
]
}И запусти:
npm startМожно указать другой путь:
AUTH_PATH=/path/to/auth.json npm start# Kimi
KIMI_TOKEN=PASTE_KIMI_TOKEN_HERE
# GLM через Z.ai
GLM_BACKEND=zai
GLM_TOKEN=PASTE_ZAI_TOKEN_HERE
# Старый GLM через chatglm.cn
# GLM_BACKEND=chatglm
# GLM_REFRESH_TOKEN=PASTE_CHATGLM_REFRESH_TOKEN_HEREЕсли API_KEYS задан, admin-запросы тоже требуют HTTP-заголовок авторизации с твоим API key.
# список аккаунтов без секретов
curl http://127.0.0.1:9766/admin/accounts
# добавить Kimi временно, без записи в auth.json
curl -X POST http://127.0.0.1:9766/admin/accounts \
-H 'Content-Type: application/json' \
-d '{"id":"kimi2","provider":"kimi","token":"KIMI_TOKEN_HERE","persist":false}'
# добавить GLM/Z.ai и сохранить в auth.json
curl -X POST http://127.0.0.1:9766/admin/accounts \
-H 'Content-Type: application/json' \
-d '{"id":"zai2","provider":"glm","token":"ZAI_TOKEN_HERE","persist":true}'
# перечитать auth.json
curl -X POST http://127.0.0.1:9766/admin/accounts/reload -d '{}'Это самый простой путь для GLM. Скрипт сам откроет видимый браузер, дождётся логина, вытащит токен и сохранит auth.json.
cd FreeGLMKimiAPI
npm run auth:browser -- ./auth.jsonЧто делать дальше:
- Откроется окно браузера с
chat.z.ai. - Войди в свой аккаунт.
- Если появится проверка/captcha — пройди её руками.
- Отправь в чате короткое сообщение, например
hi. - Вернись в терминал и дождись, пока скрипт сохранит
auth.json.
Проверка:
ZAI_BROWSER_FALLBACK=1 MODEL=GLM-5.1 npm run smoke:zaiЗапуск сервера через этот профиль:
ZAI_BROWSER_FALLBACK=1 MODEL=GLM-5.1 npm startВажно:
- профиль браузера переиспользуется, поэтому логин не нужен каждый раз;
- если Z.ai снова просит проверку — повтори
npm run auth:browser -- ./auth.jsonи пройди её в том же окне; - скрипт игнорирует временные guest-токены вида
guest-...@guest.comи ждёт реальный аккаунт; - если обычный browser fallback упирается в anti-bot, можно попробовать CloakBrowser:
ZAI_BROWSER_ENGINE=cloak \
ZAI_BROWSER_FALLBACK=1 \
ZAI_BROWSER_HEADLESS=0 \
ZAI_BROWSER_HUMANIZE=1 \
MODEL=GLM-5.1 npm run smoke:zaiПолезные переменные:
ZAI_BROWSER_FALLBACK=1
ZAI_BROWSER_ENGINE=puppeteer # или cloak
ZAI_BROWSER_PROFILE_DIR=~/.free-glm-kimi-api/zai-browser-profile
ZAI_BROWSER_PROXY=http://user:pass@host:port
ZAI_BROWSER_LOCALE=ru-RU
ZAI_BROWSER_TIMEZONE=Europe/SamaraЕсли браузерный скрипт не сработал, можно скопировать токен руками.
Простой вариант через Application:
- Открой
https://chat.z.ai/и залогинься. - Открой DevTools:
F12илиCmd+Option+I. - Перейди в Application.
- Проверь:
- Local Storage →
https://chat.z.ai→ ключtoken; - Cookies →
chat.z.ai→ cookietoken.
- Local Storage →
- Скопируй только значение токена, без
Bearerи безtoken=. - Вставь в
auth.json:
{
"accounts": [
{ "id": "zai1", "provider": "glm", "token": "PASTE_ZAI_TOKEN_HERE" }
]
}Если Z.ai требует captcha/anti-bot, одного JWT может быть мало. Тогда проще вернуться к browser fallback. Для диагностики можно добавить cookie и captcha-параметр:
{
"accounts": [
{
"id": "zai1",
"provider": "glm",
"token": "PASTE_ZAI_TOKEN_HERE",
"cookie": "cdn_sec_tc=...; acw_tc=...; ssxmod_itna=...; token=...",
"captcha_verify_param": "PASTE_BASE64_CAPTCHA_VERIFY_PARAM_HERE"
}
]
}Это отдельный старый бэкенд. Токен от chat.z.ai сюда не подходит.
Нужно получить именно refresh token от chatglm.cn:
- Открой
https://chatglm.cn/и залогинься. - Открой DevTools → Application.
- Проверь Local Storage / Cookies для
chatglm.cn. - Ищи
chatglm_refresh_token,refresh_tokenили похожий refresh token. - Если не нашёл — DevTools → Network, отправь сообщение и найди запросы:
/user-api/user/refresh;/backend-api/assistant/stream.
- В заголовке
Authorizationскопируй только значение после словаBearer.
Формат:
{
"accounts": [
{
"id": "glm-cn1",
"provider": "glm",
"backend": "chatglm",
"refresh_token": "PASTE_CHATGLM_REFRESH_TOKEN_HERE"
}
]
}Запуск:
GLM_BACKEND=chatglm npm startПроверка:
MODEL=glm-5 node scripts/smoke.jsЕсли видишь 40102 unauthorized user, значит токен не от chatglm.cn, протух или скопирован не полностью.
Kimi использует Bearer/access JWT из kimi.com.
Самый надёжный способ:
- Открой
https://www.kimi.com/и залогинься. - DevTools → Network.
- В фильтре введи
ChatService/Chatилиkimi.gateway.chat. - Отправь короткое сообщение в Kimi.
- Открой запрос к
/apiv2/kimi.gateway.chat.v1.ChatService/Chat. - В Request Headers найди заголовок
Authorization. - Скопируй только часть после
Bearer.
Формат:
{
"accounts": [
{ "id": "kimi1", "provider": "kimi", "token": "PASTE_KIMI_BEARER_TOKEN_HERE" }
]
}Или через .env:
KIMI_TOKEN=PASTE_KIMI_BEARER_TOKEN_HEREЕсли получил 401 / auth.token.invalid, обнови страницу Kimi, отправь новое сообщение и скопируй свежий Bearer.
Чтобы README не превращался в простыню, подробные примеры вынесены отдельно:
Там есть:
- health/models;
- обычный
/v1/chat/completions; - потоковый режим;
- smoke-тест GLM;
- OpenAI tools / function calling;
/v1/messagesв формате Anthropic;- Claude Code;
- OpenCode;
- OpenClaw;
- локальные smoke-тесты агентов.
Минимальный запрос:
curl http://127.0.0.1:9766/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "kimi-k2.5",
"messages": [
{"role": "user", "content": "Ответь одной фразой: привет"}
]
}'Клиент отправляет обычные OpenAI tools. Если web-модель отвечает протокольным текстом, прокси превращает его в tool_calls, совместимые с OpenAI:
{
"choices": [
{
"message": {
"role": "assistant",
"content": null,
"tool_calls": []
},
"finish_reason": "tool_calls"
}
]
}Локальные protocol-level smoke-тесты агентов без реальных токенов:
MOCK_PROVIDER=1 PORT=9766 npm start
npm run agent:allОтдельно:
npm run agent:hermes
npm run agent:claude
npm run agent:opencode
npm run agent:openclawnpm test
node scripts/doctor.js
curl http://127.0.0.1:9766/health
curl http://127.0.0.1:9766/admin/accountsРеальный smoke-тест Z.ai:
ZAI_BROWSER_FALLBACK=1 MODEL=GLM-5.1 npm run smoke:zaiИмпорт успешного browser curl для диагностики Z.ai:
pbpaste | node scripts/import_zai_curl.js /dev/stdin /tmp/freeglm-auth.json
AUTH_PATH=/tmp/freeglm-auth.json MODEL=GLM-5.1 npm run smoke:zaiСкрипты печатают только статус и наличие полей, сами секреты не выводят.
- Это не официальный API. Web API GLM/Z.ai/Kimi могут меняться.
- Для настоящего E2E нужны живые web-токены.
- Z.ai может требовать captcha/anti-bot cookies; тогда лучше использовать browser fallback.
chat.z.aiиchatglm.cn— разные бэкенды, токены между ними не взаимозаменяемы.- Tool use — эмуляция через prompt-протокол, а не нативный function calling web-модели.
- Реализация сверялась по Chat2API и покрыта локальными мок-тестами, но upstream может сломаться после очередного обновления фронта.
- Подробные запросы: docs/request-examples.md
- Заметки по CloakBrowser: docs/cloakbrowser-notes.md
- Канал с практическими AI-разборами: t.me/forgetmeai
Сделано для практических экспериментов с AI-агентами
t.me/forgetmeai