zulip_add_reaction
Add an emoji reaction to a message
Read and post in a Zulip workspace — channels and topics, channel history, direct messages, emoji reactions and the user directory.
LABSCO SUMMARY
Reading history by channel and topic rather than by channel alone means an assistant can pull one conversation instead of an interleaved firehose — the reason Zulip is organised that way. Posting works the same, so a reply lands in the thread it belongs to. The bot's own subscriptions are the boundary of what it can see, and there is a tool to change that, so a permission error usually means one missing subscription rather than a wrong key.
An MCP server over the Zulip API that runs as a bot in your organization. It covers Zulip's stream-and-topic model rather than flattening it: messages are posted into a named topic within a channel, and history is read the same way.
zulip_list_channelszulip_get_topicszulip_get_channel_historyzulip_post_message, zulip_send_direct_messagezulip_add_reactionzulip_get_userszulip_subscribe_to_channelA Zulip bot, created under Settings → Personal → Bots as a generic bot. That gives you the three values it needs: ZULIP_EMAIL for the bot's address, ZULIP_API_KEY for its key, and ZULIP_URL for the instance. The package is not on npm under its own name (@modelcontextprotocol/server-zulip), so npx runs it straight from the GitHub repository (github:Monadical-SAS/zulip-mcp); the mcp/zulip Docker image is one you build yourself from a clone. Bots start with limited permissions: subscribe the bot to every channel you expect it to read, or history calls will come back empty. Licensed Apache 2.0.
Add the configuration to your client
USE CASES
List the topics in the channel, then pull the recent messages for the topic that matters, paging back with the anchor if you need more.
Send the message into the right channel and topic rather than a general channel, so it threads with the discussion it belongs to.
Look up the users in the organization and send a direct message to the ones who need it, by email or user id.
React to a message with an emoji instead of posting a reply that pushes the thread down.
Subscribe it from the conversation, then read history that was previously invisible to it.
Counted once with only startup setup. Other versions, modes or optional credentials may expose a different list.
zulip_add_reactionAdd an emoji reaction to a message
zulip_get_channel_historyGet recent messages from a channel (stream) and topic
zulip_get_topicsGet topics in a channel (stream)
zulip_get_usersGet list of users in the Zulip organization
zulip_list_channelsList available channels (streams) in the Zulip organization
zulip_post_messagePost a new message to a Zulip channel (stream)
zulip_send_direct_messageSend a direct message to one or more users
zulip_subscribe_to_channelSubscribe the bot to a channel (stream)
BEFORE YOU INSTALL
8 tools when we connected. Four write to your workspace, including zulip_post_message and zulip_send_direct_message. A Zulip generic bot only sees streams it is subscribed to, so zulip_list_channels and zulip_get_channel_history can return empty while working correctly.
CONTEXT COST
Rated by the size of the 8 tool definitions that ride along on every turn, not by how many there are
INSTALLATION
{
"mcpServers": {
"zulip": {
"command": "npx",
"args": [
"-y",
"github:Monadical-SAS/zulip-mcp"
],
"env": {
"ZULIP_EMAIL": "<YOUR_ZULIP_EMAIL>",
"ZULIP_API_KEY": "<YOUR_ZULIP_API_KEY>",
"ZULIP_URL": "https://example.zulipchat.com"
}
}
}
}git clone https://github.com/Monadical-SAS/zulip-mcp
cd zulip-mcp
docker build -t mcp/zulip .{
"mcpServers": {
"zulip": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"ZULIP_EMAIL",
"-e",
"ZULIP_API_KEY",
"-e",
"ZULIP_URL",
"mcp/zulip"
],
"env": {
"ZULIP_EMAIL": "<YOUR_ZULIP_EMAIL>",
"ZULIP_API_KEY": "<YOUR_ZULIP_API_KEY>",
"ZULIP_URL": "https://example.zulipchat.com"
}
}
}
}