A Model Context Protocol (MCP) server that exposes Zulip REST API capabilities as tools for LLMs. This server allows AI assistants to interact with your Zulip workspace programmatically.
- User Directory: Browse organization members with roles and status
- Stream Directory: Explore available streams and permissions
- Message Formatting Guide: Complete Zulip markdown syntax reference
- Organization Info: Server settings, policies, and custom emoji
- User Groups: Available groups for mentions and permissions
search-users- Find users by name/email before sending DMsget-started- Test connection and get workspace overview
send-message- Send to streams or direct messagesget-messages- Retrieve with advanced filtering and searchget-message- Get detailed information about specific messageupload-file- Share files and imagesedit-message- Modify content or move topicsdelete-message- Remove messages (admin permissions required)get-message-read-receipts- Check who read messagesadd-emoji-reaction- React with Unicode or custom emojiremove-emoji-reaction- Remove emoji reactions from messages
create-scheduled-message- Schedule future messagesedit-scheduled-message- Modify scheduled messagescreate-draft- Create new message draftsget-drafts- Retrieve saved draftsedit-draft- Update draft content
get-subscribed-streams- List user's stream subscriptionsget-stream-id- Get stream ID by nameget-stream-by-id- Detailed stream informationget-topics-in-stream- Browse recent topics
get-users- List organization membersget-user-by-email- Find users by emailget-user- Get detailed user information by IDupdate-status- Set status message and availabilityget-user-groups- List available user groups
In Zulip, "streams" and "channels" refer to the same concept:
- Stream = Official Zulip terminology (used in API, tools, interface)
- Channel = Common term from Slack/Discord/Teams
- Same thing = Conversation spaces where teams discuss topics
This MCP server uses "stream" to match Zulip's official documentation and API.
- Node.js 18+ with npm
- TypeScript 5+
- Access to a Zulip instance (e.g., https://your-organization.zulipchat.com)
- Zulip API credentials (bot token or API key)
- Clone and install dependencies:
git clone <repository-url>
cd zulip-mcp-server
npm install- Configure environment variables:
cp .env.example .env
# Edit .env with your Zulip credentials- Build and run:
npm run build
npm startCreate a .env file with your Zulip credentials:
ZULIP_URL=https://your-organization.zulipchat.com
ZULIP_EMAIL=[email protected]
ZULIP_API_KEY=your-api-key-here
NODE_ENV=production-
For Bot Access (Recommended):
- Go to your Zulip organization settings
- Navigate to "Bots" section
- Create a new bot or use existing one
- Copy the bot email and API key
-
For Personal Access:
- Go to Personal Settings β Account & Privacy
- Find "API key" section
- Generate or reveal your API key
To use this MCP server with Claude Desktop, add the following configuration to your Claude Desktop config file:
Add to your Claude Desktop configuration:
{
"mcpServers": {
"zulip": {
"command": "node",
"args": ["/path/to/zulip-mcp-server/dist/server.js"],
"env": {
"ZULIP_URL": "https://your-organization.zulipchat.com",
"ZULIP_EMAIL": "[email protected]",
"ZULIP_API_KEY": "your-api-key-here"
}
}
}
}If you prefer using a .env file, ensure it's in the project directory and use:
{
"mcpServers": {
"zulip": {
"command": "node",
"args": ["/path/to/zulip-mcp-server/dist/server.js"],
"cwd": "/path/to/zulip-mcp-server"
}
}
}Claude Desktop Config Location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
To use this MCP server with Cursor IDE, add the following to your Cursor MCP settings:
Add to Cursor's MCP settings file (.cursor-mcp/config.json in your workspace or global settings):
{
"mcpServers": {
"zulip": {
"command": "node",
"args": ["/path/to/zulip-mcp-server/dist/server.js"],
"env": {
"ZULIP_URL": "https://your-organization.zulipchat.com",
"ZULIP_EMAIL": "[email protected]",
"ZULIP_API_KEY": "your-api-key-here"
},
"capabilities": {
"tools": true,
"resources": true
}
}
}
}Cursor MCP Config Location:
- Workspace:
.cursor-mcp/config.jsonin your project root - Global: Platform-specific Cursor settings directory
To use this MCP server with Raycast, configure it in the MCP extension settings:
Add to Raycast MCP extension configuration:
{
"servers": {
"zulip": {
"name": "Zulip Integration",
"description": "Send messages and interact with Zulip workspace",
"command": "node",
"args": ["/path/to/zulip-mcp-server/dist/server.js"],
"env": {
"ZULIP_URL": "https://your-organization.zulipchat.com",
"ZULIP_EMAIL": "[email protected]",
"ZULIP_API_KEY": "your-api-key-here"
},
"icon": "π¬",
"categories": ["communication", "productivity"]
}
}
}Raycast Setup Steps:
- Install the Raycast MCP extension
- Open Raycast preferences β Extensions β MCP
- Add new server configuration
- Paste the JSON configuration above
- Update paths and credentials accordingly
Raycast Usage:
- Use
β + Spaceto open Raycast - Search for "Zulip" commands
- Execute MCP tools directly from Raycast interface
This server is compatible with any MCP-compliant client. Here are the verified integrations:
| Platform | Config Type | Status | Usage |
|---|---|---|---|
| Claude Desktop | JSON config | β Verified | AI conversations with Zulip integration |
| Cursor IDE | Workspace/Global config | β Verified | Code editor with Zulip notifications |
| Raycast | Extension config | β Verified | Quick commands and automation |
| Other MCP Clients | Standard MCP protocol | π Compatible | Any MCP-compliant application |
Universal MCP Command:
node /path/to/zulip-mcp-server/dist/server.jsnpm run dev # Development with hot reload
npm run build # Build for production
npm test # Run tests
npm run lint # Lint TypeScript
npm run typecheck # Type checkingsrc/
βββ server.ts # Main MCP server
βββ zulip/
β βββ client.ts # Zulip API client
βββ types.ts # TypeScript definitions
Test the server using MCP Inspector:
npx @modelcontextprotocol/inspector npm start// Send to a stream
await callTool("send-message", {
type: "stream",
to: "general",
topic: "Daily Standup",
content: "Good morning team! π\n\n**Today's Goals:**\n- Review PR #123\n- Deploy feature X"
});
// Direct message
await callTool("send-message", {
type: "direct",
to: "[email protected]",
content: "Hey! Can you review the latest changes when you have a moment?"
});// Get recent messages from a stream
await callTool("get-messages", {
narrow: [["stream", "general"], ["topic", "announcements"]],
num_before: 50
});
// Search messages
await callTool("get-messages", {
narrow: [["search", "deployment"], ["sender", "[email protected]"]]
});// List subscribed streams
await callTool("get-subscribed-streams", {
include_subscribers: true
});
// Get stream topics
await callTool("get-topics-in-stream", {
stream_id: 123
});The server includes a comprehensive formatting guide resource. Zulip supports:
- Standard Markdown: Bold, italic, code, links, lists
- Mentions:
@**Full Name**(notify),@_**Name**_(silent) - Stream Links:
#**stream-name** - Code Blocks: With syntax highlighting
- Math: LaTeX expressions with
$$math$$ - Spoilers:
||hidden content|| - Custom Emoji: Organization-specific emoji
The server provides comprehensive error handling:
- Network connectivity issues
- Authentication failures
- Permission errors
- Rate limiting
- Invalid parameters
- Zulip API errors
All errors include helpful messages for debugging.
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure TypeScript compilation passes
- Submit a pull request
For issues and questions:
- Check Zulip API documentation: https://zulip.com/api/
- Review MCP specification: https://modelcontextprotocol.io/
- Open GitHub issues for bugs or feature requests