slack_search_users
Search for Slack users by partial match on username, display name, or real name. Specify a query to find matching users, with optional limit and bot inclusion.
Instructions
Search for users by partial name match across username, display name, and real name. Use this when you need to find users containing specific keywords in their names. Returns up to the specified limit of matching users.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search users by name, display name, or real name (partial match, case-insensitive) | |
| limit | No | Maximum number of users to return (default 20) | |
| include_bots | No | Include bot users in results (default false) |
Implementation Reference
- src/schemas.ts:240-259 (schema)Input validation schema for slack_search_users tool. Defines 'query' (string, required), 'limit' (1-100, default 20), and 'include_bots' (boolean, default false).
export const SearchUsersRequestSchema = z.object({ query: z .string() .describe( 'Search users by name, display name, or real name (partial match, case-insensitive)' ), limit: z .number() .int() .min(1) .max(100) .optional() .default(20) .describe('Maximum number of users to return (default 20)'), include_bots: z .boolean() .optional() .default(false) .describe('Include bot users in results (default false)'), }); - src/index.ts:170-175 (registration)Registration of slack_search_users tool in the ListTools handler. Sets name, description, and inputSchema.
{ name: 'slack_search_users', description: 'Search for users by partial name match across username, display name, and real name. Use this when you need to find users containing specific keywords in their names. Returns up to the specified limit of matching users.', inputSchema: zodToJsonSchema(SearchUsersRequestSchema), }, - src/index.ts:501-578 (handler)Handler implementation for slack_search_users. Fetches all users via Slack API (paginated), filters by case-insensitive partial match on name/display_name/real_name, excludes bots unless include_bots is true, limits results, and returns the response.
case 'slack_search_users': { const args = SearchUsersRequestSchema.parse(request.params.arguments); // Fetch all users with a reasonable limit const allUsers: Array<{ id?: string; name?: string; real_name?: string; is_bot?: boolean; profile?: { display_name?: string; display_name_normalized?: string; [key: string]: unknown; }; [key: string]: unknown; }> = []; let cursor: string | undefined; const maxPages = 5; // Limit to prevent infinite loops let pageCount = 0; // Fetch multiple pages if needed while (pageCount < maxPages) { const response = await slackClient.users.list({ limit: 1000, // Max allowed by Slack API cursor, }); if (!response.ok) { throw new Error(`Failed to search users: ${response.error}`); } if (response.members) { allUsers.push(...(response.members as typeof allUsers)); } cursor = response.response_metadata?.next_cursor; pageCount++; // Stop if no more pages if (!cursor) break; } // Filter users (case-insensitive partial match across multiple fields) const searchTerm = args.query.toLowerCase(); const filteredUsers = allUsers.filter((user) => { // Skip bots if requested if (!args.include_bots && user.is_bot) { return false; } // Search across multiple name fields const name = user.name?.toLowerCase() || ''; const realName = user.real_name?.toLowerCase() || ''; const displayName = user.profile?.display_name?.toLowerCase() || ''; const displayNameNormalized = user.profile?.display_name_normalized?.toLowerCase() || ''; return ( name.includes(searchTerm) || realName.includes(searchTerm) || displayName.includes(searchTerm) || displayNameNormalized.includes(searchTerm) ); }); // Limit results const limitedUsers = filteredUsers.slice(0, args.limit); const response = { ok: true, members: limitedUsers, }; const parsed = GetUsersResponseSchema.parse(response); return { content: [{ type: 'text', text: JSON.stringify(parsed) }], }; }