Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ The following sets of tools are available (all are on by default):
- `autoInit`: Initialize with README (boolean, optional)
- `description`: Repository description (string, optional)
- `name`: Repository name (string, required)
- `organization`: Organization to create the repository in (omit to create in your personal account) (string, optional)
- `private`: Whether repo should be private (boolean, optional)

- **delete_file** - Delete file
Expand Down
6 changes: 5 additions & 1 deletion pkg/github/__toolsnaps__/create_repository.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"title": "Create repository",
"readOnlyHint": false
},
"description": "Create a new GitHub repository in your account",
"description": "Create a new GitHub repository in your account or specified organization",
"inputSchema": {
"properties": {
"autoInit": {
Expand All @@ -18,6 +18,10 @@
"description": "Repository name",
"type": "string"
},
"organization": {
"description": "Organization to create the repository in (omit to create in your personal account)",
"type": "string"
},
"private": {
"description": "Whether repo should be private",
"type": "boolean"
Expand Down
11 changes: 9 additions & 2 deletions pkg/github/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func CreateOrUpdateFile(getClient GetClientFn, t translations.TranslationHelperF
// CreateRepository creates a tool to create a new GitHub repository.
func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
return mcp.NewTool("create_repository",
mcp.WithDescription(t("TOOL_CREATE_REPOSITORY_DESCRIPTION", "Create a new GitHub repository in your account")),
mcp.WithDescription(t("TOOL_CREATE_REPOSITORY_DESCRIPTION", "Create a new GitHub repository in your account or specified organization")),
mcp.WithToolAnnotation(mcp.ToolAnnotation{
Title: t("TOOL_CREATE_REPOSITORY_USER_TITLE", "Create repository"),
ReadOnlyHint: ToBoolPtr(false),
Expand All @@ -382,6 +382,9 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
mcp.WithString("description",
mcp.Description("Repository description"),
),
mcp.WithString("organization",
mcp.Description("Organization to create the repository in (omit to create in your personal account)"),
),
mcp.WithBoolean("private",
mcp.Description("Whether repo should be private"),
),
Expand All @@ -398,6 +401,10 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
organization, err := OptionalParam[string](request, "organization")
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
private, err := OptionalParam[bool](request, "private")
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
Expand All @@ -418,7 +425,7 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
if err != nil {
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
}
createdRepo, resp, err := client.Repositories.Create(ctx, "", repo)
createdRepo, resp, err := client.Repositories.Create(ctx, organization, repo)
if err != nil {
return ghErrors.NewGitHubAPIErrorResponse(ctx,
"failed to create repository",
Expand Down
29 changes: 29 additions & 0 deletions pkg/github/repositories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,7 @@ func Test_CreateRepository(t *testing.T) {
assert.NotEmpty(t, tool.Description)
assert.Contains(t, tool.InputSchema.Properties, "name")
assert.Contains(t, tool.InputSchema.Properties, "description")
assert.Contains(t, tool.InputSchema.Properties, "organization")
assert.Contains(t, tool.InputSchema.Properties, "private")
assert.Contains(t, tool.InputSchema.Properties, "autoInit")
assert.ElementsMatch(t, tool.InputSchema.Required, []string{"name"})
Expand Down Expand Up @@ -1119,6 +1120,34 @@ func Test_CreateRepository(t *testing.T) {
expectError: false,
expectedRepo: mockRepo,
},
{
name: "successful repository creation in organization",
mockedClient: mock.NewMockedHTTPClient(
mock.WithRequestMatchHandler(
mock.EndpointPattern{
Pattern: "/orgs/testorg/repos",
Method: "POST",
},
expectRequestBody(t, map[string]interface{}{
"name": "test-repo",
"description": "Test repository",
"private": false,
"auto_init": true,
}).andThen(
mockResponse(t, http.StatusCreated, mockRepo),
),
),
),
requestArgs: map[string]interface{}{
"name": "test-repo",
"description": "Test repository",
"organization": "testorg",
"private": false,
"autoInit": true,
},
expectError: false,
expectedRepo: mockRepo,
},
{
name: "successful repository creation with minimal parameters",
mockedClient: mock.NewMockedHTTPClient(
Expand Down
Loading