search_users
Search for GitHub users by location, language, follower count, and more using advanced query syntax. Sort results by followers, repositories, or join date.
Instructions
Search for GitHub users.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Search query using GitHub users search syntax. Examples: 'location:"San Francisco" followers:>100', 'language:python repos:>50', 'fullname:"John Doe"', 'type:user', 'type:org', 'created:>2020-01-01', 'in:email example.com' | |
| sort | No | Sort field by category | |
| order | No | Sort order | |
| per_page | No | Results per page (default 10, max 100) | |
| page | No | Page number (default 1) |
Implementation Reference
- src/tools/search.ts:257-352 (handler)The handler function for the 'search_users' tool. Calls octokit.rest.search.users and formats results (login, name, bio, location, company, repos, followers). Registered via server.tool() as an MCP tool.
// Tool: Search Users server.tool( "search_users", "Search for GitHub users.", { q: z .string() .describe( "Search query using GitHub users search syntax. Examples: 'location:\"San Francisco\" followers:>100', 'language:python repos:>50', 'fullname:\"John Doe\"', 'type:user', 'type:org', 'created:>2020-01-01', 'in:email example.com'", ), sort: z .enum(["followers", "repositories", "joined"]) .optional() .describe("Sort field by category"), order: z.enum(["asc", "desc"]).optional().describe("Sort order"), per_page: z .number() .optional() .default(10) .describe("Results per page (default 10, max 100)"), page: z .number() .optional() .default(1) .describe("Page number (default 1)"), }, async ({ q, sort, order, per_page, page }) => { try { const response = await octokit.rest.search.users({ q, sort, order, per_page, page, }) // Extract only essential information const users = response.data.items.map(user => ({ login: user.login, type: user.type, // Only include name if it exists and is different from login ...(user.name && user.name !== user.login ? { name: user.name } : {}), // Include bio if it exists (truncated) ...(user.bio ? { bio: user.bio.slice(0, 100) + (user.bio.length > 100 ? "..." : ""), } : {}), // Include location if it exists ...(user.location ? { location: user.location } : {}), // Include company if it exists ...(user.company ? { company: user.company } : {}), // Include public repos if > 0 ...(user.public_repos && user.public_repos > 0 ? { repos: user.public_repos } : {}), // Only include followers if > 0 ...(user.followers && user.followers > 0 ? { followers: user.followers } : {}), })) // Format as simple text const text = users .map((user, i) => { let line = `${i + 1}. **${user.login}**${user.name ? ` (${user.name})` : ""}${user.type === "Organization" ? " `[org]`" : ""}` const details = [] if (user.followers) details.push(`${user.followers.toLocaleString()} followers`) if (user.repos) details.push(`${user.repos} repos`) if (user.location) details.push(user.location) if (user.company) details.push(user.company) if (details.length > 0) line += `\n ${details.join(" • ")}` if (user.bio) line += `\n > ${user.bio}` return line }) .join("\n\n") return { content: [ { type: "text", text: text ? `### Found ${users.length} users:\n\n${text}` : "No users found", }, ], } } catch (e: any) { return { content: [{ type: "text", text: `Error: ${e.message}` }], } } }, ) - src/tools/search.ts:261-282 (schema)Zod schema for input validation of the search_users tool: query string (required), sort by followers/repositories/joined, order asc/desc, per_page (default 10), page (default 1).
{ q: z .string() .describe( "Search query using GitHub users search syntax. Examples: 'location:\"San Francisco\" followers:>100', 'language:python repos:>50', 'fullname:\"John Doe\"', 'type:user', 'type:org', 'created:>2020-01-01', 'in:email example.com'", ), sort: z .enum(["followers", "repositories", "joined"]) .optional() .describe("Sort field by category"), order: z.enum(["asc", "desc"]).optional().describe("Sort order"), per_page: z .number() .optional() .default(10) .describe("Results per page (default 10, max 100)"), page: z .number() .optional() .default(1) .describe("Page number (default 1)"), }, - src/tools/search.ts:257-260 (registration)Registration of the 'search_users' tool via server.tool() within the registerSearchTools function in src/tools/search.ts.
// Tool: Search Users server.tool( "search_users", "Search for GitHub users.", - src/index.ts:15-15 (registration)Call to registerSearchTools from the main index.ts entry point, which registers all search tools including search_users.
registerSearchTools(server, octokit)