Skip to content

Commit 09deac4

Browse files
initial org repo create support (#1023)
1 parent 358a415 commit 09deac4

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ The following sets of tools are available (all are on by default):
815815
- `autoInit`: Initialize with README (boolean, optional)
816816
- `description`: Repository description (string, optional)
817817
- `name`: Repository name (string, required)
818+
- `organization`: Organization to create the repository in (omit to create in your personal account) (string, optional)
818819
- `private`: Whether repo should be private (boolean, optional)
819820

820821
- **delete_file** - Delete file

pkg/github/__toolsnaps__/create_repository.snap

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"title": "Create repository",
44
"readOnlyHint": false
55
},
6-
"description": "Create a new GitHub repository in your account",
6+
"description": "Create a new GitHub repository in your account or specified organization",
77
"inputSchema": {
88
"properties": {
99
"autoInit": {
@@ -18,6 +18,10 @@
1818
"description": "Repository name",
1919
"type": "string"
2020
},
21+
"organization": {
22+
"description": "Organization to create the repository in (omit to create in your personal account)",
23+
"type": "string"
24+
},
2125
"private": {
2226
"description": "Whether repo should be private",
2327
"type": "boolean"

pkg/github/repositories.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ func CreateOrUpdateFile(getClient GetClientFn, t translations.TranslationHelperF
393393
// CreateRepository creates a tool to create a new GitHub repository.
394394
func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
395395
return mcp.NewTool("create_repository",
396-
mcp.WithDescription(t("TOOL_CREATE_REPOSITORY_DESCRIPTION", "Create a new GitHub repository in your account")),
396+
mcp.WithDescription(t("TOOL_CREATE_REPOSITORY_DESCRIPTION", "Create a new GitHub repository in your account or specified organization")),
397397
mcp.WithToolAnnotation(mcp.ToolAnnotation{
398398
Title: t("TOOL_CREATE_REPOSITORY_USER_TITLE", "Create repository"),
399399
ReadOnlyHint: ToBoolPtr(false),
@@ -405,6 +405,9 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
405405
mcp.WithString("description",
406406
mcp.Description("Repository description"),
407407
),
408+
mcp.WithString("organization",
409+
mcp.Description("Organization to create the repository in (omit to create in your personal account)"),
410+
),
408411
mcp.WithBoolean("private",
409412
mcp.Description("Whether repo should be private"),
410413
),
@@ -421,6 +424,10 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
421424
if err != nil {
422425
return mcp.NewToolResultError(err.Error()), nil
423426
}
427+
organization, err := OptionalParam[string](request, "organization")
428+
if err != nil {
429+
return mcp.NewToolResultError(err.Error()), nil
430+
}
424431
private, err := OptionalParam[bool](request, "private")
425432
if err != nil {
426433
return mcp.NewToolResultError(err.Error()), nil
@@ -441,7 +448,7 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
441448
if err != nil {
442449
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
443450
}
444-
createdRepo, resp, err := client.Repositories.Create(ctx, "", repo)
451+
createdRepo, resp, err := client.Repositories.Create(ctx, organization, repo)
445452
if err != nil {
446453
return ghErrors.NewGitHubAPIErrorResponse(ctx,
447454
"failed to create repository",

pkg/github/repositories_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,7 @@ func Test_CreateRepository(t *testing.T) {
11151115
assert.NotEmpty(t, tool.Description)
11161116
assert.Contains(t, tool.InputSchema.Properties, "name")
11171117
assert.Contains(t, tool.InputSchema.Properties, "description")
1118+
assert.Contains(t, tool.InputSchema.Properties, "organization")
11181119
assert.Contains(t, tool.InputSchema.Properties, "private")
11191120
assert.Contains(t, tool.InputSchema.Properties, "autoInit")
11201121
assert.ElementsMatch(t, tool.InputSchema.Required, []string{"name"})
@@ -1166,6 +1167,34 @@ func Test_CreateRepository(t *testing.T) {
11661167
expectError: false,
11671168
expectedRepo: mockRepo,
11681169
},
1170+
{
1171+
name: "successful repository creation in organization",
1172+
mockedClient: mock.NewMockedHTTPClient(
1173+
mock.WithRequestMatchHandler(
1174+
mock.EndpointPattern{
1175+
Pattern: "/orgs/testorg/repos",
1176+
Method: "POST",
1177+
},
1178+
expectRequestBody(t, map[string]interface{}{
1179+
"name": "test-repo",
1180+
"description": "Test repository",
1181+
"private": false,
1182+
"auto_init": true,
1183+
}).andThen(
1184+
mockResponse(t, http.StatusCreated, mockRepo),
1185+
),
1186+
),
1187+
),
1188+
requestArgs: map[string]interface{}{
1189+
"name": "test-repo",
1190+
"description": "Test repository",
1191+
"organization": "testorg",
1192+
"private": false,
1193+
"autoInit": true,
1194+
},
1195+
expectError: false,
1196+
expectedRepo: mockRepo,
1197+
},
11691198
{
11701199
name: "successful repository creation with minimal parameters",
11711200
mockedClient: mock.NewMockedHTTPClient(

0 commit comments

Comments
 (0)