get-messages
Retrieve multiple messages from Zulip workspaces with filtering, pagination, and search. Use this tool to browse conversations, locate specific content, or access message history efficiently.
Instructions
📋 BULK RETRIEVAL: Get multiple messages with filtering, pagination, and search. Use this to browse conversations, search for content, or get message history. Returns array of messages with basic details.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| anchor | No | Starting point: message ID, 'newest', 'oldest', or 'first_unread' | |
| message_id | No | Get specific message by ID instead of using anchor/num parameters | |
| narrow | No | Filters: [['stream', 'channel-name'], ['topic', 'topic-name'], ['sender', 'email'], ['search', 'query']] | |
| num_after | No | Number of messages after anchor (max 1000) | |
| num_before | No | Number of messages before anchor (max 1000) |
Implementation Reference
- src/server.ts:430-461 (handler)MCP tool registration and implementation of the 'get-messages' handler function. This is the core execution logic for the tool.server.tool( "get-messages", "📋 BULK RETRIEVAL: Get multiple messages with filtering, pagination, and search. Use this to browse conversations, search for content, or get message history. Returns array of messages with basic details.", GetMessagesSchema.shape, async ({ anchor, num_before, num_after, narrow, message_id }) => { try { const result = await zulipClient.getMessages({ anchor, num_before, num_after, narrow, message_id }); return createSuccessResponse(JSON.stringify({ message_count: result.messages.length, messages: result.messages.map(msg => ({ id: msg.id, sender: msg.sender_full_name, timestamp: new Date(msg.timestamp * 1000).toISOString(), content: msg.content, type: msg.type, topic: msg.topic || msg.subject, stream_id: msg.stream_id, reactions: msg.reactions })) }, null, 2)); } catch (error) { return createErrorResponse(`Error retrieving messages: ${error instanceof Error ? error.message : 'Unknown error'}`); } } );
- src/types.ts:120-126 (schema)Zod schema defining input parameters and validation for the 'get-messages' tool.export const GetMessagesSchema = z.object({ anchor: z.union([z.number(), z.enum(["newest", "oldest", "first_unread"])]).optional().describe("Starting point: message ID, 'newest', 'oldest', or 'first_unread'"), num_before: z.number().max(1000).optional().describe("Number of messages before anchor (max 1000)"), num_after: z.number().max(1000).optional().describe("Number of messages after anchor (max 1000)"), narrow: z.array(z.array(z.string())).optional().describe("Filters: [['stream', 'channel-name'], ['topic', 'topic-name'], ['sender', 'email'], ['search', 'query']]"), message_id: z.number().optional().describe("Get specific message by ID instead of using anchor/num parameters") });
- src/zulip/client.ts:157-182 (helper)Helper method in ZulipClient that performs the actual HTTP API call to Zulip's /messages endpoint, handling parameters and single message ID case.async getMessages(params: { anchor?: number | string; num_before?: number; num_after?: number; narrow?: string[][]; message_id?: number; } = {}): Promise<{ messages: ZulipMessage[] }> { if (params.message_id) { const response = await this.client.get(`/messages/${params.message_id}`); return { messages: [response.data.message] }; } const queryParams: any = {}; // Only set parameters that are provided, with appropriate defaults queryParams.anchor = params.anchor !== undefined ? params.anchor : 'newest'; queryParams.num_before = params.num_before !== undefined ? params.num_before : 20; queryParams.num_after = params.num_after !== undefined ? params.num_after : 0; if (params.narrow) { queryParams.narrow = JSON.stringify(params.narrow); } const response = await this.client.get('/messages', { params: queryParams }); return response.data; }