refactor(search): migrate search tools to new ServerTool pattern
Migrate search.go tools (SearchRepositories, SearchCode, SearchUsers, SearchOrgs) to use the new NewTool helper and ToolDependencies pattern. - Functions now take only TranslationHelperFunc and return ServerTool - Handler generation uses ToolDependencies for typed access to clients - Update tools.go call sites to remove getClient parameter - Update tests to use new Handler(deps) pattern This demonstrates the migration pattern for additional tool files. Co-authored-by: Adam Holt <omgitsads@users.noreply.github.com>
This commit is contained in:
+194
-175
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
ghErrors "github.com/github/github-mcp-server/pkg/errors"
|
||||
"github.com/github/github-mcp-server/pkg/toolsets"
|
||||
"github.com/github/github-mcp-server/pkg/translations"
|
||||
"github.com/github/github-mcp-server/pkg/utils"
|
||||
"github.com/google/go-github/v79/github"
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// SearchRepositories creates a tool to search for GitHub repositories.
|
||||
func SearchRepositories(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, mcp.ToolHandlerFor[map[string]any, any]) {
|
||||
func SearchRepositories(t translations.TranslationHelperFunc) toolsets.ServerTool {
|
||||
schema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
@@ -44,7 +45,8 @@ func SearchRepositories(getClient GetClientFn, t translations.TranslationHelperF
|
||||
}
|
||||
WithPagination(schema)
|
||||
|
||||
return mcp.Tool{
|
||||
return NewTool(
|
||||
mcp.Tool{
|
||||
Name: "search_repositories",
|
||||
Description: t("TOOL_SEARCH_REPOSITORIES_DESCRIPTION", "Find GitHub repositories by name, description, readme, topics, or other metadata. Perfect for discovering projects, finding examples, or locating specific repositories across GitHub."),
|
||||
Annotations: &mcp.ToolAnnotations{
|
||||
@@ -53,115 +55,118 @@ func SearchRepositories(getClient GetClientFn, t translations.TranslationHelperF
|
||||
},
|
||||
InputSchema: schema,
|
||||
},
|
||||
func(ctx context.Context, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
|
||||
query, err := RequiredParam[string](args, "query")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
sort, err := OptionalParam[string](args, "sort")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
order, err := OptionalParam[string](args, "order")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
pagination, err := OptionalPaginationParams(args)
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
minimalOutput, err := OptionalBoolParamWithDefault(args, "minimal_output", true)
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
opts := &github.SearchOptions{
|
||||
Sort: sort,
|
||||
Order: order,
|
||||
ListOptions: github.ListOptions{
|
||||
Page: pagination.Page,
|
||||
PerPage: pagination.PerPage,
|
||||
},
|
||||
}
|
||||
|
||||
client, err := getClient(ctx)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
|
||||
}
|
||||
result, resp, err := client.Search.Repositories(ctx, query, opts)
|
||||
if err != nil {
|
||||
return ghErrors.NewGitHubAPIErrorResponse(ctx,
|
||||
fmt.Sprintf("failed to search repositories with query '%s'", query),
|
||||
resp,
|
||||
err,
|
||||
), nil, nil
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
func(deps ToolDependencies) mcp.ToolHandlerFor[map[string]any, any] {
|
||||
return func(ctx context.Context, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
|
||||
query, err := RequiredParam[string](args, "query")
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to read response body", err), nil, nil
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
return utils.NewToolResultError(fmt.Sprintf("failed to search repositories: %s", string(body))), nil, nil
|
||||
}
|
||||
|
||||
// Return either minimal or full response based on parameter
|
||||
var r []byte
|
||||
if minimalOutput {
|
||||
minimalRepos := make([]MinimalRepository, 0, len(result.Repositories))
|
||||
for _, repo := range result.Repositories {
|
||||
minimalRepo := MinimalRepository{
|
||||
ID: repo.GetID(),
|
||||
Name: repo.GetName(),
|
||||
FullName: repo.GetFullName(),
|
||||
Description: repo.GetDescription(),
|
||||
HTMLURL: repo.GetHTMLURL(),
|
||||
Language: repo.GetLanguage(),
|
||||
Stars: repo.GetStargazersCount(),
|
||||
Forks: repo.GetForksCount(),
|
||||
OpenIssues: repo.GetOpenIssuesCount(),
|
||||
Private: repo.GetPrivate(),
|
||||
Fork: repo.GetFork(),
|
||||
Archived: repo.GetArchived(),
|
||||
DefaultBranch: repo.GetDefaultBranch(),
|
||||
}
|
||||
|
||||
if repo.UpdatedAt != nil {
|
||||
minimalRepo.UpdatedAt = repo.UpdatedAt.Format("2006-01-02T15:04:05Z")
|
||||
}
|
||||
if repo.CreatedAt != nil {
|
||||
minimalRepo.CreatedAt = repo.CreatedAt.Format("2006-01-02T15:04:05Z")
|
||||
}
|
||||
if repo.Topics != nil {
|
||||
minimalRepo.Topics = repo.Topics
|
||||
}
|
||||
|
||||
minimalRepos = append(minimalRepos, minimalRepo)
|
||||
}
|
||||
|
||||
minimalResult := &MinimalSearchRepositoriesResult{
|
||||
TotalCount: result.GetTotal(),
|
||||
IncompleteResults: result.GetIncompleteResults(),
|
||||
Items: minimalRepos,
|
||||
}
|
||||
|
||||
r, err = json.Marshal(minimalResult)
|
||||
sort, err := OptionalParam[string](args, "sort")
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to marshal minimal response", err), nil, nil
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
} else {
|
||||
r, err = json.Marshal(result)
|
||||
order, err := OptionalParam[string](args, "order")
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to marshal full response", err), nil, nil
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
pagination, err := OptionalPaginationParams(args)
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
minimalOutput, err := OptionalBoolParamWithDefault(args, "minimal_output", true)
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
opts := &github.SearchOptions{
|
||||
Sort: sort,
|
||||
Order: order,
|
||||
ListOptions: github.ListOptions{
|
||||
Page: pagination.Page,
|
||||
PerPage: pagination.PerPage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return utils.NewToolResultText(string(r)), nil, nil
|
||||
}
|
||||
client, err := deps.GetClient(ctx)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
|
||||
}
|
||||
result, resp, err := client.Search.Repositories(ctx, query, opts)
|
||||
if err != nil {
|
||||
return ghErrors.NewGitHubAPIErrorResponse(ctx,
|
||||
fmt.Sprintf("failed to search repositories with query '%s'", query),
|
||||
resp,
|
||||
err,
|
||||
), nil, nil
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to read response body", err), nil, nil
|
||||
}
|
||||
return utils.NewToolResultError(fmt.Sprintf("failed to search repositories: %s", string(body))), nil, nil
|
||||
}
|
||||
|
||||
// Return either minimal or full response based on parameter
|
||||
var r []byte
|
||||
if minimalOutput {
|
||||
minimalRepos := make([]MinimalRepository, 0, len(result.Repositories))
|
||||
for _, repo := range result.Repositories {
|
||||
minimalRepo := MinimalRepository{
|
||||
ID: repo.GetID(),
|
||||
Name: repo.GetName(),
|
||||
FullName: repo.GetFullName(),
|
||||
Description: repo.GetDescription(),
|
||||
HTMLURL: repo.GetHTMLURL(),
|
||||
Language: repo.GetLanguage(),
|
||||
Stars: repo.GetStargazersCount(),
|
||||
Forks: repo.GetForksCount(),
|
||||
OpenIssues: repo.GetOpenIssuesCount(),
|
||||
Private: repo.GetPrivate(),
|
||||
Fork: repo.GetFork(),
|
||||
Archived: repo.GetArchived(),
|
||||
DefaultBranch: repo.GetDefaultBranch(),
|
||||
}
|
||||
|
||||
if repo.UpdatedAt != nil {
|
||||
minimalRepo.UpdatedAt = repo.UpdatedAt.Format("2006-01-02T15:04:05Z")
|
||||
}
|
||||
if repo.CreatedAt != nil {
|
||||
minimalRepo.CreatedAt = repo.CreatedAt.Format("2006-01-02T15:04:05Z")
|
||||
}
|
||||
if repo.Topics != nil {
|
||||
minimalRepo.Topics = repo.Topics
|
||||
}
|
||||
|
||||
minimalRepos = append(minimalRepos, minimalRepo)
|
||||
}
|
||||
|
||||
minimalResult := &MinimalSearchRepositoriesResult{
|
||||
TotalCount: result.GetTotal(),
|
||||
IncompleteResults: result.GetIncompleteResults(),
|
||||
Items: minimalRepos,
|
||||
}
|
||||
|
||||
r, err = json.Marshal(minimalResult)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to marshal minimal response", err), nil, nil
|
||||
}
|
||||
} else {
|
||||
r, err = json.Marshal(result)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to marshal full response", err), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
return utils.NewToolResultText(string(r)), nil, nil
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// SearchCode creates a tool to search for code across GitHub repositories.
|
||||
func SearchCode(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, mcp.ToolHandlerFor[map[string]any, any]) {
|
||||
func SearchCode(t translations.TranslationHelperFunc) toolsets.ServerTool {
|
||||
schema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
@@ -183,7 +188,8 @@ func SearchCode(getClient GetClientFn, t translations.TranslationHelperFunc) (mc
|
||||
}
|
||||
WithPagination(schema)
|
||||
|
||||
return mcp.Tool{
|
||||
return NewTool(
|
||||
mcp.Tool{
|
||||
Name: "search_code",
|
||||
Description: t("TOOL_SEARCH_CODE_DESCRIPTION", "Fast and precise code search across ALL GitHub repositories using GitHub's native search engine. Best for finding exact symbols, functions, classes, or specific code patterns."),
|
||||
Annotations: &mcp.ToolAnnotations{
|
||||
@@ -192,66 +198,69 @@ func SearchCode(getClient GetClientFn, t translations.TranslationHelperFunc) (mc
|
||||
},
|
||||
InputSchema: schema,
|
||||
},
|
||||
func(ctx context.Context, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
|
||||
query, err := RequiredParam[string](args, "query")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
sort, err := OptionalParam[string](args, "sort")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
order, err := OptionalParam[string](args, "order")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
pagination, err := OptionalPaginationParams(args)
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
|
||||
opts := &github.SearchOptions{
|
||||
Sort: sort,
|
||||
Order: order,
|
||||
ListOptions: github.ListOptions{
|
||||
PerPage: pagination.PerPage,
|
||||
Page: pagination.Page,
|
||||
},
|
||||
}
|
||||
|
||||
client, err := getClient(ctx)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
|
||||
}
|
||||
|
||||
result, resp, err := client.Search.Code(ctx, query, opts)
|
||||
if err != nil {
|
||||
return ghErrors.NewGitHubAPIErrorResponse(ctx,
|
||||
fmt.Sprintf("failed to search code with query '%s'", query),
|
||||
resp,
|
||||
err,
|
||||
), nil, nil
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
func(deps ToolDependencies) mcp.ToolHandlerFor[map[string]any, any] {
|
||||
return func(ctx context.Context, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
|
||||
query, err := RequiredParam[string](args, "query")
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to read response body", err), nil, nil
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
sort, err := OptionalParam[string](args, "sort")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
order, err := OptionalParam[string](args, "order")
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
pagination, err := OptionalPaginationParams(args)
|
||||
if err != nil {
|
||||
return utils.NewToolResultError(err.Error()), nil, nil
|
||||
}
|
||||
return utils.NewToolResultError(fmt.Sprintf("failed to search code: %s", string(body))), nil, nil
|
||||
}
|
||||
|
||||
r, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to marshal response", err), nil, nil
|
||||
}
|
||||
opts := &github.SearchOptions{
|
||||
Sort: sort,
|
||||
Order: order,
|
||||
ListOptions: github.ListOptions{
|
||||
PerPage: pagination.PerPage,
|
||||
Page: pagination.Page,
|
||||
},
|
||||
}
|
||||
|
||||
return utils.NewToolResultText(string(r)), nil, nil
|
||||
}
|
||||
client, err := deps.GetClient(ctx)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
|
||||
}
|
||||
|
||||
result, resp, err := client.Search.Code(ctx, query, opts)
|
||||
if err != nil {
|
||||
return ghErrors.NewGitHubAPIErrorResponse(ctx,
|
||||
fmt.Sprintf("failed to search code with query '%s'", query),
|
||||
resp,
|
||||
err,
|
||||
), nil, nil
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to read response body", err), nil, nil
|
||||
}
|
||||
return utils.NewToolResultError(fmt.Sprintf("failed to search code: %s", string(body))), nil, nil
|
||||
}
|
||||
|
||||
r, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to marshal response", err), nil, nil
|
||||
}
|
||||
|
||||
return utils.NewToolResultText(string(r)), nil, nil
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func userOrOrgHandler(accountType string, getClient GetClientFn) mcp.ToolHandlerFor[map[string]any, any] {
|
||||
func userOrOrgHandler(accountType string, deps ToolDependencies) mcp.ToolHandlerFor[map[string]any, any] {
|
||||
return func(ctx context.Context, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
|
||||
query, err := RequiredParam[string](args, "query")
|
||||
if err != nil {
|
||||
@@ -279,7 +288,7 @@ func userOrOrgHandler(accountType string, getClient GetClientFn) mcp.ToolHandler
|
||||
},
|
||||
}
|
||||
|
||||
client, err := getClient(ctx)
|
||||
client, err := deps.GetClient(ctx)
|
||||
if err != nil {
|
||||
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
|
||||
}
|
||||
@@ -340,7 +349,7 @@ func userOrOrgHandler(accountType string, getClient GetClientFn) mcp.ToolHandler
|
||||
}
|
||||
|
||||
// SearchUsers creates a tool to search for GitHub users.
|
||||
func SearchUsers(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, mcp.ToolHandlerFor[map[string]any, any]) {
|
||||
func SearchUsers(t translations.TranslationHelperFunc) toolsets.ServerTool {
|
||||
schema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
@@ -363,19 +372,24 @@ func SearchUsers(getClient GetClientFn, t translations.TranslationHelperFunc) (m
|
||||
}
|
||||
WithPagination(schema)
|
||||
|
||||
return mcp.Tool{
|
||||
Name: "search_users",
|
||||
Description: t("TOOL_SEARCH_USERS_DESCRIPTION", "Find GitHub users by username, real name, or other profile information. Useful for locating developers, contributors, or team members."),
|
||||
Annotations: &mcp.ToolAnnotations{
|
||||
Title: t("TOOL_SEARCH_USERS_USER_TITLE", "Search users"),
|
||||
ReadOnlyHint: true,
|
||||
return NewTool(
|
||||
mcp.Tool{
|
||||
Name: "search_users",
|
||||
Description: t("TOOL_SEARCH_USERS_DESCRIPTION", "Find GitHub users by username, real name, or other profile information. Useful for locating developers, contributors, or team members."),
|
||||
Annotations: &mcp.ToolAnnotations{
|
||||
Title: t("TOOL_SEARCH_USERS_USER_TITLE", "Search users"),
|
||||
ReadOnlyHint: true,
|
||||
},
|
||||
InputSchema: schema,
|
||||
},
|
||||
InputSchema: schema,
|
||||
}, userOrOrgHandler("user", getClient)
|
||||
func(deps ToolDependencies) mcp.ToolHandlerFor[map[string]any, any] {
|
||||
return userOrOrgHandler("user", deps)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// SearchOrgs creates a tool to search for GitHub organizations.
|
||||
func SearchOrgs(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, mcp.ToolHandlerFor[map[string]any, any]) {
|
||||
func SearchOrgs(t translations.TranslationHelperFunc) toolsets.ServerTool {
|
||||
schema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
@@ -398,13 +412,18 @@ func SearchOrgs(getClient GetClientFn, t translations.TranslationHelperFunc) (mc
|
||||
}
|
||||
WithPagination(schema)
|
||||
|
||||
return mcp.Tool{
|
||||
Name: "search_orgs",
|
||||
Description: t("TOOL_SEARCH_ORGS_DESCRIPTION", "Find GitHub organizations by name, location, or other organization metadata. Ideal for discovering companies, open source foundations, or teams."),
|
||||
Annotations: &mcp.ToolAnnotations{
|
||||
Title: t("TOOL_SEARCH_ORGS_USER_TITLE", "Search organizations"),
|
||||
ReadOnlyHint: true,
|
||||
return NewTool(
|
||||
mcp.Tool{
|
||||
Name: "search_orgs",
|
||||
Description: t("TOOL_SEARCH_ORGS_DESCRIPTION", "Find GitHub organizations by name, location, or other organization metadata. Ideal for discovering companies, open source foundations, or teams."),
|
||||
Annotations: &mcp.ToolAnnotations{
|
||||
Title: t("TOOL_SEARCH_ORGS_USER_TITLE", "Search organizations"),
|
||||
ReadOnlyHint: true,
|
||||
},
|
||||
InputSchema: schema,
|
||||
},
|
||||
InputSchema: schema,
|
||||
}, userOrOrgHandler("org", getClient)
|
||||
func(deps ToolDependencies) mcp.ToolHandlerFor[map[string]any, any] {
|
||||
return userOrOrgHandler("org", deps)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
+34
-18
@@ -17,8 +17,8 @@ import (
|
||||
|
||||
func Test_SearchRepositories(t *testing.T) {
|
||||
// Verify tool definition once
|
||||
mockClient := github.NewClient(nil)
|
||||
tool, _ := SearchRepositories(stubGetClientFn(mockClient), translations.NullTranslationHelper)
|
||||
serverTool := SearchRepositories(translations.NullTranslationHelper)
|
||||
tool := serverTool.Tool
|
||||
require.NoError(t, toolsnaps.Test(tool.Name, tool))
|
||||
|
||||
assert.Equal(t, "search_repositories", tool.Name)
|
||||
@@ -134,13 +134,16 @@ func Test_SearchRepositories(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Setup client with mock
|
||||
client := github.NewClient(tc.mockedClient)
|
||||
_, handler := SearchRepositories(stubGetClientFn(client), translations.NullTranslationHelper)
|
||||
deps := ToolDependencies{
|
||||
GetClient: stubGetClientFn(client),
|
||||
}
|
||||
handler := serverTool.Handler(deps)
|
||||
|
||||
// Create call request
|
||||
request := createMCPRequest(tc.requestArgs)
|
||||
|
||||
// Call handler
|
||||
result, _, err := handler(context.Background(), &request, tc.requestArgs)
|
||||
result, err := handler(context.Background(), &request)
|
||||
|
||||
// Verify results
|
||||
if tc.expectError {
|
||||
@@ -205,7 +208,11 @@ func Test_SearchRepositories_FullOutput(t *testing.T) {
|
||||
)
|
||||
|
||||
client := github.NewClient(mockedClient)
|
||||
_, handlerTest := SearchRepositories(stubGetClientFn(client), translations.NullTranslationHelper)
|
||||
serverTool := SearchRepositories(translations.NullTranslationHelper)
|
||||
deps := ToolDependencies{
|
||||
GetClient: stubGetClientFn(client),
|
||||
}
|
||||
handler := serverTool.Handler(deps)
|
||||
|
||||
args := map[string]interface{}{
|
||||
"query": "golang test",
|
||||
@@ -214,7 +221,7 @@ func Test_SearchRepositories_FullOutput(t *testing.T) {
|
||||
|
||||
request := createMCPRequest(args)
|
||||
|
||||
result, _, err := handlerTest(context.Background(), &request, args)
|
||||
result, err := handler(context.Background(), &request)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.False(t, result.IsError)
|
||||
@@ -236,8 +243,8 @@ func Test_SearchRepositories_FullOutput(t *testing.T) {
|
||||
|
||||
func Test_SearchCode(t *testing.T) {
|
||||
// Verify tool definition once
|
||||
mockClient := github.NewClient(nil)
|
||||
tool, _ := SearchCode(stubGetClientFn(mockClient), translations.NullTranslationHelper)
|
||||
serverTool := SearchCode(translations.NullTranslationHelper)
|
||||
tool := serverTool.Tool
|
||||
require.NoError(t, toolsnaps.Test(tool.Name, tool))
|
||||
|
||||
assert.Equal(t, "search_code", tool.Name)
|
||||
@@ -351,13 +358,16 @@ func Test_SearchCode(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Setup client with mock
|
||||
client := github.NewClient(tc.mockedClient)
|
||||
_, handler := SearchCode(stubGetClientFn(client), translations.NullTranslationHelper)
|
||||
deps := ToolDependencies{
|
||||
GetClient: stubGetClientFn(client),
|
||||
}
|
||||
handler := serverTool.Handler(deps)
|
||||
|
||||
// Create call request
|
||||
request := createMCPRequest(tc.requestArgs)
|
||||
|
||||
// Call handler
|
||||
result, _, err := handler(context.Background(), &request, tc.requestArgs)
|
||||
result, err := handler(context.Background(), &request)
|
||||
|
||||
// Verify results
|
||||
if tc.expectError {
|
||||
@@ -394,8 +404,8 @@ func Test_SearchCode(t *testing.T) {
|
||||
|
||||
func Test_SearchUsers(t *testing.T) {
|
||||
// Verify tool definition once
|
||||
mockClient := github.NewClient(nil)
|
||||
tool, _ := SearchUsers(stubGetClientFn(mockClient), translations.NullTranslationHelper)
|
||||
serverTool := SearchUsers(translations.NullTranslationHelper)
|
||||
tool := serverTool.Tool
|
||||
require.NoError(t, toolsnaps.Test(tool.Name, tool))
|
||||
|
||||
assert.Equal(t, "search_users", tool.Name)
|
||||
@@ -548,13 +558,16 @@ func Test_SearchUsers(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Setup client with mock
|
||||
client := github.NewClient(tc.mockedClient)
|
||||
_, handler := SearchUsers(stubGetClientFn(client), translations.NullTranslationHelper)
|
||||
deps := ToolDependencies{
|
||||
GetClient: stubGetClientFn(client),
|
||||
}
|
||||
handler := serverTool.Handler(deps)
|
||||
|
||||
// Create call request
|
||||
request := createMCPRequest(tc.requestArgs)
|
||||
|
||||
// Call handler
|
||||
result, _, err := handler(context.Background(), &request, tc.requestArgs)
|
||||
result, err := handler(context.Background(), &request)
|
||||
|
||||
// Verify results
|
||||
if tc.expectError {
|
||||
@@ -592,8 +605,8 @@ func Test_SearchUsers(t *testing.T) {
|
||||
|
||||
func Test_SearchOrgs(t *testing.T) {
|
||||
// Verify tool definition once
|
||||
mockClient := github.NewClient(nil)
|
||||
tool, _ := SearchOrgs(stubGetClientFn(mockClient), translations.NullTranslationHelper)
|
||||
serverTool := SearchOrgs(translations.NullTranslationHelper)
|
||||
tool := serverTool.Tool
|
||||
|
||||
require.NoError(t, toolsnaps.Test(tool.Name, tool))
|
||||
|
||||
@@ -720,13 +733,16 @@ func Test_SearchOrgs(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Setup client with mock
|
||||
client := github.NewClient(tc.mockedClient)
|
||||
_, handler := SearchOrgs(stubGetClientFn(client), translations.NullTranslationHelper)
|
||||
deps := ToolDependencies{
|
||||
GetClient: stubGetClientFn(client),
|
||||
}
|
||||
handler := serverTool.Handler(deps)
|
||||
|
||||
// Create call request
|
||||
request := createMCPRequest(tc.requestArgs)
|
||||
|
||||
// Call handler
|
||||
result, _, err := handler(context.Background(), &request, tc.requestArgs)
|
||||
result, err := handler(context.Background(), &request)
|
||||
|
||||
// Verify results
|
||||
if tc.expectError {
|
||||
|
||||
+4
-4
@@ -179,10 +179,10 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
|
||||
repos := toolsets.NewToolset(ToolsetMetadataRepos.ID, ToolsetMetadataRepos.Description).
|
||||
SetDependencies(deps).
|
||||
AddReadTools(
|
||||
toolsets.NewServerToolLegacy(SearchRepositories(getClient, t)),
|
||||
SearchRepositories(t),
|
||||
toolsets.NewServerToolLegacy(GetFileContents(getClient, getRawClient, t)),
|
||||
toolsets.NewServerToolLegacy(ListCommits(getClient, t)),
|
||||
toolsets.NewServerToolLegacy(SearchCode(getClient, t)),
|
||||
SearchCode(t),
|
||||
toolsets.NewServerToolLegacy(GetCommit(getClient, t)),
|
||||
toolsets.NewServerToolLegacy(ListBranches(getClient, t)),
|
||||
toolsets.NewServerToolLegacy(ListTags(getClient, t)),
|
||||
@@ -232,12 +232,12 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
|
||||
users := toolsets.NewToolset(ToolsetMetadataUsers.ID, ToolsetMetadataUsers.Description).
|
||||
SetDependencies(deps).
|
||||
AddReadTools(
|
||||
toolsets.NewServerToolLegacy(SearchUsers(getClient, t)),
|
||||
SearchUsers(t),
|
||||
)
|
||||
orgs := toolsets.NewToolset(ToolsetMetadataOrgs.ID, ToolsetMetadataOrgs.Description).
|
||||
SetDependencies(deps).
|
||||
AddReadTools(
|
||||
toolsets.NewServerToolLegacy(SearchOrgs(getClient, t)),
|
||||
SearchOrgs(t),
|
||||
)
|
||||
pullRequests := toolsets.NewToolset(ToolsetMetadataPullRequests.ID, ToolsetMetadataPullRequests.Description).
|
||||
SetDependencies(deps).
|
||||
|
||||
Reference in New Issue
Block a user