Skip to main content
Glama

zulip-mcp

Minimal, secure, read-only MCP server for reading Zulip chats from Claude Code (or any MCP client). Browse streams, topics, messages, and users — nothing can be created, modified, or deleted.

Why this exists

A security review of an existing Zulip MCP server surfaced serious issues (eval()-based remote code execution, arbitrary local file read/write, SSRF). This is a clean, minimal alternative built around a strict read-only, no-code-execution design. See Security.

Related MCP server: mcp-infra-readonly

Requirements

  • Python 3.10+

  • A Zulip account and an API key (see below)

  • uv (recommended) or pip

Install

Clone the repo:

git clone https://github.com/shreyan-gupta/zulip-mcp.git
cd zulip-mcp

Then install with either uv or pip:

# Option A — uv (recommended; also installs the right Python)
uv sync

# Option B — pip + venv
python3 -m venv .venv
.venv/bin/pip install -e .

Get your Zulip API key

  1. Open your Zulip instance (e.g. https://your-org.zulipchat.com).

  2. Avatar → Personal settingsAccount & privacy.

  3. Under API key, click Manage your API key and copy it.

Add to Claude Code

Run this from inside the cloned repo ($(pwd) expands to its absolute path):

# Option A — uv
claude mcp add zulip \
  -e ZULIP_EMAIL=you@example.com \
  -e ZULIP_API_KEY=your-api-key \
  -e ZULIP_SITE=https://your-org.zulipchat.com \
  -- uv run --directory "$(pwd)" zulip-mcp

# Option B — venv entry point
claude mcp add zulip \
  -e ZULIP_EMAIL=you@example.com \
  -e ZULIP_API_KEY=your-api-key \
  -e ZULIP_SITE=https://your-org.zulipchat.com \
  -- "$(pwd)/.venv/bin/zulip-mcp"

Restart Claude Code, then try:

> List the streams I'm subscribed to
> Show messages in #engineering about "sync redesign"
> Summarize my last week of messages in #general

Tip: ask it to call get_own_profile first to confirm the connection works.

Tools

Tool

Description

get_own_profile

Verify connection, see authenticated user info

list_subscriptions

List channels you're subscribed to

list_streams

List all visible streams in the org

get_stream_id

Look up a stream's ID by name

list_topics

List topics in a stream

get_messages

Fetch messages with stream/topic/sender/search

get_message

Fetch a single message by ID

get_user

Get user profile by ID or email

list_users

List all users in the org

get_messages supports anchor-based pagination and combines filters (stream, topic, sender, full-text search) into a single query.

Security

This server is designed to be safe by construction:

  • Read-only — cannot create, modify, or delete any Zulip data.

  • No code execution — no eval(), exec(), subprocess, or dynamic imports.

  • No filesystem access — tools never read or write local files.

  • No telemetry — every network request goes exclusively to your Zulip instance.

  • Stdio only — no HTTP listener, no open ports.

  • Credentials stay local — read from env vars, never logged or returned in output.

Configuration

Configuration is via environment variables only (no .env auto-loading):

Environment Variable

Required

Description

ZULIP_EMAIL

Yes

Your Zulip login email or bot email

ZULIP_API_KEY

Yes

API key from Zulip settings

ZULIP_SITE

Yes

Base URL of your Zulip instance

Development

uv sync --extra dev        # or: pip install -e ".[dev]"
ruff check .
pytest

The test suite is offline — it never contacts a real Zulip server.

License

MIT

Available Tools

9 tools
get_messageA

Fetch a single message by its ID.

Use this when you have a specific message ID and want its full content, or when following up on a message reference from another tool's output.

Args: message_id: The numeric message ID. include_html: If True, return HTML. If False (default), raw Markdown.

Returns: JSON object with the full message details.

ParametersJSON Schema
NameRequiredDescriptionDefault
message_idYes
include_htmlNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does not disclose authorization needs, side effects, or performance implications, but as a basic fetch, the core behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the main action in the first sentence, then succinct usage guidelines, parameter details, and return info. Every sentence serves a purpose with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (2 parameters, output schema present), the description fully covers purpose, usage, parameters, and return format. It is complete for an agent to select and invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description adds full meaning: message_id is 'numeric message ID', include_html explains True returns HTML, False returns Markdown. This adds significant value beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description starts with 'Fetch a single message by its ID', clearly stating the verb and resource. The tool name 'get_message' is well-described, and it is distinct from sibling tools like 'get_messages' (plural) and others.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Description provides explicit when-to-use: 'when you have a specific message ID and want its full content, or when following up on a message reference.' It lacks explicit when-not-use or alternatives, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_messagesA

Fetch messages from Zulip with flexible filtering.

This is the primary tool for reading chat history. Combine filters to narrow down results — e.g., stream + topic to get a specific conversation, or sender + search to find specific messages from a person.

Pagination: Results are anchored at a point and fetch messages before/after it. To paginate through history:

  1. First call: anchor="newest", num_before=100

  2. Next call: anchor=, num_before=100

  3. Repeat until found_oldest is true.

Args: stream: Filter by stream/channel name (e.g., "eng-resharding"). topic: Filter by topic/thread name within a stream. sender: Filter by sender email (e.g., "shreyan@nearone.org"). search: Full-text search query across message content. anchor: Reference point — a message ID (as string) or "newest", "oldest", "first_unread". Defaults to "newest". num_before: Number of messages before the anchor. Max 5000. Defaults to 100. num_after: Number of messages after the anchor. Max 5000. Defaults to 0. include_html: If True, return HTML-rendered content. If False (default), return raw Markdown source — better for analysis.

Returns: JSON object with keys: - messages: list of message objects (id, sender, content, timestamp, etc.) - found_newest: whether there are no newer messages matching the filter - found_oldest: whether there are no older messages matching the filter - anchor: the anchor message ID used

ParametersJSON Schema
NameRequiredDescriptionDefault
topicNo
anchorNonewest
searchNo
senderNo
streamNo
num_afterNo
num_beforeNo
include_htmlNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses pagination behavior (anchor, num_before/num_after, found_newest/oldest), default values, and the effect of include_html on output format. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with an overview, usage tips, pagination instructions, and a parameter list. It is thorough but not overly verbose; could be slightly more concise, but every sentence serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (8 parameters, no required ones, output schema exists), the description covers all aspects: filter parameters, pagination, return keys. It is complete enough for an agent to invoke correctly without ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, requiring the description to fully explain parameters. It does so thoroughly: allowed anchor values, defaults, max limits for num_before/num_after, and the difference between include_html options. This significantly adds value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with 'Fetch messages from Zulip with flexible filtering,' using a specific verb and resource. It distinguishes itself from the sibling tool 'get_message' (singular) by indicating it retrieves multiple messages with filtering capabilities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states it is the 'primary tool for reading chat history' and provides usage examples (e.g., combining filters). Detailed pagination steps are given, making it clear how to iterate through results. The distinction from 'get_message' is implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_own_profileA

Get the authenticated user's own profile.

Use this to verify the connection is working and to see who is authenticated. This is the first tool to call when setting up.

Returns: JSON object with user profile: user_id, email, full_name, etc.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It mentions the return format (JSON object with user_id, email, etc.), adding some value, but does not disclose other behavioral traits like authentication requirements, side effects, or rate limits. The return description is helpful but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise at 5 lines, front-loaded with the purpose, followed by usage guidance and return details. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (0 params, output schema exists), the description adequately covers purpose, usage, and return format. It is complete for an agent to understand when and how to use the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and schema coverage is 100% (trivially). Per guidelines, a no-parameter tool baseline is 4. The description adds no parameter information because none exists.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Get the authenticated user's own profile', using a specific verb and resource. It distinguishes from siblings like get_user and get_message by focusing on the authenticated user's profile.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly advises using this tool to verify connection and to see who is authenticated, including 'This is the first tool to call when setting up.' While it does not explicitly mention when not to use it, the guidance is clear and context-rich for a simple tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_stream_idA

Look up a stream's numeric ID by its name.

Use this when you know a stream's name but need its ID for other API calls (e.g., list_topics requires a stream_id).

Args: stream_name: Exact name of the stream (case-sensitive).

Returns: JSON object with the stream_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
stream_nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description must disclose behavior. It mentions case-sensitivity and that return is a JSON object with stream_id. However, it does not cover error behavior, rate limits, or potential side effects. The description is adequate for a simple lookup tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with three short paragraphs, each serving a purpose: purpose, usage guidance, and parameter/return details. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists (though not shown), the description summarizes the return object. It does not specify behavior on failure (e.g., if stream not found), but for a straightforward lookup, it is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0% description coverage, so the description must add meaning. It does by stating that stream_name requires an exact, case-sensitive name. This goes beyond the schema's minimal type and title.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('look up') and the resource ('stream's numeric ID by its name'), distinguishing it from sibling tools like list_streams which list all streams. It is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use the tool: when you know a stream's name but need its ID for other API calls, with an example (list_topics). It does not explicitly mention when not to use, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_userA

Get a user's profile by their numeric ID or email address.

Args: identifier: Either a numeric user ID (e.g., "12345") or an email address (e.g., "alice@example.com").

Returns: JSON object with user profile details.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description states the return type (JSON object with user profile details) but does not disclose error behavior, permission requirements, or rate limits. As a simple read operation without annotations, it is adequate but lacks full transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, with a front-loaded purpose sentence followed by clear Args and Returns sections. Every word adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one parameter, output schema exists), the description covers the essential information. It could benefit from a brief note on error handling or authentication, but it is largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage for the sole parameter 'identifier', the description compensates by explaining it can be a numeric ID or email, with examples. This adds meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'get' and resource 'user's profile', and specifies the two types of identifiers (numeric ID or email). This differentiates it from sibling tools like list_users (list all users) and get_own_profile (own profile).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly indicates when to use the tool: when you need a specific user's profile and have their identifier. It doesn't explicitly state when not to use it, but the sibling names provide context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_streamsA

List all visible Zulip streams (channels).

Use this to discover what streams/channels exist in the organization. Returns stream names, IDs, descriptions, and subscriber counts.

Args: include_public: Include public streams. Defaults to True. include_subscribed: Include streams you're subscribed to. Defaults to True. exclude_archived: Exclude archived streams. Defaults to True.

Returns: JSON list of streams with their metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault
include_publicNo
exclude_archivedNo
include_subscribedNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It states the tool returns stream names, IDs, descriptions, and subscriber counts. However, it does not disclose authentication needs, rate limits, or what 'visible' entails regarding permissions. It is moderately transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two short paragraphs plus structured Args and Returns sections. It is front-loaded with the main purpose. No unnecessary words; every part serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity (3 boolean params, no nesting, output schema exists), the description covers the tool's purpose, parameters, and return format adequately. It is complete for a list tool, though could mention that an output schema provides more detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates by listing each parameter with its default value in the Args section. This adds meaningful context beyond the raw schema, though it could explain the semantics more deeply (e.g., what 'include_public' means exactly).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List all visible Zulip streams (channels).' and adds 'Use this to discover what streams/channels exist in the organization.' This provides a specific verb and resource, distinguishing it from sibling tools like get_stream_id or list_subscriptions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says 'Use this to discover what streams/channels exist.' It gives context for use but does not specify when NOT to use it or mention alternatives like list_subscriptions (which lists subscriptions, not streams). No explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_subscriptionsA

List streams (channels) you are subscribed to.

Use this to see which streams the authenticated user can access. More focused than list_streams — only shows your subscriptions.

Returns: JSON list of subscribed streams with names and IDs.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must cover behavioral traits. It implies a read operation and mentions the return format, but does not disclose authentication requirements, rate limits, or potential side effects beyond what is obvious.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, front-loaded, and contains no extraneous words. Every sentence serves a clear purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters, an existing output schema, and the simplicity of the tool, the description covers purpose, usage, and return format adequately. No gaps are evident.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters and 100% description coverage, so baseline is 4. The description does not add parameter information as none exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists streams the user is subscribed to, using a specific verb and resource. It differentiates from sibling tool list_streams by noting it is more focused and only shows subscriptions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says when to use this tool ('to see which streams the authenticated user can access') and compares it to list_streams as an alternative. It lacks explicit exclusion criteria but provides clear context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_topicsA

List topics (threads) in a stream, most recent first.

Use this to discover what conversations exist in a stream before fetching messages. Each topic is like a thread/subject line.

Args: stream_id: The numeric ID of the stream. Use get_stream_id to look this up.

Returns: JSON list of topics with names and last message IDs.

ParametersJSON Schema
NameRequiredDescriptionDefault
stream_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility. It discloses the output format (JSON list of topics with names and last message IDs) and sorting order (most recent first). It does not mention edge cases like empty lists or permissions, but for a read-only list tool it is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with no superfluous words. It front-loads the purpose, then gives usage guidance, parameter details, and return format in a logical order.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having an output schema, the description still explains the return format. With only one required parameter and clear documentation, it is fully complete for a simple list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description compensates by explaining the stream_id parameter as 'The numeric ID of the stream' and references get_stream_id for lookup. This adds meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it lists topics (threads) in a stream, most recent first. It differentiates from sibling tools like get_message and get_messages by stating it discovers conversations before fetching messages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Use this to discover what conversations exist in a stream before fetching messages.' Provides clear context for when to use it, though no exclusions are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_usersA

List all users in the Zulip organization.

Returns all active and deactivated users. Use this to find user IDs or email addresses for filtering messages.

Returns: JSON list of user objects with basic profile info.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It states the tool returns all active and deactivated users in a JSON list with basic profile info, which is transparent about the output. However, it does not disclose any behavioral traits like pagination, rate limits, or performance implications, which could be relevant for a large user list.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences, front-loaded with the core purpose. Every sentence adds value: the first states what it does, the second specifies scope, the third gives return format and usage. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool is a simple list with no parameters and an output schema exists, the description is complete. It mentions the return format and provides a concrete use case. The complexity is low, and the description adequately covers what an agent needs to know to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters and coverage is 100%, so the description adds no parameter details. Following the calibration, a baseline of 4 is appropriate when there are no parameters, as the description does not need to provide parameter semantics beyond what the schema offers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it lists all users in the Zulip organization, including active and deactivated. It distinguishes its purpose from siblings like get_user (single user) and other list tools by specifying it returns the full list and is used for finding user IDs or email addresses.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly gives a use case: 'Use this to find user IDs or email addresses for filtering messages.' This tells the agent when to use it. However, it does not explicitly mention when not to use it or name alternatives among siblings, though the use case implies differentiation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 9 tool updatesv0.1.0
    • First observedget_message
    • First observedget_messages
    • First observedget_own_profile
    • First observedget_stream_id
    • First observedget_user
    • First observedlist_streams
    • First observedlist_subscriptions
    • First observedlist_topics
    • First observedlist_users

TDQS

A4.2/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: get_message vs get_messages differ in cardinality, get_user vs get_own_profile differ in target, list_streams vs list_subscriptions differ in scope. No overlap or ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case (e.g., get_message, list_streams). There are no deviations or mixed conventions.

Tool Count5/5

9 tools is a reasonable number for a Zulip MCP server focused on reading data. Each tool serves a distinct function without being excessive or insufficient for the apparent scope.

Completeness2/5

The server is read-only, missing core write operations such as sending messages, creating streams, or subscribing. This is a significant gap for a chat platform, limiting agent capability.

Maintenance

ActivityStale
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A read-only MCP server that enables Claude Code to access MySQL databases, allowing safe querying with SELECT, SHOW, DESCRIBE, and EXPLAIN.
    32
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A read-only MCP server that gives Claude unified access to multiple Gmail and Microsoft 365 accounts, enabling email search, reading, and listing through one connection.
    126
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A read-only MCP server that gives Claude safe access to Kubernetes clusters, enabling listing, describing, and monitoring resources without mutation risks and with secret masking.
    1
    MIT

Latest Blog Posts

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/shreyan-gupta/zulip-mcp'

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