mirror of
https://gitea.com/gitea/gitea-mcp.git
synced 2025-08-24 06:43:05 +00:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
592cf51c9b | ||
|
2a9504fc5d | ||
|
2f17f37053 | ||
|
5270d2eb08 | ||
|
97b98c3fc2 | ||
|
58328680a6 | ||
|
28947a030e | ||
|
d48e233fba | ||
|
0e225f21da | ||
|
b9e575ad64 | ||
|
8395957553 | ||
|
0aa33e0d62 | ||
|
7d2a0985a3 | ||
|
6f86512a7d |
20
README.md
20
README.md
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
**Gitea MCP Server** is an integration plugin designed to connect Gitea with Model Context Protocol (MCP) systems. This allows for seamless command execution and repository management through an MCP-compatible chat interface.
|
**Gitea MCP Server** is an integration plugin designed to connect Gitea with Model Context Protocol (MCP) systems. This allows for seamless command execution and repository management through an MCP-compatible chat interface.
|
||||||
|
|
||||||
## 🚧 Installation
|
## 🚧Installation
|
||||||
|
|
||||||
There is currently no official release. You will need to build the Gitea MCP Server from source.
|
### 📥Download the official binary release
|
||||||
|
|
||||||
### 🔧 Build from Source
|
You can download the official release from [here](https://gitea.com/gitea/gitea-mcp/releases).
|
||||||
|
|
||||||
|
### 🔧Build from Source
|
||||||
|
|
||||||
You can download the source code by cloning the repository using Git:
|
You can download the source code by cloning the repository using Git:
|
||||||
|
|
||||||
@@ -25,7 +27,7 @@ Then run:
|
|||||||
make build
|
make build
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🛠️ Add to PATH
|
### 📁Add to PATH
|
||||||
|
|
||||||
After building, copy the binary gitea-mcp to a directory included in your system's PATH. For example:
|
After building, copy the binary gitea-mcp to a directory included in your system's PATH. For example:
|
||||||
|
|
||||||
@@ -33,12 +35,13 @@ After building, copy the binary gitea-mcp to a directory included in your system
|
|||||||
cp gitea-mcp /usr/local/bin/
|
cp gitea-mcp /usr/local/bin/
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 Usage
|
## 🚀Usage
|
||||||
|
|
||||||
This example is for Cursor, you can also use plugins in VSCode.
|
This example is for Cursor, you can also use plugins in VSCode.
|
||||||
To configure the MCP server for Gitea, add the following to your MCP configuration file:
|
To configure the MCP server for Gitea, add the following to your MCP configuration file:
|
||||||
|
|
||||||
- **stdio mode**
|
- **stdio mode**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
@@ -59,6 +62,7 @@ To configure the MCP server for Gitea, add the following to your MCP configurati
|
|||||||
```
|
```
|
||||||
|
|
||||||
- **sse mode**
|
- **sse mode**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
@@ -93,7 +97,7 @@ The Gitea MCP Server supports the following tools:
|
|||||||
|delete_branch|Branch|Delete a branch|
|
|delete_branch|Branch|Delete a branch|
|
||||||
|list_branches|Branch|List all branches in a repository|
|
|list_branches|Branch|List all branches in a repository|
|
||||||
|list_repo_commits|Commit|List all commits in a repository|
|
|list_repo_commits|Commit|List all commits in a repository|
|
||||||
|get_file|File|Get the content of a file|
|
|get_file_content|File|Get the content and metadata of a file|
|
||||||
|create_file|File|Create a new file|
|
|create_file|File|Create a new file|
|
||||||
|update_file|File|Update an existing file|
|
|update_file|File|Update an existing file|
|
||||||
|delete_file|File|Delete a file|
|
|delete_file|File|Delete a file|
|
||||||
@@ -109,10 +113,10 @@ The Gitea MCP Server supports the following tools:
|
|||||||
|search_repos|Repository|Search for repositories|
|
|search_repos|Repository|Search for repositories|
|
||||||
|get_gitea_mcp_server_version|Server|Get the version of the Gitea MCP Server|
|
|get_gitea_mcp_server_version|Server|Get the version of the Gitea MCP Server|
|
||||||
|
|
||||||
|
## 🐛Debugging
|
||||||
## 🐛 Debugging
|
|
||||||
|
|
||||||
To enable debug mode, add the `-d` flag when running the Gitea MCP Server with sse mode:
|
To enable debug mode, add the `-d` flag when running the Gitea MCP Server with sse mode:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./gitea-mcp -t sse --token <your personal access token> -d
|
./gitea-mcp -t sse --token <your personal access token> -d
|
||||||
```
|
```
|
||||||
|
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ go 1.24.0
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
code.gitea.io/sdk/gitea v0.20.0
|
code.gitea.io/sdk/gitea v0.20.0
|
||||||
github.com/mark3labs/mcp-go v0.15.0
|
github.com/mark3labs/mcp-go v0.17.0
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
2
go.sum
2
go.sum
@@ -14,6 +14,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe
|
|||||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/mark3labs/mcp-go v0.15.0 h1:lViiC4dk6chJHZccezaTzZLMOQVUXJDGNQPtzExr5NQ=
|
github.com/mark3labs/mcp-go v0.15.0 h1:lViiC4dk6chJHZccezaTzZLMOQVUXJDGNQPtzExr5NQ=
|
||||||
github.com/mark3labs/mcp-go v0.15.0/go.mod h1:xBB350hekQsJAK7gJAii8bcEoWemboLm2mRm5/+KBaU=
|
github.com/mark3labs/mcp-go v0.15.0/go.mod h1:xBB350hekQsJAK7gJAii8bcEoWemboLm2mRm5/+KBaU=
|
||||||
|
github.com/mark3labs/mcp-go v0.17.0 h1:5Ps6T7qXr7De/2QTqs9h6BKeZ/qdeUeGrgM5lPzi930=
|
||||||
|
github.com/mark3labs/mcp-go v0.17.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
@@ -68,19 +68,19 @@ func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
log.Debugf("Called GetIssueByIndexFn")
|
log.Debugf("Called GetIssueByIndexFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
index, ok := req.Params.Arguments["index"].(float64)
|
index, ok := req.Params.Arguments["index"].(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("index is required")
|
return to.ErrorResult(fmt.Errorf("index is required"))
|
||||||
}
|
}
|
||||||
issue, _, err := gitea.Client().GetIssue(owner, repo, int64(index))
|
issue, _, err := gitea.Client().GetIssue(owner, repo, int64(index))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get %v/%v/issue/%v err", owner, repo, int64(index))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issue)
|
return to.TextResult(issue)
|
||||||
@@ -90,11 +90,11 @@ func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
log.Debugf("Called ListIssuesFn")
|
log.Debugf("Called ListIssuesFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
state, ok := req.Params.Arguments["state"].(string)
|
state, ok := req.Params.Arguments["state"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -117,7 +117,7 @@ func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
}
|
}
|
||||||
issues, _, err := gitea.Client().ListRepoIssues(owner, repo, opt)
|
issues, _, err := gitea.Client().ListRepoIssues(owner, repo, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get %v/%v/issues err", owner, repo)
|
return to.ErrorResult(fmt.Errorf("get %v/%v/issues err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
return to.TextResult(issues)
|
return to.TextResult(issues)
|
||||||
}
|
}
|
||||||
@@ -126,26 +126,26 @@ func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
log.Debugf("Called CreateIssueFn")
|
log.Debugf("Called CreateIssueFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
title, ok := req.Params.Arguments["title"].(string)
|
title, ok := req.Params.Arguments["title"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("title is required")
|
return to.ErrorResult(fmt.Errorf("title is required"))
|
||||||
}
|
}
|
||||||
body, ok := req.Params.Arguments["body"].(string)
|
body, ok := req.Params.Arguments["body"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("body is required")
|
return to.ErrorResult(fmt.Errorf("body is required"))
|
||||||
}
|
}
|
||||||
issue, _, err := gitea.Client().CreateIssue(owner, repo, gitea_sdk.CreateIssueOption{
|
issue, _, err := gitea.Client().CreateIssue(owner, repo, gitea_sdk.CreateIssueOption{
|
||||||
Title: title,
|
Title: title,
|
||||||
Body: body,
|
Body: body,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create %v/%v/issue err", owner, repo)
|
return to.ErrorResult(fmt.Errorf("create %v/%v/issue err", owner, repo))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issue)
|
return to.TextResult(issue)
|
||||||
@@ -155,26 +155,26 @@ func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
log.Debugf("Called CreateIssueCommentFn")
|
log.Debugf("Called CreateIssueCommentFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
index, ok := req.Params.Arguments["index"].(float64)
|
index, ok := req.Params.Arguments["index"].(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("index is required")
|
return to.ErrorResult(fmt.Errorf("index is required"))
|
||||||
}
|
}
|
||||||
body, ok := req.Params.Arguments["body"].(string)
|
body, ok := req.Params.Arguments["body"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("body is required")
|
return to.ErrorResult(fmt.Errorf("body is required"))
|
||||||
}
|
}
|
||||||
opt := gitea_sdk.CreateIssueCommentOption{
|
opt := gitea_sdk.CreateIssueCommentOption{
|
||||||
Body: body,
|
Body: body,
|
||||||
}
|
}
|
||||||
issueComment, _, err := gitea.Client().CreateIssueComment(owner, repo, int64(index), opt)
|
issueComment, _, err := gitea.Client().CreateIssueComment(owner, repo, int64(index), opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create %v/%v/issue/%v/comment err", owner, repo, int64(index))
|
return to.ErrorResult(fmt.Errorf("create %v/%v/issue/%v/comment err", owner, repo, int64(index)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(issueComment)
|
return to.TextResult(issueComment)
|
||||||
|
@@ -33,9 +33,11 @@ var (
|
|||||||
mcp.WithDescription("List repository pull requests"),
|
mcp.WithDescription("List repository pull requests"),
|
||||||
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.WithString("state", mcp.Description("state")),
|
mcp.WithString("state", mcp.Description("state"), mcp.Enum("open", "closed", "all"), mcp.DefaultString("all")),
|
||||||
mcp.WithString("sort", mcp.Description("sort")),
|
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("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
||||||
)
|
)
|
||||||
|
|
||||||
CreatePullRequestTool = mcp.NewTool(
|
CreatePullRequestTool = mcp.NewTool(
|
||||||
@@ -60,19 +62,19 @@ func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
log.Debugf("Called GetPullRequestByIndexFn")
|
log.Debugf("Called GetPullRequestByIndexFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
index, ok := req.Params.Arguments["index"].(float64)
|
index, ok := req.Params.Arguments["index"].(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("index is required")
|
return to.ErrorResult(fmt.Errorf("index is required"))
|
||||||
}
|
}
|
||||||
pr, _, err := gitea.Client().GetPullRequest(owner, repo, int64(index))
|
pr, _, err := gitea.Client().GetPullRequest(owner, repo, int64(index))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get %v/%v/pr/%v err", owner, repo, int64(index))
|
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v err: %v", owner, repo, int64(index), err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(pr)
|
return to.TextResult(pr)
|
||||||
@@ -82,27 +84,38 @@ func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|||||||
log.Debugf("Called ListRepoPullRequests")
|
log.Debugf("Called ListRepoPullRequests")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
state, _ := req.Params.Arguments["state"].(string)
|
state, _ := req.Params.Arguments["state"].(string)
|
||||||
sort, _ := req.Params.Arguments["sort"].(string)
|
sort, ok := req.Params.Arguments["sort"].(string)
|
||||||
|
if !ok {
|
||||||
|
sort = "recentupdate"
|
||||||
|
}
|
||||||
milestone, _ := req.Params.Arguments["milestone"].(float64)
|
milestone, _ := req.Params.Arguments["milestone"].(float64)
|
||||||
|
page, ok := req.Params.Arguments["page"].(float64)
|
||||||
|
if !ok {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
pageSize, ok := req.Params.Arguments["pageSize"].(float64)
|
||||||
|
if !ok {
|
||||||
|
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: int64(milestone),
|
Milestone: int64(milestone),
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: 1,
|
Page: int(page),
|
||||||
PageSize: 1000,
|
PageSize: int(pageSize),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pullRequests, _, err := gitea.Client().ListRepoPullRequests("", "", opt)
|
pullRequests, _, err := gitea.Client().ListRepoPullRequests(owner, repo, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("list %v/%v/pull_requests err", owner, repo)
|
return to.ErrorResult(fmt.Errorf("list %v/%v/pull_requests err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(pullRequests)
|
return to.TextResult(pullRequests)
|
||||||
@@ -112,27 +125,27 @@ func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
|
|||||||
log.Debugf("Called CreatePullRequestFn")
|
log.Debugf("Called CreatePullRequestFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
title, ok := req.Params.Arguments["title"].(string)
|
title, ok := req.Params.Arguments["title"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("title is required")
|
return to.ErrorResult(fmt.Errorf("title is required"))
|
||||||
}
|
}
|
||||||
body, ok := req.Params.Arguments["body"].(string)
|
body, ok := req.Params.Arguments["body"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("body is required")
|
return to.ErrorResult(fmt.Errorf("body is required"))
|
||||||
}
|
}
|
||||||
head, ok := req.Params.Arguments["head"].(string)
|
head, ok := req.Params.Arguments["head"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("head is required")
|
return to.ErrorResult(fmt.Errorf("head is required"))
|
||||||
}
|
}
|
||||||
base, ok := req.Params.Arguments["base"].(string)
|
base, ok := req.Params.Arguments["base"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("base is required")
|
return to.ErrorResult(fmt.Errorf("base is required"))
|
||||||
}
|
}
|
||||||
pr, _, err := gitea.Client().CreatePullRequest(owner, repo, gitea_sdk.CreatePullRequestOption{
|
pr, _, err := gitea.Client().CreatePullRequest(owner, repo, gitea_sdk.CreatePullRequestOption{
|
||||||
Title: title,
|
Title: title,
|
||||||
@@ -141,7 +154,7 @@ func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
|
|||||||
Base: base,
|
Base: base,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create %v/%v/pull_request err", owner, repo)
|
return to.ErrorResult(fmt.Errorf("create %v/%v/pull_request err: %v", owner, repo, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(pr)
|
return to.TextResult(pr)
|
||||||
|
@@ -48,15 +48,15 @@ func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
log.Debugf("Called CreateBranchFn")
|
log.Debugf("Called CreateBranchFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
branch, ok := req.Params.Arguments["branch"].(string)
|
branch, ok := req.Params.Arguments["branch"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("branch is required")
|
return to.ErrorResult(fmt.Errorf("branch is required"))
|
||||||
}
|
}
|
||||||
oldBranch, _ := req.Params.Arguments["old_branch"].(string)
|
oldBranch, _ := req.Params.Arguments["old_branch"].(string)
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
OldBranchName: oldBranch,
|
OldBranchName: oldBranch,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Create Branch Error: %v", err)
|
return to.ErrorResult(fmt.Errorf("create branch error: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return mcp.NewToolResultText("Branch Created"), nil
|
return mcp.NewToolResultText("Branch Created"), nil
|
||||||
@@ -75,19 +75,19 @@ func DeleteBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
log.Debugf("Called DeleteBranchFn")
|
log.Debugf("Called DeleteBranchFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
branch, ok := req.Params.Arguments["branch"].(string)
|
branch, ok := req.Params.Arguments["branch"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("branch is required")
|
return to.ErrorResult(fmt.Errorf("branch is required"))
|
||||||
}
|
}
|
||||||
_, _, err := gitea.Client().DeleteRepoBranch(owner, repo, branch)
|
_, _, err := gitea.Client().DeleteRepoBranch(owner, repo, branch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Delete Branch Error: %v", err)
|
return to.ErrorResult(fmt.Errorf("delete branch error: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult("Branch Deleted")
|
return to.TextResult("Branch Deleted")
|
||||||
@@ -97,11 +97,11 @@ func ListBranchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
log.Debugf("Called ListBranchesFn")
|
log.Debugf("Called ListBranchesFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
opt := gitea_sdk.ListRepoBranchesOptions{
|
opt := gitea_sdk.ListRepoBranchesOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
@@ -111,7 +111,7 @@ func ListBranchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
}
|
}
|
||||||
branches, _, err := gitea.Client().ListRepoBranches(owner, repo, opt)
|
branches, _, err := gitea.Client().ListRepoBranches(owner, repo, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("List Branches Error: %v", err)
|
return to.ErrorResult(fmt.Errorf("list branches error: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return to.TextResult(branches)
|
return to.TextResult(branches)
|
||||||
|
@@ -22,8 +22,10 @@ var (
|
|||||||
mcp.WithDescription("List repository commits"),
|
mcp.WithDescription("List repository commits"),
|
||||||
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.WithString("sha", mcp.Description("sha")),
|
mcp.WithString("sha", mcp.Description("SHA or branch to start listing commits from")),
|
||||||
mcp.WithString("path", mcp.Description("path")),
|
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_size", mcp.Required(), mcp.Description("page size"), mcp.DefaultNumber(50), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,25 +33,33 @@ func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
log.Debugf("Called ListRepoCommitsFn")
|
log.Debugf("Called ListRepoCommitsFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
|
}
|
||||||
|
page, ok := req.Params.Arguments["page"].(float64)
|
||||||
|
if !ok {
|
||||||
|
return to.ErrorResult(fmt.Errorf("page is required"))
|
||||||
|
}
|
||||||
|
pageSize, ok := req.Params.Arguments["page_size"].(float64)
|
||||||
|
if !ok {
|
||||||
|
return to.ErrorResult(fmt.Errorf("page_size is required"))
|
||||||
}
|
}
|
||||||
sha, _ := req.Params.Arguments["sha"].(string)
|
sha, _ := req.Params.Arguments["sha"].(string)
|
||||||
path, _ := req.Params.Arguments["path"].(string)
|
path, _ := req.Params.Arguments["path"].(string)
|
||||||
opt := gitea_sdk.ListCommitOptions{
|
opt := gitea_sdk.ListCommitOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: 1,
|
Page: int(page),
|
||||||
PageSize: 1000,
|
PageSize: int(pageSize),
|
||||||
},
|
},
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
Path: path,
|
Path: path,
|
||||||
}
|
}
|
||||||
commits, _, err := gitea.Client().ListRepoCommits(owner, repo, opt)
|
commits, _, err := gitea.Client().ListRepoCommits(owner, repo, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 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(commits)
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
@@ -13,19 +14,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GetFileToolName = "get_file"
|
GetFileToolName = "get_file_content"
|
||||||
CreateFileToolName = "create_file"
|
CreateFileToolName = "create_file"
|
||||||
UpdateFileToolName = "update_file"
|
UpdateFileToolName = "update_file"
|
||||||
DeleteFileToolName = "delete_file"
|
DeleteFileToolName = "delete_file"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
GetFileTool = mcp.NewTool(
|
GetFileContentTool = mcp.NewTool(
|
||||||
GetFileToolName,
|
GetFileToolName,
|
||||||
mcp.WithDescription("Get file"),
|
mcp.WithDescription("Get file Content and Metadata"),
|
||||||
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.WithString("ref", mcp.Required(), mcp.Description("ref")),
|
mcp.WithString("ref", mcp.Required(), mcp.Description("ref can be branch/tag/commit")),
|
||||||
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -47,7 +48,8 @@ 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.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
||||||
mcp.WithString("content", mcp.Required(), mcp.Description("file content")),
|
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("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")),
|
||||||
)
|
)
|
||||||
@@ -64,47 +66,47 @@ var (
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetFileFn(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.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
ref, _ := req.Params.Arguments["ref"].(string)
|
ref, _ := req.Params.Arguments["ref"].(string)
|
||||||
filePath, ok := req.Params.Arguments["filePath"].(string)
|
filePath, ok := req.Params.Arguments["filePath"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("filePath is required")
|
return to.ErrorResult(fmt.Errorf("filePath is required"))
|
||||||
}
|
}
|
||||||
file, _, err := gitea.Client().GetFile(owner, repo, ref, filePath)
|
content, _, err := gitea.Client().GetContents(owner, repo, ref, filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get file err: %v", err)
|
return to.ErrorResult(fmt.Errorf("get file err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(file)
|
return to.TextResult(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.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
filePath, ok := req.Params.Arguments["filePath"].(string)
|
filePath, ok := req.Params.Arguments["filePath"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("filePath is required")
|
return to.ErrorResult(fmt.Errorf("filePath is required"))
|
||||||
}
|
}
|
||||||
content, _ := req.Params.Arguments["content"].(string)
|
content, _ := req.Params.Arguments["content"].(string)
|
||||||
message, _ := req.Params.Arguments["message"].(string)
|
message, _ := req.Params.Arguments["message"].(string)
|
||||||
branchName, _ := req.Params.Arguments["branch_name"].(string)
|
branchName, _ := req.Params.Arguments["branch_name"].(string)
|
||||||
opt := gitea_sdk.CreateFileOptions{
|
opt := gitea_sdk.CreateFileOptions{
|
||||||
Content: content,
|
Content: base64.StdEncoding.EncodeToString([]byte(content)),
|
||||||
FileOptions: gitea_sdk.FileOptions{
|
FileOptions: gitea_sdk.FileOptions{
|
||||||
Message: message,
|
Message: message,
|
||||||
BranchName: branchName,
|
BranchName: branchName,
|
||||||
@@ -113,7 +115,7 @@ func CreateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
|
|
||||||
_, _, err := gitea.Client().CreateFile(owner, repo, filePath, opt)
|
_, _, err := gitea.Client().CreateFile(owner, repo, filePath, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create file err: %v", err)
|
return to.ErrorResult(fmt.Errorf("create file err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult("Create file success")
|
return to.TextResult("Create file success")
|
||||||
}
|
}
|
||||||
@@ -122,20 +124,26 @@ func UpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
log.Debugf("Called UpdateFileFn")
|
log.Debugf("Called UpdateFileFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
filePath, ok := req.Params.Arguments["filePath"].(string)
|
filePath, ok := req.Params.Arguments["filePath"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("filePath is required")
|
return to.ErrorResult(fmt.Errorf("filePath is required"))
|
||||||
|
}
|
||||||
|
sha, ok := req.Params.Arguments["sha"].(string)
|
||||||
|
if !ok {
|
||||||
|
return to.ErrorResult(fmt.Errorf("sha is required"))
|
||||||
}
|
}
|
||||||
content, _ := req.Params.Arguments["content"].(string)
|
content, _ := req.Params.Arguments["content"].(string)
|
||||||
message, _ := req.Params.Arguments["message"].(string)
|
message, _ := req.Params.Arguments["message"].(string)
|
||||||
branchName, _ := req.Params.Arguments["branch_name"].(string)
|
branchName, _ := req.Params.Arguments["branch_name"].(string)
|
||||||
|
|
||||||
opt := gitea_sdk.UpdateFileOptions{
|
opt := gitea_sdk.UpdateFileOptions{
|
||||||
|
SHA: sha,
|
||||||
Content: content,
|
Content: content,
|
||||||
FileOptions: gitea_sdk.FileOptions{
|
FileOptions: gitea_sdk.FileOptions{
|
||||||
Message: message,
|
Message: message,
|
||||||
@@ -144,7 +152,7 @@ func UpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
}
|
}
|
||||||
_, _, err := gitea.Client().UpdateFile(owner, repo, filePath, opt)
|
_, _, err := gitea.Client().UpdateFile(owner, repo, filePath, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("update file err: %v", err)
|
return to.ErrorResult(fmt.Errorf("update file err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult("Update file success")
|
return to.TextResult("Update file success")
|
||||||
}
|
}
|
||||||
@@ -153,27 +161,32 @@ func DeleteFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
log.Debugf("Called DeleteFileFn")
|
log.Debugf("Called DeleteFileFn")
|
||||||
owner, ok := req.Params.Arguments["owner"].(string)
|
owner, ok := req.Params.Arguments["owner"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("owner is required")
|
return to.ErrorResult(fmt.Errorf("owner is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("repo is required")
|
return to.ErrorResult(fmt.Errorf("repo is required"))
|
||||||
}
|
}
|
||||||
filePath, ok := req.Params.Arguments["filePath"].(string)
|
filePath, ok := req.Params.Arguments["filePath"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("filePath is required")
|
return to.ErrorResult(fmt.Errorf("filePath is required"))
|
||||||
}
|
}
|
||||||
message, _ := req.Params.Arguments["message"].(string)
|
message, _ := req.Params.Arguments["message"].(string)
|
||||||
branchName, _ := req.Params.Arguments["branch_name"].(string)
|
branchName, _ := req.Params.Arguments["branch_name"].(string)
|
||||||
|
sha, ok := req.Params.Arguments["sha"].(string)
|
||||||
|
if !ok {
|
||||||
|
return to.ErrorResult(fmt.Errorf("sha is required"))
|
||||||
|
}
|
||||||
opt := gitea_sdk.DeleteFileOptions{
|
opt := gitea_sdk.DeleteFileOptions{
|
||||||
FileOptions: gitea_sdk.FileOptions{
|
FileOptions: gitea_sdk.FileOptions{
|
||||||
Message: message,
|
Message: message,
|
||||||
BranchName: branchName,
|
BranchName: branchName,
|
||||||
},
|
},
|
||||||
|
SHA: sha,
|
||||||
}
|
}
|
||||||
_, err := gitea.Client().DeleteFile(owner, repo, filePath, opt)
|
_, err := gitea.Client().DeleteFile(owner, repo, filePath, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("delete file err: %v", err)
|
return to.ErrorResult(fmt.Errorf("delete file err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult("Delete file success")
|
return to.TextResult("Delete file success")
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,7 @@ func RegisterTool(s *server.MCPServer) {
|
|||||||
s.AddTool(ListMyReposTool, ListMyReposFn)
|
s.AddTool(ListMyReposTool, ListMyReposFn)
|
||||||
|
|
||||||
// File
|
// File
|
||||||
s.AddTool(GetFileTool, GetFileFn)
|
s.AddTool(GetFileContentTool, GetFileContentFn)
|
||||||
s.AddTool(CreateFileTool, CreateFileFn)
|
s.AddTool(CreateFileTool, CreateFileFn)
|
||||||
s.AddTool(UpdateFileTool, UpdateFileFn)
|
s.AddTool(UpdateFileTool, UpdateFileFn)
|
||||||
s.AddTool(DeleteFileTool, DeleteFileFn)
|
s.AddTool(DeleteFileTool, DeleteFileFn)
|
||||||
@@ -78,7 +78,7 @@ func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
log.Debugf("Called CreateRepoFn")
|
log.Debugf("Called CreateRepoFn")
|
||||||
name, ok := req.Params.Arguments["name"].(string)
|
name, ok := req.Params.Arguments["name"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("repository name is required")
|
return to.ErrorResult(errors.New("repository name is required"))
|
||||||
}
|
}
|
||||||
description, _ := req.Params.Arguments["description"].(string)
|
description, _ := req.Params.Arguments["description"].(string)
|
||||||
private, _ := req.Params.Arguments["private"].(bool)
|
private, _ := req.Params.Arguments["private"].(bool)
|
||||||
@@ -104,7 +104,7 @@ func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
}
|
}
|
||||||
repo, _, err := gitea.Client().CreateRepo(opt)
|
repo, _, err := gitea.Client().CreateRepo(opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return to.ErrorResult(fmt.Errorf("create repo err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(repo)
|
return to.TextResult(repo)
|
||||||
}
|
}
|
||||||
@@ -113,21 +113,29 @@ func ForkRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
|
|||||||
log.Debugf("Called ForkRepoFn")
|
log.Debugf("Called ForkRepoFn")
|
||||||
user, ok := req.Params.Arguments["user"].(string)
|
user, ok := req.Params.Arguments["user"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("user name is required")
|
return to.ErrorResult(errors.New("user name is required"))
|
||||||
}
|
}
|
||||||
repo, ok := req.Params.Arguments["repo"].(string)
|
repo, ok := req.Params.Arguments["repo"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("repository name is required")
|
return to.ErrorResult(errors.New("repository name is required"))
|
||||||
|
}
|
||||||
|
organization, ok := req.Params.Arguments["organization"].(string)
|
||||||
|
organizationPtr := ptr.To(organization)
|
||||||
|
if !ok || organization == "" {
|
||||||
|
organizationPtr = nil
|
||||||
|
}
|
||||||
|
name, ok := req.Params.Arguments["name"].(string)
|
||||||
|
namePtr := ptr.To(name)
|
||||||
|
if !ok || name == "" {
|
||||||
|
namePtr = nil
|
||||||
}
|
}
|
||||||
organization, _ := req.Params.Arguments["organization"].(string)
|
|
||||||
name, _ := req.Params.Arguments["name"].(string)
|
|
||||||
opt := gitea_sdk.CreateForkOption{
|
opt := gitea_sdk.CreateForkOption{
|
||||||
Organization: ptr.To(organization),
|
Organization: organizationPtr,
|
||||||
Name: ptr.To(name),
|
Name: namePtr,
|
||||||
}
|
}
|
||||||
_, _, err := gitea.Client().CreateFork(user, repo, opt)
|
_, _, err := gitea.Client().CreateFork(user, repo, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fork repository error %v", err)
|
return to.ErrorResult(fmt.Errorf("fork repository error %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult("Fork success")
|
return to.TextResult("Fork success")
|
||||||
}
|
}
|
||||||
@@ -136,21 +144,21 @@ func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
log.Debugf("Called ListMyReposFn")
|
log.Debugf("Called ListMyReposFn")
|
||||||
page, ok := req.Params.Arguments["page"].(float64)
|
page, ok := req.Params.Arguments["page"].(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("get page number error")
|
page = 1
|
||||||
}
|
}
|
||||||
size, ok := req.Params.Arguments["pageSize"].(float64)
|
pageSize, ok := req.Params.Arguments["pageSize"].(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("get page size number error")
|
pageSize = 100
|
||||||
}
|
}
|
||||||
opt := gitea_sdk.ListReposOptions{
|
opt := gitea_sdk.ListReposOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: int(page),
|
||||||
PageSize: int(size),
|
PageSize: int(pageSize),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
repos, _, err := gitea.Client().ListMyRepos(opt)
|
repos, _, err := gitea.Client().ListMyRepos(opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 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(repos)
|
||||||
|
@@ -65,7 +65,7 @@ func SearchUsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
log.Debugf("Called SearchUsersFn")
|
log.Debugf("Called SearchUsersFn")
|
||||||
keyword, ok := req.Params.Arguments["keyword"].(string)
|
keyword, ok := req.Params.Arguments["keyword"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("keyword is required")
|
return to.ErrorResult(fmt.Errorf("keyword is required"))
|
||||||
}
|
}
|
||||||
page, ok := req.Params.Arguments["page"].(float64)
|
page, ok := req.Params.Arguments["page"].(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -84,7 +84,7 @@ func SearchUsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
}
|
}
|
||||||
users, _, err := gitea.Client().SearchUsers(opt)
|
users, _, err := gitea.Client().SearchUsers(opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return to.ErrorResult(fmt.Errorf("search users err: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(users)
|
return to.TextResult(users)
|
||||||
}
|
}
|
||||||
@@ -93,11 +93,11 @@ func SearchOrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
log.Debugf("Called SearchOrgTeamsFn")
|
log.Debugf("Called SearchOrgTeamsFn")
|
||||||
org, ok := req.Params.Arguments["org"].(string)
|
org, ok := req.Params.Arguments["org"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("organization is required")
|
return to.ErrorResult(fmt.Errorf("organization is required"))
|
||||||
}
|
}
|
||||||
query, ok := req.Params.Arguments["query"].(string)
|
query, ok := req.Params.Arguments["query"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("query is required")
|
return to.ErrorResult(fmt.Errorf("query is required"))
|
||||||
}
|
}
|
||||||
includeDescription, _ := req.Params.Arguments["includeDescription"].(bool)
|
includeDescription, _ := req.Params.Arguments["includeDescription"].(bool)
|
||||||
page, ok := req.Params.Arguments["page"].(float64)
|
page, ok := req.Params.Arguments["page"].(float64)
|
||||||
@@ -118,7 +118,7 @@ func SearchOrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
}
|
}
|
||||||
teams, _, err := gitea.Client().SearchOrgTeams(org, &opt)
|
teams, _, err := gitea.Client().SearchOrgTeams(org, &opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 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(teams)
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ func SearchReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
log.Debugf("Called SearchReposFn")
|
log.Debugf("Called SearchReposFn")
|
||||||
keyword, ok := req.Params.Arguments["keyword"].(string)
|
keyword, ok := req.Params.Arguments["keyword"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("keyword is required")
|
return to.ErrorResult(fmt.Errorf("keyword is required"))
|
||||||
}
|
}
|
||||||
keywordIsTopic, _ := req.Params.Arguments["keywordIsTopic"].(bool)
|
keywordIsTopic, _ := req.Params.Arguments["keywordIsTopic"].(bool)
|
||||||
keywordInDescription, _ := req.Params.Arguments["keywordInDescription"].(bool)
|
keywordInDescription, _ := req.Params.Arguments["keywordInDescription"].(bool)
|
||||||
@@ -160,7 +160,7 @@ func SearchReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
}
|
}
|
||||||
repos, _, err := gitea.Client().SearchRepos(opt)
|
repos, _, err := gitea.Client().SearchRepos(opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("search repos error: %v", err)
|
return to.ErrorResult(fmt.Errorf("search repos error: %v", err))
|
||||||
}
|
}
|
||||||
return to.TextResult(repos)
|
return to.TextResult(repos)
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
|
|||||||
log.Debugf("Called GetUserInfoFn")
|
log.Debugf("Called GetUserInfoFn")
|
||||||
user, _, err := gitea.Client().GetMyUserInfo()
|
user, _, err := gitea.Client().GetMyUserInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 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(user)
|
||||||
|
@@ -21,3 +21,8 @@ func TextResult(v any) (*mcp.CallToolResult, error) {
|
|||||||
log.Debugf("Text Result: %s", string(resultBytes))
|
log.Debugf("Text Result: %s", string(resultBytes))
|
||||||
return mcp.NewToolResultText(string(resultBytes)), nil
|
return mcp.NewToolResultText(string(resultBytes)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ErrorResult(err error) (*mcp.CallToolResult, error) {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user