Files
amacocian f5109abfad
CI / build (push) Successful in 19s
Gitea mcp pre-release
2026-05-25 15:22:30 +02:00

54 lines
1.8 KiB
Go

package main
import (
"context"
"fmt"
"net/url"
"strconv"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
func registerPackageTools(server *mcp.Server, api *giteaAPI) {
mcp.AddTool(server, &mcp.Tool{
Name: "list_packages",
Description: "List packages owned by a user or organisation. Optional type filter (e.g. \"container\", \"npm\", \"generic\") and name substring.",
}, listPackagesHandler(api))
}
type listPackagesInput struct {
Owner string `json:"owner" jsonschema:"package owner (user or org)"`
Type string `json:"type,omitempty" jsonschema:"package type filter (container, npm, generic, …)"`
Query string `json:"query,omitempty" jsonschema:"substring match on package name"`
Limit int `json:"limit,omitempty" jsonschema:"max packages to return (1-50, default 50)"`
}
type pkg struct {
ID int64 `json:"id"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
Version string `json:"version,omitempty"`
HTMLURL string `json:"html_url,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
}
type listPackagesOutput struct {
Packages []pkg `json:"packages"`
}
func listPackagesHandler(api *giteaAPI) mcp.ToolHandlerFor[listPackagesInput, listPackagesOutput] {
return func(ctx context.Context, _ *mcp.CallToolRequest, in listPackagesInput) (*mcp.CallToolResult, listPackagesOutput, error) {
if in.Owner == "" {
return nil, listPackagesOutput{}, fmt.Errorf("owner is required")
}
limit := clampInt(in.Limit, 1, 50, 50)
q := url.Values{"limit": []string{strconv.Itoa(limit)}}
setIf(q, "type", in.Type)
setIf(q, "q", in.Query)
path := fmt.Sprintf("/api/v1/packages/%s", url.PathEscape(in.Owner))
var packages []pkg
if err := api.get(ctx, path, q, &packages); err != nil {
return nil, listPackagesOutput{}, err
}
return nil, listPackagesOutput{Packages: packages}, nil
}
}