Skip to main content
Glama

zulipmcp

License: MIT Python 3.10+

Запускайте ИИ-агентов в Zulip в качестве ботов, которым можно писать через @mention, или подключайте их к любому MCP клиенту. Также работает как библиотека Python.

Быстрый старт

  1. Установите пакет:

    uv add zulipmcp --git https://github.com/windborne/zulipmcp.git
  2. Добавьте файл .zuliprc в корневую директорию вашего проекта с учетными данными вашего бота Zulip. Инструкции по созданию бота см. в разделе Add a bot or integration. Тип бота должен быть "generic".

  3. Добавьте MCP-сервер в ваш .mcp.json:

    {
      "mcpServers": {
        "zulip": {
          "command": "uv",
          "args": ["run", "python", "-m", "zulipmcp.mcp"]
        }
      }
    }
  4. Перезапустите ваш MCP-клиент. Инструменты Zulip должны стать доступны.

Требования

  • Python >=3.10, управляется с помощью uv

  • Файл .zuliprc для аутентификации в API Zulip (см. Быстрый старт)

Точки входа

Точка входа

Описание

uv run python -m zulipmcp.mcp

MCP-сервер для Claude Code / MCP-клиентов

uv run python -m zulipmcp.mcp --transport sse

MCP-сервер через SSE (для удаленных/веб-клиентов)

uv run python -m zulipmcp.listener

Прослушиватель: отслеживает @mentions, запускает сессии Claude Code

Использование библиотеки

zulipmcp также можно импортировать напрямую как библиотеку Python:

import zulipmcp

# Fetch and format recent messages
messages = zulipmcp.get_messages(hours_back=24, channels=["engineering"])
print(zulipmcp.format_messages(messages))

# Send a message
zulipmcp.send_message("engineering", "general", "Hello from Python!")

# Configure MCP hooks before starting the server
zulipmcp.configure(
    message_prefix=lambda: "[bot] ",
    on_session_end=lambda session: print(f"Session ended in #{session.stream}"),
)

Прослушиватель (Listener)

Опциональный модуль zulipmcp.listener отслеживает @mentions в Zulip и запускает по одной headless-сессии Claude Code на каждую пару (поток, тема). Это связующее звено между событиями Zulip и Claude Code — MCP-сервер обрабатывает все инструменты Zulip, а прослушиватель управляет только жизненным циклом.

# Minimal -- uses ./.zuliprc, ./.mcp.json (if present), and the bundled default prompt
uv run python -m zulipmcp.listener

# Full -- override MCP config and system prompt
uv run python -m zulipmcp.listener \
    --mcp-config .mcp.json \
    --system-prompt agent.md \
    --log-dir ./logs

# Pass flags through to Claude Code (everything after --)
uv run python -m zulipmcp.listener -- --strict-mcp-config --model opus

Флаги:

Флаг

По умолчанию

Описание

--zuliprc

./.zuliprc

Путь к .zuliprc (относительно текущей рабочей директории)

--mcp-config

./.mcp.json

Путь к .mcp.json для сессий Claude Code (используется только если файл существует)

--system-prompt

zulipmcp/default_system_prompt.md

Файл системного промпта (путь по умолчанию разрешается относительно listener.py, а не текущей рабочей директории)

--working-dir

.

Рабочая директория для запущенных сессий

--claude-command

claude

Имя или путь к бинарному файлу Claude CLI

--log-dir

./logs

Директория для файлов логов сессий

-- ...

(нет)

Все, что идет после --, передается в claude как есть

Для каждой сессии автоматически устанавливаются TRIGGER_MESSAGE_ID и SESSION_USER_EMAIL, чтобы set_context() привязывался к @mention, а хуки могли идентифицировать запрашивающего.

Прослушиватель намеренно сделан минималистичным (~230 строк). В нем отсутствуют ограничения параллелизма, изоляция рабочих пространств, сторожевые таймеры для зависших процессов и дашборды — добавьте их, когда они вам понадобятся.

Ключевые детали проектирования

Прослушивание сообщений

Инструмент listen использует API событий в реальном времени Zulip (long-polling) вместо повторяющихся вызовов GET /messages. При запуске он догоняет все сообщения, появившиеся после last_seen_message_id, при необходимости подписывает бота на поток, регистрирует суженную очередь событий для потока/темы, а затем выполняет long-polling через GET /events. Сервер блокируется до тех пор, пока не придет сообщение или не истечет ~90 секунд (heartbeat), что примерно в 30 раз эффективнее опроса каждые 2 секунды. Если очередь истекает (BAD_EVENT_QUEUE_ID), она автоматически перерегистрируется. Очередь удаляется в блоке finally при выходе.

Эмодзи robot_ear добавляется к последнему сообщению как визуальный индикатор во время прослушивания и удаляется, когда прослушивание останавливается. Пинги поддержания активности MCP отправляются через ctx.info() после каждого цикла long-polling.

Отсутствие пропущенных сообщений при ответе

Когда вызывается reply, он проверяет наличие новых сообщений перед отправкой. Если кто-то написал что-то, пока LLM «думала», эти сообщения извлекаются и возвращаются вместе с подтверждением «сообщение отправлено». Таким образом, LLM всегда видит то, что пропустила, и может соответствующим образом отреагировать. last_seen_message_id обновляется до самого нового значения — либо пропущенные сообщения, либо отправленное сообщение — чтобы ничего не потерялось.

Завершение сессии

Пользователи могут завершить сессию бота, отреагировав на любое сообщение бота настраиваемым эмодзи (по умолчанию: :stop_sign:). Проверка завершения выполняется как во время listen() (через события реакции), так и перед reply() (через опрос REST API), что покрывает состояние гонки, когда пользователь реагирует, пока бот занят работой. Настройте с помощью configure(dismiss_emoji={"stop_sign", "wave"}).

Фильтрация видимости бота

Темы, содержащие /nobots или /nb, полностью скрыты от бота. Сообщения, начинающиеся с /nobots или /nb, также отфильтровываются. Это позволяет людям вести приватные разговоры, которые бот не увидит.

Переменные окружения

Переменная

Описание

ZULIP_RC_PATH

Абсолютный путь к .zuliprc. Переопределяет значение по умолчанию (./.zuliprc в текущей директории).

TRIGGER_MESSAGE_ID

ID сообщения, которое инициировало сессию (например, @mention). Устанавливает якорь прослушивания, чтобы агент не пропустил сообщения после триггера.

SESSION_USER_EMAIL

Email человека, инициировавшего сессию. Сохраняется в SessionState для хуков.

SESSION_STREAM

Имя потока для автоматической инициализации сессии при запуске сервера (только для прямых вызовов run_server() — прослушиватель их не использует). Должны быть установлены и SESSION_STREAM, и SESSION_TOPIC; после этого агент может пропустить set_context().

SESSION_TOPIC

Тема для автоинициализации. Требует SESSION_STREAM.

BOT_ALLOWED_PRIVATE_STREAMS

Список разрешенных для чтения/отправки приватных потоков. Если не задано = нет доступа к приватным потокам. Принимает __ALL__, JSON-список или имена, разделенные запятыми.

BOT_ALLOWED_WRITE_STREAMS

Список разрешенных для отправки потоков. Если не задано = запись разрешена везде (обратная совместимость). Те же форматы, что и выше.

ZULIPMCP_CACHE_DIR

Переопределение директории кэша на диске (по умолчанию системная временная директория).

ZULIPMCP_LOG_DIR

Переопределение директории логов (по умолчанию /tmp/zulipmcp_logs).

Лицензия

MIT

Install Server
A
security – no known vulnerabilities
A
license - permissive license
A
quality - A tier

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/windborne/zulipmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server