Skip to main content
Glama

zulipmcp

License: MIT Python 3.10+

Ejecuta agentes de IA en Zulip como bots que admiten @menciones, o conéctalos a cualquier cliente MCP. También funciona como una biblioteca de Python.

Inicio rápido

  1. Instala el paquete:

    uv add zulipmcp --git https://github.com/windborne/zulipmcp.git
  2. Añade un archivo .zuliprc a la raíz de tu proyecto con las credenciales de tu bot de Zulip. Consulta Añadir un bot o integración para obtener instrucciones sobre cómo crear un bot. El tipo de bot debe ser "generic".

  3. Añade el servidor MCP a tu .mcp.json:

    {
      "mcpServers": {
        "zulip": {
          "command": "uv",
          "args": ["run", "python", "-m", "zulipmcp.mcp"]
        }
      }
    }
  4. Reinicia tu cliente MCP. Las herramientas de Zulip deberían estar disponibles ahora.

Requisitos

  • Python >=3.10, gestionado con uv

  • Un archivo .zuliprc para la autenticación de la API de Zulip (consulta Inicio rápido)

Puntos de entrada

Punto de entrada

Descripción

uv run python -m zulipmcp.mcp

Servidor MCP para Claude Code / clientes MCP

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

Servidor MCP sobre SSE (para clientes remotos/web)

uv run python -m zulipmcp.listener

Listener: observa @menciones, inicia sesiones de Claude Code

Uso de la biblioteca

zulipmcp también se puede importar directamente como una biblioteca de 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

El módulo opcional zulipmcp.listener observa Zulip en busca de @menciones e inicia una sesión de Claude Code sin interfaz por cada (stream, topic). Es el pegamento entre los eventos de Zulip y Claude Code: el servidor MCP maneja todas las herramientas de Zulip, el listener solo maneja el ciclo de vida.

# 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

Flags:

Flag

Predeterminado

Descripción

--zuliprc

./.zuliprc

Ruta al archivo .zuliprc (resuelta en relación con el directorio de trabajo actual)

--mcp-config

./.mcp.json

Ruta al archivo .mcp.json para sesiones de Claude Code (usado solo si el archivo existe)

--system-prompt

zulipmcp/default_system_prompt.md

Archivo de prompt del sistema adjunto (la ruta predeterminada se resuelve en relación con listener.py, no con el directorio de trabajo actual)

--working-dir

.

Directorio de trabajo para las sesiones iniciadas

--claude-command

claude

Nombre o ruta del binario de la CLI de Claude

--log-dir

./logs

Directorio para los archivos de registro de sesión

-- ...

(ninguno)

Todo lo que sigue a -- se reenvía a claude tal cual

Cada sesión tiene TRIGGER_MESSAGE_ID y SESSION_USER_EMAIL configurados automáticamente para que set_context() se ancle a la @mención y los hooks puedan identificar al solicitante.

El listener es deliberadamente minimalista (~230 líneas). Omite límites de concurrencia, aislamiento de espacio de trabajo, vigilantes de inactividad y paneles de control; añádelos cuando los necesites.

Detalles clave de diseño

Escucha de mensajes

La herramienta listen utiliza la API de eventos en tiempo real de Zulip (long-polling) en lugar de llamadas repetidas a GET /messages. Al entrar, se pone al día con cualquier mensaje desde last_seen_message_id, suscribe al bot al stream si es necesario, registra una cola de eventos restringida para el stream/topic y luego realiza long-polling a través de GET /events. El servidor se bloquea hasta que llega un mensaje o transcurren ~90 segundos (latido), lo que hace que esto sea ~30 veces más eficiente que consultar cada 2 segundos. Si la cola expira (BAD_EVENT_QUEUE_ID), se vuelve a registrar automáticamente. La cola se elimina en un bloque finally al salir.

Se añade un emoji robot_ear al último mensaje como indicador visual mientras se escucha y se elimina cuando la escucha se detiene. Los pings de mantenimiento de MCP se envían a través de ctx.info() después de cada ciclo de long-polling.

Sin mensajes perdidos al responder

Cuando se llama a reply, se comprueban nuevos mensajes antes de enviar. Si alguien publicó mientras el LLM estaba pensando, esos mensajes se recuperan y se devuelven junto con la confirmación de "mensaje enviado". De esta forma, el LLM siempre ve lo que se perdió y puede reaccionar en consecuencia. El last_seen_message_id se actualiza al más reciente (los mensajes perdidos o el mensaje enviado) para que nada se pase por alto.

Descarte de sesión

Los usuarios pueden descartar una sesión de bot reaccionando con un emoji configurable (predeterminado: :stop_sign:) en cualquier mensaje del bot. La comprobación de descarte se ejecuta tanto durante listen() (a través de eventos de reacción) como antes de reply() (a través de sondeo de la API REST), cubriendo la condición de carrera donde un usuario reacciona mientras el bot está ocupado trabajando. Personaliza con configure(dismiss_emoji={"stop_sign", "wave"}).

Filtrado de visibilidad del bot

Los temas que contienen /nobots o /nb están ocultos para el bot por completo. Los mensajes que comienzan con /nobots o /nb también se filtran. Esto permite a los humanos tener conversaciones privadas que el bot no verá.

Variables de entorno

Variable

Descripción

ZULIP_RC_PATH

Ruta absoluta a .zuliprc. Sobrescribe el predeterminado (./.zuliprc en el directorio de trabajo actual).

TRIGGER_MESSAGE_ID

ID del mensaje que activó la sesión (p. ej., la @mención). Establece el ancla de escucha para que el agente no pierda mensajes después del activador.

SESSION_USER_EMAIL

Correo electrónico del humano que activó la sesión. Almacenado en SessionState para los hooks

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