Skip to content

Commit 01c9ee0

Browse files
committed
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 <[email protected]>
1 parent 304f29a commit 01c9ee0

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

pkg/github/repositories.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,88 @@ func CreateRepository(getClient GetClientFn, t translations.TranslationHelperFun
481481
}
482482
}
483483

484+
// CreateRepositoryFromTemplate creates a tool to create a new GitHub repository from a template.
485+
func CreateRepositoryFromTemplate(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
486+
return mcp.NewTool("create_repository_from_template",
487+
mcp.WithDescription(t("TOOL_CREATE_REPOSITORY_FROM_TEMPLATE_DESCRIPTION", "Create a new GitHub repository from template in your account")),
488+
mcp.WithToolAnnotation(mcp.ToolAnnotation{
489+
Title: t("TOOL_CREATE_REPOSITORY_FROM_TEMPLATE_USER_TITLE", "Create repository from template"),
490+
ReadOnlyHint: ToBoolPtr(false),
491+
}),
492+
mcp.WithString("template_owner",
493+
mcp.Required(),
494+
mcp.Description("template owner"),
495+
),
496+
mcp.WithString("template_repo",
497+
mcp.Required(),
498+
mcp.Description("The name of the template repository"),
499+
),
500+
mcp.WithString("name",
501+
mcp.Required(),
502+
mcp.Description("Repository name"),
503+
),
504+
mcp.WithString("description",
505+
mcp.Description("Repository description"),
506+
),
507+
mcp.WithBoolean("private",
508+
mcp.Description("Whether repo should be private"),
509+
),
510+
),
511+
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
512+
templateOwner, err := RequiredParam[string](request, "template_owner")
513+
if err != nil {
514+
return mcp.NewToolResultError(err.Error()), nil
515+
}
516+
templateRepo, err := RequiredParam[string](request, "template_repo")
517+
if err != nil {
518+
return mcp.NewToolResultError(err.Error()), nil
519+
}
520+
name, err := RequiredParam[string](request, "name")
521+
if err != nil {
522+
return mcp.NewToolResultError(err.Error()), nil
523+
}
524+
description, err := OptionalParam[string](request, "description")
525+
if err != nil {
526+
return mcp.NewToolResultError(err.Error()), nil
527+
}
528+
private, err := OptionalParam[bool](request, "private")
529+
if err != nil {
530+
return mcp.NewToolResultError(err.Error()), nil
531+
}
532+
533+
repo := &github.TemplateRepoRequest{
534+
Name: github.Ptr(name),
535+
Description: github.Ptr(description),
536+
Private: github.Ptr(private),
537+
}
538+
539+
client, err := getClient(ctx)
540+
if err != nil {
541+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
542+
}
543+
createdRepo, resp, err := client.Repositories.CreateFromTemplate(ctx, templateOwner, templateRepo, repo)
544+
if err != nil {
545+
return nil, fmt.Errorf("failed to create repository from template: %w", err)
546+
}
547+
defer func() { _ = resp.Body.Close() }()
548+
549+
if resp.StatusCode != http.StatusCreated {
550+
body, err := io.ReadAll(resp.Body)
551+
if err != nil {
552+
return nil, fmt.Errorf("failed to read response body: %w", err)
553+
}
554+
return mcp.NewToolResultError(fmt.Sprintf("failed to create repository from template: %s", string(body))), nil
555+
}
556+
557+
r, err := json.Marshal(createdRepo)
558+
if err != nil {
559+
return nil, fmt.Errorf("failed to marshal response: %w", err)
560+
}
561+
562+
return mcp.NewToolResultText(string(r)), nil
563+
}
564+
}
565+
484566
// GetFileContents creates a tool to get the contents of a file or directory from a GitHub repository.
485567
func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
486568
return mcp.NewTool("get_file_contents",

pkg/github/tools.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
177177
AddWriteTools(
178178
toolsets.NewServerTool(CreateOrUpdateFile(getClient, t)),
179179
toolsets.NewServerTool(CreateRepository(getClient, t)),
180+
toolsets.NewServerTool(CreateRepositoryFromTemplate(getClient, t)),
180181
toolsets.NewServerTool(ForkRepository(getClient, t)),
181182
toolsets.NewServerTool(CreateBranch(getClient, t)),
182183
toolsets.NewServerTool(PushFiles(getClient, t)),

0 commit comments

Comments
 (0)