From 9d798a0180ff4e75df3a53ac876b946add9f946c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Arkan?= Date: Wed, 13 May 2026 16:14:13 +0300 Subject: [PATCH 1/2] Annotate create_issue and issue_write as destructive Sets destructiveHint: true on the granular create_issue tool and the unified issue_write tool so the IFC client engine can apply egress policies before invocation, regardless of which surface the client uses. Refs github/copilot-mcp-core#1623. --- pkg/github/__toolsnaps__/create_issue.snap | 2 +- pkg/github/__toolsnaps__/issue_write.snap | 1 + pkg/github/issues.go | 5 +++-- pkg/github/issues_granular.go | 2 +- pkg/github/issues_test.go | 2 ++ 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/github/__toolsnaps__/create_issue.snap b/pkg/github/__toolsnaps__/create_issue.snap index 51923c47c..00e123382 100644 --- a/pkg/github/__toolsnaps__/create_issue.snap +++ b/pkg/github/__toolsnaps__/create_issue.snap @@ -1,6 +1,6 @@ { "annotations": { - "destructiveHint": false, + "destructiveHint": true, "openWorldHint": true, "title": "Create Issue" }, diff --git a/pkg/github/__toolsnaps__/issue_write.snap b/pkg/github/__toolsnaps__/issue_write.snap index 24cff5df9..d24ab0858 100644 --- a/pkg/github/__toolsnaps__/issue_write.snap +++ b/pkg/github/__toolsnaps__/issue_write.snap @@ -9,6 +9,7 @@ } }, "annotations": { + "destructiveHint": true, "title": "Create or update issue." }, "description": "Create a new or update an existing issue in a GitHub repository.", diff --git a/pkg/github/issues.go b/pkg/github/issues.go index ab8611afb..5ff141b64 100644 --- a/pkg/github/issues.go +++ b/pkg/github/issues.go @@ -1127,8 +1127,9 @@ func IssueWrite(t translations.TranslationHelperFunc) inventory.ServerTool { Name: "issue_write", Description: t("TOOL_ISSUE_WRITE_DESCRIPTION", "Create a new or update an existing issue in a GitHub repository."), Annotations: &mcp.ToolAnnotations{ - Title: t("TOOL_ISSUE_WRITE_USER_TITLE", "Create or update issue."), - ReadOnlyHint: false, + Title: t("TOOL_ISSUE_WRITE_USER_TITLE", "Create or update issue."), + ReadOnlyHint: false, + DestructiveHint: jsonschema.Ptr(true), }, Meta: mcp.Meta{ "ui": map[string]any{ diff --git a/pkg/github/issues_granular.go b/pkg/github/issues_granular.go index 973032c4a..cd4e5e7d5 100644 --- a/pkg/github/issues_granular.go +++ b/pkg/github/issues_granular.go @@ -117,7 +117,7 @@ func GranularCreateIssue(t translations.TranslationHelperFunc) inventory.ServerT Annotations: &mcp.ToolAnnotations{ Title: t("TOOL_CREATE_ISSUE_USER_TITLE", "Create Issue"), ReadOnlyHint: false, - DestructiveHint: jsonschema.Ptr(false), + DestructiveHint: jsonschema.Ptr(true), OpenWorldHint: jsonschema.Ptr(true), }, InputSchema: &jsonschema.Schema{ diff --git a/pkg/github/issues_test.go b/pkg/github/issues_test.go index ed92c49ab..11d3bfb68 100644 --- a/pkg/github/issues_test.go +++ b/pkg/github/issues_test.go @@ -1058,6 +1058,8 @@ func Test_CreateIssue(t *testing.T) { assert.Equal(t, "issue_write", tool.Name) assert.NotEmpty(t, tool.Description) + require.NotNil(t, tool.Annotations.DestructiveHint) + assert.True(t, *tool.Annotations.DestructiveHint) assert.Contains(t, tool.InputSchema.(*jsonschema.Schema).Properties, "method") assert.Contains(t, tool.InputSchema.(*jsonschema.Schema).Properties, "owner") assert.Contains(t, tool.InputSchema.(*jsonschema.Schema).Properties, "repo") From f53dea283bb697b6bedfbb5e427a1b7b5a801fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Arkan?= Date: Wed, 13 May 2026 16:30:09 +0300 Subject: [PATCH 2/2] Add nil check for tool.Annotations and rename Test_CreateIssue to Test_IssueWrite_Create Addresses Copilot feedback on #2470. The test exercises IssueWrite, so its name now matches the tool under test. --- pkg/github/issues_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/github/issues_test.go b/pkg/github/issues_test.go index 11d3bfb68..e74f270a3 100644 --- a/pkg/github/issues_test.go +++ b/pkg/github/issues_test.go @@ -1050,7 +1050,7 @@ func unmarshalIFC(t *testing.T, ifcLabel any) map[string]any { return ifcMap } -func Test_CreateIssue(t *testing.T) { +func Test_IssueWrite_Create(t *testing.T) { // Verify tool definition once serverTool := IssueWrite(translations.NullTranslationHelper) tool := serverTool.Tool @@ -1058,6 +1058,7 @@ func Test_CreateIssue(t *testing.T) { assert.Equal(t, "issue_write", tool.Name) assert.NotEmpty(t, tool.Description) + require.NotNil(t, tool.Annotations) require.NotNil(t, tool.Annotations.DestructiveHint) assert.True(t, *tool.Annotations.DestructiveHint) assert.Contains(t, tool.InputSchema.(*jsonschema.Schema).Properties, "method")