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:
@@ -8,6 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -48,6 +49,7 @@ var (
|
|||||||
ActionsConfigReadTool = mcp.NewTool(
|
ActionsConfigReadTool = mcp.NewTool(
|
||||||
ActionsConfigReadToolName,
|
ActionsConfigReadToolName,
|
||||||
mcp.WithDescription("Read Actions secrets and variables configuration."),
|
mcp.WithDescription("Read Actions secrets and variables configuration."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read Actions secrets and variables")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_repo_secrets", "list_org_secrets", "list_repo_variables", "get_repo_variable", "list_org_variables", "get_org_variable")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_repo_secrets", "list_org_secrets", "list_repo_variables", "get_repo_variable", "list_org_variables", "get_org_variable")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
||||||
@@ -60,6 +62,7 @@ var (
|
|||||||
ActionsConfigWriteTool = mcp.NewTool(
|
ActionsConfigWriteTool = mcp.NewTool(
|
||||||
ActionsConfigWriteToolName,
|
ActionsConfigWriteToolName,
|
||||||
mcp.WithDescription("Manage Actions secrets and variables: create, update, or delete."),
|
mcp.WithDescription("Manage Actions secrets and variables: create, update, or delete."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Manage Actions secrets and variables")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("upsert_repo_secret", "delete_repo_secret", "upsert_org_secret", "delete_org_secret", "create_repo_variable", "update_repo_variable", "delete_repo_variable", "create_org_variable", "update_org_variable", "delete_org_variable")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("upsert_repo_secret", "delete_repo_secret", "upsert_org_secret", "delete_org_secret", "create_repo_variable", "update_repo_variable", "delete_repo_variable", "create_org_variable", "update_org_variable", "delete_org_variable")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -28,6 +29,7 @@ var (
|
|||||||
ActionsRunReadTool = mcp.NewTool(
|
ActionsRunReadTool = mcp.NewTool(
|
||||||
ActionsRunReadToolName,
|
ActionsRunReadToolName,
|
||||||
mcp.WithDescription("Read Actions workflow, run, and job data. Use method 'list_workflows'/'get_workflow' for workflows, 'list_runs'/'get_run' for runs, 'list_jobs'/'list_run_jobs' for jobs, 'get_job_log_preview'/'download_job_log' for logs."),
|
mcp.WithDescription("Read Actions workflow, run, and job data. Use method 'list_workflows'/'get_workflow' for workflows, 'list_runs'/'get_run' for runs, 'list_jobs'/'list_run_jobs' for jobs, 'get_job_log_preview'/'download_job_log' for logs."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read Actions workflow, run, and job data")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_workflows", "get_workflow", "list_runs", "get_run", "list_jobs", "list_run_jobs", "get_job_log_preview", "download_job_log")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_workflows", "get_workflow", "list_runs", "get_run", "list_jobs", "list_run_jobs", "get_job_log_preview", "download_job_log")),
|
||||||
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")),
|
||||||
@@ -45,6 +47,7 @@ var (
|
|||||||
ActionsRunWriteTool = mcp.NewTool(
|
ActionsRunWriteTool = mcp.NewTool(
|
||||||
ActionsRunWriteToolName,
|
ActionsRunWriteToolName,
|
||||||
mcp.WithDescription("Trigger, cancel, or rerun Actions workflows."),
|
mcp.WithDescription("Trigger, cancel, or rerun Actions workflows."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Trigger, cancel, or rerun Actions workflows")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("dispatch_workflow", "cancel_run", "rerun_run")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("dispatch_workflow", "cancel_run", "rerun_run")),
|
||||||
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")),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -40,6 +41,7 @@ var (
|
|||||||
ListRepoIssuesTool = mcp.NewTool(
|
ListRepoIssuesTool = mcp.NewTool(
|
||||||
ListRepoIssuesToolName,
|
ListRepoIssuesToolName,
|
||||||
mcp.WithDescription("List repository issues"),
|
mcp.WithDescription("List repository issues"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("List repository issues")),
|
||||||
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("issue state"), mcp.DefaultString("all")),
|
mcp.WithString("state", mcp.Description("issue state"), mcp.DefaultString("all")),
|
||||||
@@ -53,6 +55,7 @@ var (
|
|||||||
IssueReadTool = mcp.NewTool(
|
IssueReadTool = mcp.NewTool(
|
||||||
IssueReadToolName,
|
IssueReadToolName,
|
||||||
mcp.WithDescription("Get information about a specific issue. Use method 'get' for issue details, 'get_comments' for issue comments, 'get_labels' for issue labels."),
|
mcp.WithDescription("Get information about a specific issue. Use method 'get' for issue details, 'get_comments' for issue comments, 'get_labels' for issue labels."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read issue details")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("get", "get_comments", "get_labels")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("get", "get_comments", "get_labels")),
|
||||||
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")),
|
||||||
@@ -62,6 +65,7 @@ var (
|
|||||||
IssueWriteTool = mcp.NewTool(
|
IssueWriteTool = mcp.NewTool(
|
||||||
IssueWriteToolName,
|
IssueWriteToolName,
|
||||||
mcp.WithDescription("Create or update issues and comments, manage labels. Use method 'create' to create an issue, 'update' to edit, 'add_comment'/'edit_comment' for comments, 'add_labels'/'remove_label'/'replace_labels'/'clear_labels' for label management."),
|
mcp.WithDescription("Create or update issues and comments, manage labels. Use method 'create' to create an issue, 'update' to edit, 'add_comment'/'edit_comment' for comments, 'add_labels'/'remove_label'/'replace_labels'/'clear_labels' for label management."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Create or update issues, comments, and labels")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "update", "add_comment", "edit_comment", "add_labels", "remove_label", "replace_labels", "clear_labels")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "update", "add_comment", "edit_comment", "add_labels", "remove_label", "replace_labels", "clear_labels")),
|
||||||
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")),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -26,6 +27,7 @@ var (
|
|||||||
LabelReadTool = mcp.NewTool(
|
LabelReadTool = mcp.NewTool(
|
||||||
LabelReadToolName,
|
LabelReadToolName,
|
||||||
mcp.WithDescription("Read label information. Use method 'list_repo_labels' to list repository labels, 'get_repo_label' to get a specific repo label, 'list_org_labels' to list organization labels."),
|
mcp.WithDescription("Read label information. Use method 'list_repo_labels' to list repository labels, 'get_repo_label' to get a specific repo label, 'list_org_labels' to list organization labels."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read labels")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_repo_labels", "get_repo_label", "list_org_labels")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_repo_labels", "get_repo_label", "list_org_labels")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
||||||
@@ -38,6 +40,7 @@ var (
|
|||||||
LabelWriteTool = mcp.NewTool(
|
LabelWriteTool = mcp.NewTool(
|
||||||
LabelWriteToolName,
|
LabelWriteToolName,
|
||||||
mcp.WithDescription("Create, edit, or delete labels for repositories or organizations."),
|
mcp.WithDescription("Create, edit, or delete labels for repositories or organizations."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Create, update, or delete labels")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create_repo_label", "edit_repo_label", "delete_repo_label", "create_org_label", "edit_org_label", "delete_org_label")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create_repo_label", "edit_repo_label", "delete_repo_label", "create_org_label", "edit_org_label", "delete_org_label")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
mcp.WithString("owner", mcp.Description("repository owner (required for repo methods)")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -26,6 +27,7 @@ var (
|
|||||||
MilestoneReadTool = mcp.NewTool(
|
MilestoneReadTool = mcp.NewTool(
|
||||||
MilestoneReadToolName,
|
MilestoneReadToolName,
|
||||||
mcp.WithDescription("Read milestone information. Use method 'get' to get a specific milestone, 'list' to list milestones."),
|
mcp.WithDescription("Read milestone information. Use method 'get' to get a specific milestone, 'list' to list milestones."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read milestones")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("get", "list")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("get", "list")),
|
||||||
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")),
|
||||||
@@ -39,6 +41,7 @@ var (
|
|||||||
MilestoneWriteTool = mcp.NewTool(
|
MilestoneWriteTool = mcp.NewTool(
|
||||||
MilestoneWriteToolName,
|
MilestoneWriteToolName,
|
||||||
mcp.WithDescription("Create, edit, or delete milestones."),
|
mcp.WithDescription("Create, edit, or delete milestones."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Create, update, or delete milestones")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "edit", "delete")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "edit", "delete")),
|
||||||
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")),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -27,6 +28,7 @@ var (
|
|||||||
NotificationReadTool = mcp.NewTool(
|
NotificationReadTool = mcp.NewTool(
|
||||||
NotificationReadToolName,
|
NotificationReadToolName,
|
||||||
mcp.WithDescription("Get notifications. Use method 'list' to list notifications (optionally scoped to a repo), 'get' to get a single notification thread by ID."),
|
mcp.WithDescription("Get notifications. Use method 'list' to list notifications (optionally scoped to a repo), 'get' to get a single notification thread by ID."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read notifications")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list", "get")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list", "get")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (for 'list' to scope to a repo)")),
|
mcp.WithString("owner", mcp.Description("repository owner (for 'list' to scope to a repo)")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (for 'list' to scope to a repo)")),
|
mcp.WithString("repo", mcp.Description("repository name (for 'list' to scope to a repo)")),
|
||||||
@@ -42,6 +44,7 @@ var (
|
|||||||
NotificationWriteTool = mcp.NewTool(
|
NotificationWriteTool = mcp.NewTool(
|
||||||
NotificationWriteToolName,
|
NotificationWriteToolName,
|
||||||
mcp.WithDescription("Manage notifications. Use method 'mark_read' to mark a single notification as read, 'mark_all_read' to mark all notifications as read (optionally scoped to a repo)."),
|
mcp.WithDescription("Manage notifications. Use method 'mark_read' to mark a single notification as read, 'mark_all_read' to mark all notifications as read (optionally scoped to a repo)."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Manage notifications")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("mark_read", "mark_all_read")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("mark_read", "mark_all_read")),
|
||||||
mcp.WithNumber("id", mcp.Description("notification thread ID (required for 'mark_read')")),
|
mcp.WithNumber("id", mcp.Description("notification thread ID (required for 'mark_read')")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (for 'mark_all_read' to scope to a repo)")),
|
mcp.WithString("owner", mcp.Description("repository owner (for 'mark_all_read' to scope to a repo)")),
|
||||||
|
|||||||
+71
-2
@@ -6,6 +6,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -30,6 +31,7 @@ var (
|
|||||||
ListRepoPullRequestsTool = mcp.NewTool(
|
ListRepoPullRequestsTool = mcp.NewTool(
|
||||||
ListRepoPullRequestsToolName,
|
ListRepoPullRequestsToolName,
|
||||||
mcp.WithDescription("List repository pull requests"),
|
mcp.WithDescription("List repository pull requests"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("List 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.Enum("open", "closed", "all"), mcp.DefaultString("all")),
|
mcp.WithString("state", mcp.Description("state"), mcp.Enum("open", "closed", "all"), mcp.DefaultString("all")),
|
||||||
@@ -42,6 +44,7 @@ var (
|
|||||||
PullRequestReadTool = mcp.NewTool(
|
PullRequestReadTool = mcp.NewTool(
|
||||||
PullRequestReadToolName,
|
PullRequestReadToolName,
|
||||||
mcp.WithDescription("Get pull request information. Use method 'get' for PR details, 'get_diff' for diff, 'get_reviews'/'get_review'/'get_review_comments' for review data."),
|
mcp.WithDescription("Get pull request information. Use method 'get' for PR details, 'get_diff' for diff, 'get_reviews'/'get_review'/'get_review_comments' for review data."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read pull request details")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("get", "get_diff", "get_reviews", "get_review", "get_review_comments")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("get", "get_diff", "get_reviews", "get_review", "get_review_comments")),
|
||||||
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")),
|
||||||
@@ -54,8 +57,9 @@ var (
|
|||||||
|
|
||||||
PullRequestWriteTool = mcp.NewTool(
|
PullRequestWriteTool = mcp.NewTool(
|
||||||
PullRequestWriteToolName,
|
PullRequestWriteToolName,
|
||||||
mcp.WithDescription("Create, update, or merge pull requests, manage reviewers."),
|
mcp.WithDescription("Create, update, close, reopen, or merge pull requests, manage reviewers."),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "update", "merge", "add_reviewers", "remove_reviewers")),
|
mcp.WithToolAnnotation(annotation.Write("Create, update, close, reopen, or merge pull requests")),
|
||||||
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "update", "close", "reopen", "merge", "add_reviewers", "remove_reviewers")),
|
||||||
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.WithNumber("index", mcp.Description("pull request index (required for all methods except 'create')")),
|
mcp.WithNumber("index", mcp.Description("pull request index (required for all methods except 'create')")),
|
||||||
@@ -85,6 +89,7 @@ var (
|
|||||||
PullRequestReviewWriteTool = mcp.NewTool(
|
PullRequestReviewWriteTool = mcp.NewTool(
|
||||||
PullRequestReviewWriteToolName,
|
PullRequestReviewWriteToolName,
|
||||||
mcp.WithDescription("Manage pull request reviews: create, submit, delete, or dismiss."),
|
mcp.WithDescription("Manage pull request reviews: create, submit, delete, or dismiss."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Submit a pull request review")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "submit", "delete", "dismiss")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "submit", "delete", "dismiss")),
|
||||||
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")),
|
||||||
@@ -156,6 +161,10 @@ func pullRequestWriteFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
return createPullRequestFn(ctx, req)
|
return createPullRequestFn(ctx, req)
|
||||||
case "update":
|
case "update":
|
||||||
return editPullRequestFn(ctx, req)
|
return editPullRequestFn(ctx, req)
|
||||||
|
case "close":
|
||||||
|
return closePullRequestFn(ctx, req)
|
||||||
|
case "reopen":
|
||||||
|
return reopenPullRequestFn(ctx, req)
|
||||||
case "merge":
|
case "merge":
|
||||||
return mergePullRequestFn(ctx, req)
|
return mergePullRequestFn(ctx, req)
|
||||||
case "add_reviewers":
|
case "add_reviewers":
|
||||||
@@ -167,6 +176,66 @@ func pullRequestWriteFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func closePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
state := gitea_sdk.StateClosed
|
||||||
|
pr, _, err := client.EditPullRequest(owner, repo, index, gitea_sdk.EditPullRequestOption{
|
||||||
|
State: &state,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(fmt.Errorf("close %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return to.TextResult(slimPullRequest(pr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func reopenPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
|
owner, err := params.GetString(req.GetArguments(), "owner")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
repo, err := params.GetString(req.GetArguments(), "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
state := gitea_sdk.StateOpen
|
||||||
|
pr, _, err := client.EditPullRequest(owner, repo, index, gitea_sdk.EditPullRequestOption{
|
||||||
|
State: &state,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(fmt.Errorf("reopen %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return to.TextResult(slimPullRequest(pr))
|
||||||
|
}
|
||||||
|
|
||||||
func pullRequestReviewWriteFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func pullRequestReviewWriteFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
method, err := params.GetString(req.GetArguments(), "method")
|
method, err := params.GetString(req.GetArguments(), "method")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -911,3 +911,131 @@ func Test_getPullRequestByIndexFn_assetsFailureNonFatal(t *testing.T) {
|
|||||||
t.Fatalf("expected PR body preserved when assets fail, got: %s", body)
|
t.Fatalf("expected PR body preserved when assets fail, got: %s", body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_closePullRequestFn(t *testing.T) {
|
||||||
|
const (
|
||||||
|
owner = "octo"
|
||||||
|
repo = "demo"
|
||||||
|
index = 7
|
||||||
|
)
|
||||||
|
|
||||||
|
var gotBody map[string]any
|
||||||
|
|
||||||
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/api/v1/version":
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write([]byte(`{"version":"1.12.0"}`))
|
||||||
|
case fmt.Sprintf("/api/v1/repos/%s/%s", owner, repo):
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write([]byte(`{"private":false}`))
|
||||||
|
case fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d", owner, repo, index):
|
||||||
|
if r.Method != http.MethodPatch {
|
||||||
|
t.Errorf("expected PATCH method, got %s", r.Method)
|
||||||
|
}
|
||||||
|
_ = json.NewDecoder(r.Body).Decode(&gotBody)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write(fmt.Appendf(nil, `{"index":%d,"title":"Fix bug","state":"closed","head":{"ref":"fix-branch"},"base":{"ref":"main"}}`, index))
|
||||||
|
default:
|
||||||
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
server := httptest.NewServer(handler)
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
origHost := flag.Host
|
||||||
|
origToken := flag.Token
|
||||||
|
flag.Host = server.URL
|
||||||
|
flag.Token = "test-token"
|
||||||
|
t.Cleanup(func() { flag.Host = origHost; flag.Token = origToken })
|
||||||
|
|
||||||
|
req := mcp.CallToolRequest{
|
||||||
|
Params: mcp.CallToolParams{
|
||||||
|
Arguments: map[string]any{
|
||||||
|
"method": "close",
|
||||||
|
"owner": owner,
|
||||||
|
"repo": repo,
|
||||||
|
"index": float64(index),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := closePullRequestFn(context.Background(), req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("closePullRequestFn() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gotBody["state"] != "closed" {
|
||||||
|
t.Errorf("expected state=closed, got %v", gotBody["state"])
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result.Content) == 0 {
|
||||||
|
t.Fatalf("expected content in result")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_reopenPullRequestFn(t *testing.T) {
|
||||||
|
const (
|
||||||
|
owner = "octo"
|
||||||
|
repo = "demo"
|
||||||
|
index = 7
|
||||||
|
)
|
||||||
|
|
||||||
|
var gotBody map[string]any
|
||||||
|
|
||||||
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/api/v1/version":
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write([]byte(`{"version":"1.12.0"}`))
|
||||||
|
case fmt.Sprintf("/api/v1/repos/%s/%s", owner, repo):
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write([]byte(`{"private":false}`))
|
||||||
|
case fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d", owner, repo, index):
|
||||||
|
if r.Method != http.MethodPatch {
|
||||||
|
t.Errorf("expected PATCH method, got %s", r.Method)
|
||||||
|
}
|
||||||
|
_ = json.NewDecoder(r.Body).Decode(&gotBody)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write(fmt.Appendf(nil, `{"index":%d,"title":"Fix bug","state":"open","head":{"ref":"fix-branch"},"base":{"ref":"main"}}`, index))
|
||||||
|
default:
|
||||||
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
server := httptest.NewServer(handler)
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
origHost := flag.Host
|
||||||
|
origToken := flag.Token
|
||||||
|
flag.Host = server.URL
|
||||||
|
flag.Token = "test-token"
|
||||||
|
t.Cleanup(func() { flag.Host = origHost; flag.Token = origToken })
|
||||||
|
|
||||||
|
req := mcp.CallToolRequest{
|
||||||
|
Params: mcp.CallToolParams{
|
||||||
|
Arguments: map[string]any{
|
||||||
|
"method": "reopen",
|
||||||
|
"owner": owner,
|
||||||
|
"repo": repo,
|
||||||
|
"index": float64(index),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := reopenPullRequestFn(context.Background(), req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("reopenPullRequestFn() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gotBody["state"] != "open" {
|
||||||
|
t.Errorf("expected state=open, got %v", gotBody["state"])
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result.Content) == 0 {
|
||||||
|
t.Fatalf("expected content in result")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -24,6 +25,7 @@ var (
|
|||||||
CreateBranchTool = mcp.NewTool(
|
CreateBranchTool = mcp.NewTool(
|
||||||
CreateBranchToolName,
|
CreateBranchToolName,
|
||||||
mcp.WithDescription("Create branch"),
|
mcp.WithDescription("Create branch"),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Create a new branch")),
|
||||||
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("branch", mcp.Required(), mcp.Description("Name of the branch to create")),
|
mcp.WithString("branch", mcp.Required(), mcp.Description("Name of the branch to create")),
|
||||||
@@ -33,6 +35,7 @@ var (
|
|||||||
DeleteBranchTool = mcp.NewTool(
|
DeleteBranchTool = mcp.NewTool(
|
||||||
DeleteBranchToolName,
|
DeleteBranchToolName,
|
||||||
mcp.WithDescription("Delete branch"),
|
mcp.WithDescription("Delete branch"),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a branch")),
|
||||||
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("branch", mcp.Required(), mcp.Description("Name of the branch to delete")),
|
mcp.WithString("branch", mcp.Required(), mcp.Description("Name of the branch to delete")),
|
||||||
@@ -41,6 +44,7 @@ var (
|
|||||||
ListBranchesTool = mcp.NewTool(
|
ListBranchesTool = mcp.NewTool(
|
||||||
ListBranchesToolName,
|
ListBranchesToolName,
|
||||||
mcp.WithDescription("List branches"),
|
mcp.WithDescription("List branches"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("List repository branches")),
|
||||||
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.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -23,6 +24,7 @@ var (
|
|||||||
ListRepoCommitsTool = mcp.NewTool(
|
ListRepoCommitsTool = mcp.NewTool(
|
||||||
ListRepoCommitsToolName,
|
ListRepoCommitsToolName,
|
||||||
mcp.WithDescription("List repository commits"),
|
mcp.WithDescription("List repository commits"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("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 or branch to start listing commits from")),
|
mcp.WithString("sha", mcp.Description("SHA or branch to start listing commits from")),
|
||||||
@@ -34,6 +36,7 @@ var (
|
|||||||
GetCommitTool = mcp.NewTool(
|
GetCommitTool = mcp.NewTool(
|
||||||
GetCommitToolName,
|
GetCommitToolName,
|
||||||
mcp.WithDescription("Get details of a specific commit"),
|
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("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.Required(), mcp.Description("commit SHA")),
|
mcp.WithString("sha", mcp.Required(), mcp.Description("commit SHA")),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -29,6 +30,7 @@ var (
|
|||||||
GetFileContentTool = mcp.NewTool(
|
GetFileContentTool = mcp.NewTool(
|
||||||
GetFileToolName,
|
GetFileToolName,
|
||||||
mcp.WithDescription("Get file Content and Metadata"),
|
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("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 can be branch/tag/commit")),
|
mcp.WithString("ref", mcp.Required(), mcp.Description("ref can be branch/tag/commit")),
|
||||||
@@ -39,6 +41,7 @@ var (
|
|||||||
GetDirContentTool = mcp.NewTool(
|
GetDirContentTool = mcp.NewTool(
|
||||||
GetDirToolName,
|
GetDirToolName,
|
||||||
mcp.WithDescription("Get a list of entries in a directory"),
|
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("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 can be branch/tag/commit")),
|
mcp.WithString("ref", mcp.Required(), mcp.Description("ref can be branch/tag/commit")),
|
||||||
@@ -48,6 +51,7 @@ var (
|
|||||||
CreateOrUpdateFileTool = mcp.NewTool(
|
CreateOrUpdateFileTool = mcp.NewTool(
|
||||||
CreateOrUpdateFileToolName,
|
CreateOrUpdateFileToolName,
|
||||||
mcp.WithDescription("Create or update a file. If sha is provided, updates the existing file; otherwise creates a new file."),
|
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("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")),
|
||||||
@@ -61,6 +65,7 @@ var (
|
|||||||
DeleteFileTool = mcp.NewTool(
|
DeleteFileTool = mcp.NewTool(
|
||||||
DeleteFileToolName,
|
DeleteFileToolName,
|
||||||
mcp.WithDescription("Delete file"),
|
mcp.WithDescription("Delete file"),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a file")),
|
||||||
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")),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -26,6 +27,7 @@ var (
|
|||||||
CreateReleaseTool = mcp.NewTool(
|
CreateReleaseTool = mcp.NewTool(
|
||||||
CreateReleaseToolName,
|
CreateReleaseToolName,
|
||||||
mcp.WithDescription("Create release"),
|
mcp.WithDescription("Create release"),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Create a release")),
|
||||||
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("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||||
@@ -39,6 +41,7 @@ var (
|
|||||||
DeleteReleaseTool = mcp.NewTool(
|
DeleteReleaseTool = mcp.NewTool(
|
||||||
DeleteReleaseToolName,
|
DeleteReleaseToolName,
|
||||||
mcp.WithDescription("Delete release"),
|
mcp.WithDescription("Delete release"),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a release")),
|
||||||
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.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
mcp.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
||||||
@@ -47,6 +50,7 @@ var (
|
|||||||
GetReleaseTool = mcp.NewTool(
|
GetReleaseTool = mcp.NewTool(
|
||||||
GetReleaseToolName,
|
GetReleaseToolName,
|
||||||
mcp.WithDescription("Get release"),
|
mcp.WithDescription("Get release"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get release details")),
|
||||||
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.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
mcp.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
||||||
@@ -55,6 +59,7 @@ var (
|
|||||||
GetLatestReleaseTool = mcp.NewTool(
|
GetLatestReleaseTool = mcp.NewTool(
|
||||||
GetLatestReleaseToolName,
|
GetLatestReleaseToolName,
|
||||||
mcp.WithDescription("Get latest release"),
|
mcp.WithDescription("Get latest release"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get latest release")),
|
||||||
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")),
|
||||||
)
|
)
|
||||||
@@ -62,6 +67,7 @@ var (
|
|||||||
ListReleasesTool = mcp.NewTool(
|
ListReleasesTool = mcp.NewTool(
|
||||||
ListReleasesToolName,
|
ListReleasesToolName,
|
||||||
mcp.WithDescription("List releases"),
|
mcp.WithDescription("List releases"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("List releases")),
|
||||||
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.WithBoolean("is_draft", mcp.Description("Whether the release is draft"), mcp.DefaultBool(false)),
|
mcp.WithBoolean("is_draft", mcp.Description("Whether the release is draft"), mcp.DefaultBool(false)),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -29,6 +30,7 @@ var (
|
|||||||
CreateRepoTool = mcp.NewTool(
|
CreateRepoTool = mcp.NewTool(
|
||||||
CreateRepoToolName,
|
CreateRepoToolName,
|
||||||
mcp.WithDescription("Create repository in personal account or organization"),
|
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("name", mcp.Required(), mcp.Description("Name of the repository to create")),
|
||||||
mcp.WithString("description", mcp.Description("Description 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")),
|
mcp.WithBoolean("private", mcp.Description("Whether the repository is private")),
|
||||||
@@ -47,6 +49,7 @@ var (
|
|||||||
ForkRepoTool = mcp.NewTool(
|
ForkRepoTool = mcp.NewTool(
|
||||||
ForkRepoToolName,
|
ForkRepoToolName,
|
||||||
mcp.WithDescription("Fork repository"),
|
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("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("repo", mcp.Required(), mcp.Description("Repository name to fork")),
|
||||||
mcp.WithString("organization", mcp.Description("Organization name to fork")),
|
mcp.WithString("organization", mcp.Description("Organization name to fork")),
|
||||||
@@ -56,6 +59,7 @@ var (
|
|||||||
ListMyReposTool = mcp.NewTool(
|
ListMyReposTool = mcp.NewTool(
|
||||||
ListMyReposToolName,
|
ListMyReposToolName,
|
||||||
mcp.WithDescription("List my repositories"),
|
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("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)),
|
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(
|
ListOrgReposTool = mcp.NewTool(
|
||||||
ListOrgReposToolName,
|
ListOrgReposToolName,
|
||||||
mcp.WithDescription("List repositories of an organization"),
|
mcp.WithDescription("List repositories of an organization"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("List organization repositories")),
|
||||||
mcp.WithString("org", mcp.Required(), mcp.Description("Organization name")),
|
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("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)),
|
mcp.WithNumber("pageSize", mcp.Required(), mcp.Description("Page size number"), mcp.DefaultNumber(100), mcp.Min(1)),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -25,6 +26,7 @@ var (
|
|||||||
CreateTagTool = mcp.NewTool(
|
CreateTagTool = mcp.NewTool(
|
||||||
CreateTagToolName,
|
CreateTagToolName,
|
||||||
mcp.WithDescription("Create tag"),
|
mcp.WithDescription("Create tag"),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Create a tag")),
|
||||||
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("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||||
@@ -35,6 +37,7 @@ var (
|
|||||||
DeleteTagTool = mcp.NewTool(
|
DeleteTagTool = mcp.NewTool(
|
||||||
DeleteTagToolName,
|
DeleteTagToolName,
|
||||||
mcp.WithDescription("Delete tag"),
|
mcp.WithDescription("Delete tag"),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a tag")),
|
||||||
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("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||||
@@ -43,6 +46,7 @@ var (
|
|||||||
GetTagTool = mcp.NewTool(
|
GetTagTool = mcp.NewTool(
|
||||||
GetTagToolName,
|
GetTagToolName,
|
||||||
mcp.WithDescription("Get tag"),
|
mcp.WithDescription("Get tag"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get tag details")),
|
||||||
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("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
||||||
@@ -51,6 +55,7 @@ var (
|
|||||||
ListTagsTool = mcp.NewTool(
|
ListTagsTool = mcp.NewTool(
|
||||||
ListTagsToolName,
|
ListTagsToolName,
|
||||||
mcp.WithDescription("List tags"),
|
mcp.WithDescription("List tags"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("List tags")),
|
||||||
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.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -21,6 +22,7 @@ const (
|
|||||||
var GetRepoTreeTool = mcp.NewTool(
|
var GetRepoTreeTool = mcp.NewTool(
|
||||||
GetRepoTreeToolName,
|
GetRepoTreeToolName,
|
||||||
mcp.WithDescription("Get the file tree of a repository"),
|
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("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("tree_sha", mcp.Required(), mcp.Description("SHA, branch name, or tag name")),
|
mcp.WithString("tree_sha", mcp.Required(), mcp.Description("SHA, branch name, or tag name")),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -29,6 +30,7 @@ var (
|
|||||||
SearchUsersTool = mcp.NewTool(
|
SearchUsersTool = mcp.NewTool(
|
||||||
SearchUsersToolName,
|
SearchUsersToolName,
|
||||||
mcp.WithDescription("search users"),
|
mcp.WithDescription("search users"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Search users")),
|
||||||
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
||||||
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
||||||
mcp.WithNumber("perPage", mcp.Description("results per page (may be capped by the server's MAX_RESPONSE_ITEMS setting, default 50)"), mcp.DefaultNumber(30)),
|
mcp.WithNumber("perPage", mcp.Description("results per page (may be capped by the server's MAX_RESPONSE_ITEMS setting, default 50)"), mcp.DefaultNumber(30)),
|
||||||
@@ -37,6 +39,7 @@ var (
|
|||||||
SearOrgTeamsTool = mcp.NewTool(
|
SearOrgTeamsTool = mcp.NewTool(
|
||||||
SearchOrgTeamsToolName,
|
SearchOrgTeamsToolName,
|
||||||
mcp.WithDescription("search organization teams"),
|
mcp.WithDescription("search organization teams"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Search organization teams")),
|
||||||
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
mcp.WithString("org", mcp.Required(), mcp.Description("organization name")),
|
||||||
mcp.WithString("query", mcp.Required(), mcp.Description("search organization teams")),
|
mcp.WithString("query", mcp.Required(), mcp.Description("search organization teams")),
|
||||||
mcp.WithBoolean("includeDescription", mcp.Description("include description?")),
|
mcp.WithBoolean("includeDescription", mcp.Description("include description?")),
|
||||||
@@ -47,6 +50,7 @@ var (
|
|||||||
SearchReposTool = mcp.NewTool(
|
SearchReposTool = mcp.NewTool(
|
||||||
SearchReposToolName,
|
SearchReposToolName,
|
||||||
mcp.WithDescription("search repos"),
|
mcp.WithDescription("search repos"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Search repositories")),
|
||||||
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
||||||
mcp.WithBoolean("keywordIsTopic", mcp.Description("KeywordIsTopic")),
|
mcp.WithBoolean("keywordIsTopic", mcp.Description("KeywordIsTopic")),
|
||||||
mcp.WithBoolean("keywordInDescription", mcp.Description("KeywordInDescription")),
|
mcp.WithBoolean("keywordInDescription", mcp.Description("KeywordInDescription")),
|
||||||
@@ -62,6 +66,7 @@ var (
|
|||||||
SearchIssuesTool = mcp.NewTool(
|
SearchIssuesTool = mcp.NewTool(
|
||||||
SearchIssuesToolName,
|
SearchIssuesToolName,
|
||||||
mcp.WithDescription("Search for issues and pull requests across all accessible repositories"),
|
mcp.WithDescription("Search for issues and pull requests across all accessible repositories"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Search issues")),
|
||||||
mcp.WithString("query", mcp.Required(), mcp.Description("search keyword")),
|
mcp.WithString("query", mcp.Required(), mcp.Description("search keyword")),
|
||||||
mcp.WithString("state", mcp.Description("filter by state: open, closed, all"), mcp.Enum("open", "closed", "all")),
|
mcp.WithString("state", mcp.Description("filter by state: open, closed, all"), mcp.Enum("open", "closed", "all")),
|
||||||
mcp.WithString("type", mcp.Description("filter by type: issues, pulls"), mcp.Enum("issues", "pulls")),
|
mcp.WithString("type", mcp.Description("filter by type: issues, pulls"), mcp.Enum("issues", "pulls")),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -27,6 +28,7 @@ var (
|
|||||||
TimetrackingReadTool = mcp.NewTool(
|
TimetrackingReadTool = mcp.NewTool(
|
||||||
TimetrackingReadToolName,
|
TimetrackingReadToolName,
|
||||||
mcp.WithDescription("Read time tracking data. Use method 'list_issue_times' for issue times, 'list_repo_times' for repository times, 'get_my_stopwatches' for active stopwatches, 'get_my_times' for all your tracked times."),
|
mcp.WithDescription("Read time tracking data. Use method 'list_issue_times' for issue times, 'list_repo_times' for repository times, 'get_my_stopwatches' for active stopwatches, 'get_my_times' for all your tracked times."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read tracked time")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_issue_times", "list_repo_times", "get_my_stopwatches", "get_my_times")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list_issue_times", "list_repo_times", "get_my_stopwatches", "get_my_times")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (required for 'list_issue_times', 'list_repo_times')")),
|
mcp.WithString("owner", mcp.Description("repository owner (required for 'list_issue_times', 'list_repo_times')")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for 'list_issue_times', 'list_repo_times')")),
|
mcp.WithString("repo", mcp.Description("repository name (required for 'list_issue_times', 'list_repo_times')")),
|
||||||
@@ -38,6 +40,7 @@ var (
|
|||||||
TimetrackingWriteTool = mcp.NewTool(
|
TimetrackingWriteTool = mcp.NewTool(
|
||||||
TimetrackingWriteToolName,
|
TimetrackingWriteToolName,
|
||||||
mcp.WithDescription("Manage time tracking: stopwatches and tracked time entries."),
|
mcp.WithDescription("Manage time tracking: stopwatches and tracked time entries."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Write("Add or manage tracked time")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("start_stopwatch", "stop_stopwatch", "delete_stopwatch", "add_time", "delete_time")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("start_stopwatch", "stop_stopwatch", "delete_stopwatch", "add_time", "delete_time")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (required for all methods)")),
|
mcp.WithString("owner", mcp.Description("repository owner (required for all methods)")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for all methods)")),
|
mcp.WithString("repo", mcp.Description("repository name (required for all methods)")),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -36,6 +37,7 @@ var (
|
|||||||
GetMyUserInfoTool = mcp.NewTool(
|
GetMyUserInfoTool = mcp.NewTool(
|
||||||
GetMyUserInfoToolName,
|
GetMyUserInfoToolName,
|
||||||
mcp.WithDescription("Get my user info"),
|
mcp.WithDescription("Get my user info"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get current user information")),
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetUserOrgsTool is the MCP tool for listing organizations for the authenticated user.
|
// GetUserOrgsTool is the MCP tool for listing organizations for the authenticated user.
|
||||||
@@ -43,6 +45,7 @@ var (
|
|||||||
GetUserOrgsTool = mcp.NewTool(
|
GetUserOrgsTool = mcp.NewTool(
|
||||||
GetUserOrgsToolName,
|
GetUserOrgsToolName,
|
||||||
mcp.WithDescription("Get organizations associated with the authenticated user"),
|
mcp.WithDescription("Get organizations associated with the authenticated user"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get user organizations")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(defaultPage)),
|
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(defaultPage)),
|
||||||
mcp.WithNumber("perPage", mcp.Description("results per page (may be capped by the server's MAX_RESPONSE_ITEMS setting, default 50)"), mcp.DefaultNumber(defaultPageSize)),
|
mcp.WithNumber("perPage", mcp.Description("results per page (may be capped by the server's MAX_RESPONSE_ITEMS setting, default 50)"), mcp.DefaultNumber(defaultPageSize)),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/flag"
|
"gitea.com/gitea/gitea-mcp/pkg/flag"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/to"
|
"gitea.com/gitea/gitea-mcp/pkg/to"
|
||||||
@@ -22,6 +23,7 @@ const (
|
|||||||
var GetGiteaMCPServerVersionTool = mcp.NewTool(
|
var GetGiteaMCPServerVersionTool = mcp.NewTool(
|
||||||
GetGiteaMCPServerVersion,
|
GetGiteaMCPServerVersion,
|
||||||
mcp.WithDescription("Get Gitea MCP Server Version"),
|
mcp.WithDescription("Get Gitea MCP Server Version"),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get server version")),
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"gitea.com/gitea/gitea-mcp/pkg/annotation"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||||
"gitea.com/gitea/gitea-mcp/pkg/params"
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
||||||
@@ -27,6 +28,7 @@ var (
|
|||||||
WikiReadTool = mcp.NewTool(
|
WikiReadTool = mcp.NewTool(
|
||||||
WikiReadToolName,
|
WikiReadToolName,
|
||||||
mcp.WithDescription("Read wiki page information. Use method 'list' to list pages, 'get' to get page content, 'get_revisions' for revision history."),
|
mcp.WithDescription("Read wiki page information. Use method 'list' to list pages, 'get' to get page content, 'get_revisions' for revision history."),
|
||||||
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read wiki pages")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list", "get", "get_revisions")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list", "get", "get_revisions")),
|
||||||
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")),
|
||||||
@@ -36,6 +38,7 @@ var (
|
|||||||
WikiWriteTool = mcp.NewTool(
|
WikiWriteTool = mcp.NewTool(
|
||||||
WikiWriteToolName,
|
WikiWriteToolName,
|
||||||
mcp.WithDescription("Create, update, or delete wiki pages."),
|
mcp.WithDescription("Create, update, or delete wiki pages."),
|
||||||
|
mcp.WithToolAnnotation(annotation.Destructive("Create, update, or delete wiki pages")),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "update", "delete")),
|
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("create", "update", "delete")),
|
||||||
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")),
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// Package annotation provides shared MCP tool annotation helpers.
|
||||||
|
package annotation
|
||||||
|
|
||||||
|
import "github.com/mark3labs/mcp-go/mcp"
|
||||||
|
|
||||||
|
// ReadOnly returns a ToolAnnotation for read-only tools.
|
||||||
|
func ReadOnly(title string) mcp.ToolAnnotation {
|
||||||
|
t := true
|
||||||
|
return mcp.ToolAnnotation{
|
||||||
|
Title: title,
|
||||||
|
ReadOnlyHint: &t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write returns a ToolAnnotation for write tools.
|
||||||
|
func Write(title string) mcp.ToolAnnotation {
|
||||||
|
f := false
|
||||||
|
return mcp.ToolAnnotation{
|
||||||
|
Title: title,
|
||||||
|
ReadOnlyHint: &f,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructive returns a ToolAnnotation for destructive write tools.
|
||||||
|
func Destructive(title string) mcp.ToolAnnotation {
|
||||||
|
f, t := false, true
|
||||||
|
return mcp.ToolAnnotation{
|
||||||
|
Title: title,
|
||||||
|
ReadOnlyHint: &f,
|
||||||
|
DestructiveHint: &t,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user