Content-Length: 5642 | pFad | http://github.com/github/github-mcp-server/pull/521.patch
thub.com
From c3128b725b0313f50c51e1b0b1886b8c71e62877 Mon Sep 17 00:00:00 2001
From: Eran Cohen
Date: Sun, 8 Jun 2025 16:56:39 +0300
Subject: [PATCH] feat: add tool to create GitHub repository from template
Introduced a new tool 'create_repository_from_template' to allow users to create repositories from a given repository template.
Signed-off-by: Eran Cohen
---
README.md | 7 ++++
pkg/github/repositories.go | 84 ++++++++++++++++++++++++++++++++++++++
pkg/github/tools.go | 1 +
3 files changed, 92 insertions(+)
diff --git a/README.md b/README.md
index d40d8aab3..a8b7bbb8f 100644
--- a/README.md
+++ b/README.md
@@ -642,6 +642,13 @@ export GITHUB_MCP_TOOL_ADD_ISSUE_COMMENT_DESCRIPTION="an alternative description
- `private`: Whether the repository is private (boolean, optional)
- `autoInit`: Auto-initialize with README (boolean, optional)
+- **create_repository_from_template** - Create a new GitHub repository from a template
+ - `template_owner`: The account owner of the template repository
+ - `template_repo` : The name of the template repository
+ - `name`: Repository name (string, required)
+ - `description`: Repository description (string, optional)
+ - `private`: Whether the repository is private (boolean, optional)
+
- **get_file_contents** - Get contents of a file or directory
- `owner`: Repository owner (string, required)
- `repo`: Repository name (string, required)
diff --git a/pkg/github/repositories.go b/pkg/github/repositories.go
index 3475167b1..6306368e8 100644
--- a/pkg/github/repositories.go
+++ b/pkg/github/repositories.go
@@ -390,6 +390,90 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
}
createdRepo, resp, err := client.Repositories.Create(ctx, "", repo)
+
+ if err != nil {
+ return nil, fmt.Errorf("failed to create repository: %w", err)
+ }
+ defer func() { _ = resp.Body.Close() }()
+
+ if resp.StatusCode != http.StatusCreated {
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read response body: %w", err)
+ }
+ return mcp.NewToolResultError(fmt.Sprintf("failed to create repository: %s", string(body))), nil
+ }
+
+ r, err := json.Marshal(createdRepo)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal response: %w", err)
+ }
+
+ return mcp.NewToolResultText(string(r)), nil
+ }
+}
+
+// CreateRepositoryFromTemplate creates a tool to create a new GitHub repository from a template.
+func CreateRepositoryFromTemplate(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
+ return mcp.NewTool("create_repository_from_template",
+ mcp.WithDescription(t("TOOL_CREATE_REPOSITORY_FROM_TEMPLATE_DESCRIPTION", "Create a new GitHub repository from template in your account")),
+ mcp.WithToolAnnotation(mcp.ToolAnnotation{
+ Title: t("TOOL_CREATE_REPOSITORY_FROM_TEMPLATE_USER_TITLE", "Create repository from template"),
+ ReadOnlyHint: ToBoolPtr(false),
+ }),
+ mcp.WithString("template_owner",
+ mcp.Required(),
+ mcp.Description("template owner"),
+ ),
+ mcp.WithString("template_repo",
+ mcp.Required(),
+ mcp.Description("The name of the template repository"),
+ ),
+ mcp.WithString("name",
+ mcp.Required(),
+ mcp.Description("Repository name"),
+ ),
+ mcp.WithString("description",
+ mcp.Description("Repository description"),
+ ),
+ mcp.WithBoolean("private",
+ mcp.Description("Whether repo should be private"),
+ ),
+ ),
+ func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
+ template_owner, err := RequiredParam[string](request, "template_owner")
+ if err != nil {
+ return mcp.NewToolResultError(err.Error()), nil
+ }
+ template_repo, err := RequiredParam[string](request, "template_repo")
+ if err != nil {
+ return mcp.NewToolResultError(err.Error()), nil
+ }
+ name, err := RequiredParam[string](request, "name")
+ if err != nil {
+ return mcp.NewToolResultError(err.Error()), nil
+ }
+ description, err := OptionalParam[string](request, "description")
+ if err != nil {
+ return mcp.NewToolResultError(err.Error()), nil
+ }
+ private, err := OptionalParam[bool](request, "private")
+ if err != nil {
+ return mcp.NewToolResultError(err.Error()), nil
+ }
+
+ repo := &github.TemplateRepoRequest{
+ Name: github.Ptr(name),
+ Description: github.Ptr(description),
+ Private: github.Ptr(private),
+ }
+
+ client, err := getClient(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get GitHub client: %w", err)
+ }
+ createdRepo, resp, err := client.Repositories.CreateFromTemplate(ctx, template_owner, template_repo, repo)
+
if err != nil {
return nil, fmt.Errorf("failed to create repository: %w", err)
}
diff --git a/pkg/github/tools.go b/pkg/github/tools.go
index 9569c4390..cc11e3a5b 100644
--- a/pkg/github/tools.go
+++ b/pkg/github/tools.go
@@ -35,6 +35,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
AddWriteTools(
toolsets.NewServerTool(CreateOrUpdateFile(getClient, t)),
toolsets.NewServerTool(CreateRepository(getClient, t)),
+ toolsets.NewServerTool(CreateRepositoryFromTemplate(getClient, t)),
toolsets.NewServerTool(ForkRepository(getClient, t)),
toolsets.NewServerTool(CreateBranch(getClient, t)),
toolsets.NewServerTool(PushFiles(getClient, t)),
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/github/github-mcp-server/pull/521.patch
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy