ZulipChat MCP: Connect AI to Zulip with 60+ tools for messaging, streams, events, and analytics
Runs on your machine from its package; the steps are below.
At most: moves money, runs code or commands, deletes data, or sends messages for you.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
uvx zulipchat-mcp
MCP client config
{
"mcpServers": {
"zulipchat-mcp-server": {
"command": "uvx",
"args": [
"zulipchat-mcp"
]
}
}
}Quick Start · Setup Wizard · Integrations · Two-Tier Tools · Contributing
uvx zulipchat-mcp --zulip-config-file ~/.zuliprc
Configure this command in your MCP client to let the assistant read and write Zulip messages with the configured account.
Need a zuliprc? Zulip Settings > Personal > Account & privacy > API key — download the file, save it as ~/.zuliprc.
Interactive onboarding:
uvx --from zulipchat-mcp zulipchat-mcp-setup
ZulipChat MCP bridges any MCP-compatible AI assistant (Claude Code, Gemini CLI, Cursor, Windsurf, etc.) to your Zulip workspace. The assistant can:
/reply for conversation. The server is the transport; it does not launch or supervise coding agents/approve REQUEST_ID or /deny REQUEST_ID in the session topic; each decision names the request it answers# Substitute another supported client as needed.
uvx --from zulipchat-mcp zulipchat-mcp-integrate export --client clio-coder \
--output-dir /absolute/path/to/project \
--zulip-config-file /absolute/path/to/.zuliprc --extended-tools
Exports support claude-code, codex, opencode, copilot, vscode,
antigravity-cli, clio-coder, and generic. Add --mode plugin for a package.
For several Zulip organizations, export once per organization with
--server-id zulipchat-<org>; exports merge into one host configuration.
Account state lives under ~/.local/state/zulipchat-mcp/. Host trust remains explicit;
Clio configures MCP execution separately from plugin content. See the
capability matrix,
Clio guide, and
complete workflow.
For read-only access, add --tool-profile read-only: discovery and execution
both expose nine core reads or 23 extended reads. The default full profile
retains 20/60 tools. See API coverage and efficiency
for cache freshness, rate limits and the boundary between message transport and
host execution. The live Luna experiment
records normal mention-to-bot replies from a real Clio TUI driven by a private,
unshipped host adapter. Other hosts were tested through exported configuration
and fake-credential checks, not live sessions.
v0.6.0 introduced a deliberate split: 20 core tools by default, 60 tools when you need more.
The 20 tools that cover most daily use:
| Category | Tools |
|---|---|
| Messaging | send_message, edit_message, get_message, add_reaction |
| Search | search_messages, get_streams, get_stream_info, get_stream_topics |
| Users | resolve_user, get_users, get_own_user |
| Agent Comms | teleport_chat, register_agent, ensure_agent_session, agent_message, request_user_input, wait_for_response |
| System | switch_identity, server_info, manage_message_flags |
Why 20 instead of 60? Fewer tools means faster tool selection, lower token overhead, and less confusion for the AI. Most tasks — sending messages, searching, reacting, and binding an agent session to Zulip — only need the core set.
Need scheduled messages, event queues, file uploads, analytics, or advanced search?
uvx zulipchat-mcp --zulip-config-file ~/.zuliprc --extended-tools
Or via environment variable:
ZULIPCHAT_EXTENDED_TOOLS=1 uvx zulipchat-mcp --zulip-config-file ~/.zuliprc
Extended mode adds: toggle_reaction, cross_post_message, advanced_search, construct_narrow, get_scheduled_messages, manage_scheduled_message, get_drafts, create_draft, edit_draft, delete_draft, register_events, get_events, listen_events, upload_file, manage_files, get_daily_summary, manage_user_mute, get_user, get_presence, get_user_groups, and more.
Full per-client setup guide: docs/integrations/README.md
claude mcp add zulipchat -- uvx zulipchat-mcp --zulip-config-file ~/.zuliprc
With dual identity (you + a bot):
claude mcp add zulipchat -- uvx zulipchat-mcp \
--zulip-config-file ~/.zuliprc \
--zulip-bot-config-file ~/.zuliprc-bot
Optional Claude hook bridge for lifecycle and approval routing:
uvx --from zulipchat-mcp zulipchat-mcp-hook \
--zulip-config-file ~/.zuliprc \
--zulip-bot-config-file ~/.zuliprc-bot
Optional Claude package export for project-local hooks, skills, and subagents:
uvx --from zulipchat-mcp zulipchat-mcp-integrate export \
--client claude-code \
--mode standalone \
--output-dir . \
--zulip-config-file ~/.zuliprc \
--zulip-bot-config-file ~/.zuliprc-bot
Add to ~/.gemini/settings.json under mcpServers:
{
"zulipchat": {
"command": "uvx",
"args": ["zulipchat-mcp", "--zulip-config-file", "/path/to/.zuliprc"]
}
}
Add to your MCP configuration:
{
"mcpServers": {
"zulipchat": {
"command": "uvx",
"args": ["zulipchat-mcp", "--zulip-config-file", "/path/to/.zuliprc"]
}
}
}
| Option | Description |
|---|---|
--zulip-config-file PATH | Path to your zuliprc file |
--zulip-bot-config-file PATH | Bot zuliprc for dual identity |
--extended-tools | Register all 60 tools instead of the 20-tool core set |
--tool-profile {full,read-only} | Filter discovery and enforce read-only Zulip calls; default: full |
--transport {stdio,http} | Transport to serve on (default: stdio) |
--host HOST | Bind host for HTTP transport (default: 127.0.0.1) |
--port PORT | Bind port for HTTP transport (default: 8000) |
--auth-token TOKEN | Bearer auth token for HTTP transport (or ZULIPCHAT_HTTP_AUTH_TOKEN) |
--allowed-host HOST | Additional trusted HTTP hostname; repeat for multiple names |
--allowed-origin URL | Additional trusted browser origin; repeat for multiple origins |
--unsafe | Enable administrative tools (use with caution) |
--debug | Enable debug logging |
--associate-existing-db | Deliberately associate an unbound legacy database with the verified current account |
ZulipChat MCP supports stateless HTTP deployments under the MCP 2026-07-28 protocol:
# Run server over HTTP with bearer authentication
ZULIPCHAT_HTTP_AUTH_TOKEN=your-secret-token \
uvx zulipchat-mcp --zulip-config-file ~/.zuliprc --transport http --host 0.0.0.0 --port 8000 --allowed-host mcp.internal
Generate client integration snippets for remote HTTP connections:
uvx --from zulipchat-mcp zulipchat-mcp-integrate print --client claude-code --remote-url http://mcp.internal:8000/mcp --remote-token your-secret-token
HTTP startup requires a bearer token for non-loopback binds and validates Host and Origin headers. Configure --allowed-host for the hostname used by clients or a reverse proxy; terminate TLS at the proxy for remote connections. A token grants access to the configured Zulip account: deploy a separate instance per trusted account, rather than sharing it across unrelated users.
HTTP tools reject server-local file paths, outbound event callbacks, and switch_identity. Upload text with file_content or binary bytes with file_content_base64; download without download_path to obtain a URL. Use stdio for local file operations and runtime identity switching. Attachment deletion requires --unsafe.
Persistent state defaults to an account-scoped directory. An explicitly selected
ZULIPCHAT_DB_PATH is associated with the normalized realm and user/bot
principals; a different account cannot reuse it. Legacy state is left intact and
requires deliberate association. See database migration.
Agent sessions, approvals, listener cursors, and default background-task storage remain local state. Use a single instance for these workflows. Separate DuckDB paths avoid writer conflicts but do not share session data; ordinary round-robin routing across such replicas is not supported. Legacy HTTP clients may also retain transport sessions.
AI-powered analytics tools (analyze_stream_with_llm, analyze_team_activity_with_llm, intelligent_report_generator) execute using a server-side Anthropic LLM provider:
ANTHROPIC_API_KEY on the server process for LLM generation.ANTHROPIC_MODEL to override the default model (claude-opus-5).llm_unavailable: true so your client assistant can analyze the data directly.Dedicated setup pages:
Configure both a user and a bot zuliprc to let your assistant switch between identities mid-session:
uvx zulipchat-mcp \
--zulip-config-file ~/.zuliprc \
--zulip-bot-config-file ~/.zuliprc-bot
The assistant posts as you by default. Call switch_identity to post as the bot — useful for automated notifications, agent-to-agent communication, or keeping human vs. bot messages distinct.
"Catch me up on what happened in #engineering today"
→ Assistant calls search_messages with stream + time filter, summarizes the thread.
"Tell the team we're deploying at 3pm"
→ Assistant calls send_message to #engineering with the announcement.
"Who sent that message about the API migration?"
→ Assistant calls search_messages with keywords, returns sender and context.
"React with :thumbs_up: to Sarah's last message"
→ Assistant calls resolve_user ("Sarah"), search_messages (sender), then add_reaction.
"DM Jaime that the PR is ready"
→ Assistant calls teleport_chat with fuzzy name resolution — no email needed.
git clone https://github.com/akougkas/zulipchat-mcp.git
cd zulipchat-mcp
uv sync
uv run zulipchat-mcp --zulip-config-file ~/.zuliprc
Run checks:
uv run pytest -q # full test suite, 60% coverage gate
uv run ruff check . # Linting
uv run mypy src # Type checking
For packaging, dependency, FastMCP, or startup changes, run the release smoke:
uv build
scripts/pre_release_smoke.sh --version X.Y.Z --allow-dirty
See CONTRIBUTING.md for the full guide, and CLAUDE.md / AGENTS.md for AI agent instructions.
src/zulipchat_mcp/
├── core/ # Client wrapper, identity, caching, security
├── tools/ # MCP tool implementations (two-tier registration)
├── services/ # Background listener and session event routing
├── utils/ # Logging, DuckDB persistence, metrics
└── config.py # config loading (zuliprc + environment fallback)
Built on FastMCP with async-first design, DuckDB for agent state persistence, and smart user/stream caching for fast fuzzy resolution.
Full policy: PRIVACY.md
MIT — See LICENSE