Skip to main content
Glama

Zulip MCP Server

by avisekrath
CLAUDE.md8.04 kB
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is an MCP (Model Context Protocol) server that exposes Zulip REST API capabilities as tools for LLMs. The server acts as a bridge between LLMs and Zulip workspaces, enabling AI assistants to send messages, retrieve chat history, manage users, and perform other Zulip operations programmatically. ## Technology Stack - **Language**: TypeScript/Node.js (ES modules) - **Framework**: MCP TypeScript SDK (`@modelcontextprotocol/sdk`) - **API Client**: Custom Zulip REST API client with axios - **Schema Validation**: Zod for input validation - **Transport**: StdioServerTransport for CLI usage ## Essential Development Commands ```bash # Development npm run dev # Live development server with tsx npm run build # Clean build: removes dist/ then compiles TypeScript npm run clean # Remove dist/ folder (clear build artifacts) npm run build:watch # TypeScript compilation in watch mode npm start # Run compiled server from dist/ # Code Quality (Current Baseline) npm run quality # lint + typecheck + audit npm run lint # ESLint check npm run lint:fix # Auto-fix ESLint issues npm run typecheck # TypeScript compilation check npm run audit:fix # Fix npm security vulnerabilities # Quality with Tests (Future - currently fails) npm run quality-full # Includes tests when implemented npm test # Jest (no tests implemented yet) # Pre-commit npm run precommit # lint + typecheck + build ``` ## Current Project Structure ``` src/ ├── server.ts # Main MCP server - all tools/resources defined here ├── types.ts # Zod schemas and TypeScript type definitions └── zulip/ └── client.ts # Zulip REST API client implementation ``` **Note**: The architecture is currently monolithic with all MCP tools and resources defined in `server.ts`. The documented `tools/` directory structure doesn't exist yet. ## MCP Server Architecture The server is implemented as a single file (`server.ts`) that: 1. **Environment Setup**: Validates required environment variables with helpful error messages 2. **Resource Registration**: Provides contextual data (user directory, streams, formatting guide, common patterns) 3. **Tool Registration**: Implements Zulip API operations as MCP tools 4. **Transport**: Uses StdioServerTransport for CLI integration ```typescript // Key architectural pattern import 'dotenv/config'; // Automatic .env loading const server = new McpServer({ name: "zulip-mcp-server", version: "1.5.0" }); // Resources provide contextual data server.resource("users-directory", "zulip://users", handler); // Tools provide Zulip operations server.tool("send-message", SendMessageSchema.shape, handler); ``` ## Environment Configuration **Required Variables** (set in `.env` file or environment): ```bash ZULIP_URL=https://your-org.zulipchat.com ZULIP_EMAIL=your-bot@your-org.zulipchat.com ZULIP_API_KEY=your_api_key_here ``` **Optional**: ```bash DEBUG=true # Enable debug logging NODE_ENV=development # Environment mode ``` The server automatically loads `.env` files and provides detailed error messages for missing variables. ## Current MCP Tools Implementation **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 message history with filtering - `edit-message` - Modify existing messages - `delete-message` - Remove messages - `add-emoji-reaction` / `remove-emoji-reaction` - React to messages - `get-message` - Get specific message details - `get-message-read-receipts` - Check who read messages **Stream Management**: - `get-subscribed-streams` - List user's 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 user by email - `get-user` - Get user details by ID - `update-status` - Set user status message - `get-user-groups` - List available user groups **Scheduling & Drafts**: - `create-scheduled-message` / `edit-scheduled-message` - Schedule messages - `get-drafts` / `create-draft` / `edit-draft` - Manage message drafts - `upload-file` - Share files and images **MCP Resources Available**: - `users-directory` (zulip://users) - Browse organization members - `streams-directory` (zulip://streams) - Explore available streams - `message-formatting-guide` (zulip://formatting/guide) - Markdown syntax reference - `common-patterns` (zulip://patterns/common) - LLM usage workflows and troubleshooting ## Key Implementation Patterns ### Environment Validation with Helpful Errors ```typescript function validateEnvironment(): ZulipConfig { if (!url || !email || !apiKey) { throw new Error(`Missing required environment variables. Please set: - ZULIP_URL: Your Zulip server URL (e.g., https://your-org.zulipchat.com) - ZULIP_EMAIL: Your bot/user email address - ZULIP_API_KEY: Your API key from Zulip settings Missing: ${!url ? 'ZULIP_URL ' : ''}${!email ? 'ZULIP_EMAIL ' : ''}${!apiKey ? 'ZULIP_API_KEY ' : ''}`); } } ``` ### MCP Tool Pattern (using Zod schemas from types.ts) ```typescript server.tool( "tool-name", SchemaFromTypes.shape, // Import from types.ts async (params) => { try { const result = await zulipClient.operation(params); return createSuccessResponse(JSON.stringify(result, null, 2)); } catch (error) { return createErrorResponse(`Error: ${error.message}`); } } ); ``` ### Enhanced Error Messages (in zulip/client.ts) The Zulip client provides contextual error guidance: - "User not found" → Points to `search-users` tool - "Stream not found" → Points to `get-subscribed-streams` - "Invalid email" → Explains to use actual emails, not display names ## LLM Usability Features & Tool Workflows ### **Recommended Workflows** **Discovery**: `get-started` → `search-users` → `send-message` **User Lookup**: `search-users` (explore) → `get-user-by-email` (exact) → `get-user` (detailed) **Messages**: `get-messages` (bulk/search) → `get-message` (detailed analysis) **Streams**: `get-subscribed-streams` → `get-stream-id` → `get-topics-in-stream` ### **Tool Selection Guide** **When to use each user tool:** - 🔍 `search-users` - Don't know exact details, want to explore users - 📧 `get-user-by-email` - Have exact email, need profile details - 🆔 `get-user` - Have user ID from search, need complete information **When to use each message tool:** - 📋 `get-messages` - Browse conversations, search content, get history - 🔍 `get-message` - Analyze one specific message, check edit history ## Zulip Terminology: Streams vs Channels **Streams = Channels**: In Zulip, "streams" and "channels" refer to the same concept - conversation spaces for teams. This MCP server uses "stream" to match Zulip's official terminology: - **Stream** = Official Zulip terminology (used in API, tools, interface) - **Channel** = Common term from Slack/Discord/Teams - **Same thing** = Conversation spaces where teams discuss topics If you're familiar with Slack/Discord "channels", Zulip "streams" work identically. ## Testing & Quality **Current State**: No tests implemented yet (TODO item in DEVELOPMENT.md) **Interactive Testing**: ```bash npx @modelcontextprotocol/inspector # Test MCP tools interactively npm run dev # Test against real Zulip workspace ``` **Quality Checks**: ```bash npm run quality # Current baseline: lint + typecheck + audit npm run quality-full # Future: includes tests when implemented ```

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/avisekrath/zulip-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server