README.md•9.88 kB
# Zulip MCP Server
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.
## Features
### 🔄 **Resources** (Contextual Data)
- **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
### 🛠️ **Tools** (25 Available Actions)
#### Helper Tools (LLM-Friendly Discovery)
- `search-users` - Find users by name/email before sending DMs
- `get-started` - Test connection and get workspace overview
#### Message Operations
- `send-message` - Send to streams or direct messages
- `get-messages` - Retrieve with advanced filtering and search
- `get-message` - Get detailed information about specific message
- `upload-file` - Share files and images
- `edit-message` - Modify content or move topics
- `delete-message` - Remove messages (admin permissions required)
- `get-message-read-receipts` - Check who read messages
- `add-emoji-reaction` - React with Unicode or custom emoji
- `remove-emoji-reaction` - Remove emoji reactions from messages
#### Scheduled Messages & Drafts
- `create-scheduled-message` - Schedule future messages
- `edit-scheduled-message` - Modify scheduled messages
- `create-draft` - Create new message drafts
- `get-drafts` - Retrieve saved drafts
- `edit-draft` - Update draft content
#### Stream Management
- `get-subscribed-streams` - List user's stream subscriptions
- `get-stream-id` - Get stream ID by name
- `get-stream-by-id` - Detailed stream information
- `get-topics-in-stream` - Browse recent topics
#### User Operations
- `get-users` - List organization members
- `get-user-by-email` - Find users by email
- `get-user` - Get detailed user information by ID
- `update-status` - Set status message and availability
- `get-user-groups` - List available user groups
## 📝 Zulip Terminology: Streams vs Channels
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.
## Installation & Setup
### Prerequisites
- 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)
### Quick Start
1. **Clone and install dependencies:**
```bash
git clone <repository-url>
cd zulip-mcp-server
npm install
```
2. **Configure environment variables:**
```bash
cp .env.example .env
# Edit .env with your Zulip credentials
```
3. **Build and run:**
```bash
npm run build
npm start
```
### Environment Configuration
Create a `.env` file with your Zulip credentials:
```env
ZULIP_URL=https://your-organization.zulipchat.com
ZULIP_EMAIL=your-bot-email@yourcompany.com
ZULIP_API_KEY=your-api-key-here
NODE_ENV=production
```
#### Getting Zulip API Credentials
1. **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
2. **For Personal Access**:
- Go to Personal Settings → Account & Privacy
- Find "API key" section
- Generate or reveal your API key
### Claude Desktop Integration
To use this MCP server with Claude Desktop, add the following configuration to your Claude Desktop config file:
#### Option 1: Using Environment Variables (Recommended)
Add to your Claude Desktop configuration:
```json
{
"mcpServers": {
"zulip": {
"command": "node",
"args": ["/path/to/zulip-mcp-server/dist/server.js"],
"env": {
"ZULIP_URL": "https://your-organization.zulipchat.com",
"ZULIP_EMAIL": "your-bot-email@yourcompany.com",
"ZULIP_API_KEY": "your-api-key-here"
}
}
}
}
```
#### Option 2: Using .env File
If you prefer using a `.env` file, ensure it's in the project directory and use:
```json
{
"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`
### Cursor Integration
To use this MCP server with Cursor IDE, add the following to your Cursor MCP settings:
#### Cursor MCP Configuration
Add to Cursor's MCP settings file (`.cursor-mcp/config.json` in your workspace or global settings):
```json
{
"mcpServers": {
"zulip": {
"command": "node",
"args": ["/path/to/zulip-mcp-server/dist/server.js"],
"env": {
"ZULIP_URL": "https://your-organization.zulipchat.com",
"ZULIP_EMAIL": "your-bot-email@yourcompany.com",
"ZULIP_API_KEY": "your-api-key-here"
},
"capabilities": {
"tools": true,
"resources": true
}
}
}
}
```
**Cursor MCP Config Location:**
- **Workspace**: `.cursor-mcp/config.json` in your project root
- **Global**: Platform-specific Cursor settings directory
### Raycast MCP Extension
To use this MCP server with Raycast, configure it in the MCP extension settings:
#### Raycast MCP Configuration
Add to Raycast MCP extension configuration:
```json
{
"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": "your-bot-email@yourcompany.com",
"ZULIP_API_KEY": "your-api-key-here"
},
"icon": "💬",
"categories": ["communication", "productivity"]
}
}
}
```
**Raycast Setup Steps:**
1. Install the Raycast MCP extension
2. Open Raycast preferences → Extensions → MCP
3. Add new server configuration
4. Paste the JSON configuration above
5. Update paths and credentials accordingly
**Raycast Usage:**
- Use `⌘ + Space` to open Raycast
- Search for "Zulip" commands
- Execute MCP tools directly from Raycast interface
### Supported MCP Clients
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:**
```bash
node /path/to/zulip-mcp-server/dist/server.js
```
## Development
### Scripts
```bash
npm 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 checking
```
### Project Structure
```
src/
├── server.ts # Main MCP server
├── zulip/
│ └── client.ts # Zulip API client
└── types.ts # TypeScript definitions
```
### Testing
Test the server using MCP Inspector:
```bash
npx @modelcontextprotocol/inspector npm start
```
## Usage Examples
### Sending Messages
```typescript
// 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: "user@example.com",
content: "Hey! Can you review the latest changes when you have a moment?"
});
```
### Getting Messages
```typescript
// 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", "admin@example.com"]]
});
```
### Stream Management
```typescript
// List subscribed streams
await callTool("get-subscribed-streams", {
include_subscribers: true
});
// Get stream topics
await callTool("get-topics-in-stream", {
stream_id: 123
});
```
## Markdown Formatting Support
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
## Error Handling
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.
## Contributing
1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure TypeScript compilation passes
5. Submit a pull request
## Support
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