Support read only mode (#36) All checks were successful release-nightly / release-image (push) Successful in 2m51s
All checks were successful
release-nightly / release-image (push) Successful in 2m51s
Fix: #35 Reviewed-on: #36 Co-authored-by: hiifong <f@ilo.nz> Co-committed-by: hiifong <f@ilo.nz>
This commit was merged in pull request #36.
This commit is contained in:
@@ -20,6 +20,8 @@ RUN CGO_ENABLED=0 go build -ldflags="-s -w -X main.Version=${VERSION}" -o gitea- | ||||
# Final stage | ||||
FROM debian:bullseye-slim | ||||
| ||||
ENV GITEA_MODE stdio | ||||
| ||||
WORKDIR /app | ||||
| ||||
# Install ca-certificates for HTTPS requests | ||||
@@ -34,4 +36,4 @@ COPY --from=builder --chown=1000:1000 /app/gitea-mcp . | ||||
# Use the non-root user | ||||
USER gitea-mcp | ||||
| ||||
CMD ["/app/gitea-mcp", "-t", "stdio"] | ||||
CMD ["/app/gitea-mcp"] |
47 cmd/cmd.go
47
cmd/cmd.go @@ -11,23 +11,20 @@ import ( | ||||
) | ||||
| ||||
var ( | ||||
transport string | ||||
host string | ||||
port int | ||||
token string | ||||
| ||||
debug *bool | ||||
host string | ||||
port int | ||||
token string | ||||
) | ||||
| ||||
func init() { | ||||
flag.StringVar( | ||||
&transport, | ||||
&flagPkg.Mode, | ||||
"t", | ||||
"stdio", | ||||
"Transport type (stdio or sse)", | ||||
) | ||||
flag.StringVar( | ||||
&transport, | ||||
&flagPkg.Mode, | ||||
"transport", | ||||
"stdio", | ||||
"Transport type (stdio or sse)", | ||||
@@ -50,14 +47,17 @@ func init() { | ||||
"", | ||||
"Your personal access token", | ||||
) | ||||
flag.BoolFunc( | ||||
flag.BoolVar( | ||||
&flagPkg.ReadOnly, | ||||
"read-only", | ||||
false, | ||||
"Read-only mode", | ||||
) | ||||
flag.BoolVar( | ||||
&flagPkg.Debug, | ||||
"d", | ||||
false, | ||||
"debug mode (If -d flag is provided, debug mode will be enabled by default)", | ||||
func(string) error { | ||||
debug = new(bool) | ||||
*debug = true | ||||
return nil | ||||
}, | ||||
) | ||||
flag.BoolVar( | ||||
&flagPkg.Insecure, | ||||
@@ -80,13 +80,16 @@ func init() { | ||||
flagPkg.Token = os.Getenv("GITEA_ACCESS_TOKEN") | ||||
} | ||||
| ||||
flagPkg.Mode = transport | ||||
| ||||
if debug != nil && *debug { | ||||
flagPkg.Debug = *debug | ||||
if os.Getenv("GITEA_MODE") != "" { | ||||
flagPkg.Mode = os.Getenv("GITEA_MODE") | ||||
} | ||||
if debug != nil && !*debug { | ||||
flagPkg.Debug = os.Getenv("GITEA_DEBUG") == "true" | ||||
| ||||
if os.Getenv("GITEA_READONLY") == "true" { | ||||
flagPkg.ReadOnly = true | ||||
} | ||||
| ||||
if os.Getenv("GITEA_DEBUG") == "true" { | ||||
flagPkg.Debug = true | ||||
} | ||||
| ||||
// Set insecure mode based on environment variable | ||||
@@ -95,9 +98,9 @@ func init() { | ||||
} | ||||
} | ||||
| ||||
func Execute(version string) { | ||||
func Execute() { | ||||
defer log.Default().Sync() | ||||
if err := operation.Run(transport, version); err != nil { | ||||
if err := operation.Run(); err != nil { | ||||
if err == context.Canceled { | ||||
log.Info("Server shutdown due to context cancellation") | ||||
return | ||||
|
5 go.mod
5
go.mod @@ -4,7 +4,7 @@ go 1.24.0 | ||||
| ||||
require ( | ||||
code.gitea.io/sdk/gitea v0.21.0 | ||||
github.com/mark3labs/mcp-go v0.18.0 | ||||
github.com/mark3labs/mcp-go v0.22.0 | ||||
go.uber.org/zap v1.27.0 | ||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 | ||||
) | ||||
@@ -15,8 +15,9 @@ require ( | ||||
github.com/go-fed/httpsig v1.1.0 // indirect | ||||
github.com/google/uuid v1.6.0 // indirect | ||||
github.com/hashicorp/go-version v1.7.0 // indirect | ||||
github.com/spf13/cast v1.7.1 // indirect | ||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect | ||||
go.uber.org/multierr v1.11.0 // indirect | ||||
golang.org/x/crypto v0.36.0 // indirect | ||||
golang.org/x/crypto v0.37.0 // indirect | ||||
golang.org/x/sys v0.32.0 // indirect | ||||
) | ||||
|
24 go.sum
24
go.sum @@ -6,16 +6,28 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c | ||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0= | ||||
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= | ||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= | ||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= | ||||
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= | ||||
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= | ||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | ||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= | ||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||
github.com/mark3labs/mcp-go v0.18.0 h1:YuhgIVjNlTG2ZOwmrkORWyPTp0dz1opPEqvsPtySXao= | ||||
github.com/mark3labs/mcp-go v0.18.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE= | ||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||||
github.com/mark3labs/mcp-go v0.22.0 h1:cCEBWi4Yy9Kio+OW1hWIyi4WLsSr+RBBK6FI5tj+b7I= | ||||
github.com/mark3labs/mcp-go v0.22.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4= | ||||
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/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= | ||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | ||||
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= | ||||
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= | ||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= | ||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||||
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= | ||||
@@ -29,8 +41,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= | ||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= | ||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= | ||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= | ||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= | ||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= | ||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
@@ -39,8 +51,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= | ||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= | ||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= | ||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= | ||||
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= | ||||
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= | ||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
|
9 main.go
9
main.go @@ -2,12 +2,17 @@ package main | ||||
| ||||
import ( | ||||
"gitea.com/gitea/gitea-mcp/cmd" | ||||
"gitea.com/gitea/gitea-mcp/pkg/flag" | ||||
) | ||||
| ||||
var ( | ||||
Version = "dev" | ||||
) | ||||
| ||||
func main() { | ||||
cmd.Execute(Version) | ||||
func init() { | ||||
flag.Version = Version | ||||
} | ||||
| ||||
func main() { | ||||
cmd.Execute() | ||||
} | ||||
|
@@ -8,12 +8,15 @@ import ( | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/ptr" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
"gitea.com/gitea/gitea-mcp/pkg/tool" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
var Tool = tool.New() | ||||
| ||||
const ( | ||||
GetIssueByIndexToolName = "get_issue_by_index" | ||||
ListRepoIssuesToolName = "list_repo_issues" | ||||
@@ -71,12 +74,27 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func RegisterTool(s *server.MCPServer) { | ||||
s.AddTool(GetIssueByIndexTool, GetIssueByIndexFn) | ||||
s.AddTool(ListRepoIssuesTool, ListRepoIssuesFn) | ||||
s.AddTool(CreateIssueTool, CreateIssueFn) | ||||
s.AddTool(CreateIssueCommentTool, CreateIssueCommentFn) | ||||
s.AddTool(EditIssueTool, EditIssueFn) | ||||
func init() { | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetIssueByIndexTool, | ||||
Handler: GetIssueByIndexFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: ListRepoIssuesTool, | ||||
Handler: ListRepoIssuesFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreateIssueTool, | ||||
Handler: CreateIssueFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreateIssueCommentTool, | ||||
Handler: CreateIssueCommentFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: EditIssueTool, | ||||
Handler: EditIssueFn, | ||||
}) | ||||
} | ||||
| ||||
func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
|
@@ -21,29 +21,30 @@ var ( | ||||
| ||||
func RegisterTool(s *server.MCPServer) { | ||||
// User Tool | ||||
user.RegisterTool(s) | ||||
s.AddTools(user.Tool.Tools()...) | ||||
| ||||
// Repo Tool | ||||
repo.RegisterTool(s) | ||||
s.AddTools(repo.Tool.Tools()...) | ||||
| ||||
// Issue Tool | ||||
issue.RegisterTool(s) | ||||
s.AddTools(issue.Tool.Tools()...) | ||||
| ||||
// Pull Tool | ||||
pull.RegisterTool(s) | ||||
s.AddTools(pull.Tool.Tools()...) | ||||
| ||||
// Search Tool | ||||
search.RegisterTool(s) | ||||
s.AddTools(search.Tool.Tools()...) | ||||
| ||||
// Version Tool | ||||
version.RegisterTool(s) | ||||
s.AddTools(version.Tool.Tools()...) | ||||
| ||||
s.DeleteTools("") | ||||
} | ||||
| ||||
func Run(transport, version string) error { | ||||
flag.Version = version | ||||
mcpServer = newMCPServer(version) | ||||
func Run() error { | ||||
mcpServer = newMCPServer(flag.Version) | ||||
RegisterTool(mcpServer) | ||||
switch transport { | ||||
switch flag.Mode { | ||||
case "stdio": | ||||
if err := server.ServeStdio(mcpServer); err != nil { | ||||
return err | ||||
@@ -55,7 +56,7 @@ func Run(transport, version string) error { | ||||
return err | ||||
} | ||||
default: | ||||
return fmt.Errorf("invalid transport type: %s. Must be 'stdio' or 'sse'", transport) | ||||
return fmt.Errorf("invalid transport type: %s. Must be 'stdio' or 'sse'", flag.Mode) | ||||
} | ||||
return nil | ||||
} | ||||
@@ -64,6 +65,7 @@ func newMCPServer(version string) *server.MCPServer { | ||||
return server.NewMCPServer( | ||||
"Gitea MCP Server", | ||||
version, | ||||
server.WithToolCapabilities(true), | ||||
server.WithLogging(), | ||||
) | ||||
} | ||||
|
@@ -7,12 +7,15 @@ import ( | ||||
"gitea.com/gitea/gitea-mcp/pkg/gitea" | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
"gitea.com/gitea/gitea-mcp/pkg/tool" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
var Tool = tool.New() | ||||
| ||||
const ( | ||||
GetPullRequestByIndexToolName = "get_pull_request_by_index" | ||||
ListRepoPullRequestsToolName = "list_repo_pull_requests" | ||||
@@ -52,10 +55,19 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func RegisterTool(s *server.MCPServer) { | ||||
s.AddTool(GetPullRequestByIndexTool, GetPullRequestByIndexFn) | ||||
s.AddTool(ListRepoPullRequestsTool, ListRepoPullRequestsFn) | ||||
s.AddTool(CreatePullRequestTool, CreatePullRequestFn) | ||||
func init() { | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetPullRequestByIndexTool, | ||||
Handler: GetPullRequestByIndexFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: ListRepoPullRequestsTool, | ||||
Handler: ListRepoPullRequestsFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreatePullRequestTool, | ||||
Handler: CreatePullRequestFn, | ||||
}) | ||||
} | ||||
| ||||
func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
|
@@ -10,6 +10,7 @@ import ( | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
const ( | ||||
@@ -44,6 +45,21 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func init() { | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreateBranchTool, | ||||
Handler: CreateBranchFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: DeleteBranchTool, | ||||
Handler: DeleteBranchFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: ListBranchesTool, | ||||
Handler: ListBranchesFn, | ||||
}) | ||||
} | ||||
| ||||
func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
log.Debugf("Called CreateBranchFn") | ||||
owner, ok := req.Params.Arguments["owner"].(string) | ||||
|
@@ -10,6 +10,7 @@ import ( | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
const ( | ||||
@@ -29,6 +30,13 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func init() { | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: ListRepoCommitsTool, | ||||
Handler: ListRepoCommitsFn, | ||||
}) | ||||
} | ||||
| ||||
func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
log.Debugf("Called ListRepoCommitsFn") | ||||
owner, ok := req.Params.Arguments["owner"].(string) | ||||
|
@@ -11,6 +11,7 @@ import ( | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
const ( | ||||
@@ -66,6 +67,25 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func init() { | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetFileContentTool, | ||||
Handler: GetFileContentFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreateFileTool, | ||||
Handler: CreateFileFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: UpdateFileTool, | ||||
Handler: UpdateFileFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: DeleteFileTool, | ||||
Handler: DeleteFileFn, | ||||
}) | ||||
} | ||||
| ||||
func GetFileContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
log.Debugf("Called GetFileFn") | ||||
owner, ok := req.Params.Arguments["owner"].(string) | ||||
|
@@ -5,12 +5,14 @@ import ( | ||||
"fmt" | ||||
"time" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"gitea.com/gitea/gitea-mcp/pkg/gitea" | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/ptr" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
const ( | ||||
@@ -69,6 +71,29 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func init() { | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreateReleaseTool, | ||||
Handler: CreateReleaseFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: DeleteReleaseTool, | ||||
Handler: DeleteReleaseFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetReleaseTool, | ||||
Handler: GetReleaseFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetLatestReleaseTool, | ||||
Handler: GetLatestReleaseFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: ListReleasesTool, | ||||
Handler: ListReleasesFn, | ||||
}) | ||||
} | ||||
| ||||
// To avoid return too many tokens, we need to provide at least information as possible | ||||
// llm can call get release to get more information | ||||
type ListReleaseResult struct { | ||||
|
@@ -9,12 +9,15 @@ import ( | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/ptr" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
"gitea.com/gitea/gitea-mcp/pkg/tool" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
var Tool = tool.New() | ||||
| ||||
const ( | ||||
CreateRepoToolName = "create_repo" | ||||
ForkRepoToolName = "fork_repo" | ||||
@@ -54,6 +57,21 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func init() { | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreateRepoTool, | ||||
Handler: CreateRepoFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: ForkRepoTool, | ||||
Handler: ForkRepoFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: ListMyReposTool, | ||||
Handler: ListMyReposFn, | ||||
}) | ||||
} | ||||
| ||||
func RegisterTool(s *server.MCPServer) { | ||||
s.AddTool(CreateRepoTool, CreateRepoFn) | ||||
s.AddTool(ForkRepoTool, ForkRepoFn) | ||||
|
@@ -4,11 +4,13 @@ import ( | ||||
"context" | ||||
"fmt" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"gitea.com/gitea/gitea-mcp/pkg/gitea" | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
const ( | ||||
@@ -55,6 +57,25 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func init() { | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreateTagTool, | ||||
Handler: CreateTagFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: DeleteTagTool, | ||||
Handler: DeleteTagFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetTagTool, | ||||
Handler: GetTagFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: ListTagsTool, | ||||
Handler: ListTagsFn, | ||||
}) | ||||
} | ||||
| ||||
// To avoid return too many tokens, we need to provide at least information as possible | ||||
// llm can call get tag to get more information | ||||
type ListTagResult struct { | ||||
|
@@ -8,12 +8,15 @@ import ( | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/ptr" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
"gitea.com/gitea/gitea-mcp/pkg/tool" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
var Tool = tool.New() | ||||
| ||||
const ( | ||||
SearchUsersToolName = "search_users" | ||||
SearchOrgTeamsToolName = "search_org_teams" | ||||
@@ -55,10 +58,19 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func RegisterTool(s *server.MCPServer) { | ||||
s.AddTool(SearchUsersTool, SearchUsersFn) | ||||
s.AddTool(SearOrgTeamsTool, SearchOrgTeamsFn) | ||||
s.AddTool(SearchReposTool, SearchReposFn) | ||||
func init() { | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: SearchUsersTool, | ||||
Handler: SearchUsersFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: SearOrgTeamsTool, | ||||
Handler: SearchOrgTeamsFn, | ||||
}) | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: SearchReposTool, | ||||
Handler: SearchReposFn, | ||||
}) | ||||
} | ||||
| ||||
func SearchUsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
|
@@ -7,6 +7,7 @@ import ( | ||||
"gitea.com/gitea/gitea-mcp/pkg/gitea" | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
"gitea.com/gitea/gitea-mcp/pkg/tool" | ||||
| ||||
gitea_sdk "code.gitea.io/sdk/gitea" | ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
@@ -18,6 +19,8 @@ const ( | ||||
GetUserOrgsToolName = "get_user_orgs" | ||||
) | ||||
| ||||
var Tool = tool.New() | ||||
| ||||
var ( | ||||
GetMyUserInfoTool = mcp.NewTool( | ||||
GetMyUserInfoToolName, | ||||
@@ -32,9 +35,16 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func RegisterTool(s *server.MCPServer) { | ||||
s.AddTool(GetMyUserInfoTool, GetUserInfoFn) | ||||
s.AddTool(GetUserOrgsTool, GetUserOrgsFn) | ||||
func init() { | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetMyUserInfoTool, | ||||
Handler: GetUserInfoFn, | ||||
}) | ||||
| ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetUserOrgsTool, | ||||
Handler: GetUserOrgsFn, | ||||
}) | ||||
} | ||||
| ||||
func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
|
@@ -7,11 +7,14 @@ import ( | ||||
"gitea.com/gitea/gitea-mcp/pkg/flag" | ||||
"gitea.com/gitea/gitea-mcp/pkg/log" | ||||
"gitea.com/gitea/gitea-mcp/pkg/to" | ||||
"gitea.com/gitea/gitea-mcp/pkg/tool" | ||||
| ||||
"github.com/mark3labs/mcp-go/mcp" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
var Tool = tool.New() | ||||
| ||||
const ( | ||||
GetGiteaMCPServerVersion = "get_gitea_mcp_server_version" | ||||
) | ||||
@@ -23,8 +26,11 @@ var ( | ||||
) | ||||
) | ||||
| ||||
func RegisterTool(s *server.MCPServer) { | ||||
s.AddTool(GetGiteaMCPServerVersionTool, GetGiteaMCPServerVersionFn) | ||||
func init() { | ||||
Tool.RegisterRead(server.ServerTool{ | ||||
Tool: GetGiteaMCPServerVersionTool, | ||||
Handler: GetGiteaMCPServerVersionFn, | ||||
}) | ||||
} | ||||
| ||||
func GetGiteaMCPServerVersionFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
|
@@ -8,5 +8,6 @@ var ( | ||||
Mode string | ||||
| ||||
Insecure bool | ||||
ReadOnly bool | ||||
Debug bool | ||||
) | ||||
|
37 pkg/tool/tool.go Normal file
37
pkg/tool/tool.go Normal file @@ -0,0 +1,37 @@ | ||||
package tool | ||||
| ||||
import ( | ||||
"gitea.com/gitea/gitea-mcp/pkg/flag" | ||||
"github.com/mark3labs/mcp-go/server" | ||||
) | ||||
| ||||
type Tool struct { | ||||
write []server.ServerTool | ||||
read []server.ServerTool | ||||
} | ||||
| ||||
func New() *Tool { | ||||
return &Tool{ | ||||
write: make([]server.ServerTool, 100), | ||||
read: make([]server.ServerTool, 100), | ||||
} | ||||
} | ||||
| ||||
func (t *Tool) RegisterWrite(s server.ServerTool) { | ||||
t.write = append(t.write, s) | ||||
} | ||||
| ||||
func (t *Tool) RegisterRead(s server.ServerTool) { | ||||
t.read = append(t.read, s) | ||||
} | ||||
| ||||
func (t *Tool) Tools() []server.ServerTool { | ||||
tools := make([]server.ServerTool, 0, len(t.write)+len(t.read)) | ||||
if flag.ReadOnly { | ||||
tools = append(tools, t.read...) | ||||
return tools | ||||
} | ||||
tools = append(tools, t.write...) | ||||
tools = append(tools, t.read...) | ||||
return tools | ||||
} |
Reference in New Issue
Block a user