mirror of
				https://gitea.com/gitea/gitea-mcp.git
				synced 2025-11-04 04:11:50 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					de311344cd | ||
| 
						 | 
					d7addd56c4 | ||
| 
						 | 
					dc3e120e97 | ||
| 
						 | 
					f33b04a3df | ||
| 
						 | 
					ba07925969 | 
@@ -66,6 +66,8 @@ jobs:
 | 
				
			|||||||
            linux/amd64
 | 
					            linux/amd64
 | 
				
			||||||
            linux/arm64
 | 
					            linux/arm64
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
 | 
					          build-args: |
 | 
				
			||||||
 | 
					            VERSION=${{ steps.meta.outputs.REPO_VERSION }}
 | 
				
			||||||
          tags: |
 | 
					          tags: |
 | 
				
			||||||
            ${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}-server:${{ steps.meta.outputs.REPO_VERSION }}
 | 
					            ${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}-server:${{ steps.meta.outputs.REPO_VERSION }}
 | 
				
			||||||
            ${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}-server:${{ env.DOCKER_LATEST }}
 | 
					            ${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}-server:${{ env.DOCKER_LATEST }}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@@ -139,7 +139,10 @@ To configure the MCP server for Gitea, add the following to your MCP configurati
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "mcpServers": {
 | 
					  "mcpServers": {
 | 
				
			||||||
    "gitea": {
 | 
					    "gitea": {
 | 
				
			||||||
      "url": "http://localhost:8080/sse"
 | 
					      "url": "http://localhost:8080/sse",
 | 
				
			||||||
 | 
					      "headers": {
 | 
				
			||||||
 | 
					        "Authorization": "Bearer <your personal access token>"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -151,7 +154,10 @@ To configure the MCP server for Gitea, add the following to your MCP configurati
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "mcpServers": {
 | 
					  "mcpServers": {
 | 
				
			||||||
    "gitea": {
 | 
					    "gitea": {
 | 
				
			||||||
      "url": "http://localhost:8080/mcp"
 | 
					      "url": "http://localhost:8080/mcp",
 | 
				
			||||||
 | 
					      "headers": {
 | 
				
			||||||
 | 
					        "Authorization": "Bearer <your personal access token>"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -139,7 +139,10 @@ cp gitea-mcp /usr/local/bin/
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "mcpServers": {
 | 
					  "mcpServers": {
 | 
				
			||||||
    "gitea": {
 | 
					    "gitea": {
 | 
				
			||||||
      "url": "http://localhost:8080/sse"
 | 
					      "url": "http://localhost:8080/sse",
 | 
				
			||||||
 | 
					      "headers": {
 | 
				
			||||||
 | 
					        "Authorization": "Bearer <your personal access token>"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -151,7 +154,10 @@ cp gitea-mcp /usr/local/bin/
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "mcpServers": {
 | 
					  "mcpServers": {
 | 
				
			||||||
    "gitea": {
 | 
					    "gitea": {
 | 
				
			||||||
      "url": "http://localhost:8080/mcp"
 | 
					      "url": "http://localhost:8080/mcp",
 | 
				
			||||||
 | 
					      "headers": {
 | 
				
			||||||
 | 
					        "Authorization": "Bearer <your personal access token>"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -139,7 +139,10 @@ cp gitea-mcp /usr/local/bin/
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "mcpServers": {
 | 
					  "mcpServers": {
 | 
				
			||||||
    "gitea": {
 | 
					    "gitea": {
 | 
				
			||||||
      "url": "http://localhost:8080/sse"
 | 
					      "url": "http://localhost:8080/sse",
 | 
				
			||||||
 | 
					      "headers": {
 | 
				
			||||||
 | 
					        "Authorization": "Bearer <your personal access token>"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -151,7 +154,10 @@ cp gitea-mcp /usr/local/bin/
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "mcpServers": {
 | 
					  "mcpServers": {
 | 
				
			||||||
    "gitea": {
 | 
					    "gitea": {
 | 
				
			||||||
      "url": "http://localhost:8080/mcp"
 | 
					      "url": "http://localhost:8080/mcp",
 | 
				
			||||||
 | 
					      "headers": {
 | 
				
			||||||
 | 
					        "Authorization": "Bearer <your personal access token>"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -140,7 +140,11 @@ func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("index is required"))
 | 
							return to.ErrorResult(fmt.Errorf("index is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issue, _, err := gitea.Client().GetIssue(owner, repo, int64(index))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issue, _, err := client.GetIssue(owner, repo, int64(index))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("get %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("get %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -177,7 +181,11 @@ func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
 | 
				
			|||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issues, _, err := gitea.Client().ListRepoIssues(owner, repo, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issues, _, err := client.ListRepoIssues(owner, repo, opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -202,7 +210,11 @@ func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("body is required"))
 | 
							return to.ErrorResult(fmt.Errorf("body is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issue, _, err := gitea.Client().CreateIssue(owner, repo, gitea_sdk.CreateIssueOption{
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issue, _, err := client.CreateIssue(owner, repo, gitea_sdk.CreateIssueOption{
 | 
				
			||||||
		Title: title,
 | 
							Title: title,
 | 
				
			||||||
		Body:  body,
 | 
							Body:  body,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
@@ -234,7 +246,11 @@ func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
 | 
				
			|||||||
	opt := gitea_sdk.CreateIssueCommentOption{
 | 
						opt := gitea_sdk.CreateIssueCommentOption{
 | 
				
			||||||
		Body: body,
 | 
							Body: body,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issueComment, _, err := gitea.Client().CreateIssueComment(owner, repo, int64(index), opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issueComment, _, err := client.CreateIssueComment(owner, repo, int64(index), opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("create %v/%v/issue/%v/comment err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("create %v/%v/issue/%v/comment err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -280,7 +296,11 @@ func EditIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
 | 
				
			|||||||
		opt.State = ptr.To(gitea_sdk.StateType(state))
 | 
							opt.State = ptr.To(gitea_sdk.StateType(state))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	issue, _, err := gitea.Client().EditIssue(owner, repo, int64(index), opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issue, _, err := client.EditIssue(owner, repo, int64(index), opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("edit %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("edit %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -309,7 +329,11 @@ func EditIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
 | 
				
			|||||||
	opt := gitea_sdk.EditIssueCommentOption{
 | 
						opt := gitea_sdk.EditIssueCommentOption{
 | 
				
			||||||
		Body: body,
 | 
							Body: body,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issueComment, _, err := gitea.Client().EditIssueComment(owner, repo, int64(commentID), opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issueComment, _, err := client.EditIssueComment(owner, repo, int64(commentID), opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("edit %v/%v/issues/comments/%v err: %v", owner, repo, int64(commentID), err))
 | 
							return to.ErrorResult(fmt.Errorf("edit %v/%v/issues/comments/%v err: %v", owner, repo, int64(commentID), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -332,7 +356,11 @@ func GetIssueCommentsByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*m
 | 
				
			|||||||
		return to.ErrorResult(fmt.Errorf("index is required"))
 | 
							return to.ErrorResult(fmt.Errorf("index is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opt := gitea_sdk.ListIssueCommentOptions{}
 | 
						opt := gitea_sdk.ListIssueCommentOptions{}
 | 
				
			||||||
	issue, _, err := gitea.Client().ListIssueComments(owner, repo, int64(index), opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issue, _, err := client.ListIssueComments(owner, repo, int64(index), opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("get %v/%v/issues/%v/comments err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("get %v/%v/issues/%v/comments err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -176,7 +176,11 @@ func ListRepoLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
 | 
				
			|||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	labels, _, err := gitea.Client().ListRepoLabels(owner, repo, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						labels, _, err := client.ListRepoLabels(owner, repo, opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -198,7 +202,11 @@ func GetRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
 | 
				
			|||||||
		return to.ErrorResult(fmt.Errorf("label ID is required"))
 | 
							return to.ErrorResult(fmt.Errorf("label ID is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	label, _, err := gitea.Client().GetRepoLabel(owner, repo, int64(id))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						label, _, err := client.GetRepoLabel(owner, repo, int64(id))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("get %v/%v/label/%v err: %v", owner, repo, int64(id), err))
 | 
							return to.ErrorResult(fmt.Errorf("get %v/%v/label/%v err: %v", owner, repo, int64(id), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -231,7 +239,11 @@ func CreateRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
 | 
				
			|||||||
		Description: description,
 | 
							Description: description,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	label, _, err := gitea.Client().CreateLabel(owner, repo, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						label, _, err := client.CreateLabel(owner, repo, opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -264,7 +276,11 @@ func EditRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
 | 
				
			|||||||
		opt.Description = ptr.To(description)
 | 
							opt.Description = ptr.To(description)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	label, _, err := gitea.Client().EditLabel(owner, repo, int64(id), opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						label, _, err := client.EditLabel(owner, repo, int64(id), opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("edit %v/%v/label/%v err: %v", owner, repo, int64(id), err))
 | 
							return to.ErrorResult(fmt.Errorf("edit %v/%v/label/%v err: %v", owner, repo, int64(id), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -286,7 +302,11 @@ func DeleteRepoLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
 | 
				
			|||||||
		return to.ErrorResult(fmt.Errorf("label ID is required"))
 | 
							return to.ErrorResult(fmt.Errorf("label ID is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := gitea.Client().DeleteLabel(owner, repo, int64(id))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = client.DeleteLabel(owner, repo, int64(id))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("delete %v/%v/label/%v err: %v", owner, repo, int64(id), err))
 | 
							return to.ErrorResult(fmt.Errorf("delete %v/%v/label/%v err: %v", owner, repo, int64(id), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -324,7 +344,11 @@ func AddIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
 | 
				
			|||||||
		Labels: labels,
 | 
							Labels: labels,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	issueLabels, _, err := gitea.Client().AddIssueLabels(owner, repo, int64(index), opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issueLabels, _, err := client.AddIssueLabels(owner, repo, int64(index), opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("add labels to %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("add labels to %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -362,7 +386,11 @@ func ReplaceIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
 | 
				
			|||||||
		Labels: labels,
 | 
							Labels: labels,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	issueLabels, _, err := gitea.Client().ReplaceIssueLabels(owner, repo, int64(index), opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						issueLabels, _, err := client.ReplaceIssueLabels(owner, repo, int64(index), opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("replace labels on %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("replace labels on %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -384,7 +412,11 @@ func ClearIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
 | 
				
			|||||||
		return to.ErrorResult(fmt.Errorf("issue index is required"))
 | 
							return to.ErrorResult(fmt.Errorf("issue index is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := gitea.Client().ClearIssueLabels(owner, repo, int64(index))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = client.ClearIssueLabels(owner, repo, int64(index))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("clear labels on %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("clear labels on %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -410,7 +442,11 @@ func RemoveIssueLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
 | 
				
			|||||||
		return to.ErrorResult(fmt.Errorf("label ID is required"))
 | 
							return to.ErrorResult(fmt.Errorf("label ID is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := gitea.Client().DeleteIssueLabel(owner, repo, int64(index), int64(labelID))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = client.DeleteIssueLabel(owner, repo, int64(index), int64(labelID))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("remove label %v from %v/%v/issue/%v err: %v", int64(labelID), owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("remove label %v from %v/%v/issue/%v err: %v", int64(labelID), owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,10 @@
 | 
				
			|||||||
package operation
 | 
					package operation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gitea.com/gitea/gitea-mcp/operation/issue"
 | 
						"gitea.com/gitea/gitea-mcp/operation/issue"
 | 
				
			||||||
@@ -11,6 +14,7 @@ import (
 | 
				
			|||||||
	"gitea.com/gitea/gitea-mcp/operation/search"
 | 
						"gitea.com/gitea/gitea-mcp/operation/search"
 | 
				
			||||||
	"gitea.com/gitea/gitea-mcp/operation/user"
 | 
						"gitea.com/gitea/gitea-mcp/operation/user"
 | 
				
			||||||
	"gitea.com/gitea/gitea-mcp/operation/version"
 | 
						"gitea.com/gitea/gitea-mcp/operation/version"
 | 
				
			||||||
 | 
						mcpContext "gitea.com/gitea/gitea-mcp/pkg/context"
 | 
				
			||||||
	"gitea.com/gitea/gitea-mcp/pkg/flag"
 | 
						"gitea.com/gitea/gitea-mcp/pkg/flag"
 | 
				
			||||||
	"gitea.com/gitea/gitea-mcp/pkg/log"
 | 
						"gitea.com/gitea/gitea-mcp/pkg/log"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,6 +48,20 @@ func RegisterTool(s *server.MCPServer) {
 | 
				
			|||||||
	s.DeleteTools("")
 | 
						s.DeleteTools("")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getContextWithToken(ctx context.Context, r *http.Request) context.Context {
 | 
				
			||||||
 | 
						authHeader := r.Header.Get("Authorization")
 | 
				
			||||||
 | 
						if authHeader == "" {
 | 
				
			||||||
 | 
							return ctx
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parts := strings.Split(authHeader, " ")
 | 
				
			||||||
 | 
						if len(parts) != 2 || parts[0] != "Bearer" {
 | 
				
			||||||
 | 
							return ctx
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return context.WithValue(ctx, mcpContext.TokenContextKey, parts[1])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Run() error {
 | 
					func Run() error {
 | 
				
			||||||
	mcpServer = newMCPServer(flag.Version)
 | 
						mcpServer = newMCPServer(flag.Version)
 | 
				
			||||||
	RegisterTool(mcpServer)
 | 
						RegisterTool(mcpServer)
 | 
				
			||||||
@@ -57,6 +75,7 @@ func Run() error {
 | 
				
			|||||||
	case "sse":
 | 
						case "sse":
 | 
				
			||||||
		sseServer := server.NewSSEServer(
 | 
							sseServer := server.NewSSEServer(
 | 
				
			||||||
			mcpServer,
 | 
								mcpServer,
 | 
				
			||||||
 | 
								server.WithSSEContextFunc(getContextWithToken),
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
		log.Infof("Gitea MCP SSE server listening on :%d", flag.Port)
 | 
							log.Infof("Gitea MCP SSE server listening on :%d", flag.Port)
 | 
				
			||||||
		if err := sseServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil {
 | 
							if err := sseServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil {
 | 
				
			||||||
@@ -67,7 +86,7 @@ func Run() error {
 | 
				
			|||||||
			mcpServer,
 | 
								mcpServer,
 | 
				
			||||||
			server.WithLogger(log.New()),
 | 
								server.WithLogger(log.New()),
 | 
				
			||||||
			server.WithHeartbeatInterval(30*time.Second),
 | 
								server.WithHeartbeatInterval(30*time.Second),
 | 
				
			||||||
			server.WithStateLess(true),
 | 
								server.WithHTTPContextFunc(getContextWithToken),
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
		log.Infof("Gitea MCP HTTP server listening on :%d", flag.Port)
 | 
							log.Infof("Gitea MCP HTTP server listening on :%d", flag.Port)
 | 
				
			||||||
		if err := httpServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil {
 | 
							if err := httpServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,7 +84,11 @@ func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("index is required"))
 | 
							return to.ErrorResult(fmt.Errorf("index is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pr, _, err := gitea.Client().GetPullRequest(owner, repo, int64(index))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pr, _, err := client.GetPullRequest(owner, repo, int64(index))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v err: %v", owner, repo, int64(index), err))
 | 
							return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v err: %v", owner, repo, int64(index), err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -125,7 +129,11 @@ func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
 | 
				
			|||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pullRequests, _, err := gitea.Client().ListRepoPullRequests(owner, repo, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pullRequests, _, err := client.ListRepoPullRequests(owner, repo, opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -159,7 +167,11 @@ func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("base is required"))
 | 
							return to.ErrorResult(fmt.Errorf("base is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pr, _, err := gitea.Client().CreatePullRequest(owner, repo, gitea_sdk.CreatePullRequestOption{
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pr, _, err := client.CreatePullRequest(owner, repo, gitea_sdk.CreatePullRequestOption{
 | 
				
			||||||
		Title: title,
 | 
							Title: title,
 | 
				
			||||||
		Body:  body,
 | 
							Body:  body,
 | 
				
			||||||
		Head:  head,
 | 
							Head:  head,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,7 +76,11 @@ func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	oldBranch, _ := req.GetArguments()["old_branch"].(string)
 | 
						oldBranch, _ := req.GetArguments()["old_branch"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, _, err := gitea.Client().CreateBranch(owner, repo, gitea_sdk.CreateBranchOption{
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, _, err = client.CreateBranch(owner, repo, gitea_sdk.CreateBranchOption{
 | 
				
			||||||
		BranchName:    branch,
 | 
							BranchName:    branch,
 | 
				
			||||||
		OldBranchName: oldBranch,
 | 
							OldBranchName: oldBranch,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
@@ -101,7 +105,11 @@ func DeleteBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("branch is required"))
 | 
							return to.ErrorResult(fmt.Errorf("branch is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, _, err := gitea.Client().DeleteRepoBranch(owner, repo, branch)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, _, err = client.DeleteRepoBranch(owner, repo, branch)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("delete branch error: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("delete branch error: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -125,7 +133,11 @@ func ListBranchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
 | 
				
			|||||||
			PageSize: 100,
 | 
								PageSize: 100,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	branches, _, err := gitea.Client().ListRepoBranches(owner, repo, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						branches, _, err := client.ListRepoBranches(owner, repo, opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("list branches error: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("list branches error: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,7 +63,11 @@ func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
 | 
				
			|||||||
		SHA:  sha,
 | 
							SHA:  sha,
 | 
				
			||||||
		Path: path,
 | 
							Path: path,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	commits, _, err := gitea.Client().ListRepoCommits(owner, repo, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						commits, _, err := client.ListRepoCommits(owner, repo, opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,7 +64,7 @@ var (
 | 
				
			|||||||
		mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
 | 
							mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
 | 
				
			||||||
		mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
 | 
							mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
 | 
				
			||||||
		mcp.WithString("sha", mcp.Required(), mcp.Description("sha is the SHA for the file that already exists")),
 | 
							mcp.WithString("sha", mcp.Required(), mcp.Description("sha is the SHA for the file that already exists")),
 | 
				
			||||||
		mcp.WithString("content", mcp.Required(), mcp.Description("file content, base64 encoded")),
 | 
							mcp.WithString("content", mcp.Required(), mcp.Description("file content")),
 | 
				
			||||||
		mcp.WithString("message", mcp.Required(), mcp.Description("commit message")),
 | 
							mcp.WithString("message", mcp.Required(), mcp.Description("commit message")),
 | 
				
			||||||
		mcp.WithString("branch_name", mcp.Required(), mcp.Description("branch name")),
 | 
							mcp.WithString("branch_name", mcp.Required(), mcp.Description("branch name")),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
@@ -124,7 +124,11 @@ func GetFileContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("filePath is required"))
 | 
							return to.ErrorResult(fmt.Errorf("filePath is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	content, _, err := gitea.Client().GetContents(owner, repo, ref, filePath)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						content, _, err := client.GetContents(owner, repo, ref, filePath)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -184,7 +188,11 @@ func GetDirContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("filePath is required"))
 | 
							return to.ErrorResult(fmt.Errorf("filePath is required"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	content, _, err := gitea.Client().ListContents(owner, repo, ref, filePath)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						content, _, err := client.ListContents(owner, repo, ref, filePath)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -216,7 +224,11 @@ func CreateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, _, err := gitea.Client().CreateFile(owner, repo, filePath, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, _, err = client.CreateFile(owner, repo, filePath, opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("create file err: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("create file err: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -253,7 +265,11 @@ func UpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
 | 
				
			|||||||
			BranchName: branchName,
 | 
								BranchName: branchName,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, _, err := gitea.Client().UpdateFile(owner, repo, filePath, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, _, err = client.UpdateFile(owner, repo, filePath, opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("update file err: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("update file err: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -287,7 +303,11 @@ func DeleteFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		SHA: sha,
 | 
							SHA: sha,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, err := gitea.Client().DeleteFile(owner, repo, filePath, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = client.DeleteFile(owner, repo, filePath, opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("delete file err: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("delete file err: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -134,7 +134,11 @@ func CreateReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
 | 
				
			|||||||
	isPreRelease, _ := req.GetArguments()["is_pre_release"].(bool)
 | 
						isPreRelease, _ := req.GetArguments()["is_pre_release"].(bool)
 | 
				
			||||||
	body, _ := req.GetArguments()["body"].(string)
 | 
						body, _ := req.GetArguments()["body"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, _, err := gitea.Client().CreateRelease(owner, repo, gitea_sdk.CreateReleaseOption{
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, _, err = client.CreateRelease(owner, repo, gitea_sdk.CreateReleaseOption{
 | 
				
			||||||
		TagName:      tagName,
 | 
							TagName:      tagName,
 | 
				
			||||||
		Target:       target,
 | 
							Target:       target,
 | 
				
			||||||
		Title:        title,
 | 
							Title:        title,
 | 
				
			||||||
@@ -164,7 +168,11 @@ func DeleteReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
 | 
				
			|||||||
		return nil, fmt.Errorf("id is required")
 | 
							return nil, fmt.Errorf("id is required")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := gitea.Client().DeleteRelease(owner, repo, int64(id))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = client.DeleteRelease(owner, repo, int64(id))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("delete release error: %v", err)
 | 
							return nil, fmt.Errorf("delete release error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -187,7 +195,11 @@ func GetReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
 | 
				
			|||||||
		return nil, fmt.Errorf("id is required")
 | 
							return nil, fmt.Errorf("id is required")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	release, _, err := gitea.Client().GetRelease(owner, repo, int64(id))
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						release, _, err := client.GetRelease(owner, repo, int64(id))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("get release error: %v", err)
 | 
							return nil, fmt.Errorf("get release error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -206,7 +218,11 @@ func GetLatestReleaseFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
 | 
				
			|||||||
		return nil, fmt.Errorf("repo is required")
 | 
							return nil, fmt.Errorf("repo is required")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	release, _, err := gitea.Client().GetLatestRelease(owner, repo)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						release, _, err := client.GetLatestRelease(owner, repo)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("get latest release error: %v", err)
 | 
							return nil, fmt.Errorf("get latest release error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -237,7 +253,11 @@ func ListReleasesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
 | 
				
			|||||||
	page, _ := req.GetArguments()["page"].(float64)
 | 
						page, _ := req.GetArguments()["page"].(float64)
 | 
				
			||||||
	pageSize, _ := req.GetArguments()["pageSize"].(float64)
 | 
						pageSize, _ := req.GetArguments()["pageSize"].(float64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	releases, _, err := gitea.Client().ListReleases(owner, repo, gitea_sdk.ListReleasesOptions{
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						releases, _, err := client.ListReleases(owner, repo, gitea_sdk.ListReleasesOptions{
 | 
				
			||||||
		ListOptions: gitea_sdk.ListOptions{
 | 
							ListOptions: gitea_sdk.ListOptions{
 | 
				
			||||||
			Page:     int(page),
 | 
								Page:     int(page),
 | 
				
			||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ const (
 | 
				
			|||||||
var (
 | 
					var (
 | 
				
			||||||
	CreateRepoTool = mcp.NewTool(
 | 
						CreateRepoTool = mcp.NewTool(
 | 
				
			||||||
		CreateRepoToolName,
 | 
							CreateRepoToolName,
 | 
				
			||||||
		mcp.WithDescription("Create repository"),
 | 
							mcp.WithDescription("Create repository in personal account or organization"),
 | 
				
			||||||
		mcp.WithString("name", mcp.Required(), mcp.Description("Name of the repository to create")),
 | 
							mcp.WithString("name", mcp.Required(), mcp.Description("Name of the repository to create")),
 | 
				
			||||||
		mcp.WithString("description", mcp.Description("Description of the repository to create")),
 | 
							mcp.WithString("description", mcp.Description("Description of the repository to create")),
 | 
				
			||||||
		mcp.WithBoolean("private", mcp.Description("Whether the repository is private")),
 | 
							mcp.WithBoolean("private", mcp.Description("Whether the repository is private")),
 | 
				
			||||||
@@ -38,6 +38,7 @@ var (
 | 
				
			|||||||
		mcp.WithString("license", mcp.Description("License to use")),
 | 
							mcp.WithString("license", mcp.Description("License to use")),
 | 
				
			||||||
		mcp.WithString("readme", mcp.Description("Readme of the repository to create")),
 | 
							mcp.WithString("readme", mcp.Description("Readme of the repository to create")),
 | 
				
			||||||
		mcp.WithString("default_branch", mcp.Description("DefaultBranch of the repository (used when initializes and in template)")),
 | 
							mcp.WithString("default_branch", mcp.Description("DefaultBranch of the repository (used when initializes and in template)")),
 | 
				
			||||||
 | 
							mcp.WithString("organization", mcp.Description("Organization name to create repository in (optional - defaults to personal account)")),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ForkRepoTool = mcp.NewTool(
 | 
						ForkRepoTool = mcp.NewTool(
 | 
				
			||||||
@@ -120,6 +121,7 @@ func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
 | 
				
			|||||||
	license, _ := req.GetArguments()["license"].(string)
 | 
						license, _ := req.GetArguments()["license"].(string)
 | 
				
			||||||
	readme, _ := req.GetArguments()["readme"].(string)
 | 
						readme, _ := req.GetArguments()["readme"].(string)
 | 
				
			||||||
	defaultBranch, _ := req.GetArguments()["default_branch"].(string)
 | 
						defaultBranch, _ := req.GetArguments()["default_branch"].(string)
 | 
				
			||||||
 | 
						organization, _ := req.GetArguments()["organization"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opt := gitea_sdk.CreateRepoOption{
 | 
						opt := gitea_sdk.CreateRepoOption{
 | 
				
			||||||
		Name:          name,
 | 
							Name:          name,
 | 
				
			||||||
@@ -133,9 +135,22 @@ func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
 | 
				
			|||||||
		Readme:        readme,
 | 
							Readme:        readme,
 | 
				
			||||||
		DefaultBranch: defaultBranch,
 | 
							DefaultBranch: defaultBranch,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	repo, _, err := gitea.Client().CreateRepo(opt)
 | 
					
 | 
				
			||||||
 | 
						var repo *gitea_sdk.Repository
 | 
				
			||||||
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("create repo err: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if organization != "" {
 | 
				
			||||||
 | 
							repo, _, err = client.CreateOrgRepo(organization, opt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return to.ErrorResult(fmt.Errorf("create organization repository '%s' in '%s' err: %v", name, organization, err))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							repo, _, err = client.CreateRepo(opt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return to.ErrorResult(fmt.Errorf("create repository '%s' err: %v", name, err))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return to.TextResult(repo)
 | 
						return to.TextResult(repo)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -164,7 +179,11 @@ func ForkRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
 | 
				
			|||||||
		Organization: organizationPtr,
 | 
							Organization: organizationPtr,
 | 
				
			||||||
		Name:         namePtr,
 | 
							Name:         namePtr,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, _, err := gitea.Client().CreateFork(user, repo, opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, _, err = client.CreateFork(user, repo, opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("fork repository error: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("fork repository error: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -187,7 +206,11 @@ func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
 | 
				
			|||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	repos, _, err := gitea.Client().ListMyRepos(opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						repos, _, err := client.ListMyRepos(opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return to.ErrorResult(fmt.Errorf("list my repositories error: %v", err))
 | 
							return to.ErrorResult(fmt.Errorf("list my repositories error: %v", err))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,7 +102,11 @@ func CreateTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
 | 
				
			|||||||
	target, _ := req.GetArguments()["target"].(string)
 | 
						target, _ := req.GetArguments()["target"].(string)
 | 
				
			||||||
	message, _ := req.GetArguments()["message"].(string)
 | 
						message, _ := req.GetArguments()["message"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, _, err := gitea.Client().CreateTag(owner, repo, gitea_sdk.CreateTagOption{
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, _, err = client.CreateTag(owner, repo, gitea_sdk.CreateTagOption{
 | 
				
			||||||
		TagName: tagName,
 | 
							TagName: tagName,
 | 
				
			||||||
		Target:  target,
 | 
							Target:  target,
 | 
				
			||||||
		Message: message,
 | 
							Message: message,
 | 
				
			||||||
@@ -129,7 +133,11 @@ func DeleteTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
 | 
				
			|||||||
		return nil, fmt.Errorf("tag_name is required")
 | 
							return nil, fmt.Errorf("tag_name is required")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := gitea.Client().DeleteTag(owner, repo, tagName)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = client.DeleteTag(owner, repo, tagName)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("delete tag error: %v", err)
 | 
							return nil, fmt.Errorf("delete tag error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -152,7 +160,11 @@ func GetTagFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult
 | 
				
			|||||||
		return nil, fmt.Errorf("tag_name is required")
 | 
							return nil, fmt.Errorf("tag_name is required")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tag, _, err := gitea.Client().GetTag(owner, repo, tagName)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tag, _, err := client.GetTag(owner, repo, tagName)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("get tag error: %v", err)
 | 
							return nil, fmt.Errorf("get tag error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -173,7 +185,11 @@ func ListTagsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
 | 
				
			|||||||
	page, _ := req.GetArguments()["page"].(float64)
 | 
						page, _ := req.GetArguments()["page"].(float64)
 | 
				
			||||||
	pageSize, _ := req.GetArguments()["pageSize"].(float64)
 | 
						pageSize, _ := req.GetArguments()["pageSize"].(float64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tags, _, err := gitea.Client().ListRepoTags(owner, repo, gitea_sdk.ListRepoTagsOptions{
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tags, _, err := client.ListRepoTags(owner, repo, gitea_sdk.ListRepoTagsOptions{
 | 
				
			||||||
		ListOptions: gitea_sdk.ListOptions{
 | 
							ListOptions: gitea_sdk.ListOptions{
 | 
				
			||||||
			Page:     int(page),
 | 
								Page:     int(page),
 | 
				
			||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -94,7 +94,11 @@ func SearchUsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
 | 
				
			|||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	users, _, err := gitea.Client().SearchUsers(opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						users, _, err := client.SearchUsers(opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -128,7 +132,11 @@ func SearchOrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
 | 
				
			|||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	teams, _, err := gitea.Client().SearchOrgTeams(org, &opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						teams, _, err := client.SearchOrgTeams(org, &opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -178,7 +186,11 @@ func SearchReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
 | 
				
			|||||||
			PageSize: int(pageSize),
 | 
								PageSize: int(pageSize),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	repos, _, err := gitea.Client().SearchRepos(opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						repos, _, err := client.SearchRepos(opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,7 +79,11 @@ func getIntArg(req mcp.CallToolRequest, name string, def int) int {
 | 
				
			|||||||
// 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) {
 | 
				
			||||||
	log.Debugf("[User] Called GetUserInfoFn")
 | 
						log.Debugf("[User] Called GetUserInfoFn")
 | 
				
			||||||
	user, _, err := gitea.Client().GetMyUserInfo()
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						user, _, err := client.GetMyUserInfo()
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -100,7 +104,11 @@ func GetUserOrgsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
 | 
				
			|||||||
			PageSize: pageSize,
 | 
								PageSize: pageSize,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	orgs, _, err := gitea.Client().ListMyOrgs(opt)
 | 
						client, err := gitea.ClientFromContext(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						orgs, _, err := client.ListMyOrgs(opt)
 | 
				
			||||||
	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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								pkg/context/context.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkg/context/context.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type contextKey string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TokenContextKey = contextKey("token")
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -1,52 +1,47 @@
 | 
				
			|||||||
package gitea
 | 
					package gitea
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"crypto/tls"
 | 
						"crypto/tls"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"gitea.com/gitea/gitea-mcp/pkg/flag"
 | 
					 | 
				
			||||||
	"gitea.com/gitea/gitea-mcp/pkg/log"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/sdk/gitea"
 | 
						"code.gitea.io/sdk/gitea"
 | 
				
			||||||
 | 
						mcpContext "gitea.com/gitea/gitea-mcp/pkg/context"
 | 
				
			||||||
 | 
						"gitea.com/gitea/gitea-mcp/pkg/flag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					func NewClient(token string) (*gitea.Client, error) {
 | 
				
			||||||
	client     *gitea.Client
 | 
						httpClient := &http.Client{
 | 
				
			||||||
	clientOnce sync.Once
 | 
							Transport: http.DefaultTransport,
 | 
				
			||||||
)
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Client() *gitea.Client {
 | 
						opts := []gitea.ClientOption{
 | 
				
			||||||
	clientOnce.Do(func() {
 | 
							gitea.SetToken(token),
 | 
				
			||||||
		var err error
 | 
						}
 | 
				
			||||||
		if client != nil {
 | 
						if flag.Insecure {
 | 
				
			||||||
			return
 | 
							httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{
 | 
				
			||||||
 | 
								InsecureSkipVerify: true,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opts = append(opts, gitea.SetHTTPClient(httpClient))
 | 
				
			||||||
 | 
						if flag.Debug {
 | 
				
			||||||
 | 
							opts = append(opts, gitea.SetDebugMode())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						client, err := gitea.NewClient(flag.Host, opts...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("create gitea client err: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		httpClient := &http.Client{
 | 
						// Set user agent for the client
 | 
				
			||||||
			Transport: http.DefaultTransport,
 | 
						client.SetUserAgent(fmt.Sprintf("gitea-mcp-server/%s", flag.Version))
 | 
				
			||||||
		}
 | 
						return client, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		opts := []gitea.ClientOption{
 | 
					
 | 
				
			||||||
			gitea.SetToken(flag.Token),
 | 
					func ClientFromContext(ctx context.Context) (*gitea.Client, error) {
 | 
				
			||||||
		}
 | 
						token, ok := ctx.Value(mcpContext.TokenContextKey).(string)
 | 
				
			||||||
		if flag.Insecure {
 | 
						if !ok {
 | 
				
			||||||
			httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{
 | 
							token = flag.Token
 | 
				
			||||||
				InsecureSkipVerify: true,
 | 
						}
 | 
				
			||||||
			}
 | 
						return NewClient(token)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		opts = append(opts, gitea.SetHTTPClient(httpClient))
 | 
					 | 
				
			||||||
		if flag.Debug {
 | 
					 | 
				
			||||||
			opts = append(opts, gitea.SetDebugMode())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		client, err = gitea.NewClient(flag.Host, opts...)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			log.Fatalf("create gitea client err: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Set user agent for the client
 | 
					 | 
				
			||||||
		client.SetUserAgent(fmt.Sprintf("gitea-mcp-server/%s", flag.Version))
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	return client
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user