Skip to content

Commit 0ff085d

Browse files
refactor(search): expose repository visibility enum
Remove the derivable node_id from compact full repository search output and publish the visibility enum in the static output schema. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent b1baea0 commit 0ff085d

4 files changed

Lines changed: 25 additions & 13 deletions

File tree

‎pkg/github/__toolsnaps__/search_repositories.snap‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,6 @@
157157
"name": {
158158
"type": "string"
159159
},
160-
"node_id": {
161-
"description": "GraphQL node ID",
162-
"type": "string"
163-
},
164160
"open_issues_count": {
165161
"type": "integer"
166162
},
@@ -234,7 +230,12 @@
234230
"type": "string"
235231
},
236232
"visibility": {
237-
"description": "Repository visibility: public, private, or internal",
233+
"description": "Repository visibility",
234+
"enum": [
235+
"public",
236+
"private",
237+
"internal"
238+
],
238239
"type": "string"
239240
},
240241
"watchers_count": {

‎pkg/github/search.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ func SearchRepositories(t translations.TranslationHelperFunc) inventory.ServerTo
5757
Title: t("TOOL_SEARCH_REPOSITORIES_USER_TITLE", "Search repositories"),
5858
ReadOnlyHint: true,
5959
},
60-
InputSchema: schema,
60+
InputSchema: schema,
61+
OutputSchema: searchRepositoriesOutputSchema(),
6162
},
6263
scopes.PublicRead(scopes.Repo),
6364
func(ctx context.Context, deps ToolDependencies, _ *mcp.CallToolRequest, input SearchRepositoriesInput) (*mcp.CallToolResult, *SearchRepositoriesOutput, error) {

‎pkg/github/search_tool_types.go‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55

66
"github.com/google/go-github/v92/github"
7+
"github.com/google/jsonschema-go/jsonschema"
78
)
89

910
type SearchAccountsInput struct {
@@ -32,9 +33,8 @@ type SearchRepositoriesOutput struct {
3233

3334
type SearchRepository struct {
3435
MinimalRepository
35-
NodeID string `json:"node_id,omitempty" jsonschema:"GraphQL node ID"`
3636
Homepage string `json:"homepage,omitempty" jsonschema:"Repository homepage URL"`
37-
Visibility string `json:"visibility,omitempty" jsonschema:"Repository visibility: public, private, or internal"`
37+
Visibility string `json:"visibility,omitempty" jsonschema:"Repository visibility"`
3838
PushedAt string `json:"pushed_at,omitempty" jsonschema:"Last push time as an ISO 8601 UTC timestamp"`
3939
WatchersCount *int `json:"watchers_count,omitempty" jsonschema:"Number of watchers"`
4040
Size *int `json:"size,omitempty" jsonschema:"Repository size in kilobytes"`
@@ -62,6 +62,17 @@ type SearchRepositoryPermissions struct {
6262
Pull *bool `json:"pull,omitempty"`
6363
}
6464

65+
var searchRepositoryVisibilityEnum = []any{"public", "private", "internal"}
66+
67+
func searchRepositoriesOutputSchema() *jsonschema.Schema {
68+
schema, err := jsonschema.For[SearchRepositoriesOutput](nil)
69+
if err != nil {
70+
panic(err)
71+
}
72+
schema.Properties["items"].Items.Properties["visibility"].Enum = searchRepositoryVisibilityEnum
73+
return schema
74+
}
75+
6576
func minimalSearchRepository(repo *github.Repository) MinimalRepository {
6677
minimalRepo := MinimalRepository{
6778
ID: repo.GetID(),
@@ -93,7 +104,6 @@ func minimalSearchRepository(repo *github.Repository) MinimalRepository {
93104
func fullSearchRepository(repo *github.Repository) SearchRepository {
94105
out := SearchRepository{
95106
MinimalRepository: minimalSearchRepository(repo),
96-
NodeID: repo.GetNodeID(),
97107
Homepage: repo.GetHomepage(),
98108
Visibility: repo.GetVisibility(),
99109
WatchersCount: repo.WatchersCount,

‎pkg/github/typed_account_repository_search_test.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ func TestTypedAccountRepositorySearchOutputs(t *testing.T) {
195195
var full github.RepositoriesSearchResult
196196
require.NoError(t, json.Unmarshal([]byte(body), &full))
197197
checkStructured(map[string]any{"minimal_output": false}, mustMarshalJSON(t, full),
198-
`{"total_count":1,"incomplete_results":false,"items":[{"id":7,"name":"repo","full_name":"owner/repo","description":"<b>description</b>","html_url":"repo-url","stargazers_count":0,"forks_count":0,"open_issues_count":0,"created_at":"2026-01-02T03:04:05Z","topics":["go"],"private":false,"fork":false,"archived":false,"node_id":"R_7","homepage":"https://example.com","visibility":"public","pushed_at":"2026-01-03T03:04:05Z","watchers_count":4,"size":0,"disabled":false,"has_issues":true,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT"},"permissions":{"admin":false,"pull":true}}]}`)
198+
`{"total_count":1,"incomplete_results":false,"items":[{"id":7,"name":"repo","full_name":"owner/repo","description":"<b>description</b>","html_url":"repo-url","stargazers_count":0,"forks_count":0,"open_issues_count":0,"created_at":"2026-01-02T03:04:05Z","topics":["go"],"private":false,"fork":false,"archived":false,"homepage":"https://example.com","visibility":"public","pushed_at":"2026-01-03T03:04:05Z","watchers_count":4,"size":0,"disabled":false,"has_issues":true,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT"},"permissions":{"admin":false,"pull":true}}]}`)
199199
check(map[string]any{"minimal_output": true}, fixture.text)
200200
}
201201
for _, emptyBody := range []string{`{"total_count":0,"incomplete_results":false,"items":[]}`, `{"items":null}`, `{}`} {
@@ -266,10 +266,10 @@ func TestTypedAccountRepositorySearchOutputs(t *testing.T) {
266266
}
267267

268268
func TestSearchRepositoryOutputSchemaIsCompact(t *testing.T) {
269-
schema, err := jsonschema.For[SearchRepositoriesOutput](nil)
270-
require.NoError(t, err)
269+
schema := searchRepositoriesOutputSchema()
270+
assert.Equal(t, searchRepositoryVisibilityEnum, schema.Properties["items"].Items.Properties["visibility"].Enum)
271271
encoded := mustMarshalJSON(t, schema)
272-
for _, field := range []string{"custom_properties", "owner", "parent", "issues_url", "clone_url", "url\""} {
272+
for _, field := range []string{"node_id", "custom_properties", "owner", "parent", "issues_url", "clone_url", "url\""} {
273273
assert.NotContains(t, encoded, `"`+field, field)
274274
}
275275
assert.Contains(t, encoded, `"html_url"`)

0 commit comments

Comments
 (0)