diff --git a/.github/workflows/mcp-diff.yml b/.github/workflows/mcp-diff.yml index c0813bc3dc..eeb24eaea1 100644 --- a/.github/workflows/mcp-diff.yml +++ b/.github/workflows/mcp-diff.yml @@ -50,7 +50,12 @@ jobs: } >> "$GITHUB_OUTPUT" - name: Run MCP Server Diff - uses: SamMorrowDrums/mcp-server-diff@v2.3.5 + # Pinned to the cross-spec-aware mcp-server-diff v3.0.0 (full SHA required — + # Actions rejects shortened SHAs): normalizes _meta plumbing, cache hints, + # initialize envelope, tool-annotation default hints; probes each server at its + # own newest spec via the stateless SEP-2575 server/discover path. Keeps the + # go-sdk v1.6.1 -> v1.7.0-pre.1 bump an honest, signal-only diff. github/copilot-mcp-core#1709. + uses: SamMorrowDrums/mcp-server-diff@3521651bb0d3cc267a23df8d94a2a645556980a4 # v3.0.0 with: setup_go: "false" install_command: | @@ -114,7 +119,8 @@ jobs: } >> "$GITHUB_OUTPUT" - name: Run MCP Server Diff (streamable-http) - uses: SamMorrowDrums/mcp-server-diff@v2.3.5 + # Pinned to mcp-server-diff v3.0.0 — see rationale on the stdio job above. + uses: SamMorrowDrums/mcp-server-diff@3521651bb0d3cc267a23df8d94a2a645556980a4 # v3.0.0 with: setup_go: "false" install_command: | diff --git a/go.mod b/go.mod index 66c7a974ad..c2990f718a 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/josephburnett/jd/v2 v2.5.0 github.com/lithammer/fuzzysearch v1.1.8 github.com/microcosm-cc/bluemonday v1.0.27 - github.com/modelcontextprotocol/go-sdk v1.6.1 + github.com/modelcontextprotocol/go-sdk v1.7.0-pre.1 github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 github.com/shurcooL/githubv4 v0.0.0-20240727222349-48295856cce7 github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 @@ -41,8 +41,10 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/net v0.38.0 // indirect + golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.28.0 // indirect + golang.org/x/time v0.15.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index fbf06018f7..10b57f6f89 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,8 @@ github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8 github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= -github.com/modelcontextprotocol/go-sdk v1.6.1 h1:0zOSupjKUxPKSocPT1Wtago+mUHU2/uZ4xSOY0FGReU= -github.com/modelcontextprotocol/go-sdk v1.6.1/go.mod h1:kzm3kzFL1/+AziGOE0nUs3gvPoNxMCvkxokMkuFapXQ= +github.com/modelcontextprotocol/go-sdk v1.7.0-pre.1 h1:GlMIJyMHFX76bBSQuBCLXZ7pB9cGh4VBS6O5wGd0tgI= +github.com/modelcontextprotocol/go-sdk v1.7.0-pre.1/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts= github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 h1:31Y+Yu373ymebRdJN1cWLLooHH8xAr0MhKTEJGV/87g= github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021/go.mod h1:WERUkUryfUWlrHnFSO/BEUZ+7Ns8aZy7iVOGewxKzcc= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= @@ -99,6 +99,8 @@ golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwE golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -117,6 +119,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/pkg/github/__toolsnaps__/actions_get.snap b/pkg/github/__toolsnaps__/actions_get.snap index ba128875ee..661f379f5f 100644 --- a/pkg/github/__toolsnaps__/actions_get.snap +++ b/pkg/github/__toolsnaps__/actions_get.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get details of GitHub Actions resources (workflows, workflow runs, jobs, and artifacts)" }, diff --git a/pkg/github/__toolsnaps__/actions_list.snap b/pkg/github/__toolsnaps__/actions_list.snap index a7e9ec56bd..be97affbdb 100644 --- a/pkg/github/__toolsnaps__/actions_list.snap +++ b/pkg/github/__toolsnaps__/actions_list.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List GitHub Actions workflows in a repository" }, diff --git a/pkg/github/__toolsnaps__/actions_run_trigger.snap b/pkg/github/__toolsnaps__/actions_run_trigger.snap index 41a6439929..0c859b86ec 100644 --- a/pkg/github/__toolsnaps__/actions_run_trigger.snap +++ b/pkg/github/__toolsnaps__/actions_run_trigger.snap @@ -1,6 +1,8 @@ { "annotations": { "destructiveHint": true, + "idempotentHint": false, + "readOnlyHint": false, "title": "Trigger GitHub Actions workflow actions" }, "description": "Trigger GitHub Actions workflow operations, including running, re-running, cancelling workflow runs, and deleting workflow run logs.", diff --git a/pkg/github/__toolsnaps__/add_comment_to_pending_review.snap b/pkg/github/__toolsnaps__/add_comment_to_pending_review.snap index af4c41f52f..4a6e6ca9ba 100644 --- a/pkg/github/__toolsnaps__/add_comment_to_pending_review.snap +++ b/pkg/github/__toolsnaps__/add_comment_to_pending_review.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Add review comment to the requester's latest pending pull request review" }, "description": "Add review comment to the requester's latest pending pull request review. A pending review needs to already exist to call this (check with the user if not sure).", diff --git a/pkg/github/__toolsnaps__/add_issue_comment.snap b/pkg/github/__toolsnaps__/add_issue_comment.snap index 356edac2f1..f59431816e 100644 --- a/pkg/github/__toolsnaps__/add_issue_comment.snap +++ b/pkg/github/__toolsnaps__/add_issue_comment.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Add comment to issue or pull request" }, "description": "Add a comment and/or reaction to a specific issue or issue comment in a GitHub repository. Use this tool with pull requests as well (in this case pass pull request number as issue_number), but only if user is not asking specifically to add or react to review comments. At least one of body or reaction is required.", diff --git a/pkg/github/__toolsnaps__/add_issue_comment_reaction.snap b/pkg/github/__toolsnaps__/add_issue_comment_reaction.snap index 5e2953a46c..fea8434a62 100644 --- a/pkg/github/__toolsnaps__/add_issue_comment_reaction.snap +++ b/pkg/github/__toolsnaps__/add_issue_comment_reaction.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Add Reaction to Issue or Pull Request Comment" }, "description": "Add a reaction to an issue or pull request comment.", diff --git a/pkg/github/__toolsnaps__/add_issue_reaction.snap b/pkg/github/__toolsnaps__/add_issue_reaction.snap index db1148dee8..49175d1412 100644 --- a/pkg/github/__toolsnaps__/add_issue_reaction.snap +++ b/pkg/github/__toolsnaps__/add_issue_reaction.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Add Reaction to Issue or Pull Request" }, "description": "Add a reaction to an issue or pull request.", diff --git a/pkg/github/__toolsnaps__/add_pull_request_review_comment.snap b/pkg/github/__toolsnaps__/add_pull_request_review_comment.snap index 1e27c5645e..ae7450539d 100644 --- a/pkg/github/__toolsnaps__/add_pull_request_review_comment.snap +++ b/pkg/github/__toolsnaps__/add_pull_request_review_comment.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Add Pull Request Review Comment" }, "description": "Add a review comment to the current user's pending pull request review.", diff --git a/pkg/github/__toolsnaps__/add_pull_request_review_comment_reaction.snap b/pkg/github/__toolsnaps__/add_pull_request_review_comment_reaction.snap index e5fed3b013..aec4b38465 100644 --- a/pkg/github/__toolsnaps__/add_pull_request_review_comment_reaction.snap +++ b/pkg/github/__toolsnaps__/add_pull_request_review_comment_reaction.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Add Pull Request Review Comment Reaction" }, "description": "Add a reaction to a pull request review comment.", diff --git a/pkg/github/__toolsnaps__/add_reply_to_pull_request_comment.snap b/pkg/github/__toolsnaps__/add_reply_to_pull_request_comment.snap index a22720dcb6..a86ea3d4b5 100644 --- a/pkg/github/__toolsnaps__/add_reply_to_pull_request_comment.snap +++ b/pkg/github/__toolsnaps__/add_reply_to_pull_request_comment.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Add reply to pull request comment" }, "description": "Add a reply and/or reaction to an existing pull request comment. This can create a new comment linked as a reply to the specified comment, add an emoji reaction to the specified comment, or do both. At least one of body or reaction is required.", diff --git a/pkg/github/__toolsnaps__/add_sub_issue.snap b/pkg/github/__toolsnaps__/add_sub_issue.snap index ef9df400c6..a232507d4f 100644 --- a/pkg/github/__toolsnaps__/add_sub_issue.snap +++ b/pkg/github/__toolsnaps__/add_sub_issue.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Add Sub-Issue" }, "description": "Add a sub-issue to a parent issue.", diff --git a/pkg/github/__toolsnaps__/assign_copilot_to_issue.snap b/pkg/github/__toolsnaps__/assign_copilot_to_issue.snap index 9c105267bc..994d9f5709 100644 --- a/pkg/github/__toolsnaps__/assign_copilot_to_issue.snap +++ b/pkg/github/__toolsnaps__/assign_copilot_to_issue.snap @@ -1,6 +1,7 @@ { "annotations": { "idempotentHint": true, + "readOnlyHint": false, "title": "Assign Copilot to issue" }, "description": "Assign Copilot to a specific issue in a GitHub repository.\n\nThis tool can help with the following outcomes:\n- a Pull Request created with source code changes to resolve the issue\n\n\nMore information can be found at:\n- https://docs.github.com/en/copilot/using-github-copilot/using-copilot-coding-agent-to-work-on-tasks/about-assigning-tasks-to-copilot\n", diff --git a/pkg/github/__toolsnaps__/create_branch.snap b/pkg/github/__toolsnaps__/create_branch.snap index a561247ef1..e796405140 100644 --- a/pkg/github/__toolsnaps__/create_branch.snap +++ b/pkg/github/__toolsnaps__/create_branch.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Create branch" }, "description": "Create a new branch in a GitHub repository", diff --git a/pkg/github/__toolsnaps__/create_gist.snap b/pkg/github/__toolsnaps__/create_gist.snap index 0ef05aa4a7..f91810bd00 100644 --- a/pkg/github/__toolsnaps__/create_gist.snap +++ b/pkg/github/__toolsnaps__/create_gist.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Create Gist" }, "description": "Create a new gist", diff --git a/pkg/github/__toolsnaps__/create_issue.snap b/pkg/github/__toolsnaps__/create_issue.snap index 51923c47cc..e0963741ac 100644 --- a/pkg/github/__toolsnaps__/create_issue.snap +++ b/pkg/github/__toolsnaps__/create_issue.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Create Issue" }, "description": "Create a new issue in a GitHub repository with a title and optional body.", diff --git a/pkg/github/__toolsnaps__/create_or_update_file.snap b/pkg/github/__toolsnaps__/create_or_update_file.snap index e6900c9053..8feae6f934 100644 --- a/pkg/github/__toolsnaps__/create_or_update_file.snap +++ b/pkg/github/__toolsnaps__/create_or_update_file.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Create or update file" }, "description": "Create or update a single file in a GitHub repository. \nIf updating, you should provide the SHA of the file you want to update. Use this tool to create or update a file in a GitHub repository remotely; do not use it for local file operations.\n\nIn order to obtain the SHA of original file version before updating, use the following git command:\ngit rev-parse \u003cbranch\u003e:\u003cpath to file\u003e\n\nSHA MUST be provided for existing file updates.\n", diff --git a/pkg/github/__toolsnaps__/create_pull_request.snap b/pkg/github/__toolsnaps__/create_pull_request.snap index 3bd3404d49..acb74bcd7a 100644 --- a/pkg/github/__toolsnaps__/create_pull_request.snap +++ b/pkg/github/__toolsnaps__/create_pull_request.snap @@ -9,6 +9,8 @@ } }, "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Open new pull request" }, "description": "Create a new pull request in a GitHub repository.", diff --git a/pkg/github/__toolsnaps__/create_pull_request_review.snap b/pkg/github/__toolsnaps__/create_pull_request_review.snap index 1986b2cfff..f8bf3f12a8 100644 --- a/pkg/github/__toolsnaps__/create_pull_request_review.snap +++ b/pkg/github/__toolsnaps__/create_pull_request_review.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Create Pull Request Review" }, "description": "Create a review on a pull request. If event is provided, the review is submitted immediately; otherwise a pending review is created.", diff --git a/pkg/github/__toolsnaps__/create_repository.snap b/pkg/github/__toolsnaps__/create_repository.snap index 0aa2123673..d13cc69aa1 100644 --- a/pkg/github/__toolsnaps__/create_repository.snap +++ b/pkg/github/__toolsnaps__/create_repository.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Create repository" }, "description": "Create a new GitHub repository in your account or specified organization", diff --git a/pkg/github/__toolsnaps__/delete_file.snap b/pkg/github/__toolsnaps__/delete_file.snap index ff110ff786..4885c891d1 100644 --- a/pkg/github/__toolsnaps__/delete_file.snap +++ b/pkg/github/__toolsnaps__/delete_file.snap @@ -1,6 +1,8 @@ { "annotations": { "destructiveHint": true, + "idempotentHint": false, + "readOnlyHint": false, "title": "Delete file" }, "description": "Delete a file from a GitHub repository", diff --git a/pkg/github/__toolsnaps__/delete_pending_pull_request_review.snap b/pkg/github/__toolsnaps__/delete_pending_pull_request_review.snap index b457e415a8..f99f5d5632 100644 --- a/pkg/github/__toolsnaps__/delete_pending_pull_request_review.snap +++ b/pkg/github/__toolsnaps__/delete_pending_pull_request_review.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": true, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Delete Pending Pull Request Review" }, "description": "Delete a pending pull request review.", diff --git a/pkg/github/__toolsnaps__/discussion_comment_write.snap b/pkg/github/__toolsnaps__/discussion_comment_write.snap index 5edadfaeaa..eb730b48e7 100644 --- a/pkg/github/__toolsnaps__/discussion_comment_write.snap +++ b/pkg/github/__toolsnaps__/discussion_comment_write.snap @@ -1,6 +1,8 @@ { "annotations": { "destructiveHint": true, + "idempotentHint": false, + "readOnlyHint": false, "title": "Manage discussion comments" }, "description": "Write operations for discussion comments.\nSupports adding top-level comments, replying to existing comments, updating comment content, deleting comments, and marking or unmarking comments as the answer.", diff --git a/pkg/github/__toolsnaps__/dismiss_notification.snap b/pkg/github/__toolsnaps__/dismiss_notification.snap index 6c65d9ce05..6b2e38afd7 100644 --- a/pkg/github/__toolsnaps__/dismiss_notification.snap +++ b/pkg/github/__toolsnaps__/dismiss_notification.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Dismiss notification" }, "description": "Dismiss a notification by marking it as read or done", diff --git a/pkg/github/__toolsnaps__/fork_repository.snap b/pkg/github/__toolsnaps__/fork_repository.snap index d635734a95..1373ef0519 100644 --- a/pkg/github/__toolsnaps__/fork_repository.snap +++ b/pkg/github/__toolsnaps__/fork_repository.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Fork repository" }, "description": "Fork a GitHub repository to your account or specified organization", diff --git a/pkg/github/__toolsnaps__/get_code_quality_finding.snap b/pkg/github/__toolsnaps__/get_code_quality_finding.snap index 378efe835d..84ccb948e4 100644 --- a/pkg/github/__toolsnaps__/get_code_quality_finding.snap +++ b/pkg/github/__toolsnaps__/get_code_quality_finding.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get code quality finding" }, diff --git a/pkg/github/__toolsnaps__/get_code_scanning_alert.snap b/pkg/github/__toolsnaps__/get_code_scanning_alert.snap index 2a65aefa64..907870b03d 100644 --- a/pkg/github/__toolsnaps__/get_code_scanning_alert.snap +++ b/pkg/github/__toolsnaps__/get_code_scanning_alert.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get code scanning alert" }, diff --git a/pkg/github/__toolsnaps__/get_commit.snap b/pkg/github/__toolsnaps__/get_commit.snap index 122e6210b3..ad6a805515 100644 --- a/pkg/github/__toolsnaps__/get_commit.snap +++ b/pkg/github/__toolsnaps__/get_commit.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get commit details" }, diff --git a/pkg/github/__toolsnaps__/get_dependabot_alert.snap b/pkg/github/__toolsnaps__/get_dependabot_alert.snap index 78ff827d25..383e86a29e 100644 --- a/pkg/github/__toolsnaps__/get_dependabot_alert.snap +++ b/pkg/github/__toolsnaps__/get_dependabot_alert.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get dependabot alert" }, diff --git a/pkg/github/__toolsnaps__/get_discussion.snap b/pkg/github/__toolsnaps__/get_discussion.snap index b931afe79a..3f538d4e97 100644 --- a/pkg/github/__toolsnaps__/get_discussion.snap +++ b/pkg/github/__toolsnaps__/get_discussion.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get discussion" }, diff --git a/pkg/github/__toolsnaps__/get_discussion_comments.snap b/pkg/github/__toolsnaps__/get_discussion_comments.snap index 0dcd7343e7..a2705c9bf1 100644 --- a/pkg/github/__toolsnaps__/get_discussion_comments.snap +++ b/pkg/github/__toolsnaps__/get_discussion_comments.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get discussion comments" }, diff --git a/pkg/github/__toolsnaps__/get_file_blame.snap b/pkg/github/__toolsnaps__/get_file_blame.snap index 83d09f265c..33a09fea88 100644 --- a/pkg/github/__toolsnaps__/get_file_blame.snap +++ b/pkg/github/__toolsnaps__/get_file_blame.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get file blame information" }, diff --git a/pkg/github/__toolsnaps__/get_file_contents.snap b/pkg/github/__toolsnaps__/get_file_contents.snap index 94b7aeedac..ea317f6f14 100644 --- a/pkg/github/__toolsnaps__/get_file_contents.snap +++ b/pkg/github/__toolsnaps__/get_file_contents.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get file or directory contents" }, diff --git a/pkg/github/__toolsnaps__/get_gist.snap b/pkg/github/__toolsnaps__/get_gist.snap index ef316937fb..b4c053b549 100644 --- a/pkg/github/__toolsnaps__/get_gist.snap +++ b/pkg/github/__toolsnaps__/get_gist.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get Gist Content" }, diff --git a/pkg/github/__toolsnaps__/get_global_security_advisory.snap b/pkg/github/__toolsnaps__/get_global_security_advisory.snap index 97b81d17dd..74ec794740 100644 --- a/pkg/github/__toolsnaps__/get_global_security_advisory.snap +++ b/pkg/github/__toolsnaps__/get_global_security_advisory.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get a global security advisory" }, diff --git a/pkg/github/__toolsnaps__/get_label.snap b/pkg/github/__toolsnaps__/get_label.snap index 379ca7d8df..b258038506 100644 --- a/pkg/github/__toolsnaps__/get_label.snap +++ b/pkg/github/__toolsnaps__/get_label.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get a specific label from a repository" }, diff --git a/pkg/github/__toolsnaps__/get_latest_release.snap b/pkg/github/__toolsnaps__/get_latest_release.snap index 760d8f812b..4d4f0d103e 100644 --- a/pkg/github/__toolsnaps__/get_latest_release.snap +++ b/pkg/github/__toolsnaps__/get_latest_release.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get latest release" }, diff --git a/pkg/github/__toolsnaps__/get_me.snap b/pkg/github/__toolsnaps__/get_me.snap index 6f287df092..4196c6734d 100644 --- a/pkg/github/__toolsnaps__/get_me.snap +++ b/pkg/github/__toolsnaps__/get_me.snap @@ -9,6 +9,7 @@ } }, "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get my user profile" }, diff --git a/pkg/github/__toolsnaps__/get_notification_details.snap b/pkg/github/__toolsnaps__/get_notification_details.snap index 48842229ff..2929ec2fc9 100644 --- a/pkg/github/__toolsnaps__/get_notification_details.snap +++ b/pkg/github/__toolsnaps__/get_notification_details.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get notification details" }, diff --git a/pkg/github/__toolsnaps__/get_release_by_tag.snap b/pkg/github/__toolsnaps__/get_release_by_tag.snap index 6e6d30e980..60e0a3a30b 100644 --- a/pkg/github/__toolsnaps__/get_release_by_tag.snap +++ b/pkg/github/__toolsnaps__/get_release_by_tag.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get a release by tag name" }, diff --git a/pkg/github/__toolsnaps__/get_repository_tree.snap b/pkg/github/__toolsnaps__/get_repository_tree.snap index c810d1e209..6ba368f2f2 100644 --- a/pkg/github/__toolsnaps__/get_repository_tree.snap +++ b/pkg/github/__toolsnaps__/get_repository_tree.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get repository tree" }, diff --git a/pkg/github/__toolsnaps__/get_secret_scanning_alert.snap b/pkg/github/__toolsnaps__/get_secret_scanning_alert.snap index 2789cfbabc..7d04cc5ca9 100644 --- a/pkg/github/__toolsnaps__/get_secret_scanning_alert.snap +++ b/pkg/github/__toolsnaps__/get_secret_scanning_alert.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get secret scanning alert" }, diff --git a/pkg/github/__toolsnaps__/get_tag.snap b/pkg/github/__toolsnaps__/get_tag.snap index 126e8a9996..bb2751c970 100644 --- a/pkg/github/__toolsnaps__/get_tag.snap +++ b/pkg/github/__toolsnaps__/get_tag.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get tag details" }, diff --git a/pkg/github/__toolsnaps__/get_team_members.snap b/pkg/github/__toolsnaps__/get_team_members.snap index 4cde7237c1..a95be1ceda 100644 --- a/pkg/github/__toolsnaps__/get_team_members.snap +++ b/pkg/github/__toolsnaps__/get_team_members.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get team members" }, diff --git a/pkg/github/__toolsnaps__/get_teams.snap b/pkg/github/__toolsnaps__/get_teams.snap index 946364bad8..49bc62ed9f 100644 --- a/pkg/github/__toolsnaps__/get_teams.snap +++ b/pkg/github/__toolsnaps__/get_teams.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get teams" }, diff --git a/pkg/github/__toolsnaps__/issue_dependency_read_ff_issue_dependencies.snap b/pkg/github/__toolsnaps__/issue_dependency_read_ff_issue_dependencies.snap index 4a09d78713..37b4e8f113 100644 --- a/pkg/github/__toolsnaps__/issue_dependency_read_ff_issue_dependencies.snap +++ b/pkg/github/__toolsnaps__/issue_dependency_read_ff_issue_dependencies.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Read issue dependencies" }, diff --git a/pkg/github/__toolsnaps__/issue_dependency_write_ff_issue_dependencies.snap b/pkg/github/__toolsnaps__/issue_dependency_write_ff_issue_dependencies.snap index 0d1723b2f8..b907dff6cf 100644 --- a/pkg/github/__toolsnaps__/issue_dependency_write_ff_issue_dependencies.snap +++ b/pkg/github/__toolsnaps__/issue_dependency_write_ff_issue_dependencies.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Change issue dependency" }, "description": "Add or remove an issue dependency relationship in a GitHub repository. Use type 'blocked_by' to record that the subject issue is blocked by a related issue, or type 'blocking' to record that the subject issue blocks a related issue. The related issue defaults to the same repository as the subject unless related_owner/related_repo are provided.", diff --git a/pkg/github/__toolsnaps__/issue_read.snap b/pkg/github/__toolsnaps__/issue_read.snap index 9b882c79b6..b5932fb107 100644 --- a/pkg/github/__toolsnaps__/issue_read.snap +++ b/pkg/github/__toolsnaps__/issue_read.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get issue details" }, diff --git a/pkg/github/__toolsnaps__/issue_write.snap b/pkg/github/__toolsnaps__/issue_write.snap index da6a286887..55fd2dbcc2 100644 --- a/pkg/github/__toolsnaps__/issue_write.snap +++ b/pkg/github/__toolsnaps__/issue_write.snap @@ -9,6 +9,8 @@ } }, "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Create or update issue/pull request" }, "description": "Create a new or update an existing issue in a GitHub repository.", diff --git a/pkg/github/__toolsnaps__/label_write.snap b/pkg/github/__toolsnaps__/label_write.snap index de4b98bef7..6eeb9fd730 100644 --- a/pkg/github/__toolsnaps__/label_write.snap +++ b/pkg/github/__toolsnaps__/label_write.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Write operations on repository labels" }, "description": "Perform write operations on repository labels. To set labels on issues, use the 'update_issue' tool.", diff --git a/pkg/github/__toolsnaps__/list_branches.snap b/pkg/github/__toolsnaps__/list_branches.snap index 883a6fffcb..912b49d1ba 100644 --- a/pkg/github/__toolsnaps__/list_branches.snap +++ b/pkg/github/__toolsnaps__/list_branches.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List branches" }, diff --git a/pkg/github/__toolsnaps__/list_code_scanning_alerts.snap b/pkg/github/__toolsnaps__/list_code_scanning_alerts.snap index 9eddf045d8..df67380a35 100644 --- a/pkg/github/__toolsnaps__/list_code_scanning_alerts.snap +++ b/pkg/github/__toolsnaps__/list_code_scanning_alerts.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List code scanning alerts" }, diff --git a/pkg/github/__toolsnaps__/list_commits.snap b/pkg/github/__toolsnaps__/list_commits.snap index 1a773f217e..00cce882f1 100644 --- a/pkg/github/__toolsnaps__/list_commits.snap +++ b/pkg/github/__toolsnaps__/list_commits.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List commits" }, diff --git a/pkg/github/__toolsnaps__/list_dependabot_alerts.snap b/pkg/github/__toolsnaps__/list_dependabot_alerts.snap index 5fdbcd2e6f..ff602b13e1 100644 --- a/pkg/github/__toolsnaps__/list_dependabot_alerts.snap +++ b/pkg/github/__toolsnaps__/list_dependabot_alerts.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List dependabot alerts" }, diff --git a/pkg/github/__toolsnaps__/list_discussion_categories.snap b/pkg/github/__toolsnaps__/list_discussion_categories.snap index c46b75f84c..095973dc8b 100644 --- a/pkg/github/__toolsnaps__/list_discussion_categories.snap +++ b/pkg/github/__toolsnaps__/list_discussion_categories.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List discussion categories" }, diff --git a/pkg/github/__toolsnaps__/list_discussions.snap b/pkg/github/__toolsnaps__/list_discussions.snap index fdf5f6d7a3..6a2afd7dc4 100644 --- a/pkg/github/__toolsnaps__/list_discussions.snap +++ b/pkg/github/__toolsnaps__/list_discussions.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List discussions" }, diff --git a/pkg/github/__toolsnaps__/list_gists.snap b/pkg/github/__toolsnaps__/list_gists.snap index 3974173033..8f09ff3880 100644 --- a/pkg/github/__toolsnaps__/list_gists.snap +++ b/pkg/github/__toolsnaps__/list_gists.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List Gists" }, diff --git a/pkg/github/__toolsnaps__/list_global_security_advisories.snap b/pkg/github/__toolsnaps__/list_global_security_advisories.snap index f714f47829..687248f6e7 100644 --- a/pkg/github/__toolsnaps__/list_global_security_advisories.snap +++ b/pkg/github/__toolsnaps__/list_global_security_advisories.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List global security advisories" }, diff --git a/pkg/github/__toolsnaps__/list_issue_fields.snap b/pkg/github/__toolsnaps__/list_issue_fields.snap index 0eec8bc9e1..df9ae47ba6 100644 --- a/pkg/github/__toolsnaps__/list_issue_fields.snap +++ b/pkg/github/__toolsnaps__/list_issue_fields.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List issue fields" }, diff --git a/pkg/github/__toolsnaps__/list_issue_types.snap b/pkg/github/__toolsnaps__/list_issue_types.snap index 283cb5a8de..c1ea3d515a 100644 --- a/pkg/github/__toolsnaps__/list_issue_types.snap +++ b/pkg/github/__toolsnaps__/list_issue_types.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List available issue types" }, diff --git a/pkg/github/__toolsnaps__/list_issues.snap b/pkg/github/__toolsnaps__/list_issues.snap index 53a951846a..5c68c01497 100644 --- a/pkg/github/__toolsnaps__/list_issues.snap +++ b/pkg/github/__toolsnaps__/list_issues.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List issues" }, diff --git a/pkg/github/__toolsnaps__/list_label.snap b/pkg/github/__toolsnaps__/list_label.snap index 9bf8a9f3e0..9aaf90f3b2 100644 --- a/pkg/github/__toolsnaps__/list_label.snap +++ b/pkg/github/__toolsnaps__/list_label.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List labels from a repository" }, diff --git a/pkg/github/__toolsnaps__/list_notifications.snap b/pkg/github/__toolsnaps__/list_notifications.snap index bf25c4fe07..bb75d60427 100644 --- a/pkg/github/__toolsnaps__/list_notifications.snap +++ b/pkg/github/__toolsnaps__/list_notifications.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List notifications" }, diff --git a/pkg/github/__toolsnaps__/list_org_repository_security_advisories.snap b/pkg/github/__toolsnaps__/list_org_repository_security_advisories.snap index 563da98c3c..3646d86c34 100644 --- a/pkg/github/__toolsnaps__/list_org_repository_security_advisories.snap +++ b/pkg/github/__toolsnaps__/list_org_repository_security_advisories.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List org repository security advisories" }, diff --git a/pkg/github/__toolsnaps__/list_pull_requests.snap b/pkg/github/__toolsnaps__/list_pull_requests.snap index 25f1268c64..a94b6eaee1 100644 --- a/pkg/github/__toolsnaps__/list_pull_requests.snap +++ b/pkg/github/__toolsnaps__/list_pull_requests.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List pull requests" }, diff --git a/pkg/github/__toolsnaps__/list_releases.snap b/pkg/github/__toolsnaps__/list_releases.snap index 57502c3c86..d905f32087 100644 --- a/pkg/github/__toolsnaps__/list_releases.snap +++ b/pkg/github/__toolsnaps__/list_releases.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List releases" }, diff --git a/pkg/github/__toolsnaps__/list_repository_collaborators.snap b/pkg/github/__toolsnaps__/list_repository_collaborators.snap index 629e4bdf1c..5af768fe05 100644 --- a/pkg/github/__toolsnaps__/list_repository_collaborators.snap +++ b/pkg/github/__toolsnaps__/list_repository_collaborators.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List repository collaborators" }, diff --git a/pkg/github/__toolsnaps__/list_repository_security_advisories.snap b/pkg/github/__toolsnaps__/list_repository_security_advisories.snap index c86508f927..50ec8db699 100644 --- a/pkg/github/__toolsnaps__/list_repository_security_advisories.snap +++ b/pkg/github/__toolsnaps__/list_repository_security_advisories.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List repository security advisories" }, diff --git a/pkg/github/__toolsnaps__/list_secret_scanning_alerts.snap b/pkg/github/__toolsnaps__/list_secret_scanning_alerts.snap index 5c6a21a0ab..66aced9eac 100644 --- a/pkg/github/__toolsnaps__/list_secret_scanning_alerts.snap +++ b/pkg/github/__toolsnaps__/list_secret_scanning_alerts.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List secret scanning alerts" }, diff --git a/pkg/github/__toolsnaps__/list_starred_repositories.snap b/pkg/github/__toolsnaps__/list_starred_repositories.snap index e631719fde..f4c37373e5 100644 --- a/pkg/github/__toolsnaps__/list_starred_repositories.snap +++ b/pkg/github/__toolsnaps__/list_starred_repositories.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List starred repositories" }, diff --git a/pkg/github/__toolsnaps__/list_tags.snap b/pkg/github/__toolsnaps__/list_tags.snap index 1e66d2c1f6..6473040b1c 100644 --- a/pkg/github/__toolsnaps__/list_tags.snap +++ b/pkg/github/__toolsnaps__/list_tags.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List tags" }, diff --git a/pkg/github/__toolsnaps__/manage_notification_subscription.snap b/pkg/github/__toolsnaps__/manage_notification_subscription.snap index e04acd11e8..603099200a 100644 --- a/pkg/github/__toolsnaps__/manage_notification_subscription.snap +++ b/pkg/github/__toolsnaps__/manage_notification_subscription.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Manage notification subscription" }, "description": "Manage a notification subscription: ignore, watch, or delete a notification thread subscription.", diff --git a/pkg/github/__toolsnaps__/manage_repository_notification_subscription.snap b/pkg/github/__toolsnaps__/manage_repository_notification_subscription.snap index 0a4567b71c..1bd09afd14 100644 --- a/pkg/github/__toolsnaps__/manage_repository_notification_subscription.snap +++ b/pkg/github/__toolsnaps__/manage_repository_notification_subscription.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Manage repository notification subscription" }, "description": "Manage a repository notification subscription: ignore, watch, or delete repository notifications subscription for the provided repository.", diff --git a/pkg/github/__toolsnaps__/mark_all_notifications_read.snap b/pkg/github/__toolsnaps__/mark_all_notifications_read.snap index 1f5a32284e..42de313e4a 100644 --- a/pkg/github/__toolsnaps__/mark_all_notifications_read.snap +++ b/pkg/github/__toolsnaps__/mark_all_notifications_read.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Mark all notifications as read" }, "description": "Mark all notifications as read", diff --git a/pkg/github/__toolsnaps__/merge_pull_request.snap b/pkg/github/__toolsnaps__/merge_pull_request.snap index d0cdb2b1ad..4a5bdfd8b3 100644 --- a/pkg/github/__toolsnaps__/merge_pull_request.snap +++ b/pkg/github/__toolsnaps__/merge_pull_request.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Merge pull request" }, "description": "Merge a pull request in a GitHub repository.", diff --git a/pkg/github/__toolsnaps__/projects_get.snap b/pkg/github/__toolsnaps__/projects_get.snap index 864f61d83f..c1b93a9291 100644 --- a/pkg/github/__toolsnaps__/projects_get.snap +++ b/pkg/github/__toolsnaps__/projects_get.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get details of GitHub Projects resources" }, diff --git a/pkg/github/__toolsnaps__/projects_list.snap b/pkg/github/__toolsnaps__/projects_list.snap index c2bb0d3f49..bef9ec41d5 100644 --- a/pkg/github/__toolsnaps__/projects_list.snap +++ b/pkg/github/__toolsnaps__/projects_list.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "List GitHub Projects resources" }, diff --git a/pkg/github/__toolsnaps__/projects_write.snap b/pkg/github/__toolsnaps__/projects_write.snap index 6c9d349f63..f01cd1368a 100644 --- a/pkg/github/__toolsnaps__/projects_write.snap +++ b/pkg/github/__toolsnaps__/projects_write.snap @@ -1,6 +1,8 @@ { "annotations": { "destructiveHint": true, + "idempotentHint": false, + "readOnlyHint": false, "title": "Manage GitHub Projects" }, "description": "Create and manage GitHub Projects: create projects, add/update/delete items, create status updates, and add iteration fields.", diff --git a/pkg/github/__toolsnaps__/pull_request_read.snap b/pkg/github/__toolsnaps__/pull_request_read.snap index f1bb855d51..41bc90b597 100644 --- a/pkg/github/__toolsnaps__/pull_request_read.snap +++ b/pkg/github/__toolsnaps__/pull_request_read.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get details for a single pull request" }, diff --git a/pkg/github/__toolsnaps__/pull_request_review_write.snap b/pkg/github/__toolsnaps__/pull_request_review_write.snap index d4a7c30d32..74ef808559 100644 --- a/pkg/github/__toolsnaps__/pull_request_review_write.snap +++ b/pkg/github/__toolsnaps__/pull_request_review_write.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Write operations (create, submit, delete) on pull request reviews" }, "description": "Create and/or submit, delete review of a pull request.\n\nAvailable methods:\n- create: Create a new review of a pull request. If \"event\" parameter is provided, the review is submitted. If \"event\" is omitted, a pending review is created.\n- submit_pending: Submit an existing pending review of a pull request. This requires that a pending review exists for the current user on the specified pull request. The \"body\" and \"event\" parameters are used when submitting the review.\n- delete_pending: Delete an existing pending review of a pull request. This requires that a pending review exists for the current user on the specified pull request.\n- resolve_thread: Resolve a review thread. Requires only \"threadId\" parameter with the thread's node ID (e.g., PRRT_kwDOxxx). The owner, repo, and pullNumber parameters are not used for this method. Resolving an already-resolved thread is a no-op.\n- unresolve_thread: Unresolve a previously resolved review thread. Requires only \"threadId\" parameter. The owner, repo, and pullNumber parameters are not used for this method. Unresolving an already-unresolved thread is a no-op.\n", diff --git a/pkg/github/__toolsnaps__/push_files.snap b/pkg/github/__toolsnaps__/push_files.snap index df6c4d1e79..798ad18451 100644 --- a/pkg/github/__toolsnaps__/push_files.snap +++ b/pkg/github/__toolsnaps__/push_files.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Push files to repository" }, "description": "Push multiple files to a GitHub repository in a single commit", diff --git a/pkg/github/__toolsnaps__/remove_sub_issue.snap b/pkg/github/__toolsnaps__/remove_sub_issue.snap index 31fdcbb3e2..4f07c85f41 100644 --- a/pkg/github/__toolsnaps__/remove_sub_issue.snap +++ b/pkg/github/__toolsnaps__/remove_sub_issue.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": true, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Remove Sub-Issue" }, "description": "Remove a sub-issue from a parent issue.", diff --git a/pkg/github/__toolsnaps__/reprioritize_sub_issue.snap b/pkg/github/__toolsnaps__/reprioritize_sub_issue.snap index d4e1ea4be4..bb981b74ea 100644 --- a/pkg/github/__toolsnaps__/reprioritize_sub_issue.snap +++ b/pkg/github/__toolsnaps__/reprioritize_sub_issue.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Reprioritize Sub-Issue" }, "description": "Reprioritize (reorder) a sub-issue relative to other sub-issues.", diff --git a/pkg/github/__toolsnaps__/request_copilot_review.snap b/pkg/github/__toolsnaps__/request_copilot_review.snap index cd00f73fd4..5e8ecdca19 100644 --- a/pkg/github/__toolsnaps__/request_copilot_review.snap +++ b/pkg/github/__toolsnaps__/request_copilot_review.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Request Copilot review" }, "description": "Request a GitHub Copilot code review for a pull request. Use this for automated feedback on pull requests, usually before requesting a human reviewer.", diff --git a/pkg/github/__toolsnaps__/request_pull_request_reviewers.snap b/pkg/github/__toolsnaps__/request_pull_request_reviewers.snap index 20f1ab62b6..607f540d1b 100644 --- a/pkg/github/__toolsnaps__/request_pull_request_reviewers.snap +++ b/pkg/github/__toolsnaps__/request_pull_request_reviewers.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Request Pull Request Reviewers" }, "description": "Request reviewers for a pull request.", diff --git a/pkg/github/__toolsnaps__/resolve_review_thread.snap b/pkg/github/__toolsnaps__/resolve_review_thread.snap index afcd407841..5f2b21b36f 100644 --- a/pkg/github/__toolsnaps__/resolve_review_thread.snap +++ b/pkg/github/__toolsnaps__/resolve_review_thread.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Resolve Review Thread" }, "description": "Resolve a review thread on a pull request. Resolving an already-resolved thread is a no-op.", diff --git a/pkg/github/__toolsnaps__/search_code.snap b/pkg/github/__toolsnaps__/search_code.snap index 79cbbf04e9..313c2f4c5f 100644 --- a/pkg/github/__toolsnaps__/search_code.snap +++ b/pkg/github/__toolsnaps__/search_code.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Search code" }, diff --git a/pkg/github/__toolsnaps__/search_commits.snap b/pkg/github/__toolsnaps__/search_commits.snap index 394bce9a1c..8221dee480 100644 --- a/pkg/github/__toolsnaps__/search_commits.snap +++ b/pkg/github/__toolsnaps__/search_commits.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Search commits" }, diff --git a/pkg/github/__toolsnaps__/search_issues.snap b/pkg/github/__toolsnaps__/search_issues.snap index beaa5b7376..a2ec55b911 100644 --- a/pkg/github/__toolsnaps__/search_issues.snap +++ b/pkg/github/__toolsnaps__/search_issues.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Search issues" }, diff --git a/pkg/github/__toolsnaps__/search_orgs.snap b/pkg/github/__toolsnaps__/search_orgs.snap index 9670a4be8f..9796c6105d 100644 --- a/pkg/github/__toolsnaps__/search_orgs.snap +++ b/pkg/github/__toolsnaps__/search_orgs.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Search organizations" }, diff --git a/pkg/github/__toolsnaps__/search_pull_requests.snap b/pkg/github/__toolsnaps__/search_pull_requests.snap index 05376c0065..2e33af03b3 100644 --- a/pkg/github/__toolsnaps__/search_pull_requests.snap +++ b/pkg/github/__toolsnaps__/search_pull_requests.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Search pull requests" }, diff --git a/pkg/github/__toolsnaps__/search_repositories.snap b/pkg/github/__toolsnaps__/search_repositories.snap index 8e1cb31714..23b1d5e839 100644 --- a/pkg/github/__toolsnaps__/search_repositories.snap +++ b/pkg/github/__toolsnaps__/search_repositories.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Search repositories" }, diff --git a/pkg/github/__toolsnaps__/search_users.snap b/pkg/github/__toolsnaps__/search_users.snap index bed86e8c6c..27bd2eb081 100644 --- a/pkg/github/__toolsnaps__/search_users.snap +++ b/pkg/github/__toolsnaps__/search_users.snap @@ -1,5 +1,6 @@ { "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Search users" }, diff --git a/pkg/github/__toolsnaps__/set_issue_fields.snap b/pkg/github/__toolsnaps__/set_issue_fields.snap index 7a98fde2aa..c5b89077ac 100644 --- a/pkg/github/__toolsnaps__/set_issue_fields.snap +++ b/pkg/github/__toolsnaps__/set_issue_fields.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Set Issue Fields" }, "description": "Set issue field values for an issue. Fields are organization-level custom fields (text, number, date, or single select). Use this to create or update field values on an issue.", diff --git a/pkg/github/__toolsnaps__/star_repository.snap b/pkg/github/__toolsnaps__/star_repository.snap index 3d7088939b..4344d0ee06 100644 --- a/pkg/github/__toolsnaps__/star_repository.snap +++ b/pkg/github/__toolsnaps__/star_repository.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Star repository" }, "description": "Star a GitHub repository", diff --git a/pkg/github/__toolsnaps__/sub_issue_write.snap b/pkg/github/__toolsnaps__/sub_issue_write.snap index 1e4fcceabf..3ebb012def 100644 --- a/pkg/github/__toolsnaps__/sub_issue_write.snap +++ b/pkg/github/__toolsnaps__/sub_issue_write.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Change sub-issue" }, "description": "Add a sub-issue to a parent issue in a GitHub repository.", diff --git a/pkg/github/__toolsnaps__/submit_pending_pull_request_review.snap b/pkg/github/__toolsnaps__/submit_pending_pull_request_review.snap index 81223e2a9d..12438ffe71 100644 --- a/pkg/github/__toolsnaps__/submit_pending_pull_request_review.snap +++ b/pkg/github/__toolsnaps__/submit_pending_pull_request_review.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Submit Pending Pull Request Review" }, "description": "Submit a pending pull request review.", diff --git a/pkg/github/__toolsnaps__/ui_get.snap b/pkg/github/__toolsnaps__/ui_get.snap index 7f13d97c1c..85b562156d 100644 --- a/pkg/github/__toolsnaps__/ui_get.snap +++ b/pkg/github/__toolsnaps__/ui_get.snap @@ -7,6 +7,7 @@ } }, "annotations": { + "idempotentHint": false, "readOnlyHint": true, "title": "Get UI data" }, diff --git a/pkg/github/__toolsnaps__/unresolve_review_thread.snap b/pkg/github/__toolsnaps__/unresolve_review_thread.snap index d58ba31a6f..fe40bab3e9 100644 --- a/pkg/github/__toolsnaps__/unresolve_review_thread.snap +++ b/pkg/github/__toolsnaps__/unresolve_review_thread.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Unresolve Review Thread" }, "description": "Unresolve a previously resolved review thread on a pull request. Unresolving an already-unresolved thread is a no-op.", diff --git a/pkg/github/__toolsnaps__/unstar_repository.snap b/pkg/github/__toolsnaps__/unstar_repository.snap index 2bb5d68259..ac8262e22b 100644 --- a/pkg/github/__toolsnaps__/unstar_repository.snap +++ b/pkg/github/__toolsnaps__/unstar_repository.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Unstar repository" }, "description": "Unstar a GitHub repository", diff --git a/pkg/github/__toolsnaps__/update_gist.snap b/pkg/github/__toolsnaps__/update_gist.snap index 6d5ed100e4..c004a8bf14 100644 --- a/pkg/github/__toolsnaps__/update_gist.snap +++ b/pkg/github/__toolsnaps__/update_gist.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Update Gist" }, "description": "Update an existing gist", diff --git a/pkg/github/__toolsnaps__/update_issue_assignees.snap b/pkg/github/__toolsnaps__/update_issue_assignees.snap index 9c7261c9aa..ab23f72a95 100644 --- a/pkg/github/__toolsnaps__/update_issue_assignees.snap +++ b/pkg/github/__toolsnaps__/update_issue_assignees.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Issue Assignees" }, "description": "Update the assignees of an existing issue. This replaces the current assignees with the provided list.", diff --git a/pkg/github/__toolsnaps__/update_issue_body.snap b/pkg/github/__toolsnaps__/update_issue_body.snap index c54d69172a..e17043331d 100644 --- a/pkg/github/__toolsnaps__/update_issue_body.snap +++ b/pkg/github/__toolsnaps__/update_issue_body.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Issue Body" }, "description": "Update the body content of an existing issue.", diff --git a/pkg/github/__toolsnaps__/update_issue_labels.snap b/pkg/github/__toolsnaps__/update_issue_labels.snap index 2b31d756b0..2ad3877586 100644 --- a/pkg/github/__toolsnaps__/update_issue_labels.snap +++ b/pkg/github/__toolsnaps__/update_issue_labels.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Issue Labels" }, "description": "Update the labels of an existing issue. This replaces the current labels with the provided list. When setting values, include a confidence level (LOW, MEDIUM, or HIGH) reflecting how certain you are about the choice.", diff --git a/pkg/github/__toolsnaps__/update_issue_milestone.snap b/pkg/github/__toolsnaps__/update_issue_milestone.snap index 9188779f0a..cae51246b4 100644 --- a/pkg/github/__toolsnaps__/update_issue_milestone.snap +++ b/pkg/github/__toolsnaps__/update_issue_milestone.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Issue Milestone" }, "description": "Update the milestone of an existing issue.", diff --git a/pkg/github/__toolsnaps__/update_issue_state.snap b/pkg/github/__toolsnaps__/update_issue_state.snap index b14d737b7d..ceb984b1f9 100644 --- a/pkg/github/__toolsnaps__/update_issue_state.snap +++ b/pkg/github/__toolsnaps__/update_issue_state.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Issue State" }, "description": "Update the state of an existing issue (open or closed), with an optional state reason.", diff --git a/pkg/github/__toolsnaps__/update_issue_title.snap b/pkg/github/__toolsnaps__/update_issue_title.snap index 825fab0655..48c74d98ef 100644 --- a/pkg/github/__toolsnaps__/update_issue_title.snap +++ b/pkg/github/__toolsnaps__/update_issue_title.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Issue Title" }, "description": "Update the title of an existing issue.", diff --git a/pkg/github/__toolsnaps__/update_issue_type.snap b/pkg/github/__toolsnaps__/update_issue_type.snap index d07a9d43d9..21a2f64bd5 100644 --- a/pkg/github/__toolsnaps__/update_issue_type.snap +++ b/pkg/github/__toolsnaps__/update_issue_type.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Issue Type" }, "description": "Update the type of an existing issue (e.g. 'bug', 'feature'). When setting values, include a confidence level (LOW, MEDIUM, or HIGH) reflecting how certain you are about the choice.", diff --git a/pkg/github/__toolsnaps__/update_pull_request.snap b/pkg/github/__toolsnaps__/update_pull_request.snap index cadc391ef4..ae037a3e0d 100644 --- a/pkg/github/__toolsnaps__/update_pull_request.snap +++ b/pkg/github/__toolsnaps__/update_pull_request.snap @@ -9,6 +9,8 @@ } }, "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Edit pull request" }, "description": "Update an existing pull request in a GitHub repository.", diff --git a/pkg/github/__toolsnaps__/update_pull_request_body.snap b/pkg/github/__toolsnaps__/update_pull_request_body.snap index 1e6040bd4d..00b4fb978a 100644 --- a/pkg/github/__toolsnaps__/update_pull_request_body.snap +++ b/pkg/github/__toolsnaps__/update_pull_request_body.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Pull Request Body" }, "description": "Update the body description of an existing pull request.", diff --git a/pkg/github/__toolsnaps__/update_pull_request_branch.snap b/pkg/github/__toolsnaps__/update_pull_request_branch.snap index a84ac414dd..633ce6fb88 100644 --- a/pkg/github/__toolsnaps__/update_pull_request_branch.snap +++ b/pkg/github/__toolsnaps__/update_pull_request_branch.snap @@ -1,5 +1,7 @@ { "annotations": { + "idempotentHint": false, + "readOnlyHint": false, "title": "Update pull request branch" }, "description": "Update the branch of a pull request with the latest changes from the base branch.", diff --git a/pkg/github/__toolsnaps__/update_pull_request_draft_state.snap b/pkg/github/__toolsnaps__/update_pull_request_draft_state.snap index 2a397951ab..653fa3398f 100644 --- a/pkg/github/__toolsnaps__/update_pull_request_draft_state.snap +++ b/pkg/github/__toolsnaps__/update_pull_request_draft_state.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Pull Request Draft State" }, "description": "Mark a pull request as draft or ready for review.", diff --git a/pkg/github/__toolsnaps__/update_pull_request_state.snap b/pkg/github/__toolsnaps__/update_pull_request_state.snap index 9cbdb81124..440533e9b7 100644 --- a/pkg/github/__toolsnaps__/update_pull_request_state.snap +++ b/pkg/github/__toolsnaps__/update_pull_request_state.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Pull Request State" }, "description": "Update the state of an existing pull request (open or closed).", diff --git a/pkg/github/__toolsnaps__/update_pull_request_title.snap b/pkg/github/__toolsnaps__/update_pull_request_title.snap index e6398ed40a..1ac5455f77 100644 --- a/pkg/github/__toolsnaps__/update_pull_request_title.snap +++ b/pkg/github/__toolsnaps__/update_pull_request_title.snap @@ -1,7 +1,9 @@ { "annotations": { "destructiveHint": false, + "idempotentHint": false, "openWorldHint": true, + "readOnlyHint": false, "title": "Update Pull Request Title" }, "description": "Update the title of an existing pull request.", diff --git a/pkg/github/header_params_test.go b/pkg/github/header_params_test.go new file mode 100644 index 0000000000..ed08f27a79 --- /dev/null +++ b/pkg/github/header_params_test.go @@ -0,0 +1,44 @@ +package github + +import ( + "context" + "testing" + + "github.com/github/github-mcp-server/pkg/inventory" + "github.com/google/jsonschema-go/jsonschema" + "github.com/stretchr/testify/require" +) + +// TestAllToolsRoutingParamsGetHeaders enforces that every tool exposing a +// routing-relevant param (owner/repo, per inventory.HeaderParams) has it +// projected to an Mcp-Param-* header. This guards the per-request header +// optimization used by the remote proxy: a future tool must not silently ship +// without its owner/repo header, so it can never fall back to body re-parsing. +func TestAllToolsRoutingParamsGetHeaders(t *testing.T) { + inv, err := NewInventory(stubTranslator).WithToolsets([]string{"all"}).Build() + require.NoError(t, err) + + tools := inv.AvailableTools(context.Background()) + require.NotEmpty(t, tools) + + checked := 0 + for _, st := range tools { + tool := st.Tool + inventory.AnnotateHeaderParams(&tool) + schema, ok := tool.InputSchema.(*jsonschema.Schema) + if !ok || schema == nil { + continue + } + for prop, header := range inventory.HeaderParams { + ps, ok := schema.Properties[prop] + if !ok || ps == nil { + continue + } + require.NotNilf(t, ps.Extra, "tool %q param %q missing x-mcp-header annotation", tool.Name, prop) + require.Equalf(t, header, ps.Extra["x-mcp-header"], + "tool %q param %q must project to Mcp-Param-%s", tool.Name, prop, header) + checked++ + } + } + require.Positive(t, checked, "expected at least one owner/repo param across all toolsets") +} diff --git a/pkg/inventory/registry.go b/pkg/inventory/registry.go index 5f4b37ef28..6505e6b5ef 100644 --- a/pkg/inventory/registry.go +++ b/pkg/inventory/registry.go @@ -71,6 +71,7 @@ func (r *Inventory) UnrecognizedToolsets() []string { // MCP method constants for use with ForMCPRequest. const ( MCPMethodInitialize = "initialize" + MCPMethodDiscover = "server/discover" MCPMethodToolsList = "tools/list" MCPMethodToolsCall = "tools/call" MCPMethodResourcesList = "resources/list" @@ -89,7 +90,7 @@ const ( // - itemName: Name of specific item for call/get methods (tool name, resource URI, or prompt name) // // Returns a new Registry containing only the items relevant to the request: -// - MCPMethodInitialize: Empty (capabilities are set via ServerOptions, not registration) +// - MCPMethodInitialize / MCPMethodDiscover: Empty items (capabilities from ServerOptions; instructions preserved) // - MCPMethodToolsList: All available tools (no resources/prompts) // - MCPMethodToolsCall: Only the named tool // - MCPMethodResourcesList, MCPMethodResourcesTemplatesList: All available resources (no tools/prompts) @@ -114,6 +115,7 @@ func (r *Inventory) ForMCPRequest(method string, itemName string) *Inventory { featureChecker: r.featureChecker, filters: r.filters, // shared, not modified unrecognizedToolsets: r.unrecognizedToolsets, + instructions: r.instructions, // server identity; preserved for all methods } // Helper to clear all item types @@ -124,7 +126,10 @@ func (r *Inventory) ForMCPRequest(method string, itemName string) *Inventory { } switch method { - case MCPMethodInitialize: + case MCPMethodInitialize, MCPMethodDiscover: + // Both handshakes register no items; capabilities come from ServerOptions + // and instructions are preserved via the copy above (SEP-2575 discover + // must surface the same server identity as initialize). clearAll() case MCPMethodToolsList: result.resourceTemplates, result.prompts = nil, nil diff --git a/pkg/inventory/registry_test.go b/pkg/inventory/registry_test.go index 3200bedde6..0a966b289b 100644 --- a/pkg/inventory/registry_test.go +++ b/pkg/inventory/registry_test.go @@ -2268,3 +2268,16 @@ func TestShouldStripMCPAppsMetadata(t *testing.T) { }) } } + +func TestForMCPRequest_PreservesInstructions(t *testing.T) { + reg := mustBuild(t, NewBuilder(). + SetTools([]ServerTool{mockTool("tool1", "repos", true)}). + WithToolsets([]string{"all"}). + WithServerInstructions()) + want := reg.Instructions() + require.NotEmpty(t, want, "expected base inventory to generate instructions") + for _, m := range []string{MCPMethodDiscover, MCPMethodInitialize, MCPMethodToolsList} { + require.Equal(t, want, reg.ForMCPRequest(m, "").Instructions(), + "instructions must be preserved for %s (server identity)", m) + } +} diff --git a/pkg/inventory/server_tool.go b/pkg/inventory/server_tool.go index 326009b59f..05dd1a7f38 100644 --- a/pkg/inventory/server_tool.go +++ b/pkg/inventory/server_tool.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/github/github-mcp-server/pkg/octicons" + "github.com/google/jsonschema-go/jsonschema" "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -116,9 +117,40 @@ func (st *ServerTool) RegisterFunc(s *mcp.Server, deps any) { if len(toolCopy.Icons) == 0 { toolCopy.Icons = st.Toolset.Icons() } + // Project routing-relevant params to standard MCP-Param-* headers (SEP-2243) + // so a remote proxy can read owner/repo from headers instead of re-parsing the + // JSON-RPC body. No-op for tools without these params. + AnnotateHeaderParams(&toolCopy) s.AddTool(&toolCopy, handler) } +// HeaderParams maps tool input properties to the MCP-Param-* header name a +// header-aware proxy reads, avoiding a second parse of the request body. New +// routing-relevant params should be added here so projection stays automatic +// for every tool; the enforcement test in pkg/github guards full coverage. +var HeaderParams = map[string]string{"owner": "owner", "repo": "repo"} + +// AnnotateHeaderParams adds an "x-mcp-header" annotation to matching top-level +// input properties, which the SDK projects onto Mcp-Param-{name} request headers. +func AnnotateHeaderParams(tool *mcp.Tool) { + schema, ok := tool.InputSchema.(*jsonschema.Schema) + if !ok || schema == nil { + return + } + for prop, header := range HeaderParams { + ps := schema.Properties[prop] + if ps == nil { + continue + } + if ps.Extra == nil { + ps.Extra = map[string]any{} + } + if _, exists := ps.Extra["x-mcp-header"]; !exists { + ps.Extra["x-mcp-header"] = header + } + } +} + // NewServerToolWithContextHandler creates a ServerTool with a handler that receives deps via context. // This is the preferred approach for tools because it doesn't create closures at registration time, // which is critical for performance in servers that create a new instance per request. diff --git a/pkg/inventory/server_tool_test.go b/pkg/inventory/server_tool_test.go index 69cee94af0..3d2981d69b 100644 --- a/pkg/inventory/server_tool_test.go +++ b/pkg/inventory/server_tool_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "testing" + "github.com/google/jsonschema-go/jsonschema" "github.com/modelcontextprotocol/go-sdk/mcp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -78,3 +79,23 @@ func TestNewServerToolWithContextHandler_ValidArguments_Succeeds(t *testing.T) { require.True(t, ok) assert.Equal(t, "success: octocat/hello-world", textContent.Text) } + +func TestAnnotateHeaderParams(t *testing.T) { + tool := &mcp.Tool{InputSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "owner": {Type: "string"}, + "repo": {Type: "string"}, + "detail": {Type: "string"}, + }, + }} + AnnotateHeaderParams(tool) + schema := tool.InputSchema.(*jsonschema.Schema) + assert.Equal(t, "owner", schema.Properties["owner"].Extra["x-mcp-header"]) + assert.Equal(t, "repo", schema.Properties["repo"].Extra["x-mcp-header"]) + assert.Nil(t, schema.Properties["detail"].Extra) + + // No-op for tools without owner/repo and when InputSchema is not a *jsonschema.Schema + AnnotateHeaderParams(&mcp.Tool{InputSchema: &jsonschema.Schema{Properties: map[string]*jsonschema.Schema{"x": {}}}}) + AnnotateHeaderParams(&mcp.Tool{InputSchema: json.RawMessage(`{}`)}) +} diff --git a/third-party-licenses.darwin.md b/third-party-licenses.darwin.md index 5f56c1c89b..387cc5ae7f 100644 --- a/third-party-licenses.darwin.md +++ b/third-party-licenses.darwin.md @@ -24,8 +24,8 @@ The following packages are included for the amd64, arm64 architectures. - [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE)) - [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE)) - [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.1/LICENSE)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.1/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.1/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.1/LICENSE)) - [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt)) - [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE)) - [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE)) @@ -44,7 +44,9 @@ The following packages are included for the amd64, arm64 architectures. - [go.yaml.in/yaml/v3](https://pkg.go.dev/go.yaml.in/yaml/v3) ([MIT](https://github.com/yaml/go-yaml/blob/v3.0.4/LICENSE)) - [golang.org/x/net/html](https://pkg.go.dev/golang.org/x/net/html) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.38.0:LICENSE)) - [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.35.0:LICENSE)) + - [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.20.0:LICENSE)) - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.41.0:LICENSE)) - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.28.0:LICENSE)) + - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.15.0:LICENSE)) [github/github-mcp-server]: https://github.com/github/github-mcp-server diff --git a/third-party-licenses.linux.md b/third-party-licenses.linux.md index 7d8213d2f2..fa0a07af16 100644 --- a/third-party-licenses.linux.md +++ b/third-party-licenses.linux.md @@ -24,8 +24,8 @@ The following packages are included for the 386, amd64, arm64 architectures. - [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE)) - [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE)) - [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.1/LICENSE)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.1/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.1/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.1/LICENSE)) - [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt)) - [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE)) - [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE)) @@ -44,7 +44,9 @@ The following packages are included for the 386, amd64, arm64 architectures. - [go.yaml.in/yaml/v3](https://pkg.go.dev/go.yaml.in/yaml/v3) ([MIT](https://github.com/yaml/go-yaml/blob/v3.0.4/LICENSE)) - [golang.org/x/net/html](https://pkg.go.dev/golang.org/x/net/html) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.38.0:LICENSE)) - [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.35.0:LICENSE)) + - [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.20.0:LICENSE)) - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.41.0:LICENSE)) - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.28.0:LICENSE)) + - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.15.0:LICENSE)) [github/github-mcp-server]: https://github.com/github/github-mcp-server diff --git a/third-party-licenses.windows.md b/third-party-licenses.windows.md index 3d0fd8f386..398a1fa469 100644 --- a/third-party-licenses.windows.md +++ b/third-party-licenses.windows.md @@ -25,8 +25,8 @@ The following packages are included for the 386, amd64, arm64 architectures. - [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE)) - [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE)) - [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.1/LICENSE)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.1/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.1/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.1/LICENSE)) - [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt)) - [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE)) - [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE)) @@ -45,7 +45,9 @@ The following packages are included for the 386, amd64, arm64 architectures. - [go.yaml.in/yaml/v3](https://pkg.go.dev/go.yaml.in/yaml/v3) ([MIT](https://github.com/yaml/go-yaml/blob/v3.0.4/LICENSE)) - [golang.org/x/net/html](https://pkg.go.dev/golang.org/x/net/html) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.38.0:LICENSE)) - [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.35.0:LICENSE)) + - [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.20.0:LICENSE)) - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.41.0:LICENSE)) - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.28.0:LICENSE)) + - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.15.0:LICENSE)) [github/github-mcp-server]: https://github.com/github/github-mcp-server diff --git a/third-party/golang.org/x/sync/errgroup/LICENSE b/third-party/golang.org/x/sync/errgroup/LICENSE new file mode 100644 index 0000000000..2a7cf70da6 --- /dev/null +++ b/third-party/golang.org/x/sync/errgroup/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third-party/golang.org/x/time/rate/LICENSE b/third-party/golang.org/x/time/rate/LICENSE new file mode 100644 index 0000000000..2a7cf70da6 --- /dev/null +++ b/third-party/golang.org/x/time/rate/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.