{
  "markdown": "# ZulipChat MCP Server\n\n<div align=\"center\">\n\n  <h3>Model Context Protocol server for Zulip Chat. Connect Claude Code, Gemini CLI, Codex, Cursor, Windsurf, VS Code Copilot, and other MCP clients to Zulip.</h3>\n\n  [![PyPI](https://img.shields.io/pypi/v/zulipchat-mcp)](https://pypi.org/project/zulipchat-mcp/)\n  [![CI](https://github.com/akougkas/zulipchat-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/akougkas/zulipchat-mcp/actions/workflows/ci.yml)\n  [![Publish](https://github.com/akougkas/zulipchat-mcp/actions/workflows/publish.yml/badge.svg)](https://github.com/akougkas/zulipchat-mcp/actions/workflows/publish.yml)\n  [![Coverage Gate](https://img.shields.io/badge/coverage%20gate-60%25-blue)](https://github.com/akougkas/zulipchat-mcp/actions/workflows/ci.yml)\n  [![Downloads](https://img.shields.io/pypi/dm/zulipchat-mcp)](https://pypi.org/project/zulipchat-mcp/)\n  [![GitHub stars](https://img.shields.io/github/stars/akougkas/zulipchat-mcp)](https://github.com/akougkas/zulipchat-mcp/stargazers)\n  [![Python](https://img.shields.io/pypi/pyversions/zulipchat-mcp)](https://pypi.org/project/zulipchat-mcp/)\n  [![License](https://img.shields.io/github/license/akougkas/zulipchat-mcp)](LICENSE)\n  [![MCP](https://img.shields.io/badge/MCP-Compatible-blue)](https://modelcontextprotocol.io)\n\n  [Quick Start](#quick-start) · [Setup Wizard](docs/user-guide/setup-wizard.md) · [Integrations](docs/integrations/README.md) · [Two-Tier Tools](#two-tier-tool-architecture) · [Contributing](CONTRIBUTING.md)\n</div>\n\n---\n\n## Quick Start\n\n```bash\nuvx zulipchat-mcp --zulip-config-file ~/.zuliprc\n```\n\nThat's it. Your AI assistant can now read and write Zulip messages.\n\nNeed a zuliprc? **Zulip Settings > Personal > Account & privacy > API key** — download the file, save it as `~/.zuliprc`.\n\nInteractive onboarding:\n\n```bash\nuvx --from zulipchat-mcp zulipchat-mcp-setup\n```\n\n## What This Does\n\nZulipChat MCP bridges any MCP-compatible AI assistant (Claude Code, Gemini CLI, Cursor, Windsurf, etc.) to your Zulip workspace. The assistant can:\n\n- **Send and read messages** — stream messages, DMs, replies, reactions\n- **Search conversation history** — full-text search with filters for sender, stream, time range\n- **Resolve people by name** — \"message Jaime\" just works, no hunting for formal emails\n- **Switch identities** — post as yourself or as a bot, in the same session\n- **Monitor activity** — search recent messages, get stream info, check who's online\n- **Bind sessions to Zulip topics** — give long-running agent sessions a stable control topic\n- **Request approvals in-topic** — owner replies with `approve` / `deny` in the session topic\n\n## Two-Tier Tool Architecture\n\nv0.6.0 introduced a deliberate split: **20 core tools** by default, **60 tools** when you need more.\n\n### Core Mode (default)\n\nThe 20 tools that cover most daily use:\n\n| Category | Tools |\n|----------|-------|\n| **Messaging** | `send_message`, `edit_message`, `get_message`, `add_reaction` |\n| **Search** | `search_messages`, `get_streams`, `get_stream_info`, `get_stream_topics` |\n| **Users** | `resolve_user`, `get_users`, `get_own_user` |\n| **Agent Comms** | `teleport_chat`, `register_agent`, `ensure_agent_session`, `agent_message`, `request_user_input`, `wait_for_response` |\n| **System** | `switch_identity`, `server_info`, `manage_message_flags` |\n\nWhy 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.\n\n### Extended Mode\n\nNeed scheduled messages, event queues, file uploads, analytics, or advanced search?\n\n```bash\nuvx zulipchat-mcp --zulip-config-file ~/.zuliprc --extended-tools\n```\n\nOr via environment variable:\n```bash\nZULIPCHAT_EXTENDED_TOOLS=1 uvx zulipchat-mcp --zulip-config-file ~/.zuliprc\n```\n\nExtended 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.\n\n## Installation\n\nFull per-client setup guide: [docs/integrations/README.md](docs/integrations/README.md)\n\n### Claude Code\n\n```bash\nclaude mcp add zulipchat -- uvx zulipchat-mcp --zulip-config-file ~/.zuliprc\n```\n\nWith dual identity (you + a bot):\n```bash\nclaude mcp add zulipchat -- uvx zulipchat-mcp \\\n  --zulip-config-file ~/.zuliprc \\\n  --zulip-bot-config-file ~/.zuliprc-bot\n```\n\nOptional Claude hook bridge for lifecycle and approval routing:\n```bash\nuvx zulipchat-mcp-hook \\\n  --zulip-config-file ~/.zuliprc \\\n  --zulip-bot-config-file ~/.zuliprc-bot\n```\n\nOptional Claude package export for project-local hooks, skills, and subagents:\n```bash\nuvx zulipchat-mcp-integrate export \\\n  --client claude-code \\\n  --mode standalone \\\n  --output-dir . \\\n  --zulip-config-file ~/.zuliprc \\\n  --zulip-bot-config-file ~/.zuliprc-bot\n```\n\n### Gemini CLI\n\nAdd to `~/.gemini/settings.json` under `mcpServers`:\n\n```json\n{\n  \"zulipchat\": {\n    \"command\": \"uvx\",\n    \"args\": [\"zulipchat-mcp\", \"--zulip-config-file\", \"/path/to/.zuliprc\"]\n  }\n}\n```\n\n### Claude Desktop / Cursor / Any MCP Client\n\nAdd to your MCP configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"zulipchat\": {\n      \"command\": \"uvx\",\n      \"args\": [\"zulipchat-mcp\", \"--zulip-config-file\", \"/path/to/.zuliprc\"]\n    }\n  }\n}\n```\n\n### Configuration Options\n\n| Option | Description |\n|--------|-------------|\n| `--zulip-config-file PATH` | Path to your zuliprc file |\n| `--zulip-bot-config-file PATH` | Bot zuliprc for dual identity |\n| `--extended-tools` | Register all 60 tools instead of the 20-tool core set |\n| `--transport {stdio,http}` | Transport to serve on (default: `stdio`) |\n| `--host HOST` | Bind host for HTTP transport (default: `127.0.0.1`) |\n| `--port PORT` | Bind port for HTTP transport (default: `8000`) |\n| `--auth-token TOKEN` | Bearer auth token for HTTP transport (or `ZULIPCHAT_HTTP_AUTH_TOKEN`) |\n| `--unsafe` | Enable administrative tools (use with caution) |\n| `--debug` | Enable debug logging |\n\n### Remote HTTP Transport\n\nZulipChat MCP supports stateless HTTP deployments under the MCP 2026-07-28 protocol:\n\n```bash\n# Run server over HTTP with bearer authentication\nZULIPCHAT_HTTP_AUTH_TOKEN=your-secret-token \\\n  uvx zulipchat-mcp --zulip-config-file ~/.zuliprc --transport http --host 0.0.0.0 --port 8000\n```\n\nGenerate client integration snippets for remote HTTP connections:\n\n```bash\nuvx zulipchat-mcp-integrate print --client claude-code --remote-url http://mcp.internal:8000/mcp --remote-token your-secret-token\n```\n\n> **Note on Multi-Replica Deployments**: DuckDB state persistence is single-writer. When deploying multiple HTTP replicas, ensure each instance points to a distinct DuckDB path or run a single-instance deployment.\n\n### AI Analytics & LLM Provider\n\nAI-powered analytics tools (`analyze_stream_with_llm`, `analyze_team_activity_with_llm`, `intelligent_report_generator`) execute using a server-side Anthropic LLM provider:\n\n- Set `ANTHROPIC_API_KEY` on the server process for LLM generation.\n- Optionally set `ANTHROPIC_MODEL` to override the default model (`claude-opus-5`).\n- Without an API key, analytics tools return structured data summaries with `llm_unavailable: true` so your client assistant can analyze the data directly.\n\n### More clients\n\nDedicated setup pages:\n\n- [Gemini CLI](docs/integrations/gemini-cli.md)\n- [Codex](docs/integrations/codex.md)\n- [OpenCode](docs/integrations/opencode.md)\n- [VS Code + GitHub Copilot](docs/integrations/vscode-copilot.md)\n- [Cursor](docs/integrations/cursor.md)\n- [Windsurf](docs/integrations/windsurf.md)\n- [Antigravity](docs/integrations/antigravity.md)\n- [Generic MCP](docs/integrations/generic.md)\n\n## Dual Identity\n\nConfigure both a user and a bot zuliprc to let your assistant switch between identities mid-session:\n\n```bash\nuvx zulipchat-mcp \\\n  --zulip-config-file ~/.zuliprc \\\n  --zulip-bot-config-file ~/.zuliprc-bot\n```\n\nThe 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.\n\n## Real-World Examples\n\n**\"Catch me up on what happened in #engineering today\"**\n→ Assistant calls `search_messages` with stream + time filter, summarizes the thread.\n\n**\"Tell the team we're deploying at 3pm\"**\n→ Assistant calls `send_message` to #engineering with the announcement.\n\n**\"Who sent that message about the API migration?\"**\n→ Assistant calls `search_messages` with keywords, returns sender and context.\n\n**\"React with :thumbs_up: to Sarah's last message\"**\n→ Assistant calls `resolve_user` (\"Sarah\"), `search_messages` (sender), then `add_reaction`.\n\n**\"DM Jaime that the PR is ready\"**\n→ Assistant calls `teleport_chat` with fuzzy name resolution — no email needed.\n\n## Development\n\n```bash\ngit clone https://github.com/akougkas/zulipchat-mcp.git\ncd zulipchat-mcp\nuv sync\nuv run zulipchat-mcp --zulip-config-file ~/.zuliprc\n```\n\nRun checks:\n```bash\nuv run pytest -q              # full test suite, 60% coverage gate\nuv run ruff check .           # Linting\nuv run mypy src               # Type checking\n```\n\nFor packaging, dependency, FastMCP, or startup changes, run the release smoke:\n\n```bash\nuv build\nscripts/pre_release_smoke.sh --version X.Y.Z --allow-dirty\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide, and [CLAUDE.md](CLAUDE.md) / [AGENTS.md](AGENTS.md) for AI agent instructions.\n\n## Architecture\n\n```\nsrc/zulipchat_mcp/\n├── core/           # Client wrapper, identity, caching, security\n├── tools/          # MCP tool implementations (two-tier registration)\n├── services/       # Background listener and session event routing\n├── utils/          # Logging, DuckDB persistence, metrics\n└── config.py       # config loading (zuliprc + environment fallback)\n```\n\nBuilt on [FastMCP](https://github.com/PrefectHQ/fastmcp) with async-first design, [DuckDB](https://duckdb.org) for agent state persistence, and smart user/stream caching for fast fuzzy resolution.\n\n## Privacy\n\n- **No data collection** — nothing leaves your machine except Zulip API calls\n- **No telemetry** — zero analytics, tracking, or usage reporting\n- **Local execution** — all processing happens on your hardware\n- **Credentials stay local** — API keys are never logged or transmitted beyond your Zulip server\n\nFull policy: [PRIVACY.md](PRIVACY.md)\n\n## License\n\nMIT — See [LICENSE](LICENSE)\n\n## Links\n\n- [Documentation Index](docs/README.md)\n- [Support](SUPPORT.md)\n- [Security Policy](SECURITY.md)\n- [Zulip API Documentation](https://zulip.com/api/)\n- [Model Context Protocol](https://modelcontextprotocol.io)\n- [Report Issues](https://github.com/akougkas/zulipchat-mcp/issues)\n- [Discussions](https://github.com/akougkas/zulipchat-mcp/discussions)\n\n---\n\n<div align=\"center\">\n  <sub>Built for the Zulip community</sub>\n</div>\n\n<!-- mcp-name: io.github.akougkas/zulipchat -->\n",
  "bytes": 11133,
  "sha": "8f7f3bdb15f0e1745cffd0d551c903598fe27ce05105fc73b3547333df80bdec",
  "repo_slug": "akougkas/zulipchat-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_akougkas_zulipchat_edfb229b/readme"
}