Skip to content

Commit 2b7fccf

Browse files
committed
refactor to parse params individually
1 parent c590779 commit 2b7fccf

File tree

1 file changed

+123
-121
lines changed

1 file changed

+123
-121
lines changed

pkg/github/context_tools.go

Lines changed: 123 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -104,146 +104,148 @@ func GetTeams(getClient GetClientFn, getGQLClient GetGQLClientFn, t translations
104104
Teams []TeamInfo `json:"teams"`
105105
}
106106

107-
tool := mcp.NewTool("get_teams",
108-
mcp.WithDescription(t("TOOL_GET_TEAMS_DESCRIPTION", "Get details of the teams the user is a member of. Limited to organizations accessible with current credentials")),
109-
mcp.WithString("user",
110-
mcp.Description(t("TOOL_GET_TEAMS_USER_DESCRIPTION", "Username to get teams for. If not provided, uses the authenticated user.")),
107+
return mcp.NewTool("get_teams",
108+
mcp.WithDescription(t("TOOL_GET_TEAMS_DESCRIPTION", "Get details of the teams the user is a member of. Limited to organizations accessible with current credentials")),
109+
mcp.WithString("user",
110+
mcp.Description(t("TOOL_GET_TEAMS_USER_DESCRIPTION", "Username to get teams for. If not provided, uses the authenticated user.")),
111+
),
112+
mcp.WithToolAnnotation(mcp.ToolAnnotation{
113+
Title: t("TOOL_GET_TEAMS_TITLE", "Get teams"),
114+
ReadOnlyHint: ToBoolPtr(true),
115+
}),
111116
),
112-
mcp.WithToolAnnotation(mcp.ToolAnnotation{
113-
Title: t("TOOL_GET_TEAMS_TITLE", "Get teams"),
114-
ReadOnlyHint: ToBoolPtr(true),
115-
}),
116-
)
117-
118-
type args struct {
119-
User *string `json:"user,omitempty"`
120-
}
121-
handler := mcp.NewTypedToolHandler(func(ctx context.Context, _ mcp.CallToolRequest, a args) (*mcp.CallToolResult, error) {
122-
var username string
123-
if a.User != nil && *a.User != "" {
124-
username = *a.User
125-
} else {
126-
client, err := getClient(ctx)
117+
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
118+
user, err := OptionalParam[string](request, "user")
127119
if err != nil {
128-
return mcp.NewToolResultErrorFromErr("failed to get GitHub client", err), nil
120+
return mcp.NewToolResultError(err.Error()), nil
129121
}
130122

131-
user, res, err := client.Users.Get(ctx, "")
132-
if err != nil {
133-
return ghErrors.NewGitHubAPIErrorResponse(ctx,
134-
"failed to get user",
135-
res,
136-
err,
137-
), nil
123+
var username string
124+
if user != "" {
125+
username = user
126+
} else {
127+
client, err := getClient(ctx)
128+
if err != nil {
129+
return mcp.NewToolResultErrorFromErr("failed to get GitHub client", err), nil
130+
}
131+
132+
userResp, res, err := client.Users.Get(ctx, "")
133+
if err != nil {
134+
return ghErrors.NewGitHubAPIErrorResponse(ctx,
135+
"failed to get user",
136+
res,
137+
err,
138+
), nil
139+
}
140+
username = userResp.GetLogin()
138141
}
139-
username = user.GetLogin()
140-
}
141142

142-
gqlClient, err := getGQLClient(ctx)
143-
if err != nil {
144-
return mcp.NewToolResultErrorFromErr("failed to get GitHub GQL client", err), nil
145-
}
146-
147-
var q struct {
148-
User struct {
149-
Organizations struct {
150-
Nodes []struct {
151-
Login githubv4.String
152-
Teams struct {
153-
Nodes []struct {
154-
Name githubv4.String
155-
Slug githubv4.String
156-
Description githubv4.String
157-
}
158-
} `graphql:"teams(first: 100, userLogins: [$login])"`
159-
}
160-
} `graphql:"organizations(first: 100)"`
161-
} `graphql:"user(login: $login)"`
162-
}
163-
vars := map[string]interface{}{
164-
"login": githubv4.String(username),
165-
}
166-
if err := gqlClient.Query(ctx, &q, vars); err != nil {
167-
return ghErrors.NewGitHubGraphQLErrorResponse(ctx, "Failed to find teams", err), nil
168-
}
143+
gqlClient, err := getGQLClient(ctx)
144+
if err != nil {
145+
return mcp.NewToolResultErrorFromErr("failed to get GitHub GQL client", err), nil
146+
}
169147

170-
var organizations []OrganizationTeams
171-
for _, org := range q.User.Organizations.Nodes {
172-
orgTeams := OrganizationTeams{
173-
Login: string(org.Login),
174-
Teams: make([]TeamInfo, 0, len(org.Teams.Nodes)),
148+
var q struct {
149+
User struct {
150+
Organizations struct {
151+
Nodes []struct {
152+
Login githubv4.String
153+
Teams struct {
154+
Nodes []struct {
155+
Name githubv4.String
156+
Slug githubv4.String
157+
Description githubv4.String
158+
}
159+
} `graphql:"teams(first: 100, userLogins: [$login])"`
160+
}
161+
} `graphql:"organizations(first: 100)"`
162+
} `graphql:"user(login: $login)"`
163+
}
164+
vars := map[string]interface{}{
165+
"login": githubv4.String(username),
166+
}
167+
if err := gqlClient.Query(ctx, &q, vars); err != nil {
168+
return ghErrors.NewGitHubGraphQLErrorResponse(ctx, "Failed to find teams", err), nil
175169
}
176170

177-
for _, team := range org.Teams.Nodes {
178-
orgTeams.Teams = append(orgTeams.Teams, TeamInfo{
179-
Name: string(team.Name),
180-
Slug: string(team.Slug),
181-
Description: string(team.Description),
182-
})
171+
var organizations []OrganizationTeams
172+
for _, org := range q.User.Organizations.Nodes {
173+
orgTeams := OrganizationTeams{
174+
Login: string(org.Login),
175+
Teams: make([]TeamInfo, 0, len(org.Teams.Nodes)),
176+
}
177+
178+
for _, team := range org.Teams.Nodes {
179+
orgTeams.Teams = append(orgTeams.Teams, TeamInfo{
180+
Name: string(team.Name),
181+
Slug: string(team.Slug),
182+
Description: string(team.Description),
183+
})
184+
}
185+
186+
organizations = append(organizations, orgTeams)
183187
}
184188

185-
organizations = append(organizations, orgTeams)
189+
return MarshalledTextResult(organizations), nil
186190
}
187-
188-
return MarshalledTextResult(organizations), nil
189-
})
190-
191-
return tool, handler
192191
}
193192

194193
func GetTeamMembers(getGQLClient GetGQLClientFn, t translations.TranslationHelperFunc) (mcp.Tool, server.ToolHandlerFunc) {
195-
tool := mcp.NewTool("get_team_members",
196-
mcp.WithDescription(t("TOOL_GET_TEAM_MEMBERS_DESCRIPTION", "Get member usernames of a specific team in an organization. Limited to organizations accessible with current credentials")),
197-
mcp.WithString("org",
198-
mcp.Description(t("TOOL_GET_TEAM_MEMBERS_ORG_DESCRIPTION", "Organization login (owner) that contains the team.")),
199-
mcp.Required(),
200-
),
201-
mcp.WithString("team_slug",
202-
mcp.Description(t("TOOL_GET_TEAM_MEMBERS_TEAM_SLUG_DESCRIPTION", "Team slug")),
203-
mcp.Required(),
194+
return mcp.NewTool("get_team_members",
195+
mcp.WithDescription(t("TOOL_GET_TEAM_MEMBERS_DESCRIPTION", "Get member usernames of a specific team in an organization. Limited to organizations accessible with current credentials")),
196+
mcp.WithString("org",
197+
mcp.Description(t("TOOL_GET_TEAM_MEMBERS_ORG_DESCRIPTION", "Organization login (owner) that contains the team.")),
198+
mcp.Required(),
199+
),
200+
mcp.WithString("team_slug",
201+
mcp.Description(t("TOOL_GET_TEAM_MEMBERS_TEAM_SLUG_DESCRIPTION", "Team slug")),
202+
mcp.Required(),
203+
),
204+
mcp.WithToolAnnotation(mcp.ToolAnnotation{
205+
Title: t("TOOL_GET_TEAM_MEMBERS_TITLE", "Get team members"),
206+
ReadOnlyHint: ToBoolPtr(true),
207+
}),
204208
),
205-
mcp.WithToolAnnotation(mcp.ToolAnnotation{
206-
Title: t("TOOL_GET_TEAM_MEMBERS_TITLE", "Get team members"),
207-
ReadOnlyHint: ToBoolPtr(true),
208-
}),
209-
)
209+
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
210+
org, err := RequiredParam[string](request, "org")
211+
if err != nil {
212+
return mcp.NewToolResultError(err.Error()), nil
213+
}
210214

211-
type args struct {
212-
Org string `json:"org"`
213-
TeamSlug string `json:"team_slug"`
214-
}
215-
handler := mcp.NewTypedToolHandler(func(ctx context.Context, _ mcp.CallToolRequest, a args) (*mcp.CallToolResult, error) {
216-
gqlClient, err := getGQLClient(ctx)
217-
if err != nil {
218-
return mcp.NewToolResultErrorFromErr("failed to get GitHub GQL client", err), nil
219-
}
215+
teamSlug, err := RequiredParam[string](request, "team_slug")
216+
if err != nil {
217+
return mcp.NewToolResultError(err.Error()), nil
218+
}
220219

221-
var q struct {
222-
Organization struct {
223-
Team struct {
224-
Members struct {
225-
Nodes []struct {
226-
Login githubv4.String
227-
}
228-
} `graphql:"members(first: 100)"`
229-
} `graphql:"team(slug: $teamSlug)"`
230-
} `graphql:"organization(login: $org)"`
231-
}
232-
vars := map[string]interface{}{
233-
"org": githubv4.String(a.Org),
234-
"teamSlug": githubv4.String(a.TeamSlug),
235-
}
236-
if err := gqlClient.Query(ctx, &q, vars); err != nil {
237-
return ghErrors.NewGitHubGraphQLErrorResponse(ctx, "Failed to get team members", err), nil
238-
}
220+
gqlClient, err := getGQLClient(ctx)
221+
if err != nil {
222+
return mcp.NewToolResultErrorFromErr("failed to get GitHub GQL client", err), nil
223+
}
239224

240-
var members []string
241-
for _, member := range q.Organization.Team.Members.Nodes {
242-
members = append(members, string(member.Login))
243-
}
225+
var q struct {
226+
Organization struct {
227+
Team struct {
228+
Members struct {
229+
Nodes []struct {
230+
Login githubv4.String
231+
}
232+
} `graphql:"members(first: 100)"`
233+
} `graphql:"team(slug: $teamSlug)"`
234+
} `graphql:"organization(login: $org)"`
235+
}
236+
vars := map[string]interface{}{
237+
"org": githubv4.String(org),
238+
"teamSlug": githubv4.String(teamSlug),
239+
}
240+
if err := gqlClient.Query(ctx, &q, vars); err != nil {
241+
return ghErrors.NewGitHubGraphQLErrorResponse(ctx, "Failed to get team members", err), nil
242+
}
244243

245-
return MarshalledTextResult(members), nil
246-
})
244+
var members []string
245+
for _, member := range q.Organization.Team.Members.Nodes {
246+
members = append(members, string(member.Login))
247+
}
247248

248-
return tool, handler
249+
return MarshalledTextResult(members), nil
250+
}
249251
}

0 commit comments

Comments
 (0)