Skip to content

Commit 527c81e

Browse files
Merge branch 'main' into fix/update-toolsnaps-docs-a2619da9
2 parents a2619da + eb4c099 commit 527c81e

71 files changed

Lines changed: 5553 additions & 1845 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ The following sets of tools are available:
911911
- `issue_number`: The number of the issue (number, required)
912912
- `method`: The read operation to perform on a single issue.
913913
Options are:
914-
1. get - Get issue details. Also returns best-effort hierarchy flags (`has_parent`, `has_children`); `parent` and `sub_issues_summary` are optional relationship summaries.
914+
1. get - Get issue details. Also returns best-effort hierarchy flags (`has_parent`, `has_children`); `parent` and `sub_issues_summary` are optional relationship summaries, and `closed_by_pull_requests` summarizes the pull requests configured to close the issue as `total_count` plus up to 5 `references`.
915915
2. get_comments - Get issue comments.
916916
3. get_sub_issues - Get sub-issues (children) of the issue.
917917
4. get_parent - Get the parent issue, if this issue is a sub-issue of another.
@@ -926,7 +926,7 @@ The following sets of tools are available:
926926
- **Required OAuth Scopes**: `repo`
927927
- `assignees`: Usernames to assign to this issue (string[], optional)
928928
- `body`: Issue body content (string, optional)
929-
- `duplicate_of`: Issue number that this issue is a duplicate of. Only used when state_reason is 'duplicate'. (number, optional)
929+
- `duplicate_of`: Issue number that this issue is a duplicate of. Required when state_reason is 'duplicate'. (number, optional)
930930
- `issue_fields`: Issue field values to set or clear. Each item requires 'field_name' and exactly one of 'value', 'field_option_name', or 'delete: true'. (object[], optional)
931931
- `issue_number`: Issue number to update (number, optional)
932932
- `labels`: Labels to apply to this issue (string[], optional)
@@ -941,7 +941,7 @@ The following sets of tools are available:
941941
- `state`: New state (string, optional)
942942
- `state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
943943
- `title`: Issue title (string, optional)
944-
- `type`: Type of this issue. Only use if issue types are enabled for this repository. Use list_issue_types tool to get valid type values for this repository or its owner organization. If the repository doesn't support issue types, omit this parameter. (string, optional)
944+
- `type`: Type of this issue. For updates, pass null to remove the current type. Only use if issue types are enabled for this repository. Use list_issue_types to get valid type values for this repository or its owner organization. If the repository doesn't support issue types, omit this parameter. (string | null, optional)
945945

946946
- **list_issue_fields** - List issue fields
947947
- **Required OAuth Scopes (any of)**: `repo`, `read:org`
@@ -960,6 +960,7 @@ The following sets of tools are available:
960960
- `after`: Cursor for pagination. Use the cursor from the previous response. (string, optional)
961961
- `direction`: Order direction. If provided, the 'orderBy' also needs to be provided. (string, optional)
962962
- `field_filters`: Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date). (object[], optional)
963+
- `fields`: Subset of fields to return for each issue. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' and 'field_values' in particular drops the largest per-result data. (string[], optional)
963964
- `labels`: Filter by labels (string[], optional)
964965
- `orderBy`: Order issues by field. If provided, the 'direction' also needs to be provided. (string, optional)
965966
- `owner`: Repository owner (string, required)
@@ -970,11 +971,12 @@ The following sets of tools are available:
970971

971972
- **search_issues** - Search issues
972973
- **Required OAuth Scopes**: `repo`
974+
- `fields`: Subset of fields to return for each issue result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body', 'reactions', and 'labels' in particular drops the largest per-result data. (string[], optional)
973975
- `order`: Sort order (string, optional)
974976
- `owner`: Optional repository owner. If provided with repo, only issues for this repository are listed. (string, optional)
975977
- `page`: Page number for pagination (min 1) (number, optional)
976978
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
977-
- `query`: Search query using GitHub issues search syntax (string, required)
979+
- `query`: The search query, as natural language. When the user gives alternative wordings, include them as plain words rather than joining them with OR. (string, required)
978980
- `repo`: Optional repository name. If provided with owner, only issues for this repository are listed. (string, optional)
979981
- `sort`: Sort field by number of matches of categories, defaults to best match (string, optional)
980982

@@ -1121,6 +1123,7 @@ The following sets of tools are available:
11211123
- `item_owner`: The owner (user or organization) of the repository containing the issue or pull request. Required for 'add_project_item' method. Also accepted by 'update_project_item' when resolving the item by issue number. (string, optional)
11221124
- `item_repo`: The name of the repository containing the issue or pull request. Required for 'add_project_item' method. Also accepted by 'update_project_item' when resolving the item by issue number. (string, optional)
11231125
- `item_type`: The item's type, either issue or pull_request. Required for 'add_project_item' method. (string, optional)
1126+
- `items`: The items to update with the top-level 'updated_field'. Required for 'update_project_items'; prefer it over calling 'update_project_item' in a loop. Each entry must match exactly one reference variant: 'node_id', numeric 'item_id', or 'item_owner' + 'item_repo' + 'issue_number'. Limit: 50 items per call. (object[], optional)
11241127
- `iteration_duration`: Duration in days for iterations of the field (e.g. 7 for weekly, 14 for bi-weekly). Required for 'create_iteration_field' method. (number, optional)
11251128
- `iterations`: Custom iterations for 'create_iteration_field' method. Only set this when you need iterations with varying durations, breaks between them, or specific titles. Otherwise omit it: GitHub auto-creates three iterations of 'iteration_duration' days starting on 'start_date', which is the right choice for most cases. (object[], optional)
11261129
- `method`: The method to execute (string, required)
@@ -1132,7 +1135,7 @@ The following sets of tools are available:
11321135
- `status`: The status of the project. Used for 'create_project_status_update' method. (string, optional)
11331136
- `target_date`: The target date of the status update in YYYY-MM-DD format. Used for 'create_project_status_update' method. (string, optional)
11341137
- `title`: The project title. Required for 'create_project' method. (string, optional)
1135-
- `updated_field`: Object describing the field to update and its new value. Required for 'update_project_item'. Two shapes are accepted: (1) by ID — {"id": 123456, "value": "..."}; (2) by name — {"name": "Status", "value": "In Progress"}. For single-select fields, option-name resolution requires the by-name shape; on the by-ID shape, pass the option ID. Set value to null to clear the field. (object, optional)
1138+
- `updated_field`: The field/value to apply, using {"id": 123, "value": ...} or {"name": "Status", "value": ...}; null clears the field. Required for 'update_project_item' and 'update_project_items', where one top-level field/value applies to every item in a batch. For 'update_project_item' SINGLE_SELECT fields, the name form accepts option names; the ID form expects an option ID. (object, optional)
11361139

11371140
</details>
11381141

@@ -1178,6 +1181,7 @@ The following sets of tools are available:
11781181
- **Required OAuth Scopes**: `repo`
11791182
- `base`: Filter by base branch (string, optional)
11801183
- `direction`: Sort direction (string, optional)
1184+
- `fields`: Subset of fields to return for each pull request. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-result data. (string[], optional)
11811185
- `head`: Filter by head user/org and branch (string, optional)
11821186
- `owner`: Repository owner (string, required)
11831187
- `page`: Page number for pagination (min 1) (number, optional)
@@ -1229,6 +1233,7 @@ The following sets of tools are available:
12291233

12301234
- **search_pull_requests** - Search pull requests
12311235
- **Required OAuth Scopes**: `repo`
1236+
- `fields`: Subset of fields to return for each pull request result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body', 'reactions', and 'labels' in particular drops the largest per-result data. (string[], optional)
12321237
- `order`: Sort order (string, optional)
12331238
- `owner`: Optional repository owner. If provided with repo, only pull requests for this repository are listed. (string, optional)
12341239
- `page`: Page number for pagination (min 1) (number, optional)
@@ -1273,7 +1278,7 @@ The following sets of tools are available:
12731278
- **create_or_update_file** - Create or update file
12741279
- **Required OAuth Scopes**: `repo`
12751280
- `branch`: Branch to create/update the file in (string, required)
1276-
- `content`: Content of the file (string, required)
1281+
- `content`: Content of the file, exactly as it should appear once written. Do not base64-encode it; this server does that before calling the REST API. (string, required)
12771282
- `message`: Commit message (string, required)
12781283
- `owner`: Repository owner (username or organization) (string, required)
12791284
- `path`: Path where to create/update the file (string, required)
@@ -1313,6 +1318,7 @@ The following sets of tools are available:
13131318

13141319
- **get_file_contents** - Get file or directory contents
13151320
- **Required OAuth Scopes**: `repo`
1321+
- `fields`: Subset of fields to return for each entry when the path is a directory. If omitted, all fields are returned. Ignored when the path is a single file. Use this to reduce response size when listing directories and you only need specific fields, e.g. just 'name' and 'type'. (string[], optional)
13161322
- `owner`: Repository owner (username or organization) (string, required)
13171323
- `path`: Path to file/directory (string, optional)
13181324
- `ref`: Accepts optional git refs such as `refs/tags/{tag}`, `refs/heads/{branch}` or `refs/pull/{pr_number}/head` (string, optional)
@@ -1346,6 +1352,7 @@ The following sets of tools are available:
13461352
- **list_commits** - List commits
13471353
- **Required OAuth Scopes**: `repo`
13481354
- `author`: Author username or email address to filter commits by (string, optional)
1355+
- `fields`: Subset of fields to return for each commit. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields, e.g. just 'sha' and 'html_url'. (string[], optional)
13491356
- `owner`: Repository owner (string, required)
13501357
- `page`: Page number for pagination (min 1) (number, optional)
13511358
- `path`: Only commits containing this file path will be returned (string, optional)
@@ -1357,6 +1364,7 @@ The following sets of tools are available:
13571364

13581365
- **list_releases** - List releases
13591366
- **Required OAuth Scopes**: `repo`
1367+
- `fields`: Subset of fields to return for each release. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-release data. (string[], optional)
13601368
- `owner`: Repository owner (string, required)
13611369
- `page`: Page number for pagination (min 1) (number, optional)
13621370
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
@@ -1387,6 +1395,7 @@ The following sets of tools are available:
13871395

13881396
- **search_code** - Search code
13891397
- **Required OAuth Scopes**: `repo`
1398+
- `fields`: Subset of fields to return for each code search result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'repository' and 'text_matches' in particular drops the largest per-result data. (string[], optional)
13901399
- `order`: Sort order for results (string, optional)
13911400
- `page`: Page number for pagination (min 1) (number, optional)
13921401
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)

cmd/github-mcp-server/generate_docs.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -273,19 +273,7 @@ func writeToolDoc(buf *strings.Builder, tool inventory.ServerTool) {
273273
requiredStr = "required"
274274
}
275275

276-
var typeStr string
277-
278-
// Get the type and description
279-
switch prop.Type {
280-
case "array":
281-
if prop.Items != nil {
282-
typeStr = prop.Items.Type + "[]"
283-
} else {
284-
typeStr = "array"
285-
}
286-
default:
287-
typeStr = prop.Type
288-
}
276+
typeStr := schemaTypeString(prop)
289277

290278
// Indent any continuation lines in the description to maintain markdown formatting
291279
description := indentMultilineDescription(prop.Description, " ")
@@ -300,6 +288,40 @@ func writeToolDoc(buf *strings.Builder, tool inventory.ServerTool) {
300288
}
301289
}
302290

291+
func schemaTypeString(schema *jsonschema.Schema) string {
292+
switch {
293+
case schema.Type == "array":
294+
if schema.Items != nil {
295+
return schema.Items.Type + "[]"
296+
}
297+
return "array"
298+
case schema.Type != "":
299+
return schema.Type
300+
case len(schema.Types) > 0:
301+
return strings.Join(schema.Types, " | ")
302+
}
303+
304+
var union []*jsonschema.Schema
305+
switch {
306+
case len(schema.AnyOf) > 0:
307+
union = schema.AnyOf
308+
case len(schema.OneOf) > 0:
309+
union = schema.OneOf
310+
default:
311+
// A schema without type constraints accepts any value.
312+
return "any"
313+
}
314+
315+
types := make([]string, 0, len(union))
316+
for _, member := range union {
317+
memberType := schemaTypeString(member)
318+
if !slices.Contains(types, memberType) {
319+
types = append(types, memberType)
320+
}
321+
}
322+
return strings.Join(types, " | ")
323+
}
324+
303325
// scopesEqual checks if two scope slices contain the same elements (order-independent)
304326
func scopesEqual(a, b []string) bool {
305327
if len(a) != len(b) {

cmd/github-mcp-server/main_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"path/filepath"
66
"testing"
77

8+
"github.com/google/jsonschema-go/jsonschema"
89
"github.com/stretchr/testify/assert"
910
"github.com/stretchr/testify/require"
1011
)
@@ -36,3 +37,29 @@ func TestGitHubAppFlagsAreStdioOnly(t *testing.T) {
3637
assert.NotNil(t, stdioCmd.Flags().Lookup("app-id"))
3738
assert.Nil(t, httpCmd.Flags().Lookup("app-id"))
3839
}
40+
41+
func TestSchemaTypeString(t *testing.T) {
42+
tests := []struct {
43+
name string
44+
schema *jsonschema.Schema
45+
want string
46+
}{
47+
{name: "type", schema: &jsonschema.Schema{Type: "string"}, want: "string"},
48+
{name: "types", schema: &jsonschema.Schema{Types: []string{"string", "number"}}, want: "string | number"},
49+
{name: "unconstrained", schema: &jsonschema.Schema{}, want: "any"},
50+
{name: "anyOf", schema: &jsonschema.Schema{AnyOf: []*jsonschema.Schema{{Type: "string"}, {Type: "null"}}}, want: "string | null"},
51+
{name: "oneOf", schema: &jsonschema.Schema{OneOf: []*jsonschema.Schema{{Type: "number"}, {Type: "string"}}}, want: "number | string"},
52+
{
53+
name: "array",
54+
schema: &jsonschema.Schema{Type: "array", Items: &jsonschema.Schema{Type: "string"}},
55+
want: "string[]",
56+
},
57+
{name: "untyped array", schema: &jsonschema.Schema{Type: "array"}, want: "array"},
58+
}
59+
60+
for _, tc := range tests {
61+
t.Run(tc.name, func(t *testing.T) {
62+
assert.Equal(t, tc.want, schemaTypeString(tc.schema))
63+
})
64+
}
65+
}

0 commit comments

Comments
 (0)