Skip to content

Commit 3ec8699

Browse files
chore: groundwork for multi-user to server
1 parent 86fbc85 commit 3ec8699

15 files changed

+287
-143
lines changed

cmd/github-mcp-server/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,11 @@ func runStdioServer(cfg runConfig) error {
137137

138138
t, dumpTranslations := translations.TranslationHelper()
139139

140+
getClient := func(_ context.Context) (*gogithub.Client, error) {
141+
return ghClient, nil // closing over client
142+
}
140143
// Create
141-
ghServer := github.NewServer(ghClient, version, cfg.readOnly, t)
144+
ghServer := github.NewServer(getClient, version, cfg.readOnly, t)
142145
stdioServer := server.NewStdioServer(ghServer)
143146

144147
stdLogger := stdlog.New(cfg.logger.Writer(), "stdioserver", 0)

pkg/github/code_scanning.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"github.com/mark3labs/mcp-go/server"
1414
)
1515

16-
func GetCodeScanningAlert(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
16+
func GetCodeScanningAlert(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
1717
return mcp.NewTool("get_code_scanning_alert",
1818
mcp.WithDescription(t("TOOL_GET_CODE_SCANNING_ALERT_DESCRIPTION", "Get details of a specific code scanning alert in a GitHub repository.")),
1919
mcp.WithString("owner",
@@ -43,6 +43,11 @@ func GetCodeScanningAlert(client *github.Client, t translations.TranslationHelpe
4343
return mcp.NewToolResultError(err.Error()), nil
4444
}
4545

46+
client, err := getClient(ctx)
47+
if err != nil {
48+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
49+
}
50+
4651
alert, resp, err := client.CodeScanning.GetAlert(ctx, owner, repo, int64(alertNumber))
4752
if err != nil {
4853
return nil, fmt.Errorf("failed to get alert: %w", err)
@@ -66,7 +71,7 @@ func GetCodeScanningAlert(client *github.Client, t translations.TranslationHelpe
6671
}
6772
}
6873

69-
func ListCodeScanningAlerts(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
74+
func ListCodeScanningAlerts(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
7075
return mcp.NewTool("list_code_scanning_alerts",
7176
mcp.WithDescription(t("TOOL_LIST_CODE_SCANNING_ALERTS_DESCRIPTION", "List code scanning alerts in a GitHub repository.")),
7277
mcp.WithString("owner",
@@ -110,6 +115,10 @@ func ListCodeScanningAlerts(client *github.Client, t translations.TranslationHel
110115
return mcp.NewToolResultError(err.Error()), nil
111116
}
112117

118+
client, err := getClient(ctx)
119+
if err != nil {
120+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
121+
}
113122
alerts, resp, err := client.CodeScanning.ListAlertsForRepo(ctx, owner, repo, &github.AlertListOptions{Ref: ref, State: state, Severity: severity})
114123
if err != nil {
115124
return nil, fmt.Errorf("failed to list alerts: %w", err)

pkg/github/code_scanning_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
func Test_GetCodeScanningAlert(t *testing.T) {
1717
// Verify tool definition once
1818
mockClient := github.NewClient(nil)
19-
tool, _ := GetCodeScanningAlert(mockClient, translations.NullTranslationHelper)
19+
tool, _ := GetCodeScanningAlert(stubGetClientFn(mockClient), translations.NullTranslationHelper)
2020

2121
assert.Equal(t, "get_code_scanning_alert", tool.Name)
2222
assert.NotEmpty(t, tool.Description)
@@ -82,7 +82,7 @@ func Test_GetCodeScanningAlert(t *testing.T) {
8282
t.Run(tc.name, func(t *testing.T) {
8383
// Setup client with mock
8484
client := github.NewClient(tc.mockedClient)
85-
_, handler := GetCodeScanningAlert(client, translations.NullTranslationHelper)
85+
_, handler := GetCodeScanningAlert(stubGetClientFn(client), translations.NullTranslationHelper)
8686

8787
// Create call request
8888
request := createMCPRequest(tc.requestArgs)
@@ -118,7 +118,7 @@ func Test_GetCodeScanningAlert(t *testing.T) {
118118
func Test_ListCodeScanningAlerts(t *testing.T) {
119119
// Verify tool definition once
120120
mockClient := github.NewClient(nil)
121-
tool, _ := ListCodeScanningAlerts(mockClient, translations.NullTranslationHelper)
121+
tool, _ := ListCodeScanningAlerts(stubGetClientFn(mockClient), translations.NullTranslationHelper)
122122

123123
assert.Equal(t, "list_code_scanning_alerts", tool.Name)
124124
assert.NotEmpty(t, tool.Description)
@@ -201,7 +201,7 @@ func Test_ListCodeScanningAlerts(t *testing.T) {
201201
t.Run(tc.name, func(t *testing.T) {
202202
// Setup client with mock
203203
client := github.NewClient(tc.mockedClient)
204-
_, handler := ListCodeScanningAlerts(client, translations.NullTranslationHelper)
204+
_, handler := ListCodeScanningAlerts(stubGetClientFn(client), translations.NullTranslationHelper)
205205

206206
// Create call request
207207
request := createMCPRequest(tc.requestArgs)

pkg/github/issues.go

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
// GetIssue creates a tool to get details of a specific issue in a GitHub repository.
18-
func GetIssue(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
18+
func GetIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
1919
return mcp.NewTool("get_issue",
2020
mcp.WithDescription(t("TOOL_GET_ISSUE_DESCRIPTION", "Get details of a specific issue in a GitHub repository")),
2121
mcp.WithString("owner",
@@ -45,6 +45,10 @@ func GetIssue(client *github.Client, t translations.TranslationHelperFunc) (tool
4545
return mcp.NewToolResultError(err.Error()), nil
4646
}
4747

48+
client, err := getClient(ctx)
49+
if err != nil {
50+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
51+
}
4852
issue, resp, err := client.Issues.Get(ctx, owner, repo, issueNumber)
4953
if err != nil {
5054
return nil, fmt.Errorf("failed to get issue: %w", err)
@@ -69,7 +73,7 @@ func GetIssue(client *github.Client, t translations.TranslationHelperFunc) (tool
6973
}
7074

7175
// AddIssueComment creates a tool to add a comment to an issue.
72-
func AddIssueComment(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
76+
func AddIssueComment(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
7377
return mcp.NewTool("add_issue_comment",
7478
mcp.WithDescription(t("TOOL_ADD_ISSUE_COMMENT_DESCRIPTION", "Add a comment to an existing issue")),
7579
mcp.WithString("owner",
@@ -111,6 +115,10 @@ func AddIssueComment(client *github.Client, t translations.TranslationHelperFunc
111115
Body: github.Ptr(body),
112116
}
113117

118+
client, err := getClient(ctx)
119+
if err != nil {
120+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
121+
}
114122
createdComment, resp, err := client.Issues.CreateComment(ctx, owner, repo, issueNumber, comment)
115123
if err != nil {
116124
return nil, fmt.Errorf("failed to create comment: %w", err)
@@ -135,7 +143,7 @@ func AddIssueComment(client *github.Client, t translations.TranslationHelperFunc
135143
}
136144

137145
// SearchIssues creates a tool to search for issues and pull requests.
138-
func SearchIssues(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
146+
func SearchIssues(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
139147
return mcp.NewTool("search_issues",
140148
mcp.WithDescription(t("TOOL_SEARCH_ISSUES_DESCRIPTION", "Search for issues and pull requests across GitHub repositories")),
141149
mcp.WithString("q",
@@ -191,6 +199,10 @@ func SearchIssues(client *github.Client, t translations.TranslationHelperFunc) (
191199
},
192200
}
193201

202+
client, err := getClient(ctx)
203+
if err != nil {
204+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
205+
}
194206
result, resp, err := client.Search.Issues(ctx, query, opts)
195207
if err != nil {
196208
return nil, fmt.Errorf("failed to search issues: %w", err)
@@ -215,7 +227,7 @@ func SearchIssues(client *github.Client, t translations.TranslationHelperFunc) (
215227
}
216228

217229
// CreateIssue creates a tool to create a new issue in a GitHub repository.
218-
func CreateIssue(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
230+
func CreateIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
219231
return mcp.NewTool("create_issue",
220232
mcp.WithDescription(t("TOOL_CREATE_ISSUE_DESCRIPTION", "Create a new issue in a GitHub repository")),
221233
mcp.WithString("owner",
@@ -305,6 +317,10 @@ func CreateIssue(client *github.Client, t translations.TranslationHelperFunc) (t
305317
Milestone: milestoneNum,
306318
}
307319

320+
client, err := getClient(ctx)
321+
if err != nil {
322+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
323+
}
308324
issue, resp, err := client.Issues.Create(ctx, owner, repo, issueRequest)
309325
if err != nil {
310326
return nil, fmt.Errorf("failed to create issue: %w", err)
@@ -329,7 +345,7 @@ func CreateIssue(client *github.Client, t translations.TranslationHelperFunc) (t
329345
}
330346

331347
// ListIssues creates a tool to list and filter repository issues
332-
func ListIssues(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
348+
func ListIssues(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
333349
return mcp.NewTool("list_issues",
334350
mcp.WithDescription(t("TOOL_LIST_ISSUES_DESCRIPTION", "List issues in a GitHub repository with filtering options")),
335351
mcp.WithString("owner",
@@ -419,6 +435,10 @@ func ListIssues(client *github.Client, t translations.TranslationHelperFunc) (to
419435
opts.PerPage = int(perPage)
420436
}
421437

438+
client, err := getClient(ctx)
439+
if err != nil {
440+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
441+
}
422442
issues, resp, err := client.Issues.ListByRepo(ctx, owner, repo, opts)
423443
if err != nil {
424444
return nil, fmt.Errorf("failed to list issues: %w", err)
@@ -443,7 +463,7 @@ func ListIssues(client *github.Client, t translations.TranslationHelperFunc) (to
443463
}
444464

445465
// UpdateIssue creates a tool to update an existing issue in a GitHub repository.
446-
func UpdateIssue(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
466+
func UpdateIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
447467
return mcp.NewTool("update_issue",
448468
mcp.WithDescription(t("TOOL_UPDATE_ISSUE_DESCRIPTION", "Update an existing issue in a GitHub repository")),
449469
mcp.WithString("owner",
@@ -557,6 +577,10 @@ func UpdateIssue(client *github.Client, t translations.TranslationHelperFunc) (t
557577
issueRequest.Milestone = &milestoneNum
558578
}
559579

580+
client, err := getClient(ctx)
581+
if err != nil {
582+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
583+
}
560584
updatedIssue, resp, err := client.Issues.Edit(ctx, owner, repo, issueNumber, issueRequest)
561585
if err != nil {
562586
return nil, fmt.Errorf("failed to update issue: %w", err)
@@ -581,7 +605,7 @@ func UpdateIssue(client *github.Client, t translations.TranslationHelperFunc) (t
581605
}
582606

583607
// GetIssueComments creates a tool to get comments for a GitHub issue.
584-
func GetIssueComments(client *github.Client, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
608+
func GetIssueComments(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
585609
return mcp.NewTool("get_issue_comments",
586610
mcp.WithDescription(t("TOOL_GET_ISSUE_COMMENTS_DESCRIPTION", "Get comments for a GitHub issue")),
587611
mcp.WithString("owner",
@@ -632,6 +656,10 @@ func GetIssueComments(client *github.Client, t translations.TranslationHelperFun
632656
},
633657
}
634658

659+
client, err := getClient(ctx)
660+
if err != nil {
661+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
662+
}
635663
comments, resp, err := client.Issues.ListComments(ctx, owner, repo, issueNumber, opts)
636664
if err != nil {
637665
return nil, fmt.Errorf("failed to get issue comments: %w", err)

pkg/github/issues_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
func Test_GetIssue(t *testing.T) {
1919
// Verify tool definition once
2020
mockClient := github.NewClient(nil)
21-
tool, _ := GetIssue(mockClient, translations.NullTranslationHelper)
21+
tool, _ := GetIssue(stubGetClientFn(mockClient), translations.NullTranslationHelper)
2222

2323
assert.Equal(t, "get_issue", tool.Name)
2424
assert.NotEmpty(t, tool.Description)
@@ -82,7 +82,7 @@ func Test_GetIssue(t *testing.T) {
8282
t.Run(tc.name, func(t *testing.T) {
8383
// Setup client with mock
8484
client := github.NewClient(tc.mockedClient)
85-
_, handler := GetIssue(client, translations.NullTranslationHelper)
85+
_, handler := GetIssue(stubGetClientFn(client), translations.NullTranslationHelper)
8686

8787
// Create call request
8888
request := createMCPRequest(tc.requestArgs)
@@ -114,7 +114,7 @@ func Test_GetIssue(t *testing.T) {
114114
func Test_AddIssueComment(t *testing.T) {
115115
// Verify tool definition once
116116
mockClient := github.NewClient(nil)
117-
tool, _ := AddIssueComment(mockClient, translations.NullTranslationHelper)
117+
tool, _ := AddIssueComment(stubGetClientFn(mockClient), translations.NullTranslationHelper)
118118

119119
assert.Equal(t, "add_issue_comment", tool.Name)
120120
assert.NotEmpty(t, tool.Description)
@@ -185,7 +185,7 @@ func Test_AddIssueComment(t *testing.T) {
185185
t.Run(tc.name, func(t *testing.T) {
186186
// Setup client with mock
187187
client := github.NewClient(tc.mockedClient)
188-
_, handler := AddIssueComment(client, translations.NullTranslationHelper)
188+
_, handler := AddIssueComment(stubGetClientFn(client), translations.NullTranslationHelper)
189189

190190
// Create call request
191191
request := mcp.CallToolRequest{
@@ -237,7 +237,7 @@ func Test_AddIssueComment(t *testing.T) {
237237
func Test_SearchIssues(t *testing.T) {
238238
// Verify tool definition once
239239
mockClient := github.NewClient(nil)
240-
tool, _ := SearchIssues(mockClient, translations.NullTranslationHelper)
240+
tool, _ := SearchIssues(stubGetClientFn(mockClient), translations.NullTranslationHelper)
241241

242242
assert.Equal(t, "search_issues", tool.Name)
243243
assert.NotEmpty(t, tool.Description)
@@ -352,7 +352,7 @@ func Test_SearchIssues(t *testing.T) {
352352
t.Run(tc.name, func(t *testing.T) {
353353
// Setup client with mock
354354
client := github.NewClient(tc.mockedClient)
355-
_, handler := SearchIssues(client, translations.NullTranslationHelper)
355+
_, handler := SearchIssues(stubGetClientFn(client), translations.NullTranslationHelper)
356356

357357
// Create call request
358358
request := createMCPRequest(tc.requestArgs)
@@ -393,7 +393,7 @@ func Test_SearchIssues(t *testing.T) {
393393
func Test_CreateIssue(t *testing.T) {
394394
// Verify tool definition once
395395
mockClient := github.NewClient(nil)
396-
tool, _ := CreateIssue(mockClient, translations.NullTranslationHelper)
396+
tool, _ := CreateIssue(stubGetClientFn(mockClient), translations.NullTranslationHelper)
397397

398398
assert.Equal(t, "create_issue", tool.Name)
399399
assert.NotEmpty(t, tool.Description)
@@ -506,7 +506,7 @@ func Test_CreateIssue(t *testing.T) {
506506
t.Run(tc.name, func(t *testing.T) {
507507
// Setup client with mock
508508
client := github.NewClient(tc.mockedClient)
509-
_, handler := CreateIssue(client, translations.NullTranslationHelper)
509+
_, handler := CreateIssue(stubGetClientFn(client), translations.NullTranslationHelper)
510510

511511
// Create call request
512512
request := createMCPRequest(tc.requestArgs)
@@ -567,7 +567,7 @@ func Test_CreateIssue(t *testing.T) {
567567
func Test_ListIssues(t *testing.T) {
568568
// Verify tool definition
569569
mockClient := github.NewClient(nil)
570-
tool, _ := ListIssues(mockClient, translations.NullTranslationHelper)
570+
tool, _ := ListIssues(stubGetClientFn(mockClient), translations.NullTranslationHelper)
571571

572572
assert.Equal(t, "list_issues", tool.Name)
573573
assert.NotEmpty(t, tool.Description)
@@ -698,7 +698,7 @@ func Test_ListIssues(t *testing.T) {
698698
t.Run(tc.name, func(t *testing.T) {
699699
// Setup client with mock
700700
client := github.NewClient(tc.mockedClient)
701-
_, handler := ListIssues(client, translations.NullTranslationHelper)
701+
_, handler := ListIssues(stubGetClientFn(client), translations.NullTranslationHelper)
702702

703703
// Create call request
704704
request := createMCPRequest(tc.requestArgs)
@@ -743,7 +743,7 @@ func Test_ListIssues(t *testing.T) {
743743
func Test_UpdateIssue(t *testing.T) {
744744
// Verify tool definition
745745
mockClient := github.NewClient(nil)
746-
tool, _ := UpdateIssue(mockClient, translations.NullTranslationHelper)
746+
tool, _ := UpdateIssue(stubGetClientFn(mockClient), translations.NullTranslationHelper)
747747

748748
assert.Equal(t, "update_issue", tool.Name)
749749
assert.NotEmpty(t, tool.Description)
@@ -882,7 +882,7 @@ func Test_UpdateIssue(t *testing.T) {
882882
t.Run(tc.name, func(t *testing.T) {
883883
// Setup client with mock
884884
client := github.NewClient(tc.mockedClient)
885-
_, handler := UpdateIssue(client, translations.NullTranslationHelper)
885+
_, handler := UpdateIssue(stubGetClientFn(client), translations.NullTranslationHelper)
886886

887887
// Create call request
888888
request := createMCPRequest(tc.requestArgs)
@@ -1000,7 +1000,7 @@ func Test_ParseISOTimestamp(t *testing.T) {
10001000
func Test_GetIssueComments(t *testing.T) {
10011001
// Verify tool definition once
10021002
mockClient := github.NewClient(nil)
1003-
tool, _ := GetIssueComments(mockClient, translations.NullTranslationHelper)
1003+
tool, _ := GetIssueComments(stubGetClientFn(mockClient), translations.NullTranslationHelper)
10041004

10051005
assert.Equal(t, "get_issue_comments", tool.Name)
10061006
assert.NotEmpty(t, tool.Description)
@@ -1100,7 +1100,7 @@ func Test_GetIssueComments(t *testing.T) {
11001100
t.Run(tc.name, func(t *testing.T) {
11011101
// Setup client with mock
11021102
client := github.NewClient(tc.mockedClient)
1103-
_, handler := GetIssueComments(client, translations.NullTranslationHelper)
1103+
_, handler := GetIssueComments(stubGetClientFn(client), translations.NullTranslationHelper)
11041104

11051105
// Create call request
11061106
request := createMCPRequest(tc.requestArgs)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy