Skip to main content
Glama
types.ts•12.3 kB
import { z } from "zod"; // Zulip API Types export interface ZulipConfig { url: string; email: string; apiKey: string; } export interface ZulipMessage { id: number; sender_id: number; sender_full_name: string; sender_email: string; timestamp: number; content: string; content_type: string; stream_id?: number; subject?: string; topic?: string; type: "stream" | "private"; recipient_id: number; reactions: ZulipReaction[]; edit_history?: ZulipEditHistory[]; } export interface ZulipReaction { emoji_name: string; emoji_code: string; reaction_type: string; user_id: number; } export interface ZulipEditHistory { prev_content: string; prev_rendered_content: string; timestamp: number; user_id: number; } export interface ZulipStream { stream_id: number; name: string; description: string; invite_only: boolean; is_web_public: boolean; is_archived: boolean; creator_id: number; date_created: number; first_message_id: number; message_retention_days: number | null; history_public_to_subscribers: boolean; rendered_description: string; is_announcement_only: boolean; can_remove_subscribers_group: number; stream_post_policy: number; } export interface ZulipUser { user_id: number; email: string; full_name: string; date_joined: string; is_active: boolean; is_owner: boolean; is_admin: boolean; is_moderator: boolean; is_guest: boolean; is_bot: boolean; bot_type: number | null; timezone: string; avatar_url: string; delivery_email: string; profile_data: Record<string, any>; } export interface ZulipUserGroup { id: number; name: string; description: string; members: number[]; direct_subgroup_ids: number[]; is_system_group: boolean; can_manage_group: number; can_mention_group: number; } export interface ZulipTopic { name: string; max_id: number; } export interface ZulipScheduledMessage { scheduled_message_id: number; type: "stream" | "private"; to: string | number[]; content: string; topic?: string; scheduled_delivery_timestamp: number; failed: boolean; } export interface ZulipDraft { id: number; type: "stream" | "private"; to: number[]; topic: string; content: string; timestamp: number; } // MCP Tool Schemas export const SendMessageSchema = z.object({ type: z.enum(["stream", "direct"]).describe("'stream' for channel messages, 'direct' for private messages"), to: z.string().describe("For streams: channel name (e.g., 'general'). For direct: comma-separated user emails (e.g., 'user@example.com' or 'user1@example.com,user2@example.com')"), content: z.string().describe("Message content using Zulip Markdown syntax. Support mentions (@**Name**), code blocks, links, etc."), topic: z.string().optional().describe("Topic name for stream messages (required for streams, max length varies by server)") }); 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") }); export const UploadFileSchema = z.object({ filename: z.string().describe("Name of the file including extension (e.g., 'document.pdf', 'image.png')"), content: z.string().describe("Base64 encoded file content"), content_type: z.string().optional().describe("MIME type (e.g., 'image/png', 'application/pdf'). Auto-detected if not provided") }); export const EditMessageSchema = z.object({ message_id: z.number().describe("Unique ID of the message to edit"), content: z.string().optional().describe("New message content with Markdown formatting"), topic: z.string().optional().describe("New topic name (for stream messages only)") }); export const AddReactionSchema = z.object({ message_id: z.number().describe("ID of the message to react to"), emoji_name: z.string().describe("Emoji name (e.g., 'thumbs_up', 'heart', 'rocket') or custom emoji name"), emoji_code: z.string().optional().describe("Unicode code point for the emoji"), reaction_type: z.enum(["unicode_emoji", "realm_emoji", "zulip_extra_emoji"]).optional().describe("Type of emoji reaction") }); export const CreateScheduledMessageSchema = z.object({ type: z.enum(["stream", "direct"]).describe("Message type: 'stream' for channels, 'direct' for private messages"), to: z.string().describe("For streams: channel name (e.g., 'general'). For direct: comma-separated user emails (e.g., 'user@example.com,user2@example.com')"), content: z.string().describe("Message content with Markdown formatting"), topic: z.string().optional().describe("Topic for stream messages"), scheduled_delivery_timestamp: z.number().describe("Unix timestamp when message should be sent (seconds since epoch)") }); export const GetUserByEmailSchema = z.object({ email: z.string().email().describe("Email address of the user to look up"), client_gravatar: z.boolean().optional().describe("Include Gravatar profile image URL"), include_custom_profile_fields: z.boolean().optional().describe("Include organization-specific custom profile fields") }); export const UpdateStatusSchema = z.object({ status_text: z.string().max(60).optional().describe("Status message text (max 60 chars, empty string clears status)"), away: z.boolean().optional().describe("Set away status (deprecated in Zulip 6.0, will be removed)"), emoji_name: z.string().optional().describe("Emoji name: for unicode use short name (e.g., 'coffee', 'airplane'), for realm_emoji use custom name, for zulip_extra use special names like 'zulip'"), emoji_code: z.string().optional().describe("Emoji identifier: for unicode_emoji use codepoint (e.g., '2615' for coffee), for realm_emoji use custom emoji ID, for zulip_extra use emoji ID"), reaction_type: z.enum(["unicode_emoji", "realm_emoji", "zulip_extra_emoji"]).optional().describe("Emoji type: 'unicode_emoji' for standard emojis (default), 'realm_emoji' for organization custom emojis, 'zulip_extra_emoji' for special Zulip emojis") }); export const CreateDraftSchema = z.object({ type: z.enum(["stream", "private"]).describe("Draft message type: 'stream' for channels, 'private' for direct messages"), to: z.array(z.number()).describe("Array of user IDs for private messages, or single channel ID for stream messages"), topic: z.string().describe("Topic for stream messages (required even for private messages in API)"), content: z.string().describe("Draft message content with Markdown formatting"), timestamp: z.number().optional().describe("Unix timestamp for draft creation (optional, defaults to current time)") }); export const GetUserSchema = z.object({ user_id: z.number().describe("Unique user ID to retrieve information for"), client_gravatar: z.boolean().optional().describe("Include Gravatar URL (default: true)"), include_custom_profile_fields: z.boolean().optional().describe("Include custom profile fields (default: false)") }); export const GetMessageSchema = z.object({ message_id: z.number().describe("Unique message ID to retrieve"), apply_markdown: z.boolean().optional().describe("Return HTML content (true) or raw Markdown (false). Default: true"), allow_empty_topic_name: z.boolean().optional().describe("Allow empty topic names in response (default: false)") }); export const ListUsersSchema = z.object({ client_gravatar: z.boolean().optional().describe("Include Gravatar URLs for users (default: true)"), include_custom_profile_fields: z.boolean().optional().describe("Include custom profile fields (default: false)") }); export const ListStreamsSchema = z.object({ include_public: z.boolean().optional().describe("Include public streams (default: true)"), include_subscribed: z.boolean().optional().describe("Include streams user is subscribed to (default: true)"), include_all_active: z.boolean().optional().describe("Include all active streams (default: false)"), include_archived: z.boolean().optional().describe("Include archived streams (default: false)") }); export const DeleteMessageSchema = z.object({ message_id: z.number().describe("Unique ID of the message to delete") }); export const RemoveReactionSchema = z.object({ message_id: z.number().describe("ID of the message to remove reaction from"), emoji_name: z.string().describe("Emoji name to remove (e.g., 'thumbs_up', 'heart')"), emoji_code: z.string().optional().describe("Unicode code point for the emoji"), reaction_type: z.enum(["unicode_emoji", "realm_emoji", "zulip_extra_emoji"]).optional().describe("Type of emoji reaction") }); export const GetStreamTopicsSchema = z.object({ stream_id: z.number().describe("Unique stream ID to get topics for") }); export const GetMessageReadReceiptsSchema = z.object({ message_id: z.number().describe("Unique message ID to get read receipts for") }); export const EditScheduledMessageSchema = z.object({ scheduled_message_id: z.number().describe("Unique scheduled message ID to edit"), type: z.enum(["stream", "direct"]).optional().describe("Message type"), to: z.string().optional().describe("Recipients (channel name or comma-separated emails)"), content: z.string().optional().describe("New message content"), topic: z.string().optional().describe("New topic for stream messages"), scheduled_delivery_timestamp: z.number().optional().describe("New delivery timestamp") }); export const EditDraftSchema = z.object({ draft_id: z.number().describe("Unique draft ID to edit"), type: z.enum(["stream", "direct"]).describe("Draft message type"), to: z.array(z.number()).describe("Array of user IDs or channel ID"), topic: z.string().describe("Topic for the draft"), content: z.string().describe("Draft content"), timestamp: z.number().optional().describe("Updated timestamp") }); export const GetSubscribedStreamsSchema = z.object({ include_subscribers: z.boolean().optional().describe("Include subscriber lists for streams") }); export const GetStreamIdSchema = z.object({ stream_name: z.string().describe("Name of the stream to get ID for") }); export const GetStreamByIdSchema = z.object({ stream_id: z.number().describe("Unique stream ID to get details for"), include_subscribers: z.boolean().optional().describe("Include subscriber list") }); export type SendMessageParams = z.infer<typeof SendMessageSchema>; export type GetMessagesParams = z.infer<typeof GetMessagesSchema>; export type UploadFileParams = z.infer<typeof UploadFileSchema>; export type EditMessageParams = z.infer<typeof EditMessageSchema>; export type AddReactionParams = z.infer<typeof AddReactionSchema>; export type CreateScheduledMessageParams = z.infer<typeof CreateScheduledMessageSchema>; export type GetUserByEmailParams = z.infer<typeof GetUserByEmailSchema>; export type UpdateStatusParams = z.infer<typeof UpdateStatusSchema>; export type CreateDraftParams = z.infer<typeof CreateDraftSchema>; export type GetUserParams = z.infer<typeof GetUserSchema>; export type GetMessageParams = z.infer<typeof GetMessageSchema>; export type ListUsersParams = z.infer<typeof ListUsersSchema>; export type ListStreamsParams = z.infer<typeof ListStreamsSchema>; export type DeleteMessageParams = z.infer<typeof DeleteMessageSchema>; export type RemoveReactionParams = z.infer<typeof RemoveReactionSchema>; export type GetStreamTopicsParams = z.infer<typeof GetStreamTopicsSchema>; export type GetMessageReadReceiptsParams = z.infer<typeof GetMessageReadReceiptsSchema>; export type EditScheduledMessageParams = z.infer<typeof EditScheduledMessageSchema>; export type EditDraftParams = z.infer<typeof EditDraftSchema>; export type GetSubscribedStreamsParams = z.infer<typeof GetSubscribedStreamsSchema>; export type GetStreamIdParams = z.infer<typeof GetStreamIdSchema>; export type GetStreamByIdParams = z.infer<typeof GetStreamByIdSchema>;

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