Trim tool schemas, add param aliases, new PR methods (#191)
- Tool list size reduced by 26.6% (43,032 → 31,599 bytes on the `tools/list` JSON-RPC response). - Trim redundant tool/param descriptions; shared description constants for `owner`/`repo`/`page`/`per_page`. - Schemas now use github-mcp-server param names directly: `issue_number` (was `index` on issue tools), `pull_number` (was `index` on PR tools), `path` (was `filePath`), `query` (was `keyword` on user/repo search), `per_page` (was `perPage`). - New PR read methods `get_files` and `get_status`; new PR write method `update_branch` (update PR branch from base). - `list_org_repos` now uses `per_page` (was `pageSize`). - `milestone_write` accepts `update` and `edit`. - `create_branch` `old_branch` is optional; Gitea defaults to the repo default branch. - Fix `list_commits` handler to honour optional `page`/`per_page` schema (was erroring out when callers omitted them). --- This PR was written with the help of Claude Opus 4.7 Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/191 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-committed-by: silverwind <me@silverwind.io>
This commit is contained in:
+17
-17
@@ -48,29 +48,29 @@ func toSecretMetas(secrets []*gitea_sdk.Secret) []secretMeta {
|
|||||||
var (
|
var (
|
||||||
ActionsConfigReadTool = mcp.NewTool(
|
ActionsConfigReadTool = mcp.NewTool(
|
||||||
ActionsConfigReadToolName,
|
ActionsConfigReadToolName,
|
||||||
mcp.WithDescription("Read Actions secrets and variables configuration."),
|
mcp.WithDescription("Read Actions secrets and variables."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read Actions secrets and variables")),
|
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.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("for repo methods")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("for repo methods")),
|
||||||
mcp.WithString("org", mcp.Description("organization name (required for org methods)")),
|
mcp.WithString("org", mcp.Description("for org methods")),
|
||||||
mcp.WithString("name", mcp.Description("variable name (required for get methods)")),
|
mcp.WithString("name", mcp.Description("for get methods")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), mcp.DefaultNumber(1), mcp.Min(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.Min(1)),
|
mcp.WithNumber("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
ActionsConfigWriteTool = mcp.NewTool(
|
ActionsConfigWriteTool = mcp.NewTool(
|
||||||
ActionsConfigWriteToolName,
|
ActionsConfigWriteToolName,
|
||||||
mcp.WithDescription("Manage Actions secrets and variables: create, update, or delete."),
|
mcp.WithDescription("Write Actions secrets and variables: upsert, create, update, delete."),
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Manage Actions secrets and variables")),
|
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.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("for repo methods")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("for repo methods")),
|
||||||
mcp.WithString("org", mcp.Description("organization name (required for org methods)")),
|
mcp.WithString("org", mcp.Description("for org methods")),
|
||||||
mcp.WithString("name", mcp.Description("secret or variable name (required for most methods)")),
|
mcp.WithString("name", mcp.Description("secret or variable name")),
|
||||||
mcp.WithString("data", mcp.Description("secret value (required for upsert secret methods)")),
|
mcp.WithString("data", mcp.Description("secret value (upsert)")),
|
||||||
mcp.WithString("value", mcp.Description("variable value (required for create/update variable methods)")),
|
mcp.WithString("value", mcp.Description("variable value")),
|
||||||
mcp.WithString("description", mcp.Description("description for secret or variable")),
|
mcp.WithString("description"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+21
-21
@@ -28,33 +28,33 @@ const (
|
|||||||
var (
|
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 workflows, runs, jobs, and logs."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read Actions workflow, run, and job data")),
|
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.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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("workflow_id", mcp.Description("workflow ID or filename (required for 'get_workflow')")),
|
mcp.WithString("workflow_id", mcp.Description("ID or filename (for 'get_workflow')")),
|
||||||
mcp.WithNumber("run_id", mcp.Description("run ID (required for 'get_run', 'list_run_jobs')")),
|
mcp.WithNumber("run_id", mcp.Description("for 'get_run'/'list_run_jobs'")),
|
||||||
mcp.WithNumber("job_id", mcp.Description("job ID (required for 'get_job_log_preview', 'download_job_log')")),
|
mcp.WithNumber("job_id", mcp.Description("for log methods")),
|
||||||
mcp.WithString("status", mcp.Description("optional status filter (for 'list_runs', 'list_jobs')")),
|
mcp.WithString("status", mcp.Description("filter for 'list_runs'/'list_jobs'")),
|
||||||
mcp.WithNumber("tail_lines", mcp.Description("number of lines from end of log (for 'get_job_log_preview')"), mcp.DefaultNumber(200), mcp.Min(1)),
|
mcp.WithNumber("tail_lines", mcp.Description("log tail lines"), mcp.DefaultNumber(200), mcp.Min(1)),
|
||||||
mcp.WithNumber("max_bytes", mcp.Description("max bytes to return (for 'get_job_log_preview')"), mcp.DefaultNumber(65536), mcp.Min(1024)),
|
mcp.WithNumber("max_bytes", mcp.Description("max log bytes"), mcp.DefaultNumber(65536), mcp.Min(1024)),
|
||||||
mcp.WithString("output_path", mcp.Description("output file path (for 'download_job_log')")),
|
mcp.WithString("output_path", mcp.Description("for 'download_job_log'")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), mcp.DefaultNumber(1), mcp.Min(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.Min(1)),
|
mcp.WithNumber("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
ActionsRunWriteTool = mcp.NewTool(
|
ActionsRunWriteTool = mcp.NewTool(
|
||||||
ActionsRunWriteToolName,
|
ActionsRunWriteToolName,
|
||||||
mcp.WithDescription("Trigger, cancel, or rerun Actions workflows."),
|
mcp.WithDescription("Write Actions runs: dispatch, cancel, rerun."),
|
||||||
mcp.WithToolAnnotation(annotation.Write("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.Enum("dispatch_workflow", "cancel_run", "rerun_run")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("workflow_id", mcp.Description("workflow ID or filename (required for 'dispatch_workflow')")),
|
mcp.WithString("workflow_id", mcp.Description("ID or filename (for 'dispatch_workflow')")),
|
||||||
mcp.WithString("ref", mcp.Description("git ref branch or tag (required for 'dispatch_workflow')")),
|
mcp.WithString("ref", mcp.Description("branch or tag (for 'dispatch_workflow')")),
|
||||||
mcp.WithObject("inputs", mcp.Description("workflow inputs object (for 'dispatch_workflow')")),
|
mcp.WithObject("inputs", mcp.Description("for 'dispatch_workflow'")),
|
||||||
mcp.WithNumber("run_id", mcp.Description("run ID (required for 'cancel_run', 'rerun_run')")),
|
mcp.WithNumber("run_id", mcp.Description("for 'cancel_run'/'rerun_run'")),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+38
-39
@@ -40,47 +40,46 @@ const (
|
|||||||
var (
|
var (
|
||||||
ListRepoIssuesTool = mcp.NewTool(
|
ListRepoIssuesTool = mcp.NewTool(
|
||||||
ListRepoIssuesToolName,
|
ListRepoIssuesToolName,
|
||||||
mcp.WithDescription("List repository issues"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("state", mcp.Description("issue state"), mcp.DefaultString("all")),
|
mcp.WithString("state", mcp.DefaultString("all")),
|
||||||
mcp.WithArray("labels", mcp.Description("filter by label names"), mcp.Items(map[string]any{"type": "string"})),
|
mcp.WithArray("labels", mcp.Description("label name filter"), mcp.Items(map[string]any{"type": "string"})),
|
||||||
mcp.WithString("since", mcp.Description("filter issues updated after this ISO 8601 timestamp")),
|
mcp.WithString("since", mcp.Description("updated after ISO 8601")),
|
||||||
mcp.WithString("before", mcp.Description("filter issues updated before this ISO 8601 timestamp")),
|
mcp.WithString("before", mcp.Description("updated before ISO 8601")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
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("Read issue: details, comments, or labels."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read issue details")),
|
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.Enum("get", "get_comments", "get_labels")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("index", mcp.Required(), mcp.Description("repository issue index")),
|
mcp.WithNumber("issue_number", mcp.Required()),
|
||||||
)
|
)
|
||||||
|
|
||||||
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("Write issues: create, update, manage comments and labels."),
|
||||||
mcp.WithToolAnnotation(annotation.Write("Create or update issues, comments, and labels")),
|
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.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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("index", mcp.Description("issue index (required for all methods except 'create')")),
|
mcp.WithNumber("issue_number", mcp.Description("required except for 'create'")),
|
||||||
mcp.WithString("title", mcp.Description("issue title (required for 'create')")),
|
mcp.WithString("title", mcp.Description("required for 'create'")),
|
||||||
mcp.WithString("body", mcp.Description("issue/comment body (required for 'create', 'add_comment', 'edit_comment')")),
|
mcp.WithString("body", mcp.Description("required for 'create'/'add_comment'/'edit_comment'")),
|
||||||
mcp.WithArray("assignees", mcp.Description("usernames to assign (for 'create', 'update')"), mcp.Items(map[string]any{"type": "string"})),
|
mcp.WithArray("assignees", mcp.Items(map[string]any{"type": "string"})),
|
||||||
mcp.WithNumber("milestone", mcp.Description("milestone number (for 'create', 'update')")),
|
mcp.WithNumber("milestone"),
|
||||||
mcp.WithString("state", mcp.Description("issue state, one of open, closed, all (for 'update')")),
|
mcp.WithString("state", mcp.Enum("open", "closed", "all")),
|
||||||
mcp.WithNumber("commentID", mcp.Description("id of issue comment (required for 'edit_comment')")),
|
mcp.WithNumber("commentID", mcp.Description("for 'edit_comment'")),
|
||||||
mcp.WithArray("labels", mcp.Description("array of label IDs (for 'create', 'add_labels', 'replace_labels')"), mcp.Items(map[string]any{"type": "number"})),
|
mcp.WithArray("labels", mcp.Description("label IDs"), mcp.Items(map[string]any{"type": "number"})),
|
||||||
mcp.WithNumber("label_id", mcp.Description("label ID to remove (required for 'remove_label')")),
|
mcp.WithNumber("label_id", mcp.Description("for 'remove_label'")),
|
||||||
mcp.WithString("ref", mcp.Description("branch name to associate with the issue (for 'create', 'update')")),
|
mcp.WithString("ref", mcp.Description("branch to associate")),
|
||||||
mcp.WithString("deadline", mcp.Description("due date in ISO 8601 format (for 'create', 'update')")),
|
mcp.WithString("deadline", mcp.Description("ISO 8601")),
|
||||||
mcp.WithBoolean("remove_deadline", mcp.Description("unset due date (for 'update')")),
|
mcp.WithBoolean("remove_deadline"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -155,7 +154,7 @@ func getIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -267,7 +266,7 @@ func createIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -300,7 +299,7 @@ func editIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -388,7 +387,7 @@ func getIssueCommentsByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -416,7 +415,7 @@ func getIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -444,7 +443,7 @@ func addIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -474,7 +473,7 @@ func replaceIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -504,7 +503,7 @@ func clearIssueLabelsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -530,7 +529,7 @@ func removeIssueLabelFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ func Test_getIssueByIndexFn_includesAttachments(t *testing.T) {
|
|||||||
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
||||||
|
|
||||||
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
||||||
"owner": owner, "repo": repo, "index": float64(42),
|
"owner": owner, "repo": repo, "issue_number": float64(42),
|
||||||
}}}
|
}}}
|
||||||
res, err := getIssueByIndexFn(context.Background(), req)
|
res, err := getIssueByIndexFn(context.Background(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -250,7 +250,7 @@ func Test_getIssueCommentsByIndexFn_includesAttachments(t *testing.T) {
|
|||||||
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
||||||
|
|
||||||
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
||||||
"owner": owner, "repo": repo, "index": float64(7),
|
"owner": owner, "repo": repo, "issue_number": float64(7),
|
||||||
}}}
|
}}}
|
||||||
res, err := getIssueCommentsByIndexFn(context.Background(), req)
|
res, err := getIssueCommentsByIndexFn(context.Background(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+19
-19
@@ -26,31 +26,31 @@ const (
|
|||||||
var (
|
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 repo or org labels."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read 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.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("for repo methods")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("for repo methods")),
|
||||||
mcp.WithString("org", mcp.Description("organization name (required for 'list_org')")),
|
mcp.WithString("org", mcp.Description("for org methods")),
|
||||||
mcp.WithNumber("id", mcp.Description("label ID (required for 'get_repo')")),
|
mcp.WithNumber("id", mcp.Description("label ID (for 'get_repo_label')")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
LabelWriteTool = mcp.NewTool(
|
LabelWriteTool = mcp.NewTool(
|
||||||
LabelWriteToolName,
|
LabelWriteToolName,
|
||||||
mcp.WithDescription("Create, edit, or delete labels for repositories or organizations."),
|
mcp.WithDescription("Write labels (repo or org): create, edit, delete."),
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Create, update, or delete labels")),
|
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.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("for repo methods")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for repo methods)")),
|
mcp.WithString("repo", mcp.Description("for repo methods")),
|
||||||
mcp.WithString("org", mcp.Description("organization name (required for org methods)")),
|
mcp.WithString("org", mcp.Description("for org methods")),
|
||||||
mcp.WithNumber("id", mcp.Description("label ID (required for edit/delete methods)")),
|
mcp.WithNumber("id", mcp.Description("for edit/delete")),
|
||||||
mcp.WithString("name", mcp.Description("label name (required for create, optional for edit)")),
|
mcp.WithString("name", mcp.Description("required for create")),
|
||||||
mcp.WithString("color", mcp.Description("label color hex code e.g. #RRGGBB (required for create, optional for edit)")),
|
mcp.WithString("color", mcp.Description("hex (#RRGGBB); required for create")),
|
||||||
mcp.WithString("description", mcp.Description("label description")),
|
mcp.WithString("description"),
|
||||||
mcp.WithBoolean("exclusive", mcp.Description("whether the label is exclusive (org labels only)")),
|
mcp.WithBoolean("exclusive", mcp.Description("exclusive (org only)")),
|
||||||
mcp.WithBoolean("is_archived", mcp.Description("whether the label is archived (for create/edit repo label methods)")),
|
mcp.WithBoolean("is_archived", mcp.Description("archived (repo only)")),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,30 +26,30 @@ const (
|
|||||||
var (
|
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 milestones: get one or list."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read 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.Enum("get", "list")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("id", mcp.Description("milestone id (required for 'get')")),
|
mcp.WithNumber("id", mcp.Description("for 'get'")),
|
||||||
mcp.WithString("state", mcp.Description("milestone state (for 'list')"), mcp.DefaultString("all")),
|
mcp.WithString("state", mcp.DefaultString("all")),
|
||||||
mcp.WithString("name", mcp.Description("milestone name filter (for 'list')")),
|
mcp.WithString("name", mcp.Description("name filter (for 'list')")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
MilestoneWriteTool = mcp.NewTool(
|
MilestoneWriteTool = mcp.NewTool(
|
||||||
MilestoneWriteToolName,
|
MilestoneWriteToolName,
|
||||||
mcp.WithDescription("Create, edit, or delete milestones."),
|
mcp.WithDescription("Write milestones: create, update, delete."),
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Create, update, 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.Enum("create", "update", "edit", "delete")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("id", mcp.Description("milestone id (required for 'edit', 'delete')")),
|
mcp.WithNumber("id", mcp.Description("for 'update'/'delete'")),
|
||||||
mcp.WithString("title", mcp.Description("milestone title (required for 'create')")),
|
mcp.WithString("title", mcp.Description("for 'create'")),
|
||||||
mcp.WithString("description", mcp.Description("milestone description")),
|
mcp.WithString("description"),
|
||||||
mcp.WithString("due_on", mcp.Description("due date")),
|
mcp.WithString("due_on", mcp.Description("due date")),
|
||||||
mcp.WithString("state", mcp.Description("milestone state, one of open, closed (for 'edit')")),
|
mcp.WithString("state", mcp.Enum("open", "closed")),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -87,6 +87,8 @@ func milestoneWriteFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
switch method {
|
switch method {
|
||||||
case "create":
|
case "create":
|
||||||
return createMilestoneFn(ctx, req)
|
return createMilestoneFn(ctx, req)
|
||||||
|
case "update":
|
||||||
|
return editMilestoneFn(ctx, req)
|
||||||
case "edit":
|
case "edit":
|
||||||
return editMilestoneFn(ctx, req)
|
return editMilestoneFn(ctx, req)
|
||||||
case "delete":
|
case "delete":
|
||||||
|
|||||||
@@ -27,29 +27,29 @@ const (
|
|||||||
var (
|
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("Read notifications: list (optionally scoped to a repo) or get a thread by ID."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read notifications")),
|
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.Enum("list", "get")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (for 'list' to scope to a repo)")),
|
mcp.WithString("owner", mcp.Description("scope 'list' to a repo")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (for 'list' to scope to a repo)")),
|
mcp.WithString("repo", mcp.Description("scope 'list' to a repo")),
|
||||||
mcp.WithNumber("id", mcp.Description("notification thread ID (required for 'get')")),
|
mcp.WithNumber("id", mcp.Description("thread ID (for 'get')")),
|
||||||
mcp.WithString("status", mcp.Description("filter by status (for 'list')"), mcp.Enum("unread", "read", "pinned")),
|
mcp.WithString("status", mcp.Enum("unread", "read", "pinned")),
|
||||||
mcp.WithString("subject_type", mcp.Description("filter by subject type (for 'list')"), mcp.Enum("Issue", "Pull", "Commit", "Repository")),
|
mcp.WithString("subject_type", mcp.Enum("Issue", "Pull", "Commit", "Repository")),
|
||||||
mcp.WithString("since", mcp.Description("filter notifications updated after this ISO 8601 timestamp (for 'list')")),
|
mcp.WithString("since", mcp.Description("updated after ISO 8601")),
|
||||||
mcp.WithString("before", mcp.Description("filter notifications updated before this ISO 8601 timestamp (for 'list')")),
|
mcp.WithString("before", mcp.Description("updated before ISO 8601")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
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("Mark a notification or all notifications as read."),
|
||||||
mcp.WithToolAnnotation(annotation.Write("Manage notifications")),
|
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.Enum("mark_read", "mark_all_read")),
|
||||||
mcp.WithNumber("id", mcp.Description("notification thread ID (required for 'mark_read')")),
|
mcp.WithNumber("id", mcp.Description("thread ID (for 'mark_read')")),
|
||||||
mcp.WithString("owner", mcp.Description("repository owner (for 'mark_all_read' to scope to a repo)")),
|
mcp.WithString("owner", mcp.Description("scope 'mark_all_read' to a repo")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (for 'mark_all_read' to scope to a repo)")),
|
mcp.WithString("repo", mcp.Description("scope 'mark_all_read' to a repo")),
|
||||||
mcp.WithString("last_read_at", mcp.Description("ISO 8601 timestamp, marks notifications before this time as read (for 'mark_all_read', defaults to now)")),
|
mcp.WithString("last_read_at", mcp.Description("ISO 8601; defaults to now")),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -29,26 +29,26 @@ var (
|
|||||||
PackageReadTool = mcp.NewTool(
|
PackageReadTool = mcp.NewTool(
|
||||||
PackageReadToolName,
|
PackageReadToolName,
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read package registry")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Read package registry")),
|
||||||
mcp.WithDescription("Read package registry information. Use method 'list' to list all packages of an owner (returns one entry per version, use 'q' or 'type' to filter), 'list_versions' to list versions of a specific package, 'get' to get details of a specific package version."),
|
mcp.WithDescription("Read package registry: list packages (one entry per version, filter via 'q'/'type'), list versions, or get a version."),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("list", "list_versions", "get")),
|
mcp.WithString("method", mcp.Required(), mcp.Enum("list", "list_versions", "get")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("package owner (user or org)")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("user or org")),
|
||||||
mcp.WithString("type", mcp.Description("package type, e.g. container, npm, maven, pypi, cargo, generic (optional filter for 'list', required for 'list_versions' and 'get')")),
|
mcp.WithString("type", mcp.Description("container/npm/maven/pypi/cargo/generic; required except 'list'")),
|
||||||
mcp.WithString("name", mcp.Description("package name, slashes encoded automatically e.g. 'my-repo/my-image' (required for 'list_versions' and 'get')")),
|
mcp.WithString("name", mcp.Description("slashes auto-encoded; required except 'list'")),
|
||||||
mcp.WithString("version", mcp.Description("package version (required for 'get')")),
|
mcp.WithString("version", mcp.Description("for 'get'")),
|
||||||
mcp.WithString("q", mcp.Description("search query (for 'list')")),
|
mcp.WithString("q", mcp.Description("search query")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), mcp.DefaultNumber(1), mcp.Min(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.Min(1)),
|
mcp.WithNumber("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
PackageWriteTool = mcp.NewTool(
|
PackageWriteTool = mcp.NewTool(
|
||||||
PackageWriteToolName,
|
PackageWriteToolName,
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a package version")),
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a package version")),
|
||||||
mcp.WithDescription("Modify the package registry. Use method 'delete' to delete a specific package version. This is destructive and irreversible."),
|
mcp.WithDescription("Delete a package version (irreversible)."),
|
||||||
mcp.WithString("method", mcp.Required(), mcp.Description("operation to perform"), mcp.Enum("delete")),
|
mcp.WithString("method", mcp.Required(), mcp.Enum("delete")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("package owner (user or org)")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description("user or org")),
|
||||||
mcp.WithString("type", mcp.Required(), mcp.Description("package type, e.g. container, npm, maven, pypi, cargo, generic")),
|
mcp.WithString("type", mcp.Required(), mcp.Description("container/npm/maven/pypi/cargo/generic")),
|
||||||
mcp.WithString("name", mcp.Required(), mcp.Description("package name, slashes encoded automatically e.g. 'my-repo/my-image'")),
|
mcp.WithString("name", mcp.Required(), mcp.Description("slashes auto-encoded")),
|
||||||
mcp.WithString("version", mcp.Required(), mcp.Description("package version")),
|
mcp.WithString("version", mcp.Required()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -94,10 +94,10 @@ func TestPackageReadList(t *testing.T) {
|
|||||||
t.Run("with pagination", func(t *testing.T) {
|
t.Run("with pagination", func(t *testing.T) {
|
||||||
req := mcp.CallToolRequest{}
|
req := mcp.CallToolRequest{}
|
||||||
req.Params.Arguments = map[string]any{
|
req.Params.Arguments = map[string]any{
|
||||||
"method": "list",
|
"method": "list",
|
||||||
"owner": "test-org",
|
"owner": "test-org",
|
||||||
"page": float64(2),
|
"page": float64(2),
|
||||||
"perPage": float64(10),
|
"per_page": float64(10),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := packageReadFn(ctx, req)
|
_, err := packageReadFn(ctx, req)
|
||||||
|
|||||||
+164
-73
@@ -30,82 +30,81 @@ const (
|
|||||||
var (
|
var (
|
||||||
ListRepoPullRequestsTool = mcp.NewTool(
|
ListRepoPullRequestsTool = mcp.NewTool(
|
||||||
ListRepoPullRequestsToolName,
|
ListRepoPullRequestsToolName,
|
||||||
mcp.WithDescription("List repository pull requests"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("List 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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("state", mcp.Description("state"), mcp.Enum("open", "closed", "all"), mcp.DefaultString("all")),
|
mcp.WithString("state", mcp.Enum("open", "closed", "all"), mcp.DefaultString("all")),
|
||||||
mcp.WithString("sort", mcp.Description("sort"), mcp.Enum("oldest", "recentupdate", "leastupdate", "mostcomment", "leastcomment", "priority"), mcp.DefaultString("recentupdate")),
|
mcp.WithString("sort", mcp.Enum("oldest", "recentupdate", "leastupdate", "mostcomment", "leastcomment", "priority"), mcp.DefaultString("recentupdate")),
|
||||||
mcp.WithNumber("milestone", mcp.Description("milestone")),
|
mcp.WithNumber("milestone"),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
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("Read pull request: details, diff, changed files, head commit status, reviews."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read pull request details")),
|
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.Enum("get", "get_diff", "get_files", "get_status", "get_reviews", "get_review", "get_review_comments")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("index", mcp.Required(), mcp.Description("pull request index")),
|
mcp.WithNumber("pull_number", mcp.Required()),
|
||||||
mcp.WithNumber("review_id", mcp.Description("review ID (required for 'get_review', 'get_review_comments')")),
|
mcp.WithNumber("review_id", mcp.Description("for 'get_review'/'get_review_comments'")),
|
||||||
mcp.WithBoolean("binary", mcp.Description("whether to include binary file changes (for 'get_diff')")),
|
mcp.WithBoolean("binary", mcp.Description("include binary diff")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
PullRequestWriteTool = mcp.NewTool(
|
PullRequestWriteTool = mcp.NewTool(
|
||||||
PullRequestWriteToolName,
|
PullRequestWriteToolName,
|
||||||
mcp.WithDescription("Create, update, close, reopen, or merge pull requests, manage reviewers."),
|
mcp.WithDescription("Write pull requests: create, update, close, reopen, merge, update branch from base, manage reviewers."),
|
||||||
mcp.WithToolAnnotation(annotation.Write("Create, update, close, reopen, or merge pull requests")),
|
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("method", mcp.Required(), mcp.Enum("create", "update", "close", "reopen", "merge", "update_branch", "add_reviewers", "remove_reviewers")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("index", mcp.Description("pull request index (required for all methods except 'create')")),
|
mcp.WithNumber("pull_number", mcp.Description("required except for 'create'")),
|
||||||
mcp.WithString("title", mcp.Description("PR title (required for 'create', optional for 'update', 'merge')")),
|
mcp.WithString("title", mcp.Description("required for 'create'; optional for 'update'/'merge'")),
|
||||||
mcp.WithString("body", mcp.Description("PR body (required for 'create', optional for 'update')")),
|
mcp.WithString("body", mcp.Description("required for 'create'; optional for 'update'")),
|
||||||
mcp.WithString("head", mcp.Description("PR head branch (required for 'create')")),
|
mcp.WithString("head", mcp.Description("head branch (required for 'create')")),
|
||||||
mcp.WithString("base", mcp.Description("PR base branch (required for 'create', optional for 'update')")),
|
mcp.WithString("base", mcp.Description("base branch (required for 'create')")),
|
||||||
mcp.WithString("assignee", mcp.Description("username to assign (for 'update')")),
|
mcp.WithString("assignee", mcp.Description("for 'update'")),
|
||||||
mcp.WithArray("assignees", mcp.Description("usernames to assign (for 'update')"), mcp.Items(map[string]any{"type": "string"})),
|
mcp.WithArray("assignees", mcp.Description("for 'update'"), mcp.Items(map[string]any{"type": "string"})),
|
||||||
mcp.WithNumber("milestone", mcp.Description("milestone number (for 'update')")),
|
mcp.WithNumber("milestone", mcp.Description("for 'update'")),
|
||||||
mcp.WithString("state", mcp.Description("PR state (for 'update')"), mcp.Enum("open", "closed")),
|
mcp.WithString("state", mcp.Description("for 'update'"), mcp.Enum("open", "closed")),
|
||||||
mcp.WithBoolean("allow_maintainer_edit", mcp.Description("allow maintainer to edit (for 'update')")),
|
mcp.WithBoolean("allow_maintainer_edit", mcp.Description("for 'update'")),
|
||||||
mcp.WithArray("labels", mcp.Description("array of label IDs (for 'create', 'update')"), mcp.Items(map[string]any{"type": "number"})),
|
mcp.WithArray("labels", mcp.Description("label IDs"), mcp.Items(map[string]any{"type": "number"})),
|
||||||
mcp.WithString("deadline", mcp.Description("due date in ISO 8601 format (for 'create', 'update')")),
|
mcp.WithString("deadline", mcp.Description("ISO 8601")),
|
||||||
mcp.WithBoolean("remove_deadline", mcp.Description("unset due date (for 'update')")),
|
mcp.WithBoolean("remove_deadline", mcp.Description("for 'update'")),
|
||||||
mcp.WithString("merge_style", mcp.Description("merge style (for 'merge')"), mcp.Enum("merge", "rebase", "rebase-merge", "squash", "fast-forward-only"), mcp.DefaultString("merge")),
|
mcp.WithString("merge_style", mcp.Description("for 'merge'"), mcp.Enum("merge", "rebase", "rebase-merge", "squash", "fast-forward-only"), mcp.DefaultString("merge")),
|
||||||
mcp.WithString("message", mcp.Description("merge commit message (for 'merge') or dismissal reason")),
|
mcp.WithString("message", mcp.Description("merge commit message or dismissal reason")),
|
||||||
mcp.WithBoolean("delete_branch", mcp.Description("delete branch after merge (for 'merge')")),
|
mcp.WithBoolean("delete_branch", mcp.Description("for 'merge'")),
|
||||||
mcp.WithBoolean("force_merge", mcp.Description("force merge even if checks are not passing (for 'merge')")),
|
mcp.WithBoolean("force_merge", mcp.Description("merge even if checks fail")),
|
||||||
mcp.WithBoolean("merge_when_checks_succeed", mcp.Description("auto-merge when checks succeed (for 'merge')")),
|
mcp.WithBoolean("merge_when_checks_succeed", mcp.Description("for 'merge'")),
|
||||||
mcp.WithString("head_commit_id", mcp.Description("expected head commit SHA for merge conflict detection (for 'merge')")),
|
mcp.WithString("head_commit_id", mcp.Description("expected head SHA for conflict detection")),
|
||||||
mcp.WithArray("reviewers", mcp.Description("reviewer usernames (for 'add_reviewers', 'remove_reviewers')"), mcp.Items(map[string]any{"type": "string"})),
|
mcp.WithArray("reviewers", mcp.Description("for 'add_reviewers'/'remove_reviewers'"), mcp.Items(map[string]any{"type": "string"})),
|
||||||
mcp.WithArray("team_reviewers", mcp.Description("team reviewer names (for 'add_reviewers', 'remove_reviewers')"), mcp.Items(map[string]any{"type": "string"})),
|
mcp.WithArray("team_reviewers", mcp.Description("for 'add_reviewers'/'remove_reviewers'"), mcp.Items(map[string]any{"type": "string"})),
|
||||||
mcp.WithBoolean("draft", mcp.Description("mark PR as draft (for 'create', 'update'). Gitea uses a 'WIP: ' title prefix for drafts.")),
|
mcp.WithBoolean("draft", mcp.Description("uses 'WIP: ' title prefix")),
|
||||||
)
|
)
|
||||||
|
|
||||||
PullRequestReviewWriteTool = mcp.NewTool(
|
PullRequestReviewWriteTool = mcp.NewTool(
|
||||||
PullRequestReviewWriteToolName,
|
PullRequestReviewWriteToolName,
|
||||||
mcp.WithDescription("Manage pull request reviews: create, submit, delete, or dismiss."),
|
mcp.WithDescription("Write PR reviews: create, submit, delete, dismiss."),
|
||||||
mcp.WithToolAnnotation(annotation.Write("Submit a pull request review")),
|
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.Enum("create", "submit", "delete", "dismiss")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("index", mcp.Required(), mcp.Description("pull request index")),
|
mcp.WithNumber("pull_number", mcp.Required()),
|
||||||
mcp.WithNumber("review_id", mcp.Description("review ID (required for 'submit', 'delete', 'dismiss')")),
|
mcp.WithNumber("review_id", mcp.Description("required except for 'create'")),
|
||||||
mcp.WithString("state", mcp.Description("review state"), mcp.Enum("APPROVED", "REQUEST_CHANGES", "COMMENT", "PENDING")),
|
mcp.WithString("state", mcp.Enum("APPROVED", "REQUEST_CHANGES", "COMMENT", "PENDING")),
|
||||||
mcp.WithString("body", mcp.Description("review body/comment")),
|
mcp.WithString("body"),
|
||||||
mcp.WithString("commit_id", mcp.Description("commit SHA to review (for 'create')")),
|
mcp.WithString("commit_id", mcp.Description("for 'create'")),
|
||||||
mcp.WithString("message", mcp.Description("dismissal reason (for 'dismiss')")),
|
mcp.WithString("message", mcp.Description("dismissal reason")),
|
||||||
mcp.WithArray("comments", mcp.Description("inline review comments (for 'create')"), mcp.Items(map[string]any{
|
mcp.WithArray("comments", mcp.Description("inline comments (for 'create')"), mcp.Items(map[string]any{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": map[string]any{
|
"properties": map[string]any{
|
||||||
"path": map[string]any{"type": "string", "description": "file path to comment on"},
|
"path": map[string]any{"type": "string"},
|
||||||
"body": map[string]any{"type": "string", "description": "comment body"},
|
"body": map[string]any{"type": "string"},
|
||||||
"old_line_num": map[string]any{"type": "number", "description": "line number in the old file (for deletions/changes)"},
|
"old_line_num": map[string]any{"type": "number", "description": "old-file line (deletions)"},
|
||||||
"new_line_num": map[string]any{"type": "number", "description": "line number in the new file (for additions/changes)"},
|
"new_line_num": map[string]any{"type": "number", "description": "new-file line (additions)"},
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
@@ -140,6 +139,10 @@ func pullRequestReadFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
return getPullRequestByIndexFn(ctx, req)
|
return getPullRequestByIndexFn(ctx, req)
|
||||||
case "get_diff":
|
case "get_diff":
|
||||||
return getPullRequestDiffFn(ctx, req)
|
return getPullRequestDiffFn(ctx, req)
|
||||||
|
case "get_files":
|
||||||
|
return getPullRequestFilesFn(ctx, req)
|
||||||
|
case "get_status":
|
||||||
|
return getPullRequestStatusFn(ctx, req)
|
||||||
case "get_reviews":
|
case "get_reviews":
|
||||||
return listPullRequestReviewsFn(ctx, req)
|
return listPullRequestReviewsFn(ctx, req)
|
||||||
case "get_review":
|
case "get_review":
|
||||||
@@ -167,6 +170,8 @@ func pullRequestWriteFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
return reopenPullRequestFn(ctx, req)
|
return reopenPullRequestFn(ctx, req)
|
||||||
case "merge":
|
case "merge":
|
||||||
return mergePullRequestFn(ctx, req)
|
return mergePullRequestFn(ctx, req)
|
||||||
|
case "update_branch":
|
||||||
|
return updatePullRequestBranchFn(ctx, req)
|
||||||
case "add_reviewers":
|
case "add_reviewers":
|
||||||
return createPullRequestReviewerFn(ctx, req)
|
return createPullRequestReviewerFn(ctx, req)
|
||||||
case "remove_reviewers":
|
case "remove_reviewers":
|
||||||
@@ -185,7 +190,7 @@ func closePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -215,7 +220,7 @@ func reopenPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -266,7 +271,7 @@ func getPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -303,7 +308,7 @@ func getPullRequestDiffFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -446,7 +451,7 @@ func createPullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -489,7 +494,7 @@ func deletePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -532,7 +537,7 @@ func listPullRequestReviewsFn(ctx context.Context, req mcp.CallToolRequest) (*mc
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -567,7 +572,7 @@ func getPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -600,7 +605,7 @@ func listPullRequestReviewCommentsFn(ctx context.Context, req mcp.CallToolReques
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -633,7 +638,7 @@ func createPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -698,7 +703,7 @@ func submitPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -742,7 +747,7 @@ func deletePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -782,7 +787,7 @@ func dismissPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -827,7 +832,7 @@ func mergePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -891,7 +896,7 @@ func editPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(args, "index")
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -960,3 +965,89 @@ func editPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
|
|
||||||
return to.TextResult(slimPullRequest(pr))
|
return to.TextResult(slimPullRequest(pr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updatePullRequestBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
|
log.Debugf("Called updatePullRequestBranchFn")
|
||||||
|
args := req.GetArguments()
|
||||||
|
owner, err := params.GetString(args, "owner")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.Sprintf("repos/%s/%s/pulls/%d/update", url.PathEscape(owner), url.PathEscape(repo), index)
|
||||||
|
if _, err := gitea.DoJSON(ctx, "POST", path, nil, nil, nil); err != nil {
|
||||||
|
return to.ErrorResult(fmt.Errorf("update %v/%v/pr/%v branch err: %v", owner, repo, index, err))
|
||||||
|
}
|
||||||
|
return to.TextResult(map[string]any{"message": "branch updated from base"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPullRequestFilesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
|
log.Debugf("Called getPullRequestFilesFn")
|
||||||
|
args := req.GetArguments()
|
||||||
|
owner, err := params.GetString(args, "owner")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
page, pageSize := params.GetPagination(args, 30)
|
||||||
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||||
|
}
|
||||||
|
files, _, err := client.ListPullRequestFiles(owner, repo, index, gitea_sdk.ListPullRequestFilesOptions{
|
||||||
|
ListOptions: gitea_sdk.ListOptions{Page: page, PageSize: pageSize},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v files err: %v", owner, repo, index, err))
|
||||||
|
}
|
||||||
|
return to.TextResult(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPullRequestStatusFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
|
log.Debugf("Called getPullRequestStatusFn")
|
||||||
|
args := req.GetArguments()
|
||||||
|
owner, err := params.GetString(args, "owner")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
repo, err := params.GetString(args, "repo")
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(err)
|
||||||
|
}
|
||||||
|
index, err := params.GetIndex(args, "pull_number")
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
pr, _, err := client.GetPullRequest(owner, repo, index)
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||||
|
}
|
||||||
|
if pr.Head == nil || pr.Head.Sha == "" {
|
||||||
|
return to.ErrorResult(fmt.Errorf("pr %v/%v/%v has no head SHA", owner, repo, index))
|
||||||
|
}
|
||||||
|
|
||||||
|
status, _, err := client.GetCombinedStatus(owner, repo, pr.Head.Sha)
|
||||||
|
if err != nil {
|
||||||
|
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v status err: %v", owner, repo, index, err))
|
||||||
|
}
|
||||||
|
return to.TextResult(status)
|
||||||
|
}
|
||||||
|
|||||||
+25
-25
@@ -80,11 +80,11 @@ func Test_editPullRequestFn(t *testing.T) {
|
|||||||
req := mcp.CallToolRequest{
|
req := mcp.CallToolRequest{
|
||||||
Params: mcp.CallToolParams{
|
Params: mcp.CallToolParams{
|
||||||
Arguments: map[string]any{
|
Arguments: map[string]any{
|
||||||
"owner": owner,
|
"owner": owner,
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"index": ii.val,
|
"pull_number": ii.val,
|
||||||
"title": "WIP: my feature",
|
"title": "WIP: my feature",
|
||||||
"state": "open",
|
"state": "open",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ func Test_mergePullRequestFn(t *testing.T) {
|
|||||||
Arguments: map[string]any{
|
Arguments: map[string]any{
|
||||||
"owner": owner,
|
"owner": owner,
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"index": ii.val,
|
"pull_number": ii.val,
|
||||||
"merge_style": "squash",
|
"merge_style": "squash",
|
||||||
"title": "feat: my squashed commit",
|
"title": "feat: my squashed commit",
|
||||||
"message": "Squash merge of PR #5",
|
"message": "Squash merge of PR #5",
|
||||||
@@ -308,7 +308,7 @@ func Test_mergePullRequestFn_newParams(t *testing.T) {
|
|||||||
Arguments: map[string]any{
|
Arguments: map[string]any{
|
||||||
"owner": owner,
|
"owner": owner,
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"index": float64(index),
|
"pull_number": float64(index),
|
||||||
"merge_style": "merge",
|
"merge_style": "merge",
|
||||||
"force_merge": true,
|
"force_merge": true,
|
||||||
"merge_when_checks_succeed": true,
|
"merge_when_checks_succeed": true,
|
||||||
@@ -616,9 +616,9 @@ func Test_editPullRequestFn_draft(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
args := map[string]any{
|
args := map[string]any{
|
||||||
"owner": owner,
|
"owner": owner,
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"index": float64(index),
|
"pull_number": float64(index),
|
||||||
}
|
}
|
||||||
if tc.title != "" {
|
if tc.title != "" {
|
||||||
args["title"] = tc.title
|
args["title"] = tc.title
|
||||||
@@ -720,10 +720,10 @@ func Test_getPullRequestDiffFn(t *testing.T) {
|
|||||||
req := mcp.CallToolRequest{
|
req := mcp.CallToolRequest{
|
||||||
Params: mcp.CallToolParams{
|
Params: mcp.CallToolParams{
|
||||||
Arguments: map[string]any{
|
Arguments: map[string]any{
|
||||||
"owner": owner,
|
"owner": owner,
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"index": ii.val,
|
"pull_number": ii.val,
|
||||||
"binary": true,
|
"binary": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -805,7 +805,7 @@ func Test_getPullRequestByIndexFn_includesAttachments(t *testing.T) {
|
|||||||
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
||||||
|
|
||||||
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
||||||
"owner": owner, "repo": repo, "index": float64(index),
|
"owner": owner, "repo": repo, "pull_number": float64(index),
|
||||||
}}}
|
}}}
|
||||||
res, err := getPullRequestByIndexFn(context.Background(), req)
|
res, err := getPullRequestByIndexFn(context.Background(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -853,7 +853,7 @@ func Test_getPullRequestByIndexFn_emptyAssetsLeavesBody(t *testing.T) {
|
|||||||
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
||||||
|
|
||||||
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
||||||
"owner": owner, "repo": repo, "index": float64(index),
|
"owner": owner, "repo": repo, "pull_number": float64(index),
|
||||||
}}}
|
}}}
|
||||||
res, err := getPullRequestByIndexFn(context.Background(), req)
|
res, err := getPullRequestByIndexFn(context.Background(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -897,7 +897,7 @@ func Test_getPullRequestByIndexFn_assetsFailureNonFatal(t *testing.T) {
|
|||||||
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
defer func() { flag.Host, flag.Token, flag.Version = origHost, origToken, origVersion }()
|
||||||
|
|
||||||
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
req := mcp.CallToolRequest{Params: mcp.CallToolParams{Arguments: map[string]any{
|
||||||
"owner": owner, "repo": repo, "index": float64(index),
|
"owner": owner, "repo": repo, "pull_number": float64(index),
|
||||||
}}}
|
}}}
|
||||||
res, err := getPullRequestByIndexFn(context.Background(), req)
|
res, err := getPullRequestByIndexFn(context.Background(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -954,10 +954,10 @@ func Test_closePullRequestFn(t *testing.T) {
|
|||||||
req := mcp.CallToolRequest{
|
req := mcp.CallToolRequest{
|
||||||
Params: mcp.CallToolParams{
|
Params: mcp.CallToolParams{
|
||||||
Arguments: map[string]any{
|
Arguments: map[string]any{
|
||||||
"method": "close",
|
"method": "close",
|
||||||
"owner": owner,
|
"owner": owner,
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"index": float64(index),
|
"pull_number": float64(index),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1018,10 +1018,10 @@ func Test_reopenPullRequestFn(t *testing.T) {
|
|||||||
req := mcp.CallToolRequest{
|
req := mcp.CallToolRequest{
|
||||||
Params: mcp.CallToolParams{
|
Params: mcp.CallToolParams{
|
||||||
Arguments: map[string]any{
|
Arguments: map[string]any{
|
||||||
"method": "reopen",
|
"method": "reopen",
|
||||||
"owner": owner,
|
"owner": owner,
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"index": float64(index),
|
"pull_number": float64(index),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-14
@@ -24,31 +24,28 @@ const (
|
|||||||
var (
|
var (
|
||||||
CreateBranchTool = mcp.NewTool(
|
CreateBranchTool = mcp.NewTool(
|
||||||
CreateBranchToolName,
|
CreateBranchToolName,
|
||||||
mcp.WithDescription("Create branch"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Write("Create a new 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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("branch", mcp.Required(), mcp.Description("Name of the branch to create")),
|
mcp.WithString("branch", mcp.Required()),
|
||||||
mcp.WithString("old_branch", mcp.Required(), mcp.Description("Name of the old branch to create from")),
|
mcp.WithString("old_branch", mcp.Description("source branch (default: repo default)")),
|
||||||
)
|
)
|
||||||
|
|
||||||
DeleteBranchTool = mcp.NewTool(
|
DeleteBranchTool = mcp.NewTool(
|
||||||
DeleteBranchToolName,
|
DeleteBranchToolName,
|
||||||
mcp.WithDescription("Delete branch"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a branch")),
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a branch")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("branch", mcp.Required(), mcp.Description("Name of the branch to delete")),
|
mcp.WithString("branch", mcp.Required()),
|
||||||
)
|
)
|
||||||
|
|
||||||
ListBranchesTool = mcp.NewTool(
|
ListBranchesTool = mcp.NewTool(
|
||||||
ListBranchesToolName,
|
ListBranchesToolName,
|
||||||
mcp.WithDescription("List branches"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("List repository branches")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("List repository branches")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+12
-21
@@ -23,23 +23,21 @@ const (
|
|||||||
var (
|
var (
|
||||||
ListRepoCommitsTool = mcp.NewTool(
|
ListRepoCommitsTool = mcp.NewTool(
|
||||||
ListRepoCommitsToolName,
|
ListRepoCommitsToolName,
|
||||||
mcp.WithDescription("List repository commits"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("sha", mcp.Description("SHA or branch to start listing commits from")),
|
mcp.WithString("sha", mcp.Description("starting SHA or branch")),
|
||||||
mcp.WithString("path", mcp.Description("path indicates that only commits that include the path's file/dir should be returned.")),
|
mcp.WithString("path", mcp.Description("only commits touching this path")),
|
||||||
mcp.WithNumber("page", mcp.Required(), mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetCommitTool = mcp.NewTool(
|
GetCommitTool = mcp.NewTool(
|
||||||
GetCommitToolName,
|
GetCommitToolName,
|
||||||
mcp.WithDescription("Get details of a specific commit"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get commit details")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get commit details")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("sha", mcp.Required(), mcp.Description("commit SHA")),
|
mcp.WithString("sha", mcp.Required()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -65,20 +63,13 @@ func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page, err := params.GetIndex(args, "page")
|
page, pageSize := params.GetPagination(args, 30)
|
||||||
if err != nil {
|
|
||||||
return to.ErrorResult(err)
|
|
||||||
}
|
|
||||||
pageSize, err := params.GetIndex(args, "perPage")
|
|
||||||
if err != nil {
|
|
||||||
return to.ErrorResult(err)
|
|
||||||
}
|
|
||||||
sha, _ := args["sha"].(string)
|
sha, _ := args["sha"].(string)
|
||||||
path, _ := args["path"].(string)
|
path, _ := args["path"].(string)
|
||||||
opt := gitea_sdk.ListCommitOptions{
|
opt := gitea_sdk.ListCommitOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
SHA: sha,
|
SHA: sha,
|
||||||
Path: path,
|
Path: path,
|
||||||
|
|||||||
+27
-29
@@ -29,49 +29,47 @@ const (
|
|||||||
var (
|
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.WithToolAnnotation(annotation.ReadOnly("Get file content")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("ref", mcp.Required(), mcp.Description("ref can be branch/tag/commit")),
|
mcp.WithString("ref", mcp.Required(), mcp.Description("branch, tag, or commit SHA")),
|
||||||
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
mcp.WithString("path", mcp.Required()),
|
||||||
mcp.WithBoolean("withLines", mcp.Description("whether to return file content with lines")),
|
mcp.WithBoolean("withLines", mcp.Description("return numbered lines")),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetDirContentTool = mcp.NewTool(
|
GetDirContentTool = mcp.NewTool(
|
||||||
GetDirToolName,
|
GetDirToolName,
|
||||||
mcp.WithDescription("Get a list of entries in a directory"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get directory contents")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get directory contents")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("ref", mcp.Required(), mcp.Description("ref can be branch/tag/commit")),
|
mcp.WithString("ref", mcp.Required(), mcp.Description("branch, tag, or commit SHA")),
|
||||||
mcp.WithString("filePath", mcp.Required(), mcp.Description("directory path")),
|
mcp.WithString("path", mcp.Required()),
|
||||||
)
|
)
|
||||||
|
|
||||||
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 (provide sha to update an existing file)."),
|
||||||
mcp.WithToolAnnotation(annotation.Write("Create or update a 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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
mcp.WithString("path", mcp.Required()),
|
||||||
mcp.WithString("content", mcp.Required(), mcp.Description("file content")),
|
mcp.WithString("content", mcp.Required()),
|
||||||
mcp.WithString("message", mcp.Required(), mcp.Description("commit message")),
|
mcp.WithString("message", mcp.Required(), mcp.Description("commit message")),
|
||||||
mcp.WithString("branch_name", mcp.Required(), mcp.Description("branch name")),
|
mcp.WithString("branch_name", mcp.Required()),
|
||||||
mcp.WithString("sha", mcp.Description("SHA of the existing file (required for update, omit for create)")),
|
mcp.WithString("sha", mcp.Description("existing file SHA (omit to create)")),
|
||||||
mcp.WithString("new_branch_name", mcp.Description("new branch name (for create only)")),
|
mcp.WithString("new_branch_name", mcp.Description("new branch (create only)")),
|
||||||
)
|
)
|
||||||
|
|
||||||
DeleteFileTool = mcp.NewTool(
|
DeleteFileTool = mcp.NewTool(
|
||||||
DeleteFileToolName,
|
DeleteFileToolName,
|
||||||
mcp.WithDescription("Delete file"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a file")),
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a file")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("filePath", mcp.Required(), mcp.Description("file path")),
|
mcp.WithString("path", mcp.Required()),
|
||||||
mcp.WithString("message", mcp.Required(), mcp.Description("commit message")),
|
mcp.WithString("message", mcp.Required(), mcp.Description("commit message")),
|
||||||
mcp.WithString("branch_name", mcp.Required(), mcp.Description("branch name")),
|
mcp.WithString("branch_name", mcp.Required()),
|
||||||
mcp.WithString("sha", mcp.Required(), mcp.Description("sha")),
|
mcp.WithString("sha", mcp.Required()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -111,7 +109,7 @@ func GetFileContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
ref, _ := args["ref"].(string)
|
ref, _ := args["ref"].(string)
|
||||||
filePath, err := params.GetString(args, "filePath")
|
filePath, err := params.GetString(args, "path")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -175,7 +173,7 @@ func GetDirContentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
ref, _ := args["ref"].(string)
|
ref, _ := args["ref"].(string)
|
||||||
filePath, err := params.GetString(args, "filePath")
|
filePath, err := params.GetString(args, "path")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -201,7 +199,7 @@ func CreateOrUpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
filePath, err := params.GetString(args, "filePath")
|
filePath, err := params.GetString(args, "path")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -261,7 +259,7 @@ func DeleteFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
filePath, err := params.GetString(args, "filePath")
|
filePath, err := params.GetString(args, "path")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-28
@@ -26,54 +26,50 @@ const (
|
|||||||
var (
|
var (
|
||||||
CreateReleaseTool = mcp.NewTool(
|
CreateReleaseTool = mcp.NewTool(
|
||||||
CreateReleaseToolName,
|
CreateReleaseToolName,
|
||||||
mcp.WithDescription("Create release"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Write("Create a release")),
|
mcp.WithToolAnnotation(annotation.Write("Create a release")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required()),
|
||||||
mcp.WithString("target", mcp.Required(), mcp.Description("target commitish")),
|
mcp.WithString("target", mcp.Required(), mcp.Description("commitish")),
|
||||||
mcp.WithString("title", mcp.Required(), mcp.Description("release title")),
|
mcp.WithString("title", mcp.Required()),
|
||||||
mcp.WithBoolean("is_draft", mcp.Description("Whether the release is draft"), mcp.DefaultBool(false)),
|
mcp.WithBoolean("is_draft"),
|
||||||
mcp.WithBoolean("is_pre_release", mcp.Description("Whether the release is pre-release"), mcp.DefaultBool(false)),
|
mcp.WithBoolean("is_pre_release"),
|
||||||
mcp.WithString("body", mcp.Description("release body")),
|
mcp.WithString("body"),
|
||||||
)
|
)
|
||||||
|
|
||||||
DeleteReleaseTool = mcp.NewTool(
|
DeleteReleaseTool = mcp.NewTool(
|
||||||
DeleteReleaseToolName,
|
DeleteReleaseToolName,
|
||||||
mcp.WithDescription("Delete release"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a release")),
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a release")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
mcp.WithNumber("id", mcp.Required()),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetReleaseTool = mcp.NewTool(
|
GetReleaseTool = mcp.NewTool(
|
||||||
GetReleaseToolName,
|
GetReleaseToolName,
|
||||||
mcp.WithDescription("Get release"),
|
mcp.WithDescription("Get a release by ID"),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get release details")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get release details")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("id", mcp.Required(), mcp.Description("release id")),
|
mcp.WithNumber("id", mcp.Required()),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetLatestReleaseTool = mcp.NewTool(
|
GetLatestReleaseTool = mcp.NewTool(
|
||||||
GetLatestReleaseToolName,
|
GetLatestReleaseToolName,
|
||||||
mcp.WithDescription("Get latest release"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
)
|
)
|
||||||
|
|
||||||
ListReleasesTool = mcp.NewTool(
|
ListReleasesTool = mcp.NewTool(
|
||||||
ListReleasesToolName,
|
ListReleasesToolName,
|
||||||
mcp.WithDescription("List releases"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("List releases")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("List releases")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithBoolean("is_draft", mcp.Description("Whether the release is draft"), mcp.DefaultBool(false)),
|
mcp.WithBoolean("is_draft"),
|
||||||
mcp.WithBoolean("is_pre_release", mcp.Description("Whether the release is pre-release"), mcp.DefaultBool(false)),
|
mcp.WithBoolean("is_pre_release"),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("perPage", mcp.Description("results per page (may be capped by the server's MAX_RESPONSE_ITEMS setting, default 50)"), mcp.DefaultNumber(20), mcp.Min(1)),
|
mcp.WithNumber("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(20), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -248,7 +244,7 @@ func ListReleasesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
pIsPreRelease = new(isPreRelease)
|
pIsPreRelease = new(isPreRelease)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(args, "page", 1)
|
page := params.GetOptionalInt(args, "page", 1)
|
||||||
pageSize := params.GetOptionalInt(args, "perPage", 20)
|
pageSize := params.GetOptionalInt(args, "per_page", 20)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+25
-36
@@ -29,48 +29,44 @@ const (
|
|||||||
var (
|
var (
|
||||||
CreateRepoTool = mcp.NewTool(
|
CreateRepoTool = mcp.NewTool(
|
||||||
CreateRepoToolName,
|
CreateRepoToolName,
|
||||||
mcp.WithDescription("Create repository in personal account or organization"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Write("Create a new repository")),
|
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.WithString("description", mcp.Description("Description of the repository to create")),
|
mcp.WithString("description"),
|
||||||
mcp.WithBoolean("private", mcp.Description("Whether the repository is private")),
|
mcp.WithBoolean("private"),
|
||||||
mcp.WithString("issue_labels", mcp.Description("Issue Label set to use")),
|
mcp.WithString("issue_labels"),
|
||||||
mcp.WithBoolean("auto_init", mcp.Description("Whether the repository should be auto-intialized?")),
|
mcp.WithBoolean("auto_init"),
|
||||||
mcp.WithBoolean("template", mcp.Description("Whether the repository is template")),
|
mcp.WithBoolean("template"),
|
||||||
mcp.WithString("gitignores", mcp.Description("Gitignores to use")),
|
mcp.WithString("gitignores"),
|
||||||
mcp.WithString("license", mcp.Description("License to use")),
|
mcp.WithString("license"),
|
||||||
mcp.WithString("readme", mcp.Description("Readme of the repository to create")),
|
mcp.WithString("readme"),
|
||||||
mcp.WithString("default_branch", mcp.Description("DefaultBranch of the repository (used when initializes and in template)")),
|
mcp.WithString("default_branch"),
|
||||||
mcp.WithString("trust_model", mcp.Description("Trust model for verifying GPG signatures"), mcp.Enum("default", "collaborator", "committer", "collaboratorcommitter")),
|
mcp.WithString("trust_model", mcp.Enum("default", "collaborator", "committer", "collaboratorcommitter")),
|
||||||
mcp.WithString("object_format_name", mcp.Description("Object format: sha1 or sha256"), mcp.Enum("sha1", "sha256")),
|
mcp.WithString("object_format_name", mcp.Enum("sha1", "sha256")),
|
||||||
mcp.WithString("organization", mcp.Description("Organization name to create repository in (optional - defaults to personal account)")),
|
mcp.WithString("organization", mcp.Description("defaults to personal account")),
|
||||||
)
|
)
|
||||||
|
|
||||||
ForkRepoTool = mcp.NewTool(
|
ForkRepoTool = mcp.NewTool(
|
||||||
ForkRepoToolName,
|
ForkRepoToolName,
|
||||||
mcp.WithDescription("Fork repository"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Write("Fork a 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("owner of source repo")),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("Repository name to fork")),
|
mcp.WithString("repo", mcp.Required()),
|
||||||
mcp.WithString("organization", mcp.Description("Organization name to fork")),
|
mcp.WithString("organization", mcp.Description("target org")),
|
||||||
mcp.WithString("name", mcp.Description("Name of the forked repository")),
|
mcp.WithString("name", mcp.Description("fork name")),
|
||||||
)
|
)
|
||||||
|
|
||||||
ListMyReposTool = mcp.NewTool(
|
ListMyReposTool = mcp.NewTool(
|
||||||
ListMyReposToolName,
|
ListMyReposToolName,
|
||||||
mcp.WithDescription("List my repositories"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("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.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
ListOrgReposTool = mcp.NewTool(
|
ListOrgReposTool = mcp.NewTool(
|
||||||
ListOrgReposToolName,
|
ListOrgReposToolName,
|
||||||
mcp.WithDescription("List repositories of an organization"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("List organization repositories")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("List organization repositories")),
|
||||||
mcp.WithString("org", mcp.Required(), mcp.Description("Organization name")),
|
mcp.WithString("org", mcp.Required()),
|
||||||
mcp.WithNumber("page", mcp.Required(), mcp.Description("Page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("pageSize", mcp.Required(), mcp.Description("Page size number"), mcp.DefaultNumber(100), mcp.Min(1)),
|
mcp.WithNumber("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(100), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -210,18 +206,11 @@ func ListOrgReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool
|
|||||||
if !ok {
|
if !ok {
|
||||||
return to.ErrorResult(errors.New("organization name is required"))
|
return to.ErrorResult(errors.New("organization name is required"))
|
||||||
}
|
}
|
||||||
page, ok := req.GetArguments()["page"].(float64)
|
page, pageSize := params.GetPagination(req.GetArguments(), 100)
|
||||||
if !ok {
|
|
||||||
page = 1
|
|
||||||
}
|
|
||||||
pageSize, ok := req.GetArguments()["pageSize"].(float64)
|
|
||||||
if !ok {
|
|
||||||
pageSize = 100
|
|
||||||
}
|
|
||||||
opt := gitea_sdk.ListOrgReposOptions{
|
opt := gitea_sdk.ListOrgReposOptions{
|
||||||
ListOptions: gitea_sdk.ListOptions{
|
ListOptions: gitea_sdk.ListOptions{
|
||||||
Page: int(page),
|
Page: page,
|
||||||
PageSize: int(pageSize),
|
PageSize: pageSize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
|
|||||||
+16
-20
@@ -25,41 +25,37 @@ const (
|
|||||||
var (
|
var (
|
||||||
CreateTagTool = mcp.NewTool(
|
CreateTagTool = mcp.NewTool(
|
||||||
CreateTagToolName,
|
CreateTagToolName,
|
||||||
mcp.WithDescription("Create tag"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Write("Create a tag")),
|
mcp.WithToolAnnotation(annotation.Write("Create a tag")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required()),
|
||||||
mcp.WithString("target", mcp.Description("target commitish"), mcp.DefaultString("")),
|
mcp.WithString("target", mcp.Description("commitish")),
|
||||||
mcp.WithString("message", mcp.Description("tag message"), mcp.DefaultString("")),
|
mcp.WithString("message", mcp.Description("tag message")),
|
||||||
)
|
)
|
||||||
|
|
||||||
DeleteTagTool = mcp.NewTool(
|
DeleteTagTool = mcp.NewTool(
|
||||||
DeleteTagToolName,
|
DeleteTagToolName,
|
||||||
mcp.WithDescription("Delete tag"),
|
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("Delete a tag")),
|
mcp.WithToolAnnotation(annotation.Destructive("Delete a tag")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required()),
|
||||||
)
|
)
|
||||||
|
|
||||||
GetTagTool = mcp.NewTool(
|
GetTagTool = mcp.NewTool(
|
||||||
GetTagToolName,
|
GetTagToolName,
|
||||||
mcp.WithDescription("Get tag"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get tag details")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get tag details")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("tag_name", mcp.Required(), mcp.Description("tag name")),
|
mcp.WithString("tag_name", mcp.Required()),
|
||||||
)
|
)
|
||||||
|
|
||||||
ListTagsTool = mcp.NewTool(
|
ListTagsTool = mcp.NewTool(
|
||||||
ListTagsToolName,
|
ListTagsToolName,
|
||||||
mcp.WithDescription("List tags"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("List tags")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("List tags")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1), mcp.Min(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), mcp.DefaultNumber(1), mcp.Min(1)),
|
||||||
mcp.WithNumber("perPage", mcp.Description("results per page (may be capped by the server's MAX_RESPONSE_ITEMS setting, default 50)"), mcp.DefaultNumber(20), mcp.Min(1)),
|
mcp.WithNumber("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(20), mcp.Min(1)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -184,7 +180,7 @@ func ListTagsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
|
|||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
page := params.GetOptionalInt(args, "page", 1)
|
page := params.GetOptionalInt(args, "page", 1)
|
||||||
pageSize := params.GetOptionalInt(args, "perPage", 20)
|
pageSize := params.GetOptionalInt(args, "per_page", 20)
|
||||||
|
|
||||||
client, err := gitea.ClientFromContext(ctx)
|
client, err := gitea.ClientFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -21,14 +21,13 @@ const (
|
|||||||
|
|
||||||
var GetRepoTreeTool = mcp.NewTool(
|
var GetRepoTreeTool = mcp.NewTool(
|
||||||
GetRepoTreeToolName,
|
GetRepoTreeToolName,
|
||||||
mcp.WithDescription("Get the file tree of a repository"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get repository file tree")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get repository file tree")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("tree_sha", mcp.Required(), mcp.Description("SHA, branch name, or tag name")),
|
mcp.WithString("tree_sha", mcp.Required(), mcp.Description("SHA, branch, or tag")),
|
||||||
mcp.WithBoolean("recursive", mcp.Description("whether to get the tree recursively")),
|
mcp.WithBoolean("recursive"),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
+28
-31
@@ -29,51 +29,48 @@ const (
|
|||||||
var (
|
var (
|
||||||
SearchUsersTool = mcp.NewTool(
|
SearchUsersTool = mcp.NewTool(
|
||||||
SearchUsersToolName,
|
SearchUsersToolName,
|
||||||
mcp.WithDescription("search users"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Search users")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Search users")),
|
||||||
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
mcp.WithString("query", mcp.Required()),
|
||||||
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
SearOrgTeamsTool = mcp.NewTool(
|
SearOrgTeamsTool = mcp.NewTool(
|
||||||
SearchOrgTeamsToolName,
|
SearchOrgTeamsToolName,
|
||||||
mcp.WithDescription("search organization teams"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("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.WithString("query", mcp.Required(), mcp.Description("search organization teams")),
|
mcp.WithString("query", mcp.Required()),
|
||||||
mcp.WithBoolean("includeDescription", mcp.Description("include description?")),
|
mcp.WithBoolean("includeDescription"),
|
||||||
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
SearchReposTool = mcp.NewTool(
|
SearchReposTool = mcp.NewTool(
|
||||||
SearchReposToolName,
|
SearchReposToolName,
|
||||||
mcp.WithDescription("search repos"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Search repositories")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Search repositories")),
|
||||||
mcp.WithString("keyword", mcp.Required(), mcp.Description("Keyword")),
|
mcp.WithString("query", mcp.Required()),
|
||||||
mcp.WithBoolean("keywordIsTopic", mcp.Description("KeywordIsTopic")),
|
mcp.WithBoolean("keywordIsTopic"),
|
||||||
mcp.WithBoolean("keywordInDescription", mcp.Description("KeywordInDescription")),
|
mcp.WithBoolean("keywordInDescription"),
|
||||||
mcp.WithNumber("ownerID", mcp.Description("OwnerID")),
|
mcp.WithNumber("ownerID"),
|
||||||
mcp.WithBoolean("isPrivate", mcp.Description("IsPrivate")),
|
mcp.WithBoolean("isPrivate"),
|
||||||
mcp.WithBoolean("isArchived", mcp.Description("IsArchived")),
|
mcp.WithBoolean("isArchived"),
|
||||||
mcp.WithString("sort", mcp.Description("Sort")),
|
mcp.WithString("sort"),
|
||||||
mcp.WithString("order", mcp.Description("Order")),
|
mcp.WithString("order"),
|
||||||
mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
SearchIssuesTool = mcp.NewTool(
|
SearchIssuesTool = mcp.NewTool(
|
||||||
SearchIssuesToolName,
|
SearchIssuesToolName,
|
||||||
mcp.WithDescription("Search for issues and pull requests across all accessible repositories"),
|
mcp.WithDescription("Search issues and PRs across repositories"),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Search issues")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Search issues")),
|
||||||
mcp.WithString("query", mcp.Required(), mcp.Description("search keyword")),
|
mcp.WithString("query", mcp.Required()),
|
||||||
mcp.WithString("state", mcp.Description("filter by state: open, closed, all"), mcp.Enum("open", "closed", "all")),
|
mcp.WithString("state", mcp.Enum("open", "closed", "all")),
|
||||||
mcp.WithString("type", mcp.Description("filter by type: issues, pulls"), mcp.Enum("issues", "pulls")),
|
mcp.WithString("type", mcp.Enum("issues", "pulls")),
|
||||||
mcp.WithString("labels", mcp.Description("comma-separated list of label names")),
|
mcp.WithString("labels", mcp.Description("comma-separated")),
|
||||||
mcp.WithString("owner", mcp.Description("filter by repository owner")),
|
mcp.WithString("owner", mcp.Description("filter by owner")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -98,7 +95,7 @@ func init() {
|
|||||||
|
|
||||||
func UsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func UsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called UsersFn")
|
log.Debugf("Called UsersFn")
|
||||||
keyword, err := params.GetString(req.GetArguments(), "keyword")
|
keyword, err := params.GetString(req.GetArguments(), "query")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -154,7 +151,7 @@ func OrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResu
|
|||||||
|
|
||||||
func ReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func ReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
log.Debugf("Called ReposFn")
|
log.Debugf("Called ReposFn")
|
||||||
keyword, err := params.GetString(req.GetArguments(), "keyword")
|
keyword, err := params.GetString(req.GetArguments(), "query")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func TestSearchToolsRequiredFields(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "search_users",
|
name: "search_users",
|
||||||
tool: SearchUsersTool,
|
tool: SearchUsersTool,
|
||||||
required: []string{"keyword"},
|
required: []string{"query"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "search_org_teams",
|
name: "search_org_teams",
|
||||||
@@ -26,7 +26,7 @@ func TestSearchToolsRequiredFields(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "search_repos",
|
name: "search_repos",
|
||||||
tool: SearchReposTool,
|
tool: SearchReposTool,
|
||||||
required: []string{"keyword"},
|
required: []string{"query"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,26 +27,26 @@ const (
|
|||||||
var (
|
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: issue times, repo times, active stopwatches, your tracked times."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read tracked time")),
|
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.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("for list_* methods")),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for 'list_issue_times', 'list_repo_times')")),
|
mcp.WithString("repo", mcp.Description("for list_* methods")),
|
||||||
mcp.WithNumber("index", mcp.Description("issue index (required for 'list_issue_times')")),
|
mcp.WithNumber("issue_number", mcp.Description("for 'list_issue_times'")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(30)),
|
||||||
)
|
)
|
||||||
|
|
||||||
TimetrackingWriteTool = mcp.NewTool(
|
TimetrackingWriteTool = mcp.NewTool(
|
||||||
TimetrackingWriteToolName,
|
TimetrackingWriteToolName,
|
||||||
mcp.WithDescription("Manage time tracking: stopwatches and tracked time entries."),
|
mcp.WithDescription("Write time tracking: stopwatches and entries."),
|
||||||
mcp.WithToolAnnotation(annotation.Write("Add or manage tracked time")),
|
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.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(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Description("repository name (required for all methods)")),
|
mcp.WithString("repo", mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithNumber("index", mcp.Description("issue index (required for all methods)")),
|
mcp.WithNumber("issue_number"),
|
||||||
mcp.WithNumber("time", mcp.Description("time to add in seconds (required for 'add_time')")),
|
mcp.WithNumber("time", mcp.Description("seconds (for 'add_time')")),
|
||||||
mcp.WithNumber("id", mcp.Description("tracked time entry ID (required for 'delete_time')")),
|
mcp.WithNumber("id", mcp.Description("entry ID (for 'delete_time')")),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ func startStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ func stopStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ func deleteStopwatchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ func listTrackedTimesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ func addTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ func deleteTrackedTimeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
|
|||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
index, err := params.GetIndex(req.GetArguments(), "issue_number")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return to.ErrorResult(err)
|
return to.ErrorResult(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,18 +36,18 @@ var (
|
|||||||
// It is registered with a specific name and a description string.
|
// It is registered with a specific name and a description string.
|
||||||
GetMyUserInfoTool = mcp.NewTool(
|
GetMyUserInfoTool = mcp.NewTool(
|
||||||
GetMyUserInfoToolName,
|
GetMyUserInfoToolName,
|
||||||
mcp.WithDescription("Get my user info"),
|
mcp.WithDescription("Get current user"),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get current user information")),
|
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.
|
||||||
// It supports pagination via "page" and "perPage" arguments with default values specified above.
|
// It supports pagination via "page" and "per_page" arguments with default values specified above.
|
||||||
GetUserOrgsTool = mcp.NewTool(
|
GetUserOrgsTool = mcp.NewTool(
|
||||||
GetUserOrgsToolName,
|
GetUserOrgsToolName,
|
||||||
mcp.WithDescription("Get organizations associated with the authenticated user"),
|
mcp.WithDescription("List current user's organizations"),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get user organizations")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get user organizations")),
|
||||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(defaultPage)),
|
mcp.WithNumber("page", mcp.Description(params.PageDesc), 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("per_page", mcp.Description(params.PaginationDesc), mcp.DefaultNumber(defaultPageSize)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ const (
|
|||||||
|
|
||||||
var GetGiteaMCPServerVersionTool = mcp.NewTool(
|
var GetGiteaMCPServerVersionTool = mcp.NewTool(
|
||||||
GetGiteaMCPServerVersion,
|
GetGiteaMCPServerVersion,
|
||||||
mcp.WithDescription("Get Gitea MCP Server Version"),
|
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Get server version")),
|
mcp.WithToolAnnotation(annotation.ReadOnly("Get server version")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -27,24 +27,24 @@ const (
|
|||||||
var (
|
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: list pages, get content, revision history."),
|
||||||
mcp.WithToolAnnotation(annotation.ReadOnly("Read wiki pages")),
|
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.Enum("list", "get", "get_revisions")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("pageName", mcp.Description("wiki page name (required for 'get', 'get_revisions')")),
|
mcp.WithString("pageName", mcp.Description("for 'get'/'get_revisions'")),
|
||||||
)
|
)
|
||||||
|
|
||||||
WikiWriteTool = mcp.NewTool(
|
WikiWriteTool = mcp.NewTool(
|
||||||
WikiWriteToolName,
|
WikiWriteToolName,
|
||||||
mcp.WithDescription("Create, update, or delete wiki pages."),
|
mcp.WithDescription("Write wiki pages: create, update, delete."),
|
||||||
mcp.WithToolAnnotation(annotation.Destructive("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.Enum("create", "update", "delete")),
|
||||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
mcp.WithString("owner", mcp.Required(), mcp.Description(params.OwnerDesc)),
|
||||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
mcp.WithString("repo", mcp.Required(), mcp.Description(params.RepoDesc)),
|
||||||
mcp.WithString("pageName", mcp.Description("wiki page name (required for 'update', 'delete')")),
|
mcp.WithString("pageName", mcp.Description("for 'update'/'delete'")),
|
||||||
mcp.WithString("title", mcp.Description("wiki page title (required for 'create', optional for 'update')")),
|
mcp.WithString("title", mcp.Description("for 'create'")),
|
||||||
mcp.WithString("content", mcp.Description("page content (required for 'create', 'update')")),
|
mcp.WithString("content", mcp.Description("for 'create'/'update'")),
|
||||||
mcp.WithString("message", mcp.Description("commit message")),
|
mcp.WithString("message", mcp.Description("commit message")),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,27 +6,17 @@ import "github.com/mark3labs/mcp-go/mcp"
|
|||||||
// ReadOnly returns a ToolAnnotation for read-only tools.
|
// ReadOnly returns a ToolAnnotation for read-only tools.
|
||||||
func ReadOnly(title string) mcp.ToolAnnotation {
|
func ReadOnly(title string) mcp.ToolAnnotation {
|
||||||
t := true
|
t := true
|
||||||
return mcp.ToolAnnotation{
|
return mcp.ToolAnnotation{Title: title, ReadOnlyHint: &t}
|
||||||
Title: title,
|
|
||||||
ReadOnlyHint: &t,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write returns a ToolAnnotation for write tools.
|
// Write returns a ToolAnnotation for write tools.
|
||||||
func Write(title string) mcp.ToolAnnotation {
|
func Write(title string) mcp.ToolAnnotation {
|
||||||
f := false
|
f := false
|
||||||
return mcp.ToolAnnotation{
|
return mcp.ToolAnnotation{Title: title, ReadOnlyHint: &f}
|
||||||
Title: title,
|
|
||||||
ReadOnlyHint: &f,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructive returns a ToolAnnotation for destructive write tools.
|
// Destructive returns a ToolAnnotation for destructive write tools.
|
||||||
func Destructive(title string) mcp.ToolAnnotation {
|
func Destructive(title string) mcp.ToolAnnotation {
|
||||||
f, t := false, true
|
f, t := false, true
|
||||||
return mcp.ToolAnnotation{
|
return mcp.ToolAnnotation{Title: title, ReadOnlyHint: &f, DestructiveHint: &t}
|
||||||
Title: title,
|
|
||||||
ReadOnlyHint: &f,
|
|
||||||
DestructiveHint: &t,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-2
@@ -6,6 +6,16 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Shared parameter description strings used across tools. Extracted to avoid
|
||||||
|
// repeating the same boilerplate in every tool schema (saves tokens in the
|
||||||
|
// tool list sent to MCP clients).
|
||||||
|
const (
|
||||||
|
OwnerDesc = "repo owner"
|
||||||
|
RepoDesc = "repo name"
|
||||||
|
PageDesc = "page"
|
||||||
|
PaginationDesc = "results per page"
|
||||||
|
)
|
||||||
|
|
||||||
// GetString extracts a required string parameter from MCP tool arguments.
|
// GetString extracts a required string parameter from MCP tool arguments.
|
||||||
func GetString(args map[string]any, key string) (string, error) {
|
func GetString(args map[string]any, key string) (string, error) {
|
||||||
val, ok := args[key].(string)
|
val, ok := args[key].(string)
|
||||||
@@ -42,9 +52,9 @@ func GetStringSlice(args map[string]any, key string) []string {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPagination extracts page and perPage parameters, returning them as ints.
|
// GetPagination extracts page and per_page parameters, returning them as ints.
|
||||||
func GetPagination(args map[string]any, defaultPageSize int64) (page, pageSize int) {
|
func GetPagination(args map[string]any, defaultPageSize int64) (page, pageSize int) {
|
||||||
return int(GetOptionalInt(args, "page", 1)), int(GetOptionalInt(args, "perPage", defaultPageSize))
|
return int(GetOptionalInt(args, "page", 1)), int(GetOptionalInt(args, "per_page", defaultPageSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToInt64 converts a value to int64, accepting both float64 (JSON number) and
|
// ToInt64 converts a value to int64, accepting both float64 (JSON number) and
|
||||||
|
|||||||
@@ -5,6 +5,17 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestGetPagination(t *testing.T) {
|
||||||
|
page, perPage := GetPagination(map[string]any{"page": float64(2), "per_page": float64(40)}, 30)
|
||||||
|
if page != 2 || perPage != 40 {
|
||||||
|
t.Errorf("GetPagination = (%d, %d), want (2, 40)", page, perPage)
|
||||||
|
}
|
||||||
|
page, perPage = GetPagination(map[string]any{}, 30)
|
||||||
|
if page != 1 || perPage != 30 {
|
||||||
|
t.Errorf("GetPagination defaults = (%d, %d), want (1, 30)", page, perPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestToInt64(t *testing.T) {
|
func TestToInt64(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
Reference in New Issue
Block a user