mirror of
https://gitea.com/gitea/gitea-mcp.git
synced 2026-03-19 03:15:12 +00:00
feat: slim tool responses (#141)
Reduce token usage by slimming tool responses. Instead of returning full Gitea SDK objects (with nested user/repo objects, avatars, permissions, etc.), each operation now has a colocated `slim.go` that extracts only the fields an LLM needs. List endpoints return even fewer fields than single-item endpoints.
Other changes:
- Add `params` helpers to DRY parameter extraction across 40+ handlers
- Remove `{"Result": ...}` wrapper for flatter responses
- Reduce default pageSize from 100 to 30
Fixes: https://gitea.com/gitea/gitea-mcp/issues/128
*Created by Claude on behalf of @silverwind*
Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/141
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-committed-by: silverwind <me@silverwind.io>
This commit is contained in:
@@ -109,17 +109,17 @@ func limitBytes(data []byte, maxBytes int) ([]byte, bool) {
|
|||||||
|
|
||||||
func GetRepoActionJobLogPreviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetRepoActionJobLogPreviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetRepoActionJobLogPreviewFn")
|
log.Debugf("Called GetRepoActionJobLogPreviewFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
jobID, err := params.GetIndex(req.GetArguments(), "job_id")
|
jobID, err := params.GetIndex(req.GetArguments(), "job_id")
|
||||||
if err != nil || jobID <= 0 {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("job_id is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
tailLines := int(params.GetOptionalInt(req.GetArguments(), "tail_lines", 200))
|
tailLines := int(params.GetOptionalInt(req.GetArguments(), "tail_lines", 200))
|
||||||
maxBytes := int(params.GetOptionalInt(req.GetArguments(), "max_bytes", 65536))
|
maxBytes := int(params.GetOptionalInt(req.GetArguments(), "max_bytes", 65536))
|
||||||
@@ -144,17 +144,17 @@ func GetRepoActionJobLogPreviewFn(ctx context.Context, req mcp.CallToolRequest)
|
|||||||
|
|
||||||
func DownloadRepoActionJobLogFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DownloadRepoActionJobLogFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DownloadRepoActionJobLogFn")
|
log.Debugf("Called DownloadRepoActionJobLogFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
jobID, err := params.GetIndex(req.GetArguments(), "job_id")
|
jobID, err := params.GetIndex(req.GetArguments(), "job_id")
|
||||||
if err != nil || jobID <= 0 {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("job_id is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
outputPath, _ := req.GetArguments()["output_path"].(string)
|
outputPath, _ := req.GetArguments()["output_path"].(string)
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ var (
|
|||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(50), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetRepoActionWorkflowTool = mcp.NewTool(
|
GetRepoActionWorkflowTool = mcp.NewTool(
|
||||||
@@ -66,7 +66,7 @@ var (
|
|||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(50), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
mcp.WithString("status", mcp.Description("optional status filter")),
|
mcp.WithString("status", mcp.Description("optional status filter")),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ var (
|
|||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(50), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
mcp.WithString("status", mcp.Description("optional status filter")),
|
mcp.WithString("status", mcp.Description("optional status filter")),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ var (
|
|||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("run_id", mcp.Required(), mcp.Description("run ID")),
|
mcp.WithNumber("run_id", mcp.Required(), mcp.Description("run ID")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(50), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -148,22 +148,21 @@ func doJSONWithFallback(ctx context.Context, method string, paths []string, quer
|
|||||||
|
|
||||||
func ListRepoActionWorkflowsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoActionWorkflowsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoActionWorkflowsFn")
|
log.Debugf("Called ListRepoActionWorkflowsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 50)
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("page", strconv.Itoa(int(page)))
|
query.Set("page", strconv.Itoa(page))
|
||||||
query.Set("limit", strconv.Itoa(int(pageSize)))
|
query.Set("limit", strconv.Itoa(pageSize))
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
err := doJSONWithFallback(ctx, "GET",
|
err = doJSONWithFallback(ctx, "GET",
|
||||||
[]string{
|
[]string{
|
||||||
fmt.Sprintf("repos/%s/%s/actions/workflows", url.PathEscape(owner), url.PathEscape(repo)),
|
fmt.Sprintf("repos/%s/%s/actions/workflows", url.PathEscape(owner), url.PathEscape(repo)),
|
||||||
},
|
},
|
||||||
@@ -172,26 +171,26 @@ func ListRepoActionWorkflowsFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list action workflows err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list action workflows err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(result)
|
return to.TextResult(slimActionWorkflows(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRepoActionWorkflowFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetRepoActionWorkflowFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetRepoActionWorkflowFn")
|
log.Debugf("Called GetRepoActionWorkflowFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
workflowID, ok := req.GetArguments()["workflow_id"].(string)
|
workflowID, err := params.GetString(req.GetArguments(), "workflow_id")
|
||||||
if !ok || workflowID == "" {
|
if err != nil || workflowID == "" {
|
||||||
return to.ErrorResult(errors.New("workflow_id is required"))
|
return to.ErrorResult(errors.New("workflow_id is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
err := doJSONWithFallback(ctx, "GET",
|
err = doJSONWithFallback(ctx, "GET",
|
||||||
[]string{
|
[]string{
|
||||||
fmt.Sprintf("repos/%s/%s/actions/workflows/%s", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(workflowID)),
|
fmt.Sprintf("repos/%s/%s/actions/workflows/%s", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(workflowID)),
|
||||||
},
|
},
|
||||||
@@ -200,25 +199,25 @@ func GetRepoActionWorkflowFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get action workflow err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get action workflow err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(result)
|
return to.TextResult(slimActionWorkflow(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DispatchRepoActionWorkflowFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DispatchRepoActionWorkflowFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DispatchRepoActionWorkflowFn")
|
log.Debugf("Called DispatchRepoActionWorkflowFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
workflowID, ok := req.GetArguments()["workflow_id"].(string)
|
workflowID, err := params.GetString(req.GetArguments(), "workflow_id")
|
||||||
if !ok || workflowID == "" {
|
if err != nil || workflowID == "" {
|
||||||
return to.ErrorResult(errors.New("workflow_id is required"))
|
return to.ErrorResult(errors.New("workflow_id is required"))
|
||||||
}
|
}
|
||||||
ref, ok := req.GetArguments()["ref"].(string)
|
ref, err := params.GetString(req.GetArguments(), "ref")
|
||||||
if !ok || ref == "" {
|
if err != nil || ref == "" {
|
||||||
return to.ErrorResult(errors.New("ref is required"))
|
return to.ErrorResult(errors.New("ref is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +238,7 @@ func DispatchRepoActionWorkflowFn(ctx context.Context, req mcp.CallToolRequest)
|
|||||||
body["inputs"] = inputs
|
body["inputs"] = inputs
|
||||||
}
|
}
|
||||||
|
|
||||||
err := doJSONWithFallback(ctx, "POST",
|
err = doJSONWithFallback(ctx, "POST",
|
||||||
[]string{
|
[]string{
|
||||||
fmt.Sprintf("repos/%s/%s/actions/workflows/%s/dispatches", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(workflowID)),
|
fmt.Sprintf("repos/%s/%s/actions/workflows/%s/dispatches", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(workflowID)),
|
||||||
fmt.Sprintf("repos/%s/%s/actions/workflows/%s/dispatch", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(workflowID)),
|
fmt.Sprintf("repos/%s/%s/actions/workflows/%s/dispatch", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(workflowID)),
|
||||||
@@ -258,27 +257,26 @@ func DispatchRepoActionWorkflowFn(ctx context.Context, req mcp.CallToolRequest)
|
|||||||
|
|
||||||
func ListRepoActionRunsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoActionRunsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoActionRunsFn")
|
log.Debugf("Called ListRepoActionRunsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 50)
|
|
||||||
statusFilter, _ := req.GetArguments()["status"].(string)
|
statusFilter, _ := req.GetArguments()["status"].(string)
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("page", strconv.Itoa(int(page)))
|
query.Set("page", strconv.Itoa(page))
|
||||||
query.Set("limit", strconv.Itoa(int(pageSize)))
|
query.Set("limit", strconv.Itoa(pageSize))
|
||||||
if statusFilter != "" {
|
if statusFilter != "" {
|
||||||
query.Set("status", statusFilter)
|
query.Set("status", statusFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
err := doJSONWithFallback(ctx, "GET",
|
err = doJSONWithFallback(ctx, "GET",
|
||||||
[]string{
|
[]string{
|
||||||
fmt.Sprintf("repos/%s/%s/actions/runs", url.PathEscape(owner), url.PathEscape(repo)),
|
fmt.Sprintf("repos/%s/%s/actions/runs", url.PathEscape(owner), url.PathEscape(repo)),
|
||||||
},
|
},
|
||||||
@@ -287,17 +285,17 @@ func ListRepoActionRunsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list action runs err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list action runs err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(result)
|
return to.TextResult(slimActionRuns(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetRepoActionRunFn")
|
log.Debugf("Called GetRepoActionRunFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
||||||
@@ -315,17 +313,17 @@ func GetRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get action run err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get action run err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(result)
|
return to.TextResult(slimActionRun(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CancelRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CancelRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CancelRepoActionRunFn")
|
log.Debugf("Called CancelRepoActionRunFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
||||||
@@ -347,12 +345,12 @@ func CancelRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.C
|
|||||||
|
|
||||||
func RerunRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func RerunRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called RerunRepoActionRunFn")
|
log.Debugf("Called RerunRepoActionRunFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
||||||
@@ -379,27 +377,26 @@ func RerunRepoActionRunFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
|
|
||||||
func ListRepoActionJobsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoActionJobsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoActionJobsFn")
|
log.Debugf("Called ListRepoActionJobsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 50)
|
|
||||||
statusFilter, _ := req.GetArguments()["status"].(string)
|
statusFilter, _ := req.GetArguments()["status"].(string)
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("page", strconv.Itoa(int(page)))
|
query.Set("page", strconv.Itoa(page))
|
||||||
query.Set("limit", strconv.Itoa(int(pageSize)))
|
query.Set("limit", strconv.Itoa(pageSize))
|
||||||
if statusFilter != "" {
|
if statusFilter != "" {
|
||||||
query.Set("status", statusFilter)
|
query.Set("status", statusFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
err := doJSONWithFallback(ctx, "GET",
|
err = doJSONWithFallback(ctx, "GET",
|
||||||
[]string{
|
[]string{
|
||||||
fmt.Sprintf("repos/%s/%s/actions/jobs", url.PathEscape(owner), url.PathEscape(repo)),
|
fmt.Sprintf("repos/%s/%s/actions/jobs", url.PathEscape(owner), url.PathEscape(repo)),
|
||||||
},
|
},
|
||||||
@@ -408,29 +405,28 @@ func ListRepoActionJobsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list action jobs err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list action jobs err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(result)
|
return to.TextResult(slimActionJobs(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListRepoActionRunJobsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoActionRunJobsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoActionRunJobsFn")
|
log.Debugf("Called ListRepoActionRunJobsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
runID, err := params.GetIndex(req.GetArguments(), "run_id")
|
||||||
if err != nil || runID <= 0 {
|
if err != nil || runID <= 0 {
|
||||||
return to.ErrorResult(errors.New("run_id is required"))
|
return to.ErrorResult(errors.New("run_id is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 50)
|
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("page", strconv.Itoa(int(page)))
|
query.Set("page", strconv.Itoa(page))
|
||||||
query.Set("limit", strconv.Itoa(int(pageSize)))
|
query.Set("limit", strconv.Itoa(pageSize))
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
err = doJSONWithFallback(ctx, "GET",
|
err = doJSONWithFallback(ctx, "GET",
|
||||||
@@ -442,5 +438,5 @@ func ListRepoActionRunJobsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list action run jobs err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list action run jobs err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(result)
|
return to.TextResult(slimActionJobs(result))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ var (
|
|||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
UpsertRepoActionSecretTool = mcp.NewTool(
|
UpsertRepoActionSecretTool = mcp.NewTool(
|
||||||
@@ -65,7 +65,7 @@ var (
|
|||||||
mcp.WithDescription("List organization Actions secrets (metadata only; secret values are never returned)"),
|
mcp.WithDescription("List organization Actions secrets (metadata only; secret values are never returned)"),
|
||||||
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
UpsertOrgActionSecretTool = mcp.NewTool(
|
UpsertOrgActionSecretTool = mcp.NewTool(
|
||||||
@@ -97,16 +97,15 @@ func init() {
|
|||||||
|
|
||||||
func ListRepoActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoActionSecretsFn")
|
log.Debugf("Called ListRepoActionSecretsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -114,7 +113,7 @@ func ListRepoActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
}
|
}
|
||||||
|
|
||||||
secrets, _, err := client.ListRepoActionSecret(owner, repo, gitea_sdk.ListRepoActionSecretOption{
|
secrets, _, err := client.ListRepoActionSecret(owner, repo, gitea_sdk.ListRepoActionSecretOption{
|
||||||
ListOptions: gitea_sdk.ListOptions{Page: int(page), PageSize: int(pageSize)},
|
ListOptions: gitea_sdk.ListOptions{Page: page, PageSize: pageSize},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list repo action secrets err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list repo action secrets err: %v", err))
|
||||||
@@ -136,20 +135,20 @@ func ListRepoActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
|
|
||||||
func UpsertRepoActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UpsertRepoActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UpsertRepoActionSecretFn")
|
log.Debugf("Called UpsertRepoActionSecretFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
data, ok := req.GetArguments()["data"].(string)
|
data, err := params.GetString(req.GetArguments(), "data")
|
||||||
if !ok || data == "" {
|
if err != nil || data == "" {
|
||||||
return to.ErrorResult(errors.New("data is required"))
|
return to.ErrorResult(errors.New("data is required"))
|
||||||
}
|
}
|
||||||
description, _ := req.GetArguments()["description"].(string)
|
description, _ := req.GetArguments()["description"].(string)
|
||||||
@@ -171,16 +170,16 @@ func UpsertRepoActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mc
|
|||||||
|
|
||||||
func DeleteRepoActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteRepoActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteRepoActionSecretFn")
|
log.Debugf("Called DeleteRepoActionSecretFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
secretName, ok := req.GetArguments()["secretName"].(string)
|
secretName, err := params.GetString(req.GetArguments(), "secretName")
|
||||||
if !ok || secretName == "" {
|
if err != nil || secretName == "" {
|
||||||
return to.ErrorResult(errors.New("secretName is required"))
|
return to.ErrorResult(errors.New("secretName is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,12 +196,11 @@ func DeleteRepoActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mc
|
|||||||
|
|
||||||
func ListOrgActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListOrgActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListOrgActionSecretsFn")
|
log.Debugf("Called ListOrgActionSecretsFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -210,7 +208,7 @@ func ListOrgActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|||||||
}
|
}
|
||||||
|
|
||||||
secrets, _, err := client.ListOrgActionSecret(org, gitea_sdk.ListOrgActionSecretOption{
|
secrets, _, err := client.ListOrgActionSecret(org, gitea_sdk.ListOrgActionSecretOption{
|
||||||
ListOptions: gitea_sdk.ListOptions{Page: int(page), PageSize: int(pageSize)},
|
ListOptions: gitea_sdk.ListOptions{Page: page, PageSize: pageSize},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list org action secrets err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list org action secrets err: %v", err))
|
||||||
@@ -232,16 +230,16 @@ func ListOrgActionSecretsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|||||||
|
|
||||||
func UpsertOrgActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UpsertOrgActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UpsertOrgActionSecretFn")
|
log.Debugf("Called UpsertOrgActionSecretFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
data, ok := req.GetArguments()["data"].(string)
|
data, err := params.GetString(req.GetArguments(), "data")
|
||||||
if !ok || data == "" {
|
if err != nil || data == "" {
|
||||||
return to.ErrorResult(errors.New("data is required"))
|
return to.ErrorResult(errors.New("data is required"))
|
||||||
}
|
}
|
||||||
description, _ := req.GetArguments()["description"].(string)
|
description, _ := req.GetArguments()["description"].(string)
|
||||||
@@ -263,18 +261,18 @@ func UpsertOrgActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
|
|
||||||
func DeleteOrgActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteOrgActionSecretFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteOrgActionSecretFn")
|
log.Debugf("Called DeleteOrgActionSecretFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
secretName, ok := req.GetArguments()["secretName"].(string)
|
secretName, err := params.GetString(req.GetArguments(), "secretName")
|
||||||
if !ok || secretName == "" {
|
if err != nil || secretName == "" {
|
||||||
return to.ErrorResult(errors.New("secretName is required"))
|
return to.ErrorResult(errors.New("secretName is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
escapedOrg := url.PathEscape(org)
|
escapedOrg := url.PathEscape(org)
|
||||||
escapedSecret := url.PathEscape(secretName)
|
escapedSecret := url.PathEscape(secretName)
|
||||||
_, err := gitea.DoJSON(ctx, "DELETE", fmt.Sprintf("orgs/%s/actions/secrets/%s", escapedOrg, escapedSecret), nil, nil, nil)
|
_, err = gitea.DoJSON(ctx, "DELETE", fmt.Sprintf("orgs/%s/actions/secrets/%s", escapedOrg, escapedSecret), nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("delete org action secret err: %v", err))
|
return to.ErrorResult(fmt.Errorf("delete org action secret err: %v", err))
|
||||||
}
|
}
|
||||||
|
|||||||
92
operation/actions/slim.go
Normal file
92
operation/actions/slim.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package actions
|
||||||
|
|
||||||
|
func pick(m map[string]any, keys ...string) map[string]any {
|
||||||
|
out := make(map[string]any, len(keys))
|
||||||
|
for _, k := range keys {
|
||||||
|
if v, ok := m[k]; ok {
|
||||||
|
out[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimPaginated(raw any, itemFn func(map[string]any) map[string]any) any {
|
||||||
|
m, ok := raw.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
result := make(map[string]any)
|
||||||
|
if tc, ok := m["total_count"]; ok {
|
||||||
|
result["total_count"] = tc
|
||||||
|
}
|
||||||
|
for key, val := range m {
|
||||||
|
if key == "total_count" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
arr, ok := val.([]any)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
slimmed := make([]any, 0, len(arr))
|
||||||
|
for _, item := range arr {
|
||||||
|
if im, ok := item.(map[string]any); ok {
|
||||||
|
slimmed = append(slimmed, itemFn(im))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[key] = slimmed
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimRun(m map[string]any) map[string]any {
|
||||||
|
return pick(m, "id", "name", "head_branch", "head_sha", "run_number",
|
||||||
|
"event", "status", "conclusion", "workflow_id",
|
||||||
|
"html_url", "created_at", "updated_at")
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimJob(m map[string]any) map[string]any {
|
||||||
|
out := pick(m, "id", "run_id", "name", "workflow_name",
|
||||||
|
"status", "conclusion", "html_url",
|
||||||
|
"started_at", "completed_at")
|
||||||
|
if steps, ok := m["steps"].([]any); ok {
|
||||||
|
slim := make([]any, 0, len(steps))
|
||||||
|
for _, s := range steps {
|
||||||
|
if sm, ok := s.(map[string]any); ok {
|
||||||
|
slim = append(slim, pick(sm, "name", "number", "status", "conclusion"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out["steps"] = slim
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimWorkflow(m map[string]any) map[string]any {
|
||||||
|
return pick(m, "id", "name", "path", "state", "html_url", "created_at", "updated_at")
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimActionRun(raw any) any {
|
||||||
|
if m, ok := raw.(map[string]any); ok {
|
||||||
|
return slimRun(m)
|
||||||
|
}
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimActionRuns(raw any) any {
|
||||||
|
return slimPaginated(raw, slimRun)
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimActionJobs(raw any) any {
|
||||||
|
return slimPaginated(raw, slimJob)
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimActionWorkflow(raw any) any {
|
||||||
|
if m, ok := raw.(map[string]any); ok {
|
||||||
|
return slimWorkflow(m)
|
||||||
|
}
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimActionWorkflows(raw any) any {
|
||||||
|
return slimPaginated(raw, slimWorkflow)
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ var (
|
|||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetRepoActionVariableTool = mcp.NewTool(
|
GetRepoActionVariableTool = mcp.NewTool(
|
||||||
@@ -80,7 +80,7 @@ var (
|
|||||||
mcp.WithDescription("List organization Actions variables"),
|
mcp.WithDescription("List organization Actions variables"),
|
||||||
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100), mcp.Min(1)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetOrgActionVariableTool = mcp.NewTool(
|
GetOrgActionVariableTool = mcp.NewTool(
|
||||||
@@ -132,23 +132,22 @@ func init() {
|
|||||||
|
|
||||||
func ListRepoActionVariablesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoActionVariablesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoActionVariablesFn")
|
log.Debugf("Called ListRepoActionVariablesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("page", strconv.Itoa(int(page)))
|
query.Set("page", strconv.Itoa(page))
|
||||||
query.Set("limit", strconv.Itoa(int(pageSize)))
|
query.Set("limit", strconv.Itoa(pageSize))
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
_, err := gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/actions/variables", url.PathEscape(owner), url.PathEscape(repo)), query, nil, &result)
|
_, err = gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/actions/variables", url.PathEscape(owner), url.PathEscape(repo)), query, nil, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list repo action variables err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list repo action variables err: %v", err))
|
||||||
}
|
}
|
||||||
@@ -157,16 +156,16 @@ func ListRepoActionVariablesFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
|
|
||||||
func GetRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetRepoActionVariableFn")
|
log.Debugf("Called GetRepoActionVariableFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,20 +182,20 @@ func GetRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
|
|
||||||
func CreateRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateRepoActionVariableFn")
|
log.Debugf("Called CreateRepoActionVariableFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
value, ok := req.GetArguments()["value"].(string)
|
value, err := params.GetString(req.GetArguments(), "value")
|
||||||
if !ok || value == "" {
|
if err != nil || value == "" {
|
||||||
return to.ErrorResult(errors.New("value is required"))
|
return to.ErrorResult(errors.New("value is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,20 +212,20 @@ func CreateRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*
|
|||||||
|
|
||||||
func UpdateRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UpdateRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UpdateRepoActionVariableFn")
|
log.Debugf("Called UpdateRepoActionVariableFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
value, ok := req.GetArguments()["value"].(string)
|
value, err := params.GetString(req.GetArguments(), "value")
|
||||||
if !ok || value == "" {
|
if err != nil || value == "" {
|
||||||
return to.ErrorResult(errors.New("value is required"))
|
return to.ErrorResult(errors.New("value is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,16 +242,16 @@ func UpdateRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*
|
|||||||
|
|
||||||
func DeleteRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteRepoActionVariableFn")
|
log.Debugf("Called DeleteRepoActionVariableFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok || owner == "" {
|
if err != nil || owner == "" {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(errors.New("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok || repo == "" {
|
if err != nil || repo == "" {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(errors.New("repo is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,19 +268,18 @@ func DeleteRepoActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*
|
|||||||
|
|
||||||
func ListOrgActionVariablesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListOrgActionVariablesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListOrgActionVariablesFn")
|
log.Debugf("Called ListOrgActionVariablesFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||||
}
|
}
|
||||||
variables, _, err := client.ListOrgActionVariable(org, gitea_sdk.ListOrgActionVariableOption{
|
variables, _, err := client.ListOrgActionVariable(org, gitea_sdk.ListOrgActionVariableOption{
|
||||||
ListOptions: gitea_sdk.ListOptions{Page: int(page), PageSize: int(pageSize)},
|
ListOptions: gitea_sdk.ListOptions{Page: page, PageSize: pageSize},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list org action variables err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list org action variables err: %v", err))
|
||||||
@@ -291,12 +289,12 @@ func ListOrgActionVariablesFn(ctx context.Context, req mcp.CallToolRequest) (*mc
|
|||||||
|
|
||||||
func GetOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetOrgActionVariableFn")
|
log.Debugf("Called GetOrgActionVariableFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,16 +311,16 @@ func GetOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|||||||
|
|
||||||
func CreateOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateOrgActionVariableFn")
|
log.Debugf("Called CreateOrgActionVariableFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
value, ok := req.GetArguments()["value"].(string)
|
value, err := params.GetString(req.GetArguments(), "value")
|
||||||
if !ok || value == "" {
|
if err != nil || value == "" {
|
||||||
return to.ErrorResult(errors.New("value is required"))
|
return to.ErrorResult(errors.New("value is required"))
|
||||||
}
|
}
|
||||||
description, _ := req.GetArguments()["description"].(string)
|
description, _ := req.GetArguments()["description"].(string)
|
||||||
@@ -344,16 +342,16 @@ func CreateOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
|
|
||||||
func UpdateOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UpdateOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UpdateOrgActionVariableFn")
|
log.Debugf("Called UpdateOrgActionVariableFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
value, ok := req.GetArguments()["value"].(string)
|
value, err := params.GetString(req.GetArguments(), "value")
|
||||||
if !ok || value == "" {
|
if err != nil || value == "" {
|
||||||
return to.ErrorResult(errors.New("value is required"))
|
return to.ErrorResult(errors.New("value is required"))
|
||||||
}
|
}
|
||||||
description, _ := req.GetArguments()["description"].(string)
|
description, _ := req.GetArguments()["description"].(string)
|
||||||
@@ -374,16 +372,16 @@ func UpdateOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
|
|
||||||
func DeleteOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteOrgActionVariableFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteOrgActionVariableFn")
|
log.Debugf("Called DeleteOrgActionVariableFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok || org == "" {
|
if err != nil || org == "" {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(errors.New("org is required"))
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok || name == "" {
|
if err != nil || name == "" {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(errors.New("name is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := gitea.DoJSON(ctx, "DELETE", fmt.Sprintf("orgs/%s/actions/variables/%s", url.PathEscape(org), url.PathEscape(name)), nil, nil, nil)
|
_, err = gitea.DoJSON(ctx, "DELETE", fmt.Sprintf("orgs/%s/actions/variables/%s", url.PathEscape(org), url.PathEscape(name)), nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("delete org action variable err: %v", err))
|
return to.ErrorResult(fmt.Errorf("delete org action variable err: %v", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package issue
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -44,7 +43,7 @@ var (
|
|||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithString("state", mcp.Description("issue state"), mcp.DefaultString("all")),
|
mcp.WithString("state", mcp.Description("issue state"), mcp.DefaultString("all")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
CreateIssueTool = mcp.NewTool(
|
CreateIssueTool = mcp.NewTool(
|
||||||
@@ -129,13 +128,13 @@ func init() {
|
|||||||
|
|
||||||
func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetIssueByIndexFn")
|
log.Debugf("Called GetIssueByIndexFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -150,30 +149,29 @@ func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/issue/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/issue/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issue)
|
return to.TextResult(slimIssue(issue))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListIssuesFn")
|
log.Debugf("Called ListIssuesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
state, ok := req.GetArguments()["state"].(string)
|
state, ok := req.GetArguments()["state"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
state = "all"
|
state = "all"
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
opt := gitea_sdk.ListIssueOption{
|
opt := gitea_sdk.ListIssueOption{
|
||||||
State: gitea_sdk.StateType(state),
|
State: gitea_sdk.StateType(state),
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -184,26 +182,26 @@ func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/issues err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/issues err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(issues)
|
return to.TextResult(slimIssues(issues))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateIssueFn")
|
log.Debugf("Called CreateIssueFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
title, ok := req.GetArguments()["title"].(string)
|
title, err := params.GetString(req.GetArguments(), "title")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("title is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
body, ok := req.GetArguments()["body"].(string)
|
body, err := params.GetString(req.GetArguments(), "body")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("body is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -217,26 +215,26 @@ func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
return to.ErrorResult(fmt.Errorf("create %v/%v/issue err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("create %v/%v/issue err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issue)
|
return to.TextResult(slimIssue(issue))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateIssueCommentFn")
|
log.Debugf("Called CreateIssueCommentFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
body, ok := req.GetArguments()["body"].(string)
|
body, err := params.GetString(req.GetArguments(), "body")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("body is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
opt := gitea_sdk.CreateIssueCommentOption{
|
opt := gitea_sdk.CreateIssueCommentOption{
|
||||||
Body: body,
|
Body: body,
|
||||||
@@ -250,18 +248,18 @@ func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
return to.ErrorResult(fmt.Errorf("create %v/%v/issue/%v/comment err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("create %v/%v/issue/%v/comment err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issueComment)
|
return to.TextResult(slimComment(issueComment))
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func EditIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called EditIssueFn")
|
log.Debugf("Called EditIssueFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -278,17 +276,7 @@ func EditIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
|
|||||||
if ok {
|
if ok {
|
||||||
opt.Body = new(body)
|
opt.Body = new(body)
|
||||||
}
|
}
|
||||||
var assignees []string
|
opt.Assignees = params.GetStringSlice(req.GetArguments(), "assignees")
|
||||||
if assigneesArg, exists := req.GetArguments()["assignees"]; exists {
|
|
||||||
if assigneesSlice, ok := assigneesArg.([]any); ok {
|
|
||||||
for _, assignee := range assigneesSlice {
|
|
||||||
if assigneeStr, ok := assignee.(string); ok {
|
|
||||||
assignees = append(assignees, assigneeStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opt.Assignees = assignees
|
|
||||||
if val, exists := req.GetArguments()["milestone"]; exists {
|
if val, exists := req.GetArguments()["milestone"]; exists {
|
||||||
if milestone, ok := params.ToInt64(val); ok {
|
if milestone, ok := params.ToInt64(val); ok {
|
||||||
opt.Milestone = new(milestone)
|
opt.Milestone = new(milestone)
|
||||||
@@ -308,26 +296,26 @@ func EditIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
|
|||||||
return to.ErrorResult(fmt.Errorf("edit %v/%v/issue/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("edit %v/%v/issue/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issue)
|
return to.TextResult(slimIssue(issue))
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func EditIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called EditIssueCommentFn")
|
log.Debugf("Called EditIssueCommentFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
commentID, err := params.GetIndex(req.GetArguments(), "commentID")
|
commentID, err := params.GetIndex(req.GetArguments(), "commentID")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
body, ok := req.GetArguments()["body"].(string)
|
body, err := params.GetString(req.GetArguments(), "body")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("body is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
opt := gitea_sdk.EditIssueCommentOption{
|
opt := gitea_sdk.EditIssueCommentOption{
|
||||||
Body: body,
|
Body: body,
|
||||||
@@ -341,18 +329,18 @@ func EditIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
return to.ErrorResult(fmt.Errorf("edit %v/%v/issues/comments/%v err: %v", owner, repo, commentID, err))
|
return to.ErrorResult(fmt.Errorf("edit %v/%v/issues/comments/%v err: %v", owner, repo, commentID, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issueComment)
|
return to.TextResult(slimComment(issueComment))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetIssueCommentsByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetIssueCommentsByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetIssueCommentsByIndexFn")
|
log.Debugf("Called GetIssueCommentsByIndexFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -368,5 +356,5 @@ func GetIssueCommentsByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/issues/%v/comments err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/issues/%v/comments err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issue)
|
return to.TextResult(slimComments(issue))
|
||||||
}
|
}
|
||||||
|
|||||||
116
operation/issue/slim.go
Normal file
116
operation/issue/slim.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package issue
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func userLogin(u *gitea_sdk.User) string {
|
||||||
|
if u == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return u.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
func userLogins(users []*gitea_sdk.User) []string {
|
||||||
|
if len(users) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := make([]string, 0, len(users))
|
||||||
|
for _, u := range users {
|
||||||
|
if u != nil {
|
||||||
|
out = append(out, u.UserName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func labelNames(labels []*gitea_sdk.Label) []string {
|
||||||
|
if len(labels) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := make([]string, 0, len(labels))
|
||||||
|
for _, l := range labels {
|
||||||
|
if l != nil {
|
||||||
|
out = append(out, l.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimIssue(i *gitea_sdk.Issue) map[string]any {
|
||||||
|
if i == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"number": i.Index,
|
||||||
|
"title": i.Title,
|
||||||
|
"body": i.Body,
|
||||||
|
"state": i.State,
|
||||||
|
"html_url": i.HTMLURL,
|
||||||
|
"user": userLogin(i.Poster),
|
||||||
|
"labels": labelNames(i.Labels),
|
||||||
|
"comments": i.Comments,
|
||||||
|
"created_at": i.Created,
|
||||||
|
"updated_at": i.Updated,
|
||||||
|
"closed_at": i.Closed,
|
||||||
|
}
|
||||||
|
if len(i.Assignees) > 0 {
|
||||||
|
m["assignees"] = userLogins(i.Assignees)
|
||||||
|
}
|
||||||
|
if i.Milestone != nil {
|
||||||
|
m["milestone"] = map[string]any{
|
||||||
|
"id": i.Milestone.ID,
|
||||||
|
"title": i.Milestone.Title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i.PullRequest != nil {
|
||||||
|
m["is_pull"] = true
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimIssues(issues []*gitea_sdk.Issue) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(issues))
|
||||||
|
for _, i := range issues {
|
||||||
|
if i == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"number": i.Index,
|
||||||
|
"title": i.Title,
|
||||||
|
"state": i.State,
|
||||||
|
"html_url": i.HTMLURL,
|
||||||
|
"user": userLogin(i.Poster),
|
||||||
|
"comments": i.Comments,
|
||||||
|
"created_at": i.Created,
|
||||||
|
"updated_at": i.Updated,
|
||||||
|
}
|
||||||
|
if len(i.Labels) > 0 {
|
||||||
|
m["labels"] = labelNames(i.Labels)
|
||||||
|
}
|
||||||
|
out = append(out, m)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimComment(c *gitea_sdk.Comment) map[string]any {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": c.ID,
|
||||||
|
"body": c.Body,
|
||||||
|
"user": userLogin(c.Poster),
|
||||||
|
"html_url": c.HTMLURL,
|
||||||
|
"created_at": c.Created,
|
||||||
|
"updated_at": c.Updated,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimComments(comments []*gitea_sdk.Comment) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(comments))
|
||||||
|
for _, c := range comments {
|
||||||
|
out = append(out, slimComment(c))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
69
operation/issue/slim_test.go
Normal file
69
operation/issue/slim_test.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package issue
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSlimIssue(t *testing.T) {
|
||||||
|
i := &gitea_sdk.Issue{
|
||||||
|
Index: 42,
|
||||||
|
Title: "Bug report",
|
||||||
|
Body: "Something is broken",
|
||||||
|
State: "open",
|
||||||
|
HTMLURL: "https://gitea.com/org/repo/issues/42",
|
||||||
|
Poster: &gitea_sdk.User{UserName: "alice"},
|
||||||
|
Labels: []*gitea_sdk.Label{{Name: "bug"}},
|
||||||
|
Milestone: &gitea_sdk.Milestone{
|
||||||
|
ID: 1,
|
||||||
|
Title: "v1.0",
|
||||||
|
},
|
||||||
|
PullRequest: &gitea_sdk.PullRequestMeta{HasMerged: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := slimIssue(i)
|
||||||
|
|
||||||
|
if m["number"] != int64(42) {
|
||||||
|
t.Errorf("expected number 42, got %v", m["number"])
|
||||||
|
}
|
||||||
|
if m["body"] != "Something is broken" {
|
||||||
|
t.Errorf("expected body, got %v", m["body"])
|
||||||
|
}
|
||||||
|
if m["is_pull"] != true {
|
||||||
|
t.Error("expected is_pull true for issue with PullRequest")
|
||||||
|
}
|
||||||
|
|
||||||
|
ms := m["milestone"].(map[string]any)
|
||||||
|
if ms["title"] != "v1.0" {
|
||||||
|
t.Errorf("expected milestone title v1.0, got %v", ms["title"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimIssues_ListIsSlimmer(t *testing.T) {
|
||||||
|
i := &gitea_sdk.Issue{
|
||||||
|
Index: 1,
|
||||||
|
Title: "Issue",
|
||||||
|
State: "open",
|
||||||
|
Body: "Full body",
|
||||||
|
Poster: &gitea_sdk.User{UserName: "alice"},
|
||||||
|
Labels: []*gitea_sdk.Label{{Name: "enhancement"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
single := slimIssue(i)
|
||||||
|
list := slimIssues([]*gitea_sdk.Issue{i})
|
||||||
|
|
||||||
|
// Single has body, list does not
|
||||||
|
if _, ok := single["body"]; !ok {
|
||||||
|
t.Error("single issue should have body")
|
||||||
|
}
|
||||||
|
if _, ok := list[0]["body"]; ok {
|
||||||
|
t.Error("list issue should not have body")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimIssues_Nil(t *testing.T) {
|
||||||
|
if r := slimIssues(nil); len(r) != 0 {
|
||||||
|
t.Errorf("expected empty slice, got %v", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ var (
|
|||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetRepoLabelTool = mcp.NewTool(
|
GetRepoLabelTool = mcp.NewTool(
|
||||||
@@ -121,7 +121,7 @@ var (
|
|||||||
mcp.WithDescription("Lists labels defined at organization level"),
|
mcp.WithDescription("Lists labels defined at organization level"),
|
||||||
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
CreateOrgLabelTool = mcp.NewTool(
|
CreateOrgLabelTool = mcp.NewTool(
|
||||||
@@ -210,21 +210,20 @@ func init() {
|
|||||||
|
|
||||||
func ListRepoLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoLabelsFn")
|
log.Debugf("Called ListRepoLabelsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
|
|
||||||
opt := gitea_sdk.ListLabelsOptions{
|
opt := gitea_sdk.ListLabelsOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -235,18 +234,18 @@ func ListRepoLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list %v/%v/labels err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("list %v/%v/labels err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(labels)
|
return to.TextResult(slimLabels(labels))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetRepoLabelFn")
|
log.Debugf("Called GetRepoLabelFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -261,26 +260,26 @@ func GetRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/label/%v err: %v", owner, repo, id, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/label/%v err: %v", owner, repo, id, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(label)
|
return to.TextResult(slimLabel(label))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateRepoLabelFn")
|
log.Debugf("Called CreateRepoLabelFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
color, ok := req.GetArguments()["color"].(string)
|
color, err := params.GetString(req.GetArguments(), "color")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("color is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
description, _ := req.GetArguments()["description"].(string) // Optional
|
description, _ := req.GetArguments()["description"].(string) // Optional
|
||||||
|
|
||||||
@@ -298,18 +297,18 @@ func CreateRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("create %v/%v/label err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("create %v/%v/label err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(label)
|
return to.TextResult(slimLabel(label))
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func EditRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called EditRepoLabelFn")
|
log.Debugf("Called EditRepoLabelFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -335,18 +334,18 @@ func EditRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("edit %v/%v/label/%v err: %v", owner, repo, id, err))
|
return to.ErrorResult(fmt.Errorf("edit %v/%v/label/%v err: %v", owner, repo, id, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(label)
|
return to.TextResult(slimLabel(label))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteRepoLabelFn")
|
log.Debugf("Called DeleteRepoLabelFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -366,13 +365,13 @@ func DeleteRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
|
|
||||||
func AddIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func AddIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called AddIssueLabelsFn")
|
log.Debugf("Called AddIssueLabelsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -403,18 +402,18 @@ func AddIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("add labels to %v/%v/issue/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("add labels to %v/%v/issue/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(issueLabels)
|
return to.TextResult(slimLabels(issueLabels))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReplaceIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ReplaceIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ReplaceIssueLabelsFn")
|
log.Debugf("Called ReplaceIssueLabelsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -445,18 +444,18 @@ func ReplaceIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("replace labels on %v/%v/issue/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("replace labels on %v/%v/issue/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(issueLabels)
|
return to.TextResult(slimLabels(issueLabels))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ClearIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ClearIssueLabelsFn")
|
log.Debugf("Called ClearIssueLabelsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -476,13 +475,13 @@ func ClearIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
|
|
||||||
func RemoveIssueLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func RemoveIssueLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called RemoveIssueLabelFn")
|
log.Debugf("Called RemoveIssueLabelFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -506,17 +505,16 @@ func RemoveIssueLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
|
|
||||||
func ListOrgLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListOrgLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListOrgLabelsFn")
|
log.Debugf("Called ListOrgLabelsFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
|
|
||||||
opt := gitea_sdk.ListOrgLabelsOptions{
|
opt := gitea_sdk.ListOrgLabelsOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -527,22 +525,22 @@ func ListOrgLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list %v/labels err: %v", org, err))
|
return to.ErrorResult(fmt.Errorf("list %v/labels err: %v", org, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(labels)
|
return to.TextResult(slimLabels(labels))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateOrgLabelFn")
|
log.Debugf("Called CreateOrgLabelFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, err := params.GetString(req.GetArguments(), "name")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("name is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
color, ok := req.GetArguments()["color"].(string)
|
color, err := params.GetString(req.GetArguments(), "color")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("color is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
description, _ := req.GetArguments()["description"].(string)
|
description, _ := req.GetArguments()["description"].(string)
|
||||||
exclusive, _ := req.GetArguments()["exclusive"].(bool)
|
exclusive, _ := req.GetArguments()["exclusive"].(bool)
|
||||||
@@ -562,14 +560,14 @@ func CreateOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("create %v/labels err: %v", org, err))
|
return to.ErrorResult(fmt.Errorf("create %v/labels err: %v", org, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(label)
|
return to.TextResult(slimLabel(label))
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func EditOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called EditOrgLabelFn")
|
log.Debugf("Called EditOrgLabelFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -598,14 +596,14 @@ func EditOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("edit %v/labels/%v err: %v", org, id, err))
|
return to.ErrorResult(fmt.Errorf("edit %v/labels/%v err: %v", org, id, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(label)
|
return to.TextResult(slimLabel(label))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteOrgLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteOrgLabelFn")
|
log.Debugf("Called DeleteOrgLabelFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("org is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
26
operation/label/slim.go
Normal file
26
operation/label/slim.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package label
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func slimLabel(l *gitea_sdk.Label) map[string]any {
|
||||||
|
if l == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": l.ID,
|
||||||
|
"name": l.Name,
|
||||||
|
"color": l.Color,
|
||||||
|
"description": l.Description,
|
||||||
|
"exclusive": l.Exclusive,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimLabels(labels []*gitea_sdk.Label) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(labels))
|
||||||
|
for _, l := range labels {
|
||||||
|
out = append(out, slimLabel(l))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
25
operation/label/slim_test.go
Normal file
25
operation/label/slim_test.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package label
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSlimLabel(t *testing.T) {
|
||||||
|
l := &gitea_sdk.Label{
|
||||||
|
ID: 1,
|
||||||
|
Name: "bug",
|
||||||
|
Color: "#d73a4a",
|
||||||
|
Description: "Something isn't working",
|
||||||
|
Exclusive: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
m := slimLabel(l)
|
||||||
|
if m["name"] != "bug" {
|
||||||
|
t.Errorf("expected name bug, got %v", m["name"])
|
||||||
|
}
|
||||||
|
if m["color"] != "#d73a4a" {
|
||||||
|
t.Errorf("expected color, got %v", m["color"])
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package milestone
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -43,7 +42,7 @@ var (
|
|||||||
mcp.WithString("state", mcp.Description("milestone state"), mcp.DefaultString("all")),
|
mcp.WithString("state", mcp.Description("milestone state"), mcp.DefaultString("all")),
|
||||||
mcp.WithString("name", mcp.Description("milestone name")),
|
mcp.WithString("name", mcp.Description("milestone name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
CreateMilestoneTool = mcp.NewTool(
|
CreateMilestoneTool = mcp.NewTool(
|
||||||
@@ -102,13 +101,13 @@ func init() {
|
|||||||
|
|
||||||
func GetMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetMilestoneFn")
|
log.Debugf("Called GetMilestoneFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -123,35 +122,28 @@ func GetMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/milestone/%v err: %v", owner, repo, id, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/milestone/%v err: %v", owner, repo, id, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(milestone)
|
return to.TextResult(slimMilestone(milestone))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListMilestonesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListMilestonesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListMilestonesFn")
|
log.Debugf("Called ListMilestonesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
state, ok := req.GetArguments()["state"].(string)
|
state := params.GetOptionalString(req.GetArguments(), "state", "all")
|
||||||
if !ok {
|
name := params.GetOptionalString(req.GetArguments(), "name", "")
|
||||||
state = "all"
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
}
|
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
|
||||||
if !ok {
|
|
||||||
name = ""
|
|
||||||
}
|
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
opt := gitea_sdk.ListMilestoneOption{
|
opt := gitea_sdk.ListMilestoneOption{
|
||||||
State: gitea_sdk.StateType(state),
|
State: gitea_sdk.StateType(state),
|
||||||
Name: name,
|
Name: name,
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -162,22 +154,22 @@ func ListMilestonesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/milestones err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/milestones err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(milestones)
|
return to.TextResult(slimMilestones(milestones))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateMilestoneFn")
|
log.Debugf("Called CreateMilestoneFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
title, ok := req.GetArguments()["title"].(string)
|
title, err := params.GetString(req.GetArguments(), "title")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("title is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := gitea_sdk.CreateMilestoneOption{
|
opt := gitea_sdk.CreateMilestoneOption{
|
||||||
@@ -198,18 +190,18 @@ func CreateMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
return to.ErrorResult(fmt.Errorf("create %v/%v/milestone err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("create %v/%v/milestone err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(milestone)
|
return to.TextResult(slimMilestone(milestone))
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func EditMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called EditMilestoneFn")
|
log.Debugf("Called EditMilestoneFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -240,18 +232,18 @@ func EditMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
return to.ErrorResult(fmt.Errorf("edit %v/%v/milestone/%v err: %v", owner, repo, id, err))
|
return to.ErrorResult(fmt.Errorf("edit %v/%v/milestone/%v err: %v", owner, repo, id, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(milestone)
|
return to.TextResult(slimMilestone(milestone))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteMilestoneFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteMilestoneFn")
|
log.Debugf("Called DeleteMilestoneFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(req.GetArguments(), "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
28
operation/milestone/slim.go
Normal file
28
operation/milestone/slim.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package milestone
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func slimMilestone(m *gitea_sdk.Milestone) map[string]any {
|
||||||
|
if m == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": m.ID,
|
||||||
|
"title": m.Title,
|
||||||
|
"description": m.Description,
|
||||||
|
"state": m.State,
|
||||||
|
"open_issues": m.OpenIssues,
|
||||||
|
"closed_issues": m.ClosedIssues,
|
||||||
|
"due_on": m.Deadline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimMilestones(milestones []*gitea_sdk.Milestone) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(milestones))
|
||||||
|
for _, m := range milestones {
|
||||||
|
out = append(out, slimMilestone(m))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package pull
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -63,7 +62,7 @@ var (
|
|||||||
mcp.WithString("sort", mcp.Description("sort"), mcp.Enum("oldest", "recentupdate", "leastupdate", "mostcomment", "leastcomment", "priority"), mcp.DefaultString("recentupdate")),
|
mcp.WithString("sort", mcp.Description("sort"), mcp.Enum("oldest", "recentupdate", "leastupdate", "mostcomment", "leastcomment", "priority"), mcp.DefaultString("recentupdate")),
|
||||||
mcp.WithNumber("milestone", mcp.Description("milestone")),
|
mcp.WithNumber("milestone", mcp.Description("milestone")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
CreatePullRequestTool = mcp.NewTool(
|
CreatePullRequestTool = mcp.NewTool(
|
||||||
@@ -104,7 +103,7 @@ var (
|
|||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("index", mcp.Required(), mcp.Description("pull request index")),
|
mcp.WithNumber("index", mcp.Required(), mcp.Description("pull request index")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetPullRequestReviewTool = mcp.NewTool(
|
GetPullRequestReviewTool = mcp.NewTool(
|
||||||
@@ -269,15 +268,16 @@ func init() {
|
|||||||
|
|
||||||
func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetPullRequestByIndexFn")
|
log.Debugf("Called GetPullRequestByIndexFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(args, "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -290,24 +290,25 @@ func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(pr)
|
return to.TextResult(slimPullRequest(pr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPullRequestDiffFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetPullRequestDiffFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetPullRequestDiffFn")
|
log.Debugf("Called GetPullRequestDiffFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
binary, _ := req.GetArguments()["binary"].(bool)
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "index")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
binary, _ := args["binary"].(bool)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -320,41 +321,31 @@ func GetPullRequestDiffFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v diff err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v diff err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
result := map[string]any{
|
return to.TextResult(string(diffBytes))
|
||||||
"diff": string(diffBytes),
|
|
||||||
"binary": binary,
|
|
||||||
"index": index,
|
|
||||||
"repo": repo,
|
|
||||||
"owner": owner,
|
|
||||||
}
|
|
||||||
return to.TextResult(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoPullRequests")
|
log.Debugf("Called ListRepoPullRequests")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
state, _ := req.GetArguments()["state"].(string)
|
state, _ := args["state"].(string)
|
||||||
sort, ok := req.GetArguments()["sort"].(string)
|
sort := params.GetOptionalString(args, "sort", "recentupdate")
|
||||||
if !ok {
|
milestone := params.GetOptionalInt(args, "milestone", 0)
|
||||||
sort = "recentupdate"
|
page, pageSize := params.GetPagination(args, 30)
|
||||||
}
|
|
||||||
milestone := params.GetOptionalInt(req.GetArguments(), "milestone", 0)
|
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
opt := gitea_sdk.ListPullRequestsOptions{
|
opt := gitea_sdk.ListPullRequestsOptions{
|
||||||
State: gitea_sdk.StateType(state),
|
State: gitea_sdk.StateType(state),
|
||||||
Sort: sort,
|
Sort: sort,
|
||||||
Milestone: milestone,
|
Milestone: milestone,
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -366,34 +357,35 @@ func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|||||||
return to.ErrorResult(fmt.Errorf("list %v/%v/pull_requests err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("list %v/%v/pull_requests err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(pullRequests)
|
return to.TextResult(slimPullRequests(pullRequests))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreatePullRequestFn")
|
log.Debugf("Called CreatePullRequestFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
title, ok := req.GetArguments()["title"].(string)
|
title, err := params.GetString(args, "title")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("title is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
body, ok := req.GetArguments()["body"].(string)
|
body, err := params.GetString(args, "body")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("body is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
head, ok := req.GetArguments()["head"].(string)
|
head, err := params.GetString(args, "head")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("head is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
base, ok := req.GetArguments()["base"].(string)
|
base, err := params.GetString(args, "base")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("base is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -409,45 +401,27 @@ func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
|
|||||||
return to.ErrorResult(fmt.Errorf("create %v/%v/pull_request err: %v", owner, repo, err))
|
return to.ErrorResult(fmt.Errorf("create %v/%v/pull_request err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(pr)
|
return to.TextResult(slimPullRequest(pr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreatePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreatePullRequestReviewerFn")
|
log.Debugf("Called CreatePullRequestReviewerFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(args, "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var reviewers []string
|
reviewers := params.GetStringSlice(args, "reviewers")
|
||||||
if reviewersArg, exists := req.GetArguments()["reviewers"]; exists {
|
teamReviewers := params.GetStringSlice(args, "team_reviewers")
|
||||||
if reviewersSlice, ok := reviewersArg.([]any); ok {
|
|
||||||
for _, reviewer := range reviewersSlice {
|
|
||||||
if reviewerStr, ok := reviewer.(string); ok {
|
|
||||||
reviewers = append(reviewers, reviewerStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var teamReviewers []string
|
|
||||||
if teamReviewersArg, exists := req.GetArguments()["team_reviewers"]; exists {
|
|
||||||
if teamReviewersSlice, ok := teamReviewersArg.([]any); ok {
|
|
||||||
for _, teamReviewer := range teamReviewersSlice {
|
|
||||||
if teamReviewerStr, ok := teamReviewer.(string); ok {
|
|
||||||
teamReviewers = append(teamReviewers, teamReviewerStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -476,40 +450,22 @@ func CreatePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (
|
|||||||
|
|
||||||
func DeletePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeletePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeletePullRequestReviewerFn")
|
log.Debugf("Called DeletePullRequestReviewerFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(args, "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var reviewers []string
|
reviewers := params.GetStringSlice(args, "reviewers")
|
||||||
if reviewersArg, exists := req.GetArguments()["reviewers"]; exists {
|
teamReviewers := params.GetStringSlice(args, "team_reviewers")
|
||||||
if reviewersSlice, ok := reviewersArg.([]any); ok {
|
|
||||||
for _, reviewer := range reviewersSlice {
|
|
||||||
if reviewerStr, ok := reviewer.(string); ok {
|
|
||||||
reviewers = append(reviewers, reviewerStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var teamReviewers []string
|
|
||||||
if teamReviewersArg, exists := req.GetArguments()["team_reviewers"]; exists {
|
|
||||||
if teamReviewersSlice, ok := teamReviewersArg.([]any); ok {
|
|
||||||
for _, teamReviewer := range teamReviewersSlice {
|
|
||||||
if teamReviewerStr, ok := teamReviewer.(string); ok {
|
|
||||||
teamReviewers = append(teamReviewers, teamReviewerStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -537,20 +493,20 @@ func DeletePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (
|
|||||||
|
|
||||||
func ListPullRequestReviewsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListPullRequestReviewsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListPullRequestReviewsFn")
|
log.Debugf("Called ListPullRequestReviewsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
repo, err := params.GetString(args, "repo")
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "index")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
page, pageSize := params.GetPagination(args, 30)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -559,32 +515,33 @@ func ListPullRequestReviewsFn(ctx context.Context, req mcp.CallToolRequest) (*mc
|
|||||||
|
|
||||||
reviews, _, err := client.ListPullReviews(owner, repo, index, gitea_sdk.ListPullReviewsOptions{
|
reviews, _, err := client.ListPullReviews(owner, repo, index, gitea_sdk.ListPullReviewsOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list reviews for %v/%v/pr/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("list reviews for %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(reviews)
|
return to.TextResult(slimReviews(reviews))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetPullRequestReviewFn")
|
log.Debugf("Called GetPullRequestReviewFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "index")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
reviewID, err := params.GetIndex(args, "review_id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -599,24 +556,25 @@ func GetPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|||||||
return to.ErrorResult(fmt.Errorf("get review %v for %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("get review %v for %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(review)
|
return to.TextResult(slimReview(review))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListPullRequestReviewCommentsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListPullRequestReviewCommentsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListPullRequestReviewCommentsFn")
|
log.Debugf("Called ListPullRequestReviewCommentsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "index")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
reviewID, err := params.GetIndex(args, "review_id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -631,38 +589,39 @@ func ListPullRequestReviewCommentsFn(ctx context.Context, req mcp.CallToolReques
|
|||||||
return to.ErrorResult(fmt.Errorf("list review comments for review %v on %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("list review comments for review %v on %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(comments)
|
return to.TextResult(slimReviewComments(comments))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreatePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreatePullRequestReviewFn")
|
log.Debugf("Called CreatePullRequestReviewFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(args, "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := gitea_sdk.CreatePullReviewOptions{}
|
opt := gitea_sdk.CreatePullReviewOptions{}
|
||||||
|
|
||||||
if state, ok := req.GetArguments()["state"].(string); ok {
|
if state, ok := args["state"].(string); ok {
|
||||||
opt.State = gitea_sdk.ReviewStateType(state)
|
opt.State = gitea_sdk.ReviewStateType(state)
|
||||||
}
|
}
|
||||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
if body, ok := args["body"].(string); ok {
|
||||||
opt.Body = body
|
opt.Body = body
|
||||||
}
|
}
|
||||||
if commitID, ok := req.GetArguments()["commit_id"].(string); ok {
|
if commitID, ok := args["commit_id"].(string); ok {
|
||||||
opt.CommitID = commitID
|
opt.CommitID = commitID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse inline comments
|
// Parse inline comments
|
||||||
if commentsArg, exists := req.GetArguments()["comments"]; exists {
|
if commentsArg, exists := args["comments"]; exists {
|
||||||
if commentsSlice, ok := commentsArg.([]any); ok {
|
if commentsSlice, ok := commentsArg.([]any); ok {
|
||||||
for _, comment := range commentsSlice {
|
for _, comment := range commentsSlice {
|
||||||
if commentMap, ok := comment.(map[string]any); ok {
|
if commentMap, ok := comment.(map[string]any); ok {
|
||||||
@@ -695,36 +654,37 @@ func CreatePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
return to.ErrorResult(fmt.Errorf("create review for %v/%v/pr/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("create review for %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(review)
|
return to.TextResult(slimReview(review))
|
||||||
}
|
}
|
||||||
|
|
||||||
func SubmitPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func SubmitPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called SubmitPullRequestReviewFn")
|
log.Debugf("Called SubmitPullRequestReviewFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
repo, err := params.GetString(args, "repo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
state, ok := req.GetArguments()["state"].(string)
|
index, err := params.GetIndex(args, "index")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("state is required"))
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
reviewID, err := params.GetIndex(args, "review_id")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
state, err := params.GetString(args, "state")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := gitea_sdk.SubmitPullReviewOptions{
|
opt := gitea_sdk.SubmitPullReviewOptions{
|
||||||
State: gitea_sdk.ReviewStateType(state),
|
State: gitea_sdk.ReviewStateType(state),
|
||||||
}
|
}
|
||||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
if body, ok := args["body"].(string); ok {
|
||||||
opt.Body = body
|
opt.Body = body
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,24 +698,25 @@ func SubmitPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
return to.ErrorResult(fmt.Errorf("submit review %v for %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("submit review %v for %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(review)
|
return to.TextResult(slimReview(review))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeletePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeletePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeletePullRequestReviewFn")
|
log.Debugf("Called DeletePullRequestReviewFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "index")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
reviewID, err := params.GetIndex(args, "review_id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -782,25 +743,26 @@ func DeletePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
|
|
||||||
func DismissPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DismissPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DismissPullRequestReviewFn")
|
log.Debugf("Called DismissPullRequestReviewFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "index")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
reviewID, err := params.GetIndex(args, "review_id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := gitea_sdk.DismissPullReviewOptions{}
|
opt := gitea_sdk.DismissPullReviewOptions{}
|
||||||
if message, ok := req.GetArguments()["message"].(string); ok {
|
if message, ok := args["message"].(string); ok {
|
||||||
opt.Message = message
|
opt.Message = message
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -826,38 +788,24 @@ func DismissPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*
|
|||||||
|
|
||||||
func MergePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func MergePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called MergePullRequestFn")
|
log.Debugf("Called MergePullRequestFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(args, "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeStyle := "merge"
|
mergeStyle := params.GetOptionalString(args, "merge_style", "merge")
|
||||||
if style, exists := req.GetArguments()["merge_style"].(string); exists && style != "" {
|
title, _ := args["title"].(string)
|
||||||
mergeStyle = style
|
message, _ := args["message"].(string)
|
||||||
}
|
deleteBranch, _ := args["delete_branch"].(bool)
|
||||||
|
|
||||||
title := ""
|
|
||||||
if t, exists := req.GetArguments()["title"].(string); exists {
|
|
||||||
title = t
|
|
||||||
}
|
|
||||||
|
|
||||||
message := ""
|
|
||||||
if msg, exists := req.GetArguments()["message"].(string); exists {
|
|
||||||
message = msg
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteBranch := false
|
|
||||||
if del, exists := req.GetArguments()["delete_branch"].(bool); exists {
|
|
||||||
deleteBranch = del
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -897,53 +845,46 @@ func MergePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
|
|
||||||
func EditPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func EditPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called EditPullRequestFn")
|
log.Debugf("Called EditPullRequestFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(args, "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := gitea_sdk.EditPullRequestOption{}
|
opt := gitea_sdk.EditPullRequestOption{}
|
||||||
|
|
||||||
if title, ok := req.GetArguments()["title"].(string); ok {
|
if title, ok := args["title"].(string); ok {
|
||||||
opt.Title = title
|
opt.Title = title
|
||||||
}
|
}
|
||||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
if body, ok := args["body"].(string); ok {
|
||||||
opt.Body = new(body)
|
opt.Body = new(body)
|
||||||
}
|
}
|
||||||
if base, ok := req.GetArguments()["base"].(string); ok {
|
if base, ok := args["base"].(string); ok {
|
||||||
opt.Base = base
|
opt.Base = base
|
||||||
}
|
}
|
||||||
if assignee, ok := req.GetArguments()["assignee"].(string); ok {
|
if assignee, ok := args["assignee"].(string); ok {
|
||||||
opt.Assignee = assignee
|
opt.Assignee = assignee
|
||||||
}
|
}
|
||||||
if assigneesArg, exists := req.GetArguments()["assignees"]; exists {
|
if assignees := params.GetStringSlice(args, "assignees"); assignees != nil {
|
||||||
if assigneesSlice, ok := assigneesArg.([]any); ok {
|
opt.Assignees = assignees
|
||||||
var assignees []string
|
|
||||||
for _, a := range assigneesSlice {
|
|
||||||
if s, ok := a.(string); ok {
|
|
||||||
assignees = append(assignees, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opt.Assignees = assignees
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if val, exists := req.GetArguments()["milestone"]; exists {
|
if val, exists := args["milestone"]; exists {
|
||||||
if milestone, ok := params.ToInt64(val); ok {
|
if milestone, ok := params.ToInt64(val); ok {
|
||||||
opt.Milestone = milestone
|
opt.Milestone = milestone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if state, ok := req.GetArguments()["state"].(string); ok {
|
if state, ok := args["state"].(string); ok {
|
||||||
opt.State = new(gitea_sdk.StateType(state))
|
opt.State = new(gitea_sdk.StateType(state))
|
||||||
}
|
}
|
||||||
if allowMaintainerEdit, ok := req.GetArguments()["allow_maintainer_edit"].(bool); ok {
|
if allowMaintainerEdit, ok := args["allow_maintainer_edit"].(bool); ok {
|
||||||
opt.AllowMaintainerEdit = new(allowMaintainerEdit)
|
opt.AllowMaintainerEdit = new(allowMaintainerEdit)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,5 +898,5 @@ func EditPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
return to.ErrorResult(fmt.Errorf("edit %v/%v/pr/%v err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("edit %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(pr)
|
return to.TextResult(slimPullRequest(pr))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,13 +116,11 @@ func TestEditPullRequestFn(t *testing.T) {
|
|||||||
t.Fatalf("expected text content, got %T", result.Content[0])
|
t.Fatalf("expected text content, got %T", result.Content[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed struct {
|
var parsed map[string]any
|
||||||
Result map[string]any `json:"Result"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
||||||
t.Fatalf("unmarshal result text: %v", err)
|
t.Fatalf("unmarshal result text: %v", err)
|
||||||
}
|
}
|
||||||
if got := parsed.Result["title"].(string); got != "WIP: my feature" {
|
if got := parsed["title"].(string); got != "WIP: my feature" {
|
||||||
t.Fatalf("result title = %q, want %q", got, "WIP: my feature")
|
t.Fatalf("result title = %q, want %q", got, "WIP: my feature")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -239,20 +237,18 @@ func TestMergePullRequestFn(t *testing.T) {
|
|||||||
t.Fatalf("expected text content, got %T", result.Content[0])
|
t.Fatalf("expected text content, got %T", result.Content[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed struct {
|
var parsed map[string]any
|
||||||
Result map[string]any `json:"Result"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
||||||
t.Fatalf("unmarshal result text: %v", err)
|
t.Fatalf("unmarshal result text: %v", err)
|
||||||
}
|
}
|
||||||
if parsed.Result["merged"] != true {
|
if parsed["merged"] != true {
|
||||||
t.Fatalf("expected merged=true, got %v", parsed.Result["merged"])
|
t.Fatalf("expected merged=true, got %v", parsed["merged"])
|
||||||
}
|
}
|
||||||
if parsed.Result["merge_style"] != "squash" {
|
if parsed["merge_style"] != "squash" {
|
||||||
t.Fatalf("expected merge_style 'squash', got %v", parsed.Result["merge_style"])
|
t.Fatalf("expected merge_style 'squash', got %v", parsed["merge_style"])
|
||||||
}
|
}
|
||||||
if parsed.Result["branch_deleted"] != true {
|
if parsed["branch_deleted"] != true {
|
||||||
t.Fatalf("expected branch_deleted=true, got %v", parsed.Result["branch_deleted"])
|
t.Fatalf("expected branch_deleted=true, got %v", parsed["branch_deleted"])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -370,27 +366,13 @@ func TestGetPullRequestDiffFn(t *testing.T) {
|
|||||||
t.Fatalf("expected text content, got %T", result.Content[0])
|
t.Fatalf("expected text content, got %T", result.Content[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed struct {
|
// The diff response is now a plain string
|
||||||
Result map[string]any `json:"Result"`
|
var parsed string
|
||||||
}
|
|
||||||
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
||||||
t.Fatalf("unmarshal result text: %v", err)
|
t.Fatalf("unmarshal result text: %v", err)
|
||||||
}
|
}
|
||||||
|
if parsed != diffRaw {
|
||||||
if got, ok := parsed.Result["diff"].(string); !ok || got != diffRaw {
|
t.Fatalf("diff = %q, want %q", parsed, diffRaw)
|
||||||
t.Fatalf("diff = %q, want %q", got, diffRaw)
|
|
||||||
}
|
|
||||||
if got, ok := parsed.Result["binary"].(bool); !ok || got != true {
|
|
||||||
t.Fatalf("binary = %v, want true", got)
|
|
||||||
}
|
|
||||||
if got, ok := parsed.Result["index"].(float64); !ok || int64(got) != int64(index) {
|
|
||||||
t.Fatalf("index = %v, want %d", got, index)
|
|
||||||
}
|
|
||||||
if got, ok := parsed.Result["owner"].(string); !ok || got != owner {
|
|
||||||
t.Fatalf("owner = %q, want %q", got, owner)
|
|
||||||
}
|
|
||||||
if got, ok := parsed.Result["repo"].(string); !ok || got != repo {
|
|
||||||
t.Fatalf("repo = %q, want %q", got, repo)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
191
operation/pull/slim.go
Normal file
191
operation/pull/slim.go
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
package pull
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func userLogin(u *gitea_sdk.User) string {
|
||||||
|
if u == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return u.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
func userLogins(users []*gitea_sdk.User) []string {
|
||||||
|
if len(users) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := make([]string, 0, len(users))
|
||||||
|
for _, u := range users {
|
||||||
|
if u != nil {
|
||||||
|
out = append(out, u.UserName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func labelNames(labels []*gitea_sdk.Label) []string {
|
||||||
|
if len(labels) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := make([]string, 0, len(labels))
|
||||||
|
for _, l := range labels {
|
||||||
|
if l != nil {
|
||||||
|
out = append(out, l.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func repoRef(r *gitea_sdk.Repository) map[string]any {
|
||||||
|
if r == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"full_name": r.FullName,
|
||||||
|
"description": r.Description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimPullRequest(pr *gitea_sdk.PullRequest) map[string]any {
|
||||||
|
if pr == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"number": pr.Index,
|
||||||
|
"title": pr.Title,
|
||||||
|
"body": pr.Body,
|
||||||
|
"state": pr.State,
|
||||||
|
"draft": pr.Draft,
|
||||||
|
"merged": pr.HasMerged,
|
||||||
|
"mergeable": pr.Mergeable,
|
||||||
|
"html_url": pr.HTMLURL,
|
||||||
|
"user": userLogin(pr.Poster),
|
||||||
|
"labels": labelNames(pr.Labels),
|
||||||
|
"comments": pr.Comments,
|
||||||
|
"created_at": pr.Created,
|
||||||
|
"updated_at": pr.Updated,
|
||||||
|
"closed_at": pr.Closed,
|
||||||
|
}
|
||||||
|
if pr.HasMerged {
|
||||||
|
m["merged_at"] = pr.Merged
|
||||||
|
m["merge_commit_sha"] = pr.MergedCommitID
|
||||||
|
m["merged_by"] = userLogin(pr.MergedBy)
|
||||||
|
}
|
||||||
|
if pr.Head != nil {
|
||||||
|
head := map[string]any{"ref": pr.Head.Ref, "sha": pr.Head.Sha}
|
||||||
|
if pr.Head.Repository != nil {
|
||||||
|
head["repo"] = repoRef(pr.Head.Repository)
|
||||||
|
}
|
||||||
|
m["head"] = head
|
||||||
|
}
|
||||||
|
if pr.Base != nil {
|
||||||
|
base := map[string]any{"ref": pr.Base.Ref, "sha": pr.Base.Sha}
|
||||||
|
if pr.Base.Repository != nil {
|
||||||
|
base["repo"] = repoRef(pr.Base.Repository)
|
||||||
|
}
|
||||||
|
m["base"] = base
|
||||||
|
}
|
||||||
|
if pr.Additions != nil {
|
||||||
|
m["additions"] = *pr.Additions
|
||||||
|
}
|
||||||
|
if pr.Deletions != nil {
|
||||||
|
m["deletions"] = *pr.Deletions
|
||||||
|
}
|
||||||
|
if pr.ChangedFiles != nil {
|
||||||
|
m["changed_files"] = *pr.ChangedFiles
|
||||||
|
}
|
||||||
|
if len(pr.Assignees) > 0 {
|
||||||
|
m["assignees"] = userLogins(pr.Assignees)
|
||||||
|
}
|
||||||
|
if pr.Milestone != nil {
|
||||||
|
m["milestone"] = pr.Milestone.Title
|
||||||
|
}
|
||||||
|
if pr.ReviewComments > 0 {
|
||||||
|
m["review_comments"] = pr.ReviewComments
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimPullRequests(prs []*gitea_sdk.PullRequest) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(prs))
|
||||||
|
for _, pr := range prs {
|
||||||
|
if pr == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"number": pr.Index,
|
||||||
|
"title": pr.Title,
|
||||||
|
"state": pr.State,
|
||||||
|
"draft": pr.Draft,
|
||||||
|
"merged": pr.HasMerged,
|
||||||
|
"html_url": pr.HTMLURL,
|
||||||
|
"user": userLogin(pr.Poster),
|
||||||
|
"created_at": pr.Created,
|
||||||
|
"updated_at": pr.Updated,
|
||||||
|
}
|
||||||
|
if pr.Head != nil {
|
||||||
|
m["head"] = pr.Head.Ref
|
||||||
|
}
|
||||||
|
if pr.Base != nil {
|
||||||
|
m["base"] = pr.Base.Ref
|
||||||
|
}
|
||||||
|
if len(pr.Labels) > 0 {
|
||||||
|
m["labels"] = labelNames(pr.Labels)
|
||||||
|
}
|
||||||
|
out = append(out, m)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimReview(r *gitea_sdk.PullReview) map[string]any {
|
||||||
|
if r == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": r.ID,
|
||||||
|
"state": r.State,
|
||||||
|
"body": r.Body,
|
||||||
|
"user": userLogin(r.Reviewer),
|
||||||
|
"comments_count": r.CodeCommentsCount,
|
||||||
|
"submitted_at": r.Submitted,
|
||||||
|
"html_url": r.HTMLURL,
|
||||||
|
"stale": r.Stale,
|
||||||
|
"official": r.Official,
|
||||||
|
"dismissed": r.Dismissed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimReviews(reviews []*gitea_sdk.PullReview) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(reviews))
|
||||||
|
for _, r := range reviews {
|
||||||
|
out = append(out, slimReview(r))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimReviewComment(c *gitea_sdk.PullReviewComment) map[string]any {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": c.ID,
|
||||||
|
"body": c.Body,
|
||||||
|
"path": c.Path,
|
||||||
|
"position": c.LineNum,
|
||||||
|
"old_position": c.OldLineNum,
|
||||||
|
"diff_hunk": c.DiffHunk,
|
||||||
|
"user": userLogin(c.Reviewer),
|
||||||
|
"html_url": c.HTMLURL,
|
||||||
|
"created_at": c.Created,
|
||||||
|
"updated_at": c.Updated,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimReviewComments(comments []*gitea_sdk.PullReviewComment) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(comments))
|
||||||
|
for _, c := range comments {
|
||||||
|
out = append(out, slimReviewComment(c))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
124
operation/pull/slim_test.go
Normal file
124
operation/pull/slim_test.go
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
package pull
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSlimPullRequest(t *testing.T) {
|
||||||
|
now := time.Now()
|
||||||
|
additions := 10
|
||||||
|
deletions := 5
|
||||||
|
changedFiles := 3
|
||||||
|
pr := &gitea_sdk.PullRequest{
|
||||||
|
Index: 1,
|
||||||
|
Title: "Fix bug",
|
||||||
|
Body: "Fixes #123",
|
||||||
|
State: "open",
|
||||||
|
Draft: false,
|
||||||
|
HasMerged: false,
|
||||||
|
Mergeable: true,
|
||||||
|
HTMLURL: "https://gitea.com/org/repo/pulls/1",
|
||||||
|
Poster: &gitea_sdk.User{UserName: "bob"},
|
||||||
|
Labels: []*gitea_sdk.Label{
|
||||||
|
{Name: "bug"},
|
||||||
|
{Name: "priority"},
|
||||||
|
},
|
||||||
|
Comments: 2,
|
||||||
|
Created: &now,
|
||||||
|
Updated: &now,
|
||||||
|
Additions: &additions,
|
||||||
|
Deletions: &deletions,
|
||||||
|
ChangedFiles: &changedFiles,
|
||||||
|
Head: &gitea_sdk.PRBranchInfo{
|
||||||
|
Ref: "fix-branch",
|
||||||
|
Sha: "abc123",
|
||||||
|
},
|
||||||
|
Base: &gitea_sdk.PRBranchInfo{
|
||||||
|
Ref: "main",
|
||||||
|
Sha: "def456",
|
||||||
|
},
|
||||||
|
Assignees: []*gitea_sdk.User{
|
||||||
|
{UserName: "alice"},
|
||||||
|
},
|
||||||
|
Milestone: &gitea_sdk.Milestone{Title: "v1.0"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := slimPullRequest(pr)
|
||||||
|
|
||||||
|
if m["number"] != int64(1) {
|
||||||
|
t.Errorf("expected number 1, got %v", m["number"])
|
||||||
|
}
|
||||||
|
if m["title"] != "Fix bug" {
|
||||||
|
t.Errorf("expected title Fix bug, got %v", m["title"])
|
||||||
|
}
|
||||||
|
if m["user"] != "bob" {
|
||||||
|
t.Errorf("expected user bob, got %v", m["user"])
|
||||||
|
}
|
||||||
|
if m["additions"] != 10 {
|
||||||
|
t.Errorf("expected additions 10, got %v", m["additions"])
|
||||||
|
}
|
||||||
|
if m["milestone"] != "v1.0" {
|
||||||
|
t.Errorf("expected milestone v1.0, got %v", m["milestone"])
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := m["labels"].([]string)
|
||||||
|
if len(labels) != 2 || labels[0] != "bug" {
|
||||||
|
t.Errorf("expected labels [bug priority], got %v", labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
head := m["head"].(map[string]any)
|
||||||
|
if head["ref"] != "fix-branch" {
|
||||||
|
t.Errorf("expected head ref fix-branch, got %v", head["ref"])
|
||||||
|
}
|
||||||
|
|
||||||
|
assignees := m["assignees"].([]string)
|
||||||
|
if len(assignees) != 1 || assignees[0] != "alice" {
|
||||||
|
t.Errorf("expected assignees [alice], got %v", assignees)
|
||||||
|
}
|
||||||
|
|
||||||
|
// merged fields should not be present for unmerged PR
|
||||||
|
if _, ok := m["merged_at"]; ok {
|
||||||
|
t.Error("merged_at should not be present for unmerged PR")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimPullRequests_ListIsSlimmer(t *testing.T) {
|
||||||
|
pr := &gitea_sdk.PullRequest{
|
||||||
|
Index: 1,
|
||||||
|
Title: "PR title",
|
||||||
|
State: "open",
|
||||||
|
HTMLURL: "https://gitea.com/org/repo/pulls/1",
|
||||||
|
Poster: &gitea_sdk.User{UserName: "bob"},
|
||||||
|
Body: "Full body text here",
|
||||||
|
Head: &gitea_sdk.PRBranchInfo{Ref: "feature"},
|
||||||
|
Base: &gitea_sdk.PRBranchInfo{Ref: "main"},
|
||||||
|
}
|
||||||
|
|
||||||
|
single := slimPullRequest(pr)
|
||||||
|
list := slimPullRequests([]*gitea_sdk.PullRequest{pr})
|
||||||
|
|
||||||
|
// Single has body, list does not
|
||||||
|
if _, ok := single["body"]; !ok {
|
||||||
|
t.Error("single PR should have body")
|
||||||
|
}
|
||||||
|
if _, ok := list[0]["body"]; ok {
|
||||||
|
t.Error("list PR should not have body")
|
||||||
|
}
|
||||||
|
|
||||||
|
// List has head as string ref, single has head as map
|
||||||
|
if _, ok := single["head"].(map[string]any); !ok {
|
||||||
|
t.Error("single PR head should be a map")
|
||||||
|
}
|
||||||
|
if list[0]["head"] != "feature" {
|
||||||
|
t.Errorf("list PR head should be string ref, got %v", list[0]["head"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimPullRequests_Nil(t *testing.T) {
|
||||||
|
if r := slimPullRequests(nil); len(r) != 0 {
|
||||||
|
t.Errorf("expected empty slice, got %v", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,11 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/to"
|
"gitea.com/gitea/gitea-mcp/pkg/to"
|
||||||
|
|
||||||
gitea_sdk "code.gitea.io/sdk/gitea"
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
@@ -63,19 +63,20 @@ func init() {
|
|||||||
|
|
||||||
func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateBranchFn")
|
log.Debugf("Called CreateBranchFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
branch, ok := req.GetArguments()["branch"].(string)
|
branch, err := params.GetString(args, "branch")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("branch is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
oldBranch, _ := req.GetArguments()["old_branch"].(string)
|
oldBranch, _ := args["old_branch"].(string)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -94,17 +95,18 @@ func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
|
|
||||||
func DeleteBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteBranchFn")
|
log.Debugf("Called DeleteBranchFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
branch, ok := req.GetArguments()["branch"].(string)
|
branch, err := params.GetString(args, "branch")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("branch is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -120,18 +122,19 @@ func DeleteBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
|
|
||||||
func ListBranchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListBranchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListBranchesFn")
|
log.Debugf("Called ListBranchesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
opt := gitea_sdk.ListRepoBranchesOptions{
|
opt := gitea_sdk.ListRepoBranchesOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
PageSize: 100,
|
PageSize: 30,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -143,5 +146,5 @@ func ListBranchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
return to.ErrorResult(fmt.Errorf("list branches error: %v", err))
|
return to.ErrorResult(fmt.Errorf("list branches error: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(branches)
|
return to.TextResult(slimBranches(branches))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -27,7 +26,7 @@ var ListRepoCommitsTool = mcp.NewTool(
|
|||||||
mcp.WithString("sha", mcp.Description("SHA or branch to start listing commits from")),
|
mcp.WithString("sha", mcp.Description("SHA or branch to start listing commits from")),
|
||||||
mcp.WithString("path", mcp.Description("path indicates that only commits that include the path's file/dir should be returned.")),
|
mcp.WithString("path", mcp.Description("path indicates that only commits that include the path's file/dir should be returned.")),
|
||||||
mcp.WithNumber("page", mcp.Required(), mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Required(), mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("page_size", mcp.Required(), mcp.Description("page size"), mcp.DefaultNumber(50), mcp.Min(1)),
|
mcp.WithNumber("page_size", mcp.Required(), mcp.Description("page size"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -39,24 +38,25 @@ func init() {
|
|||||||
|
|
||||||
func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoCommitsFn")
|
log.Debugf("Called ListRepoCommitsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
|
||||||
}
|
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
|
||||||
if !ok {
|
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
|
||||||
}
|
|
||||||
page, err := params.GetIndex(req.GetArguments(), "page")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
pageSize, err := params.GetIndex(req.GetArguments(), "page_size")
|
repo, err := params.GetString(args, "repo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
sha, _ := req.GetArguments()["sha"].(string)
|
page, err := params.GetIndex(args, "page")
|
||||||
path, _ := req.GetArguments()["path"].(string)
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
pageSize, err := params.GetIndex(args, "page_size")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
sha, _ := args["sha"].(string)
|
||||||
|
path, _ := args["path"].(string)
|
||||||
opt := gitea_sdk.ListCommitOptions{
|
opt := gitea_sdk.ListCommitOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: int(page),
|
||||||
@@ -73,5 +73,5 @@ func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list repo commits err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list repo commits err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(commits)
|
return to.TextResult(slimCommits(commits))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/to"
|
"gitea.com/gitea/gitea-mcp/pkg/to"
|
||||||
|
|
||||||
gitea_sdk "code.gitea.io/sdk/gitea"
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
@@ -112,18 +112,19 @@ type ContentLine struct {
|
|||||||
|
|
||||||
func GetFileContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetFileContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetFileFn")
|
log.Debugf("Called GetFileFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
ref, _ := req.GetArguments()["ref"].(string)
|
ref, _ := args["ref"].(string)
|
||||||
filePath, ok := req.GetArguments()["filePath"].(string)
|
filePath, err := params.GetString(args, "filePath")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("filePath is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -133,7 +134,7 @@ func GetFileContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get file err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get file err: %v", err))
|
||||||
}
|
}
|
||||||
withLines, _ := req.GetArguments()["withLines"].(bool)
|
withLines, _ := args["withLines"].(bool)
|
||||||
if withLines {
|
if withLines {
|
||||||
rawContent, err := base64.StdEncoding.DecodeString(*content.Content)
|
rawContent, err := base64.StdEncoding.DecodeString(*content.Content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -170,23 +171,24 @@ func GetFileContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
contentStr := string(contentBytes)
|
contentStr := string(contentBytes)
|
||||||
content.Content = &contentStr
|
content.Content = &contentStr
|
||||||
}
|
}
|
||||||
return to.TextResult(content)
|
return to.TextResult(slimContents(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDirContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetDirContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetDirContentFn")
|
log.Debugf("Called GetDirContentFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
ref, _ := req.GetArguments()["ref"].(string)
|
ref, _ := args["ref"].(string)
|
||||||
filePath, ok := req.GetArguments()["filePath"].(string)
|
filePath, err := params.GetString(args, "filePath")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("filePath is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -196,26 +198,27 @@ func GetDirContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get dir content err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get dir content err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(content)
|
return to.TextResult(slimDirEntries(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateFileFn")
|
log.Debugf("Called CreateFileFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
filePath, ok := req.GetArguments()["filePath"].(string)
|
filePath, err := params.GetString(args, "filePath")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("filePath is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
content, _ := req.GetArguments()["content"].(string)
|
content, _ := args["content"].(string)
|
||||||
message, _ := req.GetArguments()["message"].(string)
|
message, _ := args["message"].(string)
|
||||||
branchName, _ := req.GetArguments()["branch_name"].(string)
|
branchName, _ := args["branch_name"].(string)
|
||||||
opt := gitea_sdk.CreateFileOptions{
|
opt := gitea_sdk.CreateFileOptions{
|
||||||
Content: base64.StdEncoding.EncodeToString([]byte(content)),
|
Content: base64.StdEncoding.EncodeToString([]byte(content)),
|
||||||
FileOptions: gitea_sdk.FileOptions{
|
FileOptions: gitea_sdk.FileOptions{
|
||||||
@@ -237,25 +240,26 @@ func CreateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
|
|
||||||
func UpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UpdateFileFn")
|
log.Debugf("Called UpdateFileFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
filePath, ok := req.GetArguments()["filePath"].(string)
|
filePath, err := params.GetString(args, "filePath")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("filePath is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
sha, ok := req.GetArguments()["sha"].(string)
|
sha, err := params.GetString(args, "sha")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("sha is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
content, _ := req.GetArguments()["content"].(string)
|
content, _ := args["content"].(string)
|
||||||
message, _ := req.GetArguments()["message"].(string)
|
message, _ := args["message"].(string)
|
||||||
branchName, _ := req.GetArguments()["branch_name"].(string)
|
branchName, _ := args["branch_name"].(string)
|
||||||
|
|
||||||
opt := gitea_sdk.UpdateFileOptions{
|
opt := gitea_sdk.UpdateFileOptions{
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
@@ -278,23 +282,24 @@ func UpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
|
|
||||||
func DeleteFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteFileFn")
|
log.Debugf("Called DeleteFileFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
filePath, ok := req.GetArguments()["filePath"].(string)
|
filePath, err := params.GetString(args, "filePath")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("filePath is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
message, _ := req.GetArguments()["message"].(string)
|
message, _ := args["message"].(string)
|
||||||
branchName, _ := req.GetArguments()["branch_name"].(string)
|
branchName, _ := args["branch_name"].(string)
|
||||||
sha, ok := req.GetArguments()["sha"].(string)
|
sha, err := params.GetString(args, "sha")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("sha is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
opt := gitea_sdk.DeleteFileOptions{
|
opt := gitea_sdk.DeleteFileOptions{
|
||||||
FileOptions: gitea_sdk.FileOptions{
|
FileOptions: gitea_sdk.FileOptions{
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
@@ -96,44 +94,32 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// To avoid return too many tokens, we need to provide at least information as possible
|
|
||||||
// llm can call get release to get more information
|
|
||||||
type ListReleaseResult struct {
|
|
||||||
ID int64 `json:"id"`
|
|
||||||
TagName string `json:"tag_name"`
|
|
||||||
Target string `json:"target_commitish"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
IsDraft bool `json:"draft"`
|
|
||||||
IsPrerelease bool `json:"prerelease"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
PublishedAt time.Time `json:"published_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateReleasesFn")
|
log.Debugf("Called CreateReleasesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
tagName, ok := req.GetArguments()["tag_name"].(string)
|
tagName, err := params.GetString(args, "tag_name")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("tag_name is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
target, ok := req.GetArguments()["target"].(string)
|
target, err := params.GetString(args, "target")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("target is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
title, ok := req.GetArguments()["title"].(string)
|
title, err := params.GetString(args, "title")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("title is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
isDraft, _ := req.GetArguments()["is_draft"].(bool)
|
isDraft, _ := args["is_draft"].(bool)
|
||||||
isPreRelease, _ := req.GetArguments()["is_pre_release"].(bool)
|
isPreRelease, _ := args["is_pre_release"].(bool)
|
||||||
body, _ := req.GetArguments()["body"].(string)
|
body, _ := args["body"].(string)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -156,15 +142,16 @@ func CreateReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
|
|
||||||
func DeleteReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteReleaseFn")
|
log.Debugf("Called DeleteReleaseFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(args, "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -183,15 +170,16 @@ func DeleteReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
|
|
||||||
func GetReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetReleaseFn")
|
log.Debugf("Called GetReleaseFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
id, err := params.GetIndex(req.GetArguments(), "id")
|
id, err := params.GetIndex(args, "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -205,18 +193,19 @@ func GetReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
return nil, fmt.Errorf("get release error: %v", err)
|
return nil, fmt.Errorf("get release error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(release)
|
return to.TextResult(slimRelease(release))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLatestReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetLatestReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetLatestReleaseFn")
|
log.Debugf("Called GetLatestReleaseFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -228,31 +217,32 @@ func GetLatestReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
return nil, fmt.Errorf("get latest release error: %v", err)
|
return nil, fmt.Errorf("get latest release error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(release)
|
return to.TextResult(slimRelease(release))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListReleasesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListReleasesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListReleasesFn")
|
log.Debugf("Called ListReleasesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
var pIsDraft *bool
|
var pIsDraft *bool
|
||||||
isDraft, ok := req.GetArguments()["is_draft"].(bool)
|
isDraft, ok := args["is_draft"].(bool)
|
||||||
if ok {
|
if ok {
|
||||||
pIsDraft = new(isDraft)
|
pIsDraft = new(isDraft)
|
||||||
}
|
}
|
||||||
var pIsPreRelease *bool
|
var pIsPreRelease *bool
|
||||||
isPreRelease, ok := req.GetArguments()["is_pre_release"].(bool)
|
isPreRelease, ok := args["is_pre_release"].(bool)
|
||||||
if ok {
|
if ok {
|
||||||
pIsPreRelease = new(isPreRelease)
|
pIsPreRelease = new(isPreRelease)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page := params.GetOptionalInt(args, "page", 1)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 20)
|
pageSize := params.GetOptionalInt(args, "pageSize", 20)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -270,18 +260,5 @@ func ListReleasesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
return nil, fmt.Errorf("list releases error: %v", err)
|
return nil, fmt.Errorf("list releases error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([]ListReleaseResult, len(releases))
|
return to.TextResult(slimReleases(releases))
|
||||||
for _, release := range releases {
|
|
||||||
results = append(results, ListReleaseResult{
|
|
||||||
ID: release.ID,
|
|
||||||
TagName: release.TagName,
|
|
||||||
Target: release.Target,
|
|
||||||
Title: release.Title,
|
|
||||||
IsDraft: release.IsDraft,
|
|
||||||
IsPrerelease: release.IsPrerelease,
|
|
||||||
CreatedAt: release.CreatedAt,
|
|
||||||
PublishedAt: release.PublishedAt,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return to.TextResult(results)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -54,7 +53,7 @@ var (
|
|||||||
ListMyReposToolName,
|
ListMyReposToolName,
|
||||||
mcp.WithDescription("List my repositories"),
|
mcp.WithDescription("List my repositories"),
|
||||||
mcp.WithNumber("page", mcp.Required(), mcp.Description("Page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
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)),
|
mcp.WithNumber("pageSize", mcp.Required(), mcp.Description("Page size number"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -108,20 +107,21 @@ func RegisterTool(s *server.MCPServer) {
|
|||||||
|
|
||||||
func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateRepoFn")
|
log.Debugf("Called CreateRepoFn")
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
name, err := params.GetString(args, "name")
|
||||||
return to.ErrorResult(errors.New("repository name is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
description, _ := req.GetArguments()["description"].(string)
|
description, _ := args["description"].(string)
|
||||||
private, _ := req.GetArguments()["private"].(bool)
|
private, _ := args["private"].(bool)
|
||||||
issueLabels, _ := req.GetArguments()["issue_labels"].(string)
|
issueLabels, _ := args["issue_labels"].(string)
|
||||||
autoInit, _ := req.GetArguments()["auto_init"].(bool)
|
autoInit, _ := args["auto_init"].(bool)
|
||||||
template, _ := req.GetArguments()["template"].(bool)
|
template, _ := args["template"].(bool)
|
||||||
gitignores, _ := req.GetArguments()["gitignores"].(string)
|
gitignores, _ := args["gitignores"].(string)
|
||||||
license, _ := req.GetArguments()["license"].(string)
|
license, _ := args["license"].(string)
|
||||||
readme, _ := req.GetArguments()["readme"].(string)
|
readme, _ := args["readme"].(string)
|
||||||
defaultBranch, _ := req.GetArguments()["default_branch"].(string)
|
defaultBranch, _ := args["default_branch"].(string)
|
||||||
organization, _ := req.GetArguments()["organization"].(string)
|
organization, _ := args["organization"].(string)
|
||||||
|
|
||||||
opt := gitea_sdk.CreateRepoOption{
|
opt := gitea_sdk.CreateRepoOption{
|
||||||
Name: name,
|
Name: name,
|
||||||
@@ -152,25 +152,26 @@ func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
return to.ErrorResult(fmt.Errorf("create repository '%s' err: %v", name, err))
|
return to.ErrorResult(fmt.Errorf("create repository '%s' err: %v", name, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return to.TextResult(repo)
|
return to.TextResult(slimRepo(repo))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ForkRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ForkRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ForkRepoFn")
|
log.Debugf("Called ForkRepoFn")
|
||||||
user, ok := req.GetArguments()["user"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
user, err := params.GetString(args, "user")
|
||||||
return to.ErrorResult(errors.New("user name is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repository name is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
organization, ok := req.GetArguments()["organization"].(string)
|
organization, ok := args["organization"].(string)
|
||||||
organizationPtr := new(organization)
|
organizationPtr := new(organization)
|
||||||
if !ok || organization == "" {
|
if !ok || organization == "" {
|
||||||
organizationPtr = nil
|
organizationPtr = nil
|
||||||
}
|
}
|
||||||
name, ok := req.GetArguments()["name"].(string)
|
name, ok := args["name"].(string)
|
||||||
namePtr := new(name)
|
namePtr := new(name)
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
namePtr = nil
|
namePtr = nil
|
||||||
@@ -192,12 +193,11 @@ func ForkRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
|
|||||||
|
|
||||||
func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListMyReposFn")
|
log.Debugf("Called ListMyReposFn")
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
opt := gitea_sdk.ListReposOptions{
|
opt := gitea_sdk.ListReposOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -209,5 +209,5 @@ func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
return to.ErrorResult(fmt.Errorf("list my repositories error: %v", err))
|
return to.ErrorResult(fmt.Errorf("list my repositories error: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(repos)
|
return to.TextResult(slimRepos(repos))
|
||||||
}
|
}
|
||||||
|
|||||||
201
operation/repo/slim.go
Normal file
201
operation/repo/slim.go
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func userLogin(u *gitea_sdk.User) string {
|
||||||
|
if u == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return u.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimRepo(r *gitea_sdk.Repository) map[string]any {
|
||||||
|
if r == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"id": r.ID,
|
||||||
|
"full_name": r.FullName,
|
||||||
|
"description": r.Description,
|
||||||
|
"html_url": r.HTMLURL,
|
||||||
|
"clone_url": r.CloneURL,
|
||||||
|
"ssh_url": r.SSHURL,
|
||||||
|
"default_branch": r.DefaultBranch,
|
||||||
|
"private": r.Private,
|
||||||
|
"fork": r.Fork,
|
||||||
|
"archived": r.Archived,
|
||||||
|
"language": r.Language,
|
||||||
|
"stars_count": r.Stars,
|
||||||
|
"forks_count": r.Forks,
|
||||||
|
"open_issues_count": r.OpenIssues,
|
||||||
|
"open_pr_counter": r.OpenPulls,
|
||||||
|
"created_at": r.Created,
|
||||||
|
"updated_at": r.Updated,
|
||||||
|
}
|
||||||
|
if r.Owner != nil {
|
||||||
|
m["owner"] = r.Owner.UserName
|
||||||
|
}
|
||||||
|
if len(r.Topics) > 0 {
|
||||||
|
m["topics"] = r.Topics
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimRepos(repos []*gitea_sdk.Repository) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(repos))
|
||||||
|
for _, r := range repos {
|
||||||
|
out = append(out, slimRepo(r))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimBranch(b *gitea_sdk.Branch) map[string]any {
|
||||||
|
if b == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"name": b.Name,
|
||||||
|
"protected": b.Protected,
|
||||||
|
}
|
||||||
|
if b.Commit != nil {
|
||||||
|
m["commit_sha"] = b.Commit.ID
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimBranches(branches []*gitea_sdk.Branch) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(branches))
|
||||||
|
for _, b := range branches {
|
||||||
|
out = append(out, slimBranch(b))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimCommit(c *gitea_sdk.Commit) map[string]any {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"sha": c.SHA,
|
||||||
|
"html_url": c.HTMLURL,
|
||||||
|
"created": c.Created,
|
||||||
|
}
|
||||||
|
if c.RepoCommit != nil {
|
||||||
|
m["message"] = c.RepoCommit.Message
|
||||||
|
if c.RepoCommit.Author != nil {
|
||||||
|
m["author"] = map[string]any{
|
||||||
|
"name": c.RepoCommit.Author.Name,
|
||||||
|
"email": c.RepoCommit.Author.Email,
|
||||||
|
"date": c.RepoCommit.Author.Date,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimCommits(commits []*gitea_sdk.Commit) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(commits))
|
||||||
|
for _, c := range commits {
|
||||||
|
out = append(out, slimCommit(c))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimTag(t *gitea_sdk.Tag) map[string]any {
|
||||||
|
if t == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"name": t.Name,
|
||||||
|
"message": t.Message,
|
||||||
|
}
|
||||||
|
if t.Commit != nil {
|
||||||
|
m["commit_sha"] = t.Commit.SHA
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimTags(tags []*gitea_sdk.Tag) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(tags))
|
||||||
|
for _, t := range tags {
|
||||||
|
m := map[string]any{
|
||||||
|
"name": t.Name,
|
||||||
|
}
|
||||||
|
if t.Commit != nil {
|
||||||
|
m["commit_sha"] = t.Commit.SHA
|
||||||
|
}
|
||||||
|
out = append(out, m)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimRelease(r *gitea_sdk.Release) map[string]any {
|
||||||
|
if r == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": r.ID,
|
||||||
|
"tag_name": r.TagName,
|
||||||
|
"target": r.Target,
|
||||||
|
"title": r.Title,
|
||||||
|
"body": r.Note,
|
||||||
|
"draft": r.IsDraft,
|
||||||
|
"prerelease": r.IsPrerelease,
|
||||||
|
"html_url": r.HTMLURL,
|
||||||
|
"author": userLogin(r.Publisher),
|
||||||
|
"created_at": r.CreatedAt,
|
||||||
|
"published_at": r.PublishedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimReleases(releases []*gitea_sdk.Release) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(releases))
|
||||||
|
for _, r := range releases {
|
||||||
|
out = append(out, slimRelease(r))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimContents(c *gitea_sdk.ContentsResponse) map[string]any {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"name": c.Name,
|
||||||
|
"path": c.Path,
|
||||||
|
"sha": c.SHA,
|
||||||
|
"type": c.Type,
|
||||||
|
"size": c.Size,
|
||||||
|
}
|
||||||
|
if c.Content != nil {
|
||||||
|
m["content"] = *c.Content
|
||||||
|
}
|
||||||
|
if c.Encoding != nil {
|
||||||
|
m["encoding"] = *c.Encoding
|
||||||
|
}
|
||||||
|
if c.HTMLURL != nil {
|
||||||
|
m["html_url"] = *c.HTMLURL
|
||||||
|
}
|
||||||
|
if c.DownloadURL != nil {
|
||||||
|
m["download_url"] = *c.DownloadURL
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimDirEntries(entries []*gitea_sdk.ContentsResponse) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(entries))
|
||||||
|
for _, c := range entries {
|
||||||
|
if c == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out = append(out, map[string]any{
|
||||||
|
"name": c.Name,
|
||||||
|
"path": c.Path,
|
||||||
|
"type": c.Type,
|
||||||
|
"size": c.Size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
142
operation/repo/slim_test.go
Normal file
142
operation/repo/slim_test.go
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSlimRepo(t *testing.T) {
|
||||||
|
r := &gitea_sdk.Repository{
|
||||||
|
ID: 1,
|
||||||
|
FullName: "org/repo",
|
||||||
|
Description: "A test repo",
|
||||||
|
HTMLURL: "https://gitea.com/org/repo",
|
||||||
|
CloneURL: "https://gitea.com/org/repo.git",
|
||||||
|
SSHURL: "git@gitea.com:org/repo.git",
|
||||||
|
DefaultBranch: "main",
|
||||||
|
Private: false,
|
||||||
|
Fork: false,
|
||||||
|
Archived: false,
|
||||||
|
Language: "Go",
|
||||||
|
Stars: 10,
|
||||||
|
Forks: 2,
|
||||||
|
Owner: &gitea_sdk.User{UserName: "org"},
|
||||||
|
Topics: []string{"mcp", "gitea"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := slimRepo(r)
|
||||||
|
|
||||||
|
if m["full_name"] != "org/repo" {
|
||||||
|
t.Errorf("expected full_name org/repo, got %v", m["full_name"])
|
||||||
|
}
|
||||||
|
if m["owner"] != "org" {
|
||||||
|
t.Errorf("expected owner org, got %v", m["owner"])
|
||||||
|
}
|
||||||
|
topics := m["topics"].([]string)
|
||||||
|
if len(topics) != 2 {
|
||||||
|
t.Errorf("expected 2 topics, got %d", len(topics))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimTag(t *testing.T) {
|
||||||
|
tag := &gitea_sdk.Tag{
|
||||||
|
Name: "v1.0.0",
|
||||||
|
Message: "Release v1.0.0",
|
||||||
|
Commit: &gitea_sdk.CommitMeta{SHA: "abc123"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := slimTag(tag)
|
||||||
|
if m["name"] != "v1.0.0" {
|
||||||
|
t.Errorf("expected name v1.0.0, got %v", m["name"])
|
||||||
|
}
|
||||||
|
if m["message"] != "Release v1.0.0" {
|
||||||
|
t.Errorf("expected message, got %v", m["message"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// List variant omits message
|
||||||
|
list := slimTags([]*gitea_sdk.Tag{tag})
|
||||||
|
if _, ok := list[0]["message"]; ok {
|
||||||
|
t.Error("Tags list should omit message")
|
||||||
|
}
|
||||||
|
if list[0]["name"] != "v1.0.0" {
|
||||||
|
t.Errorf("expected name in list, got %v", list[0]["name"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimRelease(t *testing.T) {
|
||||||
|
r := &gitea_sdk.Release{
|
||||||
|
ID: 1,
|
||||||
|
TagName: "v1.0.0",
|
||||||
|
Title: "First Release",
|
||||||
|
Note: "Release notes",
|
||||||
|
IsDraft: false,
|
||||||
|
Publisher: &gitea_sdk.User{UserName: "alice"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := slimRelease(r)
|
||||||
|
if m["tag_name"] != "v1.0.0" {
|
||||||
|
t.Errorf("expected tag_name v1.0.0, got %v", m["tag_name"])
|
||||||
|
}
|
||||||
|
if m["body"] != "Release notes" {
|
||||||
|
t.Errorf("expected body from Note field, got %v", m["body"])
|
||||||
|
}
|
||||||
|
if m["author"] != "alice" {
|
||||||
|
t.Errorf("expected author alice, got %v", m["author"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimContents(t *testing.T) {
|
||||||
|
content := "package main"
|
||||||
|
encoding := "base64"
|
||||||
|
htmlURL := "https://gitea.com/org/repo/src/branch/main/main.go"
|
||||||
|
c := &gitea_sdk.ContentsResponse{
|
||||||
|
Name: "main.go",
|
||||||
|
Path: "main.go",
|
||||||
|
SHA: "abc123",
|
||||||
|
Type: "file",
|
||||||
|
Size: 12,
|
||||||
|
Content: &content,
|
||||||
|
Encoding: &encoding,
|
||||||
|
HTMLURL: &htmlURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
m := slimContents(c)
|
||||||
|
if m["name"] != "main.go" {
|
||||||
|
t.Errorf("expected name main.go, got %v", m["name"])
|
||||||
|
}
|
||||||
|
if m["content"] != "package main" {
|
||||||
|
t.Errorf("expected content, got %v", m["content"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimDirEntries(t *testing.T) {
|
||||||
|
entries := []*gitea_sdk.ContentsResponse{
|
||||||
|
{Name: "src", Path: "src", Type: "dir", Size: 0},
|
||||||
|
{Name: "main.go", Path: "main.go", Type: "file", Size: 100},
|
||||||
|
}
|
||||||
|
|
||||||
|
result := slimDirEntries(entries)
|
||||||
|
if len(result) != 2 {
|
||||||
|
t.Fatalf("expected 2 entries, got %d", len(result))
|
||||||
|
}
|
||||||
|
if result[0]["name"] != "src" {
|
||||||
|
t.Errorf("expected first entry name src, got %v", result[0]["name"])
|
||||||
|
}
|
||||||
|
// Dir entries should not have content
|
||||||
|
if _, ok := result[0]["content"]; ok {
|
||||||
|
t.Error("dir entries should not have content field")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimTags_Nil(t *testing.T) {
|
||||||
|
if r := slimTags(nil); len(r) != 0 {
|
||||||
|
t.Errorf("expected empty slice, got %v", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimReleases_Nil(t *testing.T) {
|
||||||
|
if r := slimReleases(nil); len(r) != 0 {
|
||||||
|
t.Errorf("expected empty slice, got %v", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -78,31 +77,23 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// To avoid return too many tokens, we need to provide at least information as possible
|
|
||||||
// llm can call get tag to get more information
|
|
||||||
type ListTagResult struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Commit *gitea_sdk.CommitMeta `json:"commit"`
|
|
||||||
// message may be a long text, so we should not provide it here
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateTagFn")
|
log.Debugf("Called CreateTagFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
tagName, ok := req.GetArguments()["tag_name"].(string)
|
tagName, err := params.GetString(args, "tag_name")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("tag_name is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
target, _ := req.GetArguments()["target"].(string)
|
target, _ := args["target"].(string)
|
||||||
message, _ := req.GetArguments()["message"].(string)
|
message, _ := args["message"].(string)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -122,17 +113,18 @@ func CreateTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
|
|||||||
|
|
||||||
func DeleteTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteTagFn")
|
log.Debugf("Called DeleteTagFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
tagName, ok := req.GetArguments()["tag_name"].(string)
|
tagName, err := params.GetString(args, "tag_name")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("tag_name is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -149,17 +141,18 @@ func DeleteTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
|
|||||||
|
|
||||||
func GetTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetTagFn")
|
log.Debugf("Called GetTagFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
tagName, ok := req.GetArguments()["tag_name"].(string)
|
tagName, err := params.GetString(args, "tag_name")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("tag_name is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -171,21 +164,22 @@ func GetTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult
|
|||||||
return nil, fmt.Errorf("get tag error: %v", err)
|
return nil, fmt.Errorf("get tag error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(tag)
|
return to.TextResult(slimTag(tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListTagsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListTagsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListTagsFn")
|
log.Debugf("Called ListTagsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return nil, errors.New("owner is required")
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("repo is required")
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page := params.GetOptionalInt(args, "page", 1)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 20)
|
pageSize := params.GetOptionalInt(args, "pageSize", 20)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -201,13 +195,5 @@ func ListTagsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
|
|||||||
return nil, fmt.Errorf("list tags error: %v", err)
|
return nil, fmt.Errorf("list tags error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([]ListTagResult, 0, len(tags))
|
return to.TextResult(slimTags(tags))
|
||||||
for _, tag := range tags {
|
|
||||||
results = append(results, ListTagResult{
|
|
||||||
ID: tag.ID,
|
|
||||||
Name: tag.Name,
|
|
||||||
Commit: tag.Commit,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return to.TextResult(results)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package search
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -30,7 +29,7 @@ var (
|
|||||||
mcp.WithDescription("search users"),
|
mcp.WithDescription("search users"),
|
||||||
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
||||||
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
SearOrgTeamsTool = mcp.NewTool(
|
SearOrgTeamsTool = mcp.NewTool(
|
||||||
@@ -40,7 +39,7 @@ var (
|
|||||||
mcp.WithString("query", mcp.Required(), mcp.Description("search organization teams")),
|
mcp.WithString("query", mcp.Required(), mcp.Description("search organization teams")),
|
||||||
mcp.WithBoolean("includeDescription", mcp.Description("include description?")),
|
mcp.WithBoolean("includeDescription", mcp.Description("include description?")),
|
||||||
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
SearchReposTool = mcp.NewTool(
|
SearchReposTool = mcp.NewTool(
|
||||||
@@ -55,7 +54,7 @@ var (
|
|||||||
mcp.WithString("sort", mcp.Description("Sort")),
|
mcp.WithString("sort", mcp.Description("Sort")),
|
||||||
mcp.WithString("order", mcp.Description("Order")),
|
mcp.WithString("order", mcp.Description("Order")),
|
||||||
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -76,17 +75,16 @@ func init() {
|
|||||||
|
|
||||||
func UsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UsersFn")
|
log.Debugf("Called UsersFn")
|
||||||
keyword, ok := req.GetArguments()["keyword"].(string)
|
keyword, err := params.GetString(req.GetArguments(), "keyword")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("keyword is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
opt := gitea_sdk.SearchUsersOption{
|
opt := gitea_sdk.SearchUsersOption{
|
||||||
KeyWord: keyword,
|
KeyWord: keyword,
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -97,28 +95,27 @@ func UsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("search users err: %v", err))
|
return to.ErrorResult(fmt.Errorf("search users err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(users)
|
return to.TextResult(slimUserDetails(users))
|
||||||
}
|
}
|
||||||
|
|
||||||
func OrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func OrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called OrgTeamsFn")
|
log.Debugf("Called OrgTeamsFn")
|
||||||
org, ok := req.GetArguments()["org"].(string)
|
org, err := params.GetString(req.GetArguments(), "org")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("organization is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
query, ok := req.GetArguments()["query"].(string)
|
query, err := params.GetString(req.GetArguments(), "query")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("query is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
includeDescription, _ := req.GetArguments()["includeDescription"].(bool)
|
includeDescription, _ := req.GetArguments()["includeDescription"].(bool)
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
opt := gitea_sdk.SearchTeamsOptions{
|
opt := gitea_sdk.SearchTeamsOptions{
|
||||||
Query: query,
|
Query: query,
|
||||||
IncludeDescription: includeDescription,
|
IncludeDescription: includeDescription,
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -129,14 +126,14 @@ func OrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("search organization teams error: %v", err))
|
return to.ErrorResult(fmt.Errorf("search organization teams error: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(teams)
|
return to.TextResult(slimTeams(teams))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ReposFn")
|
log.Debugf("Called ReposFn")
|
||||||
keyword, ok := req.GetArguments()["keyword"].(string)
|
keyword, err := params.GetString(req.GetArguments(), "keyword")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("keyword is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
keywordIsTopic, _ := req.GetArguments()["keywordIsTopic"].(bool)
|
keywordIsTopic, _ := req.GetArguments()["keywordIsTopic"].(bool)
|
||||||
keywordInDescription, _ := req.GetArguments()["keywordInDescription"].(bool)
|
keywordInDescription, _ := req.GetArguments()["keywordInDescription"].(bool)
|
||||||
@@ -153,8 +150,7 @@ func ReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult,
|
|||||||
}
|
}
|
||||||
sort, _ := req.GetArguments()["sort"].(string)
|
sort, _ := req.GetArguments()["sort"].(string)
|
||||||
order, _ := req.GetArguments()["order"].(string)
|
order, _ := req.GetArguments()["order"].(string)
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
opt := gitea_sdk.SearchRepoOptions{
|
opt := gitea_sdk.SearchRepoOptions{
|
||||||
Keyword: keyword,
|
Keyword: keyword,
|
||||||
KeywordIsTopic: keywordIsTopic,
|
KeywordIsTopic: keywordIsTopic,
|
||||||
@@ -165,8 +161,8 @@ func ReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult,
|
|||||||
Sort: sort,
|
Sort: sort,
|
||||||
Order: order,
|
Order: order,
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
@@ -177,5 +173,5 @@ func ReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("search repos error: %v", err))
|
return to.ErrorResult(fmt.Errorf("search repos error: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(repos)
|
return to.TextResult(slimRepos(repos))
|
||||||
}
|
}
|
||||||
|
|||||||
88
operation/search/slim.go
Normal file
88
operation/search/slim.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func slimUserDetail(u *gitea_sdk.User) map[string]any {
|
||||||
|
if u == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": u.ID,
|
||||||
|
"login": u.UserName,
|
||||||
|
"full_name": u.FullName,
|
||||||
|
"email": u.Email,
|
||||||
|
"avatar_url": u.AvatarURL,
|
||||||
|
"html_url": u.HTMLURL,
|
||||||
|
"is_admin": u.IsAdmin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimUserDetails(users []*gitea_sdk.User) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(users))
|
||||||
|
for _, u := range users {
|
||||||
|
out = append(out, slimUserDetail(u))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimTeam(t *gitea_sdk.Team) map[string]any {
|
||||||
|
if t == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": t.ID,
|
||||||
|
"name": t.Name,
|
||||||
|
"description": t.Description,
|
||||||
|
"permission": t.Permission,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimTeams(teams []*gitea_sdk.Team) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(teams))
|
||||||
|
for _, t := range teams {
|
||||||
|
out = append(out, slimTeam(t))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimRepo(r *gitea_sdk.Repository) map[string]any {
|
||||||
|
if r == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m := map[string]any{
|
||||||
|
"id": r.ID,
|
||||||
|
"full_name": r.FullName,
|
||||||
|
"description": r.Description,
|
||||||
|
"html_url": r.HTMLURL,
|
||||||
|
"clone_url": r.CloneURL,
|
||||||
|
"ssh_url": r.SSHURL,
|
||||||
|
"default_branch": r.DefaultBranch,
|
||||||
|
"private": r.Private,
|
||||||
|
"fork": r.Fork,
|
||||||
|
"archived": r.Archived,
|
||||||
|
"language": r.Language,
|
||||||
|
"stars_count": r.Stars,
|
||||||
|
"forks_count": r.Forks,
|
||||||
|
"open_issues_count": r.OpenIssues,
|
||||||
|
"open_pr_counter": r.OpenPulls,
|
||||||
|
"created_at": r.Created,
|
||||||
|
"updated_at": r.Updated,
|
||||||
|
}
|
||||||
|
if r.Owner != nil {
|
||||||
|
m["owner"] = r.Owner.UserName
|
||||||
|
}
|
||||||
|
if len(r.Topics) > 0 {
|
||||||
|
m["topics"] = r.Topics
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimRepos(repos []*gitea_sdk.Repository) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(repos))
|
||||||
|
for _, r := range repos {
|
||||||
|
out = append(out, slimRepo(r))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
47
operation/timetracking/slim.go
Normal file
47
operation/timetracking/slim.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package timetracking
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func slimStopWatch(s *gitea_sdk.StopWatch) map[string]any {
|
||||||
|
if s == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"issue_index": s.IssueIndex,
|
||||||
|
"issue_title": s.IssueTitle,
|
||||||
|
"repo_name": s.RepoName,
|
||||||
|
"repo_owner": s.RepoOwnerName,
|
||||||
|
"created": s.Created,
|
||||||
|
"seconds": s.Seconds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimStopWatches(watches []*gitea_sdk.StopWatch) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(watches))
|
||||||
|
for _, s := range watches {
|
||||||
|
out = append(out, slimStopWatch(s))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimTrackedTime(t *gitea_sdk.TrackedTime) map[string]any {
|
||||||
|
if t == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": t.ID,
|
||||||
|
"time": t.Time,
|
||||||
|
"user_name": t.UserName,
|
||||||
|
"created": t.Created,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimTrackedTimes(times []*gitea_sdk.TrackedTime) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(times))
|
||||||
|
for _, t := range times {
|
||||||
|
out = append(out, slimTrackedTime(t))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@ package timetracking
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
gitea_sdk "code.gitea.io/sdk/gitea"
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
@@ -73,7 +72,7 @@ var (
|
|||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("index", mcp.Required(), mcp.Description("issue index")),
|
mcp.WithNumber("index", mcp.Required(), mcp.Description("issue index")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
AddTrackedTimeTool = mcp.NewTool(
|
AddTrackedTimeTool = mcp.NewTool(
|
||||||
@@ -100,7 +99,7 @@ var (
|
|||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetMyTimesTool = mcp.NewTool(
|
GetMyTimesTool = mcp.NewTool(
|
||||||
@@ -128,13 +127,13 @@ func init() {
|
|||||||
|
|
||||||
func StartStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func StartStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called StartStopwatchFn")
|
log.Debugf("Called StartStopwatchFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -153,13 +152,13 @@ func StartStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
|
|
||||||
func StopStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func StopStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called StopStopwatchFn")
|
log.Debugf("Called StopStopwatchFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -178,13 +177,13 @@ func StopStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
|
|
||||||
func DeleteStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteStopwatchFn")
|
log.Debugf("Called DeleteStopwatchFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -214,27 +213,26 @@ func GetMyStopwatchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if len(stopwatches) == 0 {
|
if len(stopwatches) == 0 {
|
||||||
return to.TextResult("No active stopwatches")
|
return to.TextResult("No active stopwatches")
|
||||||
}
|
}
|
||||||
return to.TextResult(stopwatches)
|
return to.TextResult(slimStopWatches(stopwatches))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tracked time handler functions
|
// Tracked time handler functions
|
||||||
|
|
||||||
func ListTrackedTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListTrackedTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListTrackedTimesFn")
|
log.Debugf("Called ListTrackedTimesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||||
@@ -242,8 +240,8 @@ func ListTrackedTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
|
|
||||||
times, _, err := client.ListIssueTrackedTimes(owner, repo, index, gitea_sdk.ListTrackedTimesOptions{
|
times, _, err := client.ListIssueTrackedTimes(owner, repo, index, gitea_sdk.ListTrackedTimesOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -252,18 +250,18 @@ func ListTrackedTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if len(times) == 0 {
|
if len(times) == 0 {
|
||||||
return to.TextResult(fmt.Sprintf("No tracked times for issue %s/%s#%d", owner, repo, index))
|
return to.TextResult(fmt.Sprintf("No tracked times for issue %s/%s#%d", owner, repo, index))
|
||||||
}
|
}
|
||||||
return to.TextResult(times)
|
return to.TextResult(slimTrackedTimes(times))
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func AddTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called AddTrackedTimeFn")
|
log.Debugf("Called AddTrackedTimeFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -284,18 +282,18 @@ func AddTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("add tracked time to %s/%s#%d err: %v", owner, repo, index, err))
|
return to.ErrorResult(fmt.Errorf("add tracked time to %s/%s#%d err: %v", owner, repo, index, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(trackedTime)
|
return to.TextResult(slimTrackedTime(trackedTime))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteTrackedTimeFn")
|
log.Debugf("Called DeleteTrackedTimeFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
@@ -319,25 +317,24 @@ func DeleteTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
|
|||||||
|
|
||||||
func ListRepoTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListRepoTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListRepoTimesFn")
|
log.Debugf("Called ListRepoTimesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
page, pageSize := params.GetPagination(req.GetArguments(), 30)
|
||||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||||
}
|
}
|
||||||
times, _, err := client.ListRepoTrackedTimes(owner, repo, gitea_sdk.ListTrackedTimesOptions{
|
times, _, err := client.ListRepoTrackedTimes(owner, repo, gitea_sdk.ListTrackedTimesOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -346,7 +343,7 @@ func ListRepoTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
if len(times) == 0 {
|
if len(times) == 0 {
|
||||||
return to.TextResult(fmt.Sprintf("No tracked times for repository %s/%s", owner, repo))
|
return to.TextResult(fmt.Sprintf("No tracked times for repository %s/%s", owner, repo))
|
||||||
}
|
}
|
||||||
return to.TextResult(times)
|
return to.TextResult(slimTrackedTimes(times))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMyTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetMyTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
@@ -362,5 +359,5 @@ func GetMyTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
if len(times) == 0 {
|
if len(times) == 0 {
|
||||||
return to.TextResult("No tracked times found")
|
return to.TextResult("No tracked times found")
|
||||||
}
|
}
|
||||||
return to.TextResult(times)
|
return to.TextResult(slimTrackedTimes(times))
|
||||||
}
|
}
|
||||||
|
|||||||
42
operation/user/slim.go
Normal file
42
operation/user/slim.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func slimUserDetail(u *gitea_sdk.User) map[string]any {
|
||||||
|
if u == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": u.ID,
|
||||||
|
"login": u.UserName,
|
||||||
|
"full_name": u.FullName,
|
||||||
|
"email": u.Email,
|
||||||
|
"avatar_url": u.AvatarURL,
|
||||||
|
"html_url": u.HTMLURL,
|
||||||
|
"is_admin": u.IsAdmin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimOrg(o *gitea_sdk.Organization) map[string]any {
|
||||||
|
if o == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return map[string]any{
|
||||||
|
"id": o.ID,
|
||||||
|
"name": o.Name,
|
||||||
|
"full_name": o.FullName,
|
||||||
|
"description": o.Description,
|
||||||
|
"avatar_url": o.AvatarURL,
|
||||||
|
"website": o.Website,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func slimOrgs(orgs []*gitea_sdk.Organization) []map[string]any {
|
||||||
|
out := make([]map[string]any, 0, len(orgs))
|
||||||
|
for _, o := range orgs {
|
||||||
|
out = append(out, slimOrg(o))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
39
operation/user/slim_test.go
Normal file
39
operation/user/slim_test.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSlimUserDetail(t *testing.T) {
|
||||||
|
u := &gitea_sdk.User{
|
||||||
|
ID: 42,
|
||||||
|
UserName: "alice",
|
||||||
|
FullName: "Alice Smith",
|
||||||
|
Email: "alice@example.com",
|
||||||
|
AvatarURL: "https://gitea.com/avatars/42",
|
||||||
|
HTMLURL: "https://gitea.com/alice",
|
||||||
|
IsAdmin: true,
|
||||||
|
}
|
||||||
|
m := slimUserDetail(u)
|
||||||
|
|
||||||
|
if m["id"] != int64(42) {
|
||||||
|
t.Errorf("expected id 42, got %v", m["id"])
|
||||||
|
}
|
||||||
|
if m["login"] != "alice" {
|
||||||
|
t.Errorf("expected login alice, got %v", m["login"])
|
||||||
|
}
|
||||||
|
if m["full_name"] != "Alice Smith" {
|
||||||
|
t.Errorf("expected full_name Alice Smith, got %v", m["full_name"])
|
||||||
|
}
|
||||||
|
if m["is_admin"] != true {
|
||||||
|
t.Errorf("expected is_admin true, got %v", m["is_admin"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSlimUserDetail_Nil(t *testing.T) {
|
||||||
|
if m := slimUserDetail(nil); m != nil {
|
||||||
|
t.Errorf("expected nil for nil user, got %v", m)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ const (
|
|||||||
// defaultPage is the default starting page number used for paginated organization listings.
|
// defaultPage is the default starting page number used for paginated organization listings.
|
||||||
defaultPage = 1
|
defaultPage = 1
|
||||||
// defaultPageSize is the default number of organizations per page for paginated queries.
|
// defaultPageSize is the default number of organizations per page for paginated queries.
|
||||||
defaultPageSize = 100
|
defaultPageSize = 30
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tool is the MCP tool manager instance for registering all MCP tools in this package.
|
// Tool is the MCP tool manager instance for registering all MCP tools in this package.
|
||||||
@@ -66,16 +66,6 @@ func registerTools() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getIntArg parses an integer argument from the MCP request arguments map.
|
|
||||||
// Returns def if missing, not a number, or less than 1. Used for pagination arguments.
|
|
||||||
func getIntArg(req mcp.CallToolRequest, name string, def int) int {
|
|
||||||
v := params.GetOptionalInt(req.GetArguments(), name, int64(def))
|
|
||||||
if v < 1 {
|
|
||||||
return def
|
|
||||||
}
|
|
||||||
return int(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserInfoFn is the handler for "get_my_user_info" MCP tool requests.
|
// GetUserInfoFn is the handler for "get_my_user_info" MCP tool requests.
|
||||||
// Logs invocation, fetches current user info from gitea, wraps result for MCP.
|
// Logs invocation, fetches current user info from gitea, wraps result for MCP.
|
||||||
func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
@@ -88,7 +78,7 @@ func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get user info err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get user info err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(user)
|
return to.TextResult(slimUserDetail(user))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserOrgsFn is the handler for "get_user_orgs" MCP tool requests.
|
// GetUserOrgsFn is the handler for "get_user_orgs" MCP tool requests.
|
||||||
@@ -96,8 +86,7 @@ func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
// performs Gitea organization listing, and wraps the result for MCP.
|
// performs Gitea organization listing, and wraps the result for MCP.
|
||||||
func GetUserOrgsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetUserOrgsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("[User] Called GetUserOrgsFn")
|
log.Debugf("[User] Called GetUserOrgsFn")
|
||||||
page := getIntArg(req, "page", defaultPage)
|
page, pageSize := params.GetPagination(req.GetArguments(), defaultPageSize)
|
||||||
pageSize := getIntArg(req, "pageSize", defaultPageSize)
|
|
||||||
|
|
||||||
opt := gitea_sdk.ListOrgsOptions{
|
opt := gitea_sdk.ListOrgsOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
@@ -113,5 +102,5 @@ func GetUserOrgsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get user orgs err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get user orgs err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(orgs)
|
return to.TextResult(slimOrgs(orgs))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package wiki
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/to"
|
"gitea.com/gitea/gitea-mcp/pkg/to"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/tool"
|
"gitea.com/gitea/gitea-mcp/pkg/tool"
|
||||||
|
|
||||||
@@ -109,18 +109,19 @@ func init() {
|
|||||||
|
|
||||||
func ListWikiPagesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ListWikiPagesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ListWikiPagesFn")
|
log.Debugf("Called ListWikiPagesFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use direct HTTP request because SDK does not support yet wikis
|
// Use direct HTTP request because SDK does not support yet wikis
|
||||||
var result any
|
var result any
|
||||||
_, err := gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/wiki/pages", url.QueryEscape(owner), url.QueryEscape(repo)), nil, nil, &result)
|
_, err = gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/wiki/pages", url.QueryEscape(owner), url.QueryEscape(repo)), nil, nil, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("list wiki pages err: %v", err))
|
return to.ErrorResult(fmt.Errorf("list wiki pages err: %v", err))
|
||||||
}
|
}
|
||||||
@@ -130,21 +131,22 @@ func ListWikiPagesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
|
|
||||||
func GetWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetWikiPageFn")
|
log.Debugf("Called GetWikiPageFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
pageName, ok := req.GetArguments()["pageName"].(string)
|
pageName, err := params.GetString(args, "pageName")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("pageName is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
_, err := gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/wiki/page/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, nil, &result)
|
_, err = gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/wiki/page/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, nil, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get wiki page err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get wiki page err: %v", err))
|
||||||
}
|
}
|
||||||
@@ -154,21 +156,22 @@ func GetWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
|
|
||||||
func GetWikiRevisionsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func GetWikiRevisionsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called GetWikiRevisionsFn")
|
log.Debugf("Called GetWikiRevisionsFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
pageName, ok := req.GetArguments()["pageName"].(string)
|
pageName, err := params.GetString(args, "pageName")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("pageName is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
_, err := gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/wiki/revisions/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, nil, &result)
|
_, err = gitea.DoJSON(ctx, "GET", fmt.Sprintf("repos/%s/%s/wiki/revisions/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, nil, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("get wiki revisions err: %v", err))
|
return to.ErrorResult(fmt.Errorf("get wiki revisions err: %v", err))
|
||||||
}
|
}
|
||||||
@@ -178,24 +181,25 @@ func GetWikiRevisionsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
|
|
||||||
func CreateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func CreateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called CreateWikiPageFn")
|
log.Debugf("Called CreateWikiPageFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
title, ok := req.GetArguments()["title"].(string)
|
title, err := params.GetString(args, "title")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("title is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
contentBase64, ok := req.GetArguments()["content_base64"].(string)
|
contentBase64, err := params.GetString(args, "content_base64")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("content_base64 is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
message, _ := req.GetArguments()["message"].(string)
|
message, _ := args["message"].(string)
|
||||||
if message == "" {
|
if message == "" {
|
||||||
message = fmt.Sprintf("Create wiki page '%s'", title)
|
message = fmt.Sprintf("Create wiki page '%s'", title)
|
||||||
}
|
}
|
||||||
@@ -207,7 +211,7 @@ func CreateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
_, err := gitea.DoJSON(ctx, "POST", fmt.Sprintf("repos/%s/%s/wiki/new", url.QueryEscape(owner), url.QueryEscape(repo)), nil, requestBody, &result)
|
_, err = gitea.DoJSON(ctx, "POST", fmt.Sprintf("repos/%s/%s/wiki/new", url.QueryEscape(owner), url.QueryEscape(repo)), nil, requestBody, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("create wiki page err: %v", err))
|
return to.ErrorResult(fmt.Errorf("create wiki page err: %v", err))
|
||||||
}
|
}
|
||||||
@@ -217,21 +221,22 @@ func CreateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
|
|
||||||
func UpdateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UpdateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UpdateWikiPageFn")
|
log.Debugf("Called UpdateWikiPageFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
pageName, ok := req.GetArguments()["pageName"].(string)
|
pageName, err := params.GetString(args, "pageName")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("pageName is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
contentBase64, ok := req.GetArguments()["content_base64"].(string)
|
contentBase64, err := params.GetString(args, "content_base64")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("content_base64 is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBody := map[string]string{
|
requestBody := map[string]string{
|
||||||
@@ -239,21 +244,21 @@ func UpdateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If title is given, use it. Otherwise, keep current page name
|
// If title is given, use it. Otherwise, keep current page name
|
||||||
if title, ok := req.GetArguments()["title"].(string); ok && title != "" {
|
if title, ok := args["title"].(string); ok && title != "" {
|
||||||
requestBody["title"] = title
|
requestBody["title"] = title
|
||||||
} else {
|
} else {
|
||||||
// Utiliser pageName comme fallback pour éviter "unnamed"
|
// Utiliser pageName comme fallback pour éviter "unnamed"
|
||||||
requestBody["title"] = pageName
|
requestBody["title"] = pageName
|
||||||
}
|
}
|
||||||
|
|
||||||
if message, ok := req.GetArguments()["message"].(string); ok && message != "" {
|
if message, ok := args["message"].(string); ok && message != "" {
|
||||||
requestBody["message"] = message
|
requestBody["message"] = message
|
||||||
} else {
|
} else {
|
||||||
requestBody["message"] = fmt.Sprintf("Update wiki page '%s'", pageName)
|
requestBody["message"] = fmt.Sprintf("Update wiki page '%s'", pageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result any
|
var result any
|
||||||
_, err := gitea.DoJSON(ctx, "PATCH", fmt.Sprintf("repos/%s/%s/wiki/page/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, requestBody, &result)
|
_, err = gitea.DoJSON(ctx, "PATCH", fmt.Sprintf("repos/%s/%s/wiki/page/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, requestBody, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("update wiki page err: %v", err))
|
return to.ErrorResult(fmt.Errorf("update wiki page err: %v", err))
|
||||||
}
|
}
|
||||||
@@ -263,20 +268,21 @@ func UpdateWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
|
|
||||||
func DeleteWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func DeleteWikiPageFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called DeleteWikiPageFn")
|
log.Debugf("Called DeleteWikiPageFn")
|
||||||
owner, ok := req.GetArguments()["owner"].(string)
|
args := req.GetArguments()
|
||||||
if !ok {
|
owner, err := params.GetString(args, "owner")
|
||||||
return to.ErrorResult(errors.New("owner is required"))
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
repo, ok := req.GetArguments()["repo"].(string)
|
repo, err := params.GetString(args, "repo")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("repo is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
pageName, ok := req.GetArguments()["pageName"].(string)
|
pageName, err := params.GetString(args, "pageName")
|
||||||
if !ok {
|
if err != nil {
|
||||||
return to.ErrorResult(errors.New("pageName is required"))
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := gitea.DoJSON(ctx, "DELETE", fmt.Sprintf("repos/%s/%s/wiki/page/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, nil, nil)
|
_, err = gitea.DoJSON(ctx, "DELETE", fmt.Sprintf("repos/%s/%s/wiki/page/%s", url.QueryEscape(owner), url.QueryEscape(repo), url.QueryEscape(pageName)), nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(fmt.Errorf("delete wiki page err: %v", err))
|
return to.ErrorResult(fmt.Errorf("delete wiki page err: %v", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,47 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetString extracts a required string parameter from MCP tool arguments.
|
||||||
|
func GetString(args map[string]any, key string) (string, error) {
|
||||||
|
val, ok := args[key].(string)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("%s is required", key)
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOptionalString extracts an optional string parameter with a default value.
|
||||||
|
func GetOptionalString(args map[string]any, key, defaultVal string) string {
|
||||||
|
if val, ok := args[key].(string); ok {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStringSlice extracts an optional string slice parameter from MCP tool arguments.
|
||||||
|
func GetStringSlice(args map[string]any, key string) []string {
|
||||||
|
val, ok := args[key]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sliceVal, ok := val.([]any)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := make([]string, 0, len(sliceVal))
|
||||||
|
for _, item := range sliceVal {
|
||||||
|
if s, ok := item.(string); ok {
|
||||||
|
out = append(out, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPagination extracts page and pageSize parameters, returning them as ints.
|
||||||
|
func GetPagination(args map[string]any, defaultPageSize int64) (page, pageSize int) {
|
||||||
|
return int(GetOptionalInt(args, "page", 1)), int(GetOptionalInt(args, "pageSize", defaultPageSize))
|
||||||
|
}
|
||||||
|
|
||||||
// ToInt64 converts a value to int64, accepting both float64 (JSON number) and
|
// ToInt64 converts a value to int64, accepting both float64 (JSON number) and
|
||||||
// string representations. Returns false if the value cannot be converted.
|
// string representations. Returns false if the value cannot be converted.
|
||||||
func ToInt64(val any) (int64, bool) {
|
func ToInt64(val any) (int64, bool) {
|
||||||
|
|||||||
@@ -8,13 +8,8 @@ import (
|
|||||||
"github.com/mark3labs/mcp-go/mcp"
|
"github.com/mark3labs/mcp-go/mcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type textResult struct {
|
|
||||||
Result any
|
|
||||||
}
|
|
||||||
|
|
||||||
func TextResult(v any) (*mcp.CallToolResult, error) {
|
func TextResult(v any) (*mcp.CallToolResult, error) {
|
||||||
result := textResult{v}
|
resultBytes, err := json.Marshal(v)
|
||||||
resultBytes, err := json.Marshal(result)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("marshal result err: %v", err)
|
return nil, fmt.Errorf("marshal result err: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user