From e0abd256a3543c65cf24d9749f78e0c8723b29d4 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Thu, 12 Mar 2026 05:46:07 +0000 Subject: [PATCH] feat(mcp): add MCP tool to list organization repositories (#152) Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/152 Co-authored-by: Bo-Yi Wu Co-committed-by: Bo-Yi Wu --- operation/repo/repo.go | 51 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/operation/repo/repo.go b/operation/repo/repo.go index a52781e..88aabc1 100644 --- a/operation/repo/repo.go +++ b/operation/repo/repo.go @@ -2,6 +2,7 @@ package repo import ( "context" + "errors" "fmt" "gitea.com/gitea/gitea-mcp/pkg/gitea" @@ -18,9 +19,10 @@ import ( var Tool = tool.New() const ( - CreateRepoToolName = "create_repo" - ForkRepoToolName = "fork_repo" - ListMyReposToolName = "list_my_repos" + CreateRepoToolName = "create_repo" + ForkRepoToolName = "fork_repo" + ListMyReposToolName = "list_my_repos" + ListOrgReposToolName = "list_org_repos" ) var ( @@ -55,6 +57,14 @@ var ( mcp.WithNumber("page", mcp.Required(), mcp.Description("Page number"), mcp.DefaultNumber(1), mcp.Min(1)), mcp.WithNumber("perPage", mcp.Required(), mcp.Description("results per page"), mcp.DefaultNumber(30), mcp.Min(1)), ) + + ListOrgReposTool = mcp.NewTool( + ListOrgReposToolName, + mcp.WithDescription("List repositories of an organization"), + mcp.WithString("org", mcp.Required(), mcp.Description("Organization name")), + mcp.WithNumber("page", mcp.Required(), mcp.Description("Page number"), mcp.DefaultNumber(1), mcp.Min(1)), + mcp.WithNumber("pageSize", mcp.Required(), mcp.Description("Page size number"), mcp.DefaultNumber(100), mcp.Min(1)), + ) ) func init() { @@ -70,6 +80,10 @@ func init() { Tool: ListMyReposTool, Handler: ListMyReposFn, }) + Tool.RegisterRead(server.ServerTool{ + Tool: ListOrgReposTool, + Handler: ListOrgReposFn, + }) } func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -178,3 +192,34 @@ func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR return to.TextResult(slimRepos(repos)) } + +func ListOrgReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called ListOrgReposFn") + org, ok := req.GetArguments()["org"].(string) + if !ok { + return to.ErrorResult(errors.New("organization name is required")) + } + page, ok := req.GetArguments()["page"].(float64) + if !ok { + page = 1 + } + pageSize, ok := req.GetArguments()["pageSize"].(float64) + if !ok { + pageSize = 100 + } + opt := gitea_sdk.ListOrgReposOptions{ + ListOptions: gitea_sdk.ListOptions{ + Page: int(page), + PageSize: int(pageSize), + }, + } + client, err := gitea.ClientFromContext(ctx) + if err != nil { + return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) + } + repos, _, err := client.ListOrgRepos(org, opt) + if err != nil { + return to.ErrorResult(fmt.Errorf("list organization '%s' repositories error: %v", org, err)) + } + return to.TextResult(repos) +}