Skip to content

feat: add get_user tool to fetch user by username (#1970)#2246

Open
sierikov wants to merge 1 commit intogithub:mainfrom
sierikov:feat/1970-add-get-user-tool
Open

feat: add get_user tool to fetch user by username (#1970)#2246
sierikov wants to merge 1 commit intogithub:mainfrom
sierikov:feat/1970-add-get-user-tool

Conversation

@sierikov
Copy link

Summary

Add a new get_user MCP tool that retrieves a GitHub user's profile by username using the public GET /users/{username} endpoint. Returns a MinimalUser with UserDetails to keep responses token-efficient for LLM consumers.

Why

Fixes #1970

What changed

  • Added pkg/github/users.go with GetUser tool definition and getUserHandler implementation
  • Added pkg/github/users_test.go with tests for successful lookup, user not found, and API error cases
  • Registered GetUser in the users toolset in pkg/github/tools.go
  • Renamed GetUser test constant to GetAuthenticatedUser in pkg/github/helper_test.go to avoid conflict with the new function name, and added GetUserByUsername constant
  • Updated 5 references in pkg/github/context_tools_test.go to use renamed constant
  • Auto-generated pkg/github/__toolsnaps__/get_user.snap and updated README.md via script/generate-docs

MCP impact

  • No tool or API changes
  • Tool schema or behavior changed
  • New tool added — get_user accepts a required username string parameter and returns the user's profile as a MinimalUser with UserDetails. Annotated with ReadOnlyHint: true. Registered under the users toolset.

Prompts tested (tool changes only)

  • "Get the profile of user octocat"
  • "Who is SamMorrowDrums on GitHub?"
  • "use the get_user tool for torvalds"

Security / limits

  • Auth / permissions considered — Uses the public GET /users/{username} endpoint. Scopes are nil since GitHub returns data based on the token's existing permissions without requiring additional scopes.
  • Data exposure, filtering, or token/size limits considered — Returns MinimalUser with UserDetail rather than the full github.User` object.

Tool renaming

  • I am not renaming tools as part of this PR

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Updated (README / docs / examples) — README.md regenerated via script/generate-docs

@sierikov sierikov requested a review from a team as a code owner March 21, 2026 13:46
Copilot AI review requested due to automatic review settings March 21, 2026 13:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new MCP tool (get_user) to fetch a GitHub user profile by username via GET /users/{username}, returning the existing token-efficient MinimalUser shape with UserDetails.

Changes:

  • Added get_user tool implementation and tool snapshot.
  • Added unit tests covering success and error paths for get_user.
  • Registered the tool in the users toolset and updated docs/README generation output.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/github/users.go Introduces the get_user tool definition and handler that calls client.Users.Get(ctx, username) and returns MinimalUser + UserDetails.
pkg/github/users_test.go Adds tests validating the tool schema snapshot and handler behavior across success/error scenarios.
pkg/github/tools.go Registers GetUser in AllTools under the users tools grouping.
pkg/github/helper_test.go Renames the existing /user endpoint constant to avoid naming conflict; adds /users/{username} endpoint constant.
pkg/github/context_tools_test.go Updates references to the renamed authenticated-user endpoint constant.
pkg/github/toolsnaps/get_user.snap Adds the generated schema snapshot for the new tool.
README.md Updates tool documentation list to include get_user.

Comment on lines +64 to +88
minimalUser := MinimalUser{
Login: user.GetLogin(),
ID: user.GetID(),
ProfileURL: user.GetHTMLURL(),
AvatarURL: user.GetAvatarURL(),
Details: &UserDetails{
Name: user.GetName(),
Company: user.GetCompany(),
Blog: user.GetBlog(),
Location: user.GetLocation(),
Email: user.GetEmail(),
Hireable: user.GetHireable(),
Bio: user.GetBio(),
TwitterUsername: user.GetTwitterUsername(),
PublicRepos: user.GetPublicRepos(),
PublicGists: user.GetPublicGists(),
Followers: user.GetFollowers(),
Following: user.GetFollowing(),
CreatedAt: user.GetCreatedAt().Time,
UpdatedAt: user.GetUpdatedAt().Time,
PrivateGists: user.GetPrivateGists(),
TotalPrivateRepos: user.GetTotalPrivateRepos(),
OwnedPrivateRepos: user.GetOwnedPrivateRepos(),
},
}
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MinimalUser/UserDetails mapping here duplicates the same field-by-field conversion logic in GetMe (context_tools.go). Since this is now shared behavior across multiple tools, consider extracting a small helper (e.g., buildMinimalUserWithDetails(*github.User)) to avoid future divergence when the shape changes.

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. But right now there are only two call sites (GetMe and GetUser), and the conversion is straightforward field mapping. I'd prefer to wait for a third consumer before extracting a helper.

Add a new `get_user` MCP tool that retrieves a GitHub user's profile
by username using the public `GET /users/{username}` endpoint. Returns
a MinimalUser with UserDetails.
@sierikov sierikov force-pushed the feat/1970-add-get-user-tool branch from fed1050 to 016e243 Compare March 21, 2026 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Add get_user tool to fetch a user profile by username

2 participants