Add tool annotations and PR close/reopen support (#174)
Add MCP `ToolAnnotation` metadata (Title, ReadOnlyHint, DestructiveHint) to all registered tools so MCP hosts (VS Code, Claude, Cursor) get accurate per-tool hints. A shared `pkg/annotation` package exposes `ReadOnly`, `Write`, and `Destructive` helpers for consistency. Add `close` and `reopen` methods to `pull_request_write` so PR state can be toggled without going through the generic `update` path. Co-Authored-By: silverwind <me@silverwind.io> Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
@@ -24,6 +25,7 @@ var (
|
||||
CreateBranchTool = mcp.NewTool(
|
||||
CreateBranchToolName,
|
||||
mcp.WithDescription("Create branch"),
|
||||
mcp.WithToolAnnotation(annotation.Write("Create a new branch")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("branch", mcp.Required(), mcp.Description("Name of the branch to create")),
|
||||
@@ -33,6 +35,7 @@ var (
|
||||
DeleteBranchTool = mcp.NewTool(
|
||||
DeleteBranchToolName,
|
||||
mcp.WithDescription("Delete branch"),
|
||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a branch")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("branch", mcp.Required(), mcp.Description("Name of the branch to delete")),
|
||||
@@ -41,6 +44,7 @@ var (
|
||||
ListBranchesTool = mcp.NewTool(
|
||||
ListBranchesToolName,
|
||||
mcp.WithDescription("List branches"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("List repository branches")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
@@ -23,6 +24,7 @@ var (
|
||||
ListRepoCommitsTool = mcp.NewTool(
|
||||
ListRepoCommitsToolName,
|
||||
mcp.WithDescription("List repository commits"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("List repository commits")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("sha", mcp.Description("SHA or branch to start listing commits from")),
|
||||
@@ -34,6 +36,7 @@ var (
|
||||
GetCommitTool = mcp.NewTool(
|
||||
GetCommitToolName,
|
||||
mcp.WithDescription("Get details of a specific commit"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get commit details")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("sha", mcp.Required(), mcp.Description("commit SHA")),
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
@@ -29,6 +30,7 @@ var (
|
||||
GetFileContentTool = mcp.NewTool(
|
||||
GetFileToolName,
|
||||
mcp.WithDescription("Get file Content and Metadata"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get file content")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("ref", mcp.Required(), mcp.Description("ref can be branch/tag/commit")),
|
||||
@@ -39,6 +41,7 @@ var (
|
||||
GetDirContentTool = mcp.NewTool(
|
||||
GetDirToolName,
|
||||
mcp.WithDescription("Get a list of entries in a directory"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get directory contents")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("ref", mcp.Required(), mcp.Description("ref can be branch/tag/commit")),
|
||||
@@ -48,6 +51,7 @@ var (
|
||||
CreateOrUpdateFileTool = mcp.NewTool(
|
||||
CreateOrUpdateFileToolName,
|
||||
mcp.WithDescription("Create or update a file. If sha is provided, updates the existing file; otherwise creates a new file."),
|
||||
mcp.WithToolAnnotation(annotation.Write("Create or update a file")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
||||
@@ -61,6 +65,7 @@ var (
|
||||
DeleteFileTool = mcp.NewTool(
|
||||
DeleteFileToolName,
|
||||
mcp.WithDescription("Delete file"),
|
||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a file")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
@@ -26,6 +27,7 @@ var (
|
||||
CreateReleaseTool = mcp.NewTool(
|
||||
CreateReleaseToolName,
|
||||
mcp.WithDescription("Create release"),
|
||||
mcp.WithToolAnnotation(annotation.Write("Create a release")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||
@@ -39,6 +41,7 @@ var (
|
||||
DeleteReleaseTool = mcp.NewTool(
|
||||
DeleteReleaseToolName,
|
||||
mcp.WithDescription("Delete release"),
|
||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a release")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
||||
@@ -47,6 +50,7 @@ var (
|
||||
GetReleaseTool = mcp.NewTool(
|
||||
GetReleaseToolName,
|
||||
mcp.WithDescription("Get release"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get release details")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
||||
@@ -55,6 +59,7 @@ var (
|
||||
GetLatestReleaseTool = mcp.NewTool(
|
||||
GetLatestReleaseToolName,
|
||||
mcp.WithDescription("Get latest release"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get latest release")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
)
|
||||
@@ -62,6 +67,7 @@ var (
|
||||
ListReleasesTool = mcp.NewTool(
|
||||
ListReleasesToolName,
|
||||
mcp.WithDescription("List releases"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("List releases")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithBoolean("is_draft", mcp.Description("Whether the release is draft"), mcp.DefaultBool(false)),
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
@@ -29,6 +30,7 @@ var (
|
||||
CreateRepoTool = mcp.NewTool(
|
||||
CreateRepoToolName,
|
||||
mcp.WithDescription("Create repository in personal account or organization"),
|
||||
mcp.WithToolAnnotation(annotation.Write("Create a new repository")),
|
||||
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.WithBoolean("private", mcp.Description("Whether the repository is private")),
|
||||
@@ -47,6 +49,7 @@ var (
|
||||
ForkRepoTool = mcp.NewTool(
|
||||
ForkRepoToolName,
|
||||
mcp.WithDescription("Fork repository"),
|
||||
mcp.WithToolAnnotation(annotation.Write("Fork a repository")),
|
||||
mcp.WithString("user", mcp.Required(), mcp.Description("User name of the repository to fork")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("Repository name to fork")),
|
||||
mcp.WithString("organization", mcp.Description("Organization name to fork")),
|
||||
@@ -56,6 +59,7 @@ var (
|
||||
ListMyReposTool = mcp.NewTool(
|
||||
ListMyReposToolName,
|
||||
mcp.WithDescription("List my repositories"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("List my repositories")),
|
||||
mcp.WithNumber("page", mcp.Required(), mcp.Description("Page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||
mcp.WithNumber("perPage", mcp.Required(), mcp.Description("results per page (may be capped by the server's MAX_RESPONSE_ITEMS setting, default 50)"), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||
)
|
||||
@@ -63,6 +67,7 @@ var (
|
||||
ListOrgReposTool = mcp.NewTool(
|
||||
ListOrgReposToolName,
|
||||
mcp.WithDescription("List repositories of an organization"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("List organization repositories")),
|
||||
mcp.WithString("org", mcp.Required(), mcp.Description("Organization name")),
|
||||
mcp.WithNumber("page", mcp.Required(), mcp.Description("Page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||
mcp.WithNumber("pageSize", mcp.Required(), mcp.Description("Page size number"), mcp.DefaultNumber(100), mcp.Min(1)),
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
@@ -25,6 +26,7 @@ var (
|
||||
CreateTagTool = mcp.NewTool(
|
||||
CreateTagToolName,
|
||||
mcp.WithDescription("Create tag"),
|
||||
mcp.WithToolAnnotation(annotation.Write("Create a tag")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||
@@ -35,6 +37,7 @@ var (
|
||||
DeleteTagTool = mcp.NewTool(
|
||||
DeleteTagToolName,
|
||||
mcp.WithDescription("Delete tag"),
|
||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a tag")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||
@@ -43,6 +46,7 @@ var (
|
||||
GetTagTool = mcp.NewTool(
|
||||
GetTagToolName,
|
||||
mcp.WithDescription("Get tag"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get tag details")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||
@@ -51,6 +55,7 @@ var (
|
||||
ListTagsTool = mcp.NewTool(
|
||||
ListTagsToolName,
|
||||
mcp.WithDescription("List tags"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("List tags")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||
@@ -21,6 +22,7 @@ const (
|
||||
var GetRepoTreeTool = mcp.NewTool(
|
||||
GetRepoTreeToolName,
|
||||
mcp.WithDescription("Get the file tree of a repository"),
|
||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get repository file tree")),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("tree_sha", mcp.Required(), mcp.Description("SHA, branch name, or tag name")),
|
||||
|
||||
Reference in New Issue
Block a user