Initial commit: Gitea MCP Server
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
package sshkey
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/to"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/tool"
|
||||
|
||||
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||
"github.com/mark3labs/mcp-go/mcp"
|
||||
"github.com/mark3labs/mcp-go/server"
|
||||
)
|
||||
|
||||
const (
|
||||
ListMySSHKeysToolName = "list_my_ssh_keys"
|
||||
GetSSHKeyToolName = "get_ssh_key"
|
||||
CreateSSHKeyToolName = "create_ssh_key"
|
||||
DeleteSSHKeyToolName = "delete_ssh_key"
|
||||
ListUserSSHKeysToolName = "list_user_ssh_keys"
|
||||
)
|
||||
|
||||
var Tool = tool.New()
|
||||
|
||||
var (
|
||||
ListMySSHKeysTool = mcp.NewTool(
|
||||
ListMySSHKeysToolName,
|
||||
mcp.WithDescription("List SSH keys for the authenticated user"),
|
||||
)
|
||||
|
||||
GetSSHKeyTool = mcp.NewTool(
|
||||
GetSSHKeyToolName,
|
||||
mcp.WithDescription("Get a specific SSH key by ID"),
|
||||
mcp.WithNumber("id", mcp.Required(), mcp.Description("SSH key ID")),
|
||||
)
|
||||
|
||||
CreateSSHKeyTool = mcp.NewTool(
|
||||
CreateSSHKeyToolName,
|
||||
mcp.WithDescription("Create a new SSH key for the authenticated user"),
|
||||
mcp.WithString("title", mcp.Required(), mcp.Description("Title/description for the SSH key")),
|
||||
mcp.WithString("key", mcp.Required(), mcp.Description("The SSH public key content")),
|
||||
)
|
||||
|
||||
DeleteSSHKeyTool = mcp.NewTool(
|
||||
DeleteSSHKeyToolName,
|
||||
mcp.WithDescription("Delete an SSH key"),
|
||||
mcp.WithNumber("id", mcp.Required(), mcp.Description("SSH key ID to delete")),
|
||||
)
|
||||
|
||||
ListUserSSHKeysTool = mcp.NewTool(
|
||||
ListUserSSHKeysToolName,
|
||||
mcp.WithDescription("List SSH keys for a specific user"),
|
||||
mcp.WithString("username", mcp.Required(), mcp.Description("Username")),
|
||||
)
|
||||
)
|
||||
|
||||
func init() {
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: ListMySSHKeysTool,
|
||||
Handler: listMySSHKeysFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: GetSSHKeyTool,
|
||||
Handler: getSSHKeyFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: ListUserSSHKeysTool,
|
||||
Handler: listUserSSHKeysFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: CreateSSHKeyTool,
|
||||
Handler: createSSHKeyFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: DeleteSSHKeyTool,
|
||||
Handler: deleteSSHKeyFn,
|
||||
})
|
||||
}
|
||||
|
||||
func listMySSHKeysFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[SSHKey] Called listMySSHKeysFn")
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
keys, _, err := client.ListMyPublicKeys(gitea_sdk.ListPublicKeysOptions{})
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("list SSH keys err: %v", err))
|
||||
}
|
||||
return to.TextResult(slimSSHKeys(keys))
|
||||
}
|
||||
|
||||
func getSSHKeyFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[SSHKey] Called getSSHKeyFn")
|
||||
args := req.GetArguments()
|
||||
id, err := params.GetIndex(args, "id")
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("invalid key id: %v", err))
|
||||
}
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
key, _, err := client.GetPublicKey(id)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get SSH key err: %v", err))
|
||||
}
|
||||
return to.TextResult(slimSSHKey(key))
|
||||
}
|
||||
|
||||
func createSSHKeyFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[SSHKey] Called createSSHKeyFn")
|
||||
args := req.GetArguments()
|
||||
title, err := params.GetString(args, "title")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
key, err := params.GetString(args, "key")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
createOpt := gitea_sdk.CreateKeyOption{
|
||||
Title: title,
|
||||
Key: key,
|
||||
}
|
||||
respKey, _, err := client.CreatePublicKey(createOpt)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("create SSH key err: %v", err))
|
||||
}
|
||||
return to.TextResult(slimSSHKey(respKey))
|
||||
}
|
||||
|
||||
func deleteSSHKeyFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[SSHKey] Called deleteSSHKeyFn")
|
||||
args := req.GetArguments()
|
||||
id, err := params.GetIndex(args, "id")
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("invalid key id: %v", err))
|
||||
}
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
_, err = client.DeletePublicKey(id)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("delete SSH key err: %v", err))
|
||||
}
|
||||
return to.TextResult("SSH key deleted successfully")
|
||||
}
|
||||
|
||||
func listUserSSHKeysFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[SSHKey] Called listUserSSHKeysFn")
|
||||
args := req.GetArguments()
|
||||
username, err := params.GetString(args, "username")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
keys, _, err := client.ListPublicKeys(username, gitea_sdk.ListPublicKeysOptions{})
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("list user SSH keys err: %v", err))
|
||||
}
|
||||
return to.TextResult(slimSSHKeys(keys))
|
||||
}
|
||||
|
||||
func slimSSHKeys(keys []*gitea_sdk.PublicKey) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, len(keys))
|
||||
for i, k := range keys {
|
||||
result[i] = slimSSHKey(k)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func slimSSHKey(k *gitea_sdk.PublicKey) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": k.ID,
|
||||
"key": k.Key,
|
||||
"title": k.Title,
|
||||
"created": k.Created,
|
||||
"fingerprint": k.Fingerprint,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user