Skip to content

Commit c8eea3e

Browse files
committed
Narrow issue type removal to MCP tools
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea8faa5c-7f26-4e2d-bf9c-6f0b5f173e8c
1 parent 3e93371 commit c8eea3e

6 files changed

Lines changed: 26 additions & 41 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ The following sets of tools are available:
941941
- `state`: New state (string, optional)
942942
- `state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
943943
- `title`: Issue title (string, optional)
944-
- `type`: Type of this issue. Use list_issue_types to get valid values. For updates, pass null to remove the current type. If the repository doesn't support issue types, omit this parameter. (string | null, optional)
944+
- `type`: Type of this issue. Use list_issue_types to get valid values. For updates, pass null to remove the current type. If the repository doesn't support issue types, omit this parameter. (, optional)
945945

946946
- **list_issue_fields** - List issue fields
947947
- **Required OAuth Scopes (any of)**: `repo`, `read:org`

cmd/github-mcp-server/generate_docs.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,19 +276,15 @@ func writeToolDoc(buf *strings.Builder, tool inventory.ServerTool) {
276276
var typeStr string
277277

278278
// Get the type and description
279-
if len(prop.Types) > 0 {
280-
typeStr = strings.Join(prop.Types, " | ")
281-
} else {
282-
switch prop.Type {
283-
case "array":
284-
if prop.Items != nil {
285-
typeStr = prop.Items.Type + "[]"
286-
} else {
287-
typeStr = "array"
288-
}
289-
default:
290-
typeStr = prop.Type
279+
switch prop.Type {
280+
case "array":
281+
if prop.Items != nil {
282+
typeStr = prop.Items.Type + "[]"
283+
} else {
284+
typeStr = "array"
291285
}
286+
default:
287+
typeStr = prop.Type
292288
}
293289

294290
// Indent any continuation lines in the description to maintain markdown formatting

docs/feature-flags.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ runtime behavior (such as output formatting) won't appear here.
7171
- `state`: New state (string, optional)
7272
- `state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
7373
- `title`: Issue title (string, optional)
74-
- `type`: Type of this issue. Use list_issue_types to get valid values. For updates, pass null to remove the current type. If the repository doesn't support issue types, omit this parameter. (string | null, optional)
74+
- `type`: Type of this issue. Use list_issue_types to get valid values. For updates, pass null to remove the current type. If the repository doesn't support issue types, omit this parameter. (, optional)
7575

7676
- **ui_get** - Get UI data
7777
- **Required OAuth Scopes (any of)**: `repo`, `read:org`
@@ -200,7 +200,7 @@ runtime behavior (such as output formatting) won't appear here.
200200
- `confidence`: How confident you are in this choice. Use 'HIGH' for clear signal or explicit user request, 'MEDIUM' for reasonable inference with some ambiguity, 'LOW' for best guess with limited signal. (string, optional)
201201
- `is_suggestion`: If true, this issue type change is sent to the API as a suggestion (suggest:true) rather than an applied value. Whether the type is applied or recorded as a proposal is determined by the API. (boolean, optional)
202202
- `issue_number`: The issue number to update (number, required)
203-
- `issue_type`: The issue type to set, or null to remove the current type (string | null, required)
203+
- `issue_type`: The issue type to set, or null to remove the current type (, required)
204204
- `owner`: Repository owner (username or organization) (string, required)
205205
- `rationale`: One concise sentence explaining what specifically about the issue led you to choose this type. State the concrete signal (e.g. 'Reports a crash when saving' → bug, 'Asks for dark mode support' → feature). (string, optional)
206206
- `repo`: Repository name (string, required)

docs/insiders-features.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ The list below is generated from the Go source. It covers tool **inventory and s
6565
- `state`: New state (string, optional)
6666
- `state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
6767
- `title`: Issue title (string, optional)
68-
- `type`: Type of this issue. Use list_issue_types to get valid values. For updates, pass null to remove the current type. If the repository doesn't support issue types, omit this parameter. (string | null, optional)
68+
- `type`: Type of this issue. Use list_issue_types to get valid values. For updates, pass null to remove the current type. If the repository doesn't support issue types, omit this parameter. (, optional)
6969

7070
- **ui_get** - Get UI data
7171
- **Required OAuth Scopes (any of)**: `repo`, `read:org`

pkg/github/issues.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,7 +2048,8 @@ var issueWriteFormParams = map[string]struct{}{
20482048
}
20492049

20502050
// issueWriteAwaitingFormResult builds the "awaiting form submission" stub
2051-
// returned when issue_write hands off to the MCP App form. The result is marked IsError=true so
2051+
// returned when issue_write hands off to the MCP App form. The body is shared
2052+
// by IssueWrite and LegacyIssueWrite. The result is marked IsError=true so
20522053
// agents that bail on error don't claim success or chain dependent tool calls
20532054
// while the user is still interacting with the form; the host renders the UI
20542055
// regardless because rendering is keyed off the tool's _meta.ui resourceUri.
@@ -2076,8 +2077,12 @@ func issueWriteAwaitingFormResult(method, owner, repo string, issueNumber int) *
20762077
return utils.NewToolResultAwaitingFormSubmission(msg)
20772078
}
20782079

2079-
// IssueWrite creates the consolidated issue_write tool. It is disabled when
2080-
// the granular issue tools are enabled.
2080+
// IssueWrite is the FeatureFlagIssueFields-enabled variant of issue_write
2081+
// (with the issue_fields parameter). LegacyIssueWrite is served when the flag
2082+
// is off. Both register under the tool name "issue_write"; exactly one is
2083+
// active at a time via mutually exclusive feature-flag annotations. When the
2084+
// flag is removed, delete LegacyIssueWrite outright and drop the feature-flag
2085+
// fields on IssueWrite.
20812086
func IssueWrite(t translations.TranslationHelperFunc) inventory.ServerTool {
20822087
st := NewTool(
20832088
ToolsetMetadataIssues,

ui/src/apps/issue-write/App.tsx

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ function CreateIssueApp() {
418418
// Issue types state
419419
const [availableIssueTypes, setAvailableIssueTypes] = useState<IssueTypeItem[]>([]);
420420
const [selectedIssueType, setSelectedIssueType] = useState<IssueTypeItem | null>(null);
421-
const [issueTypeChanged, setIssueTypeChanged] = useState(false);
422421
const [issueTypesLoading, setIssueTypesLoading] = useState(false);
423422

424423
// State transition state
@@ -456,7 +455,6 @@ function CreateIssueApp() {
456455
const method = (toolInput?.method as string) || "create";
457456
const issueNumber = toolInput?.issue_number as number | undefined;
458457
const isUpdateMode = method === "update" && issueNumber !== undefined;
459-
const hasExplicitIssueType = Object.prototype.hasOwnProperty.call(toolInput ?? {}, "type");
460458

461459
// Initialize from toolInput or selected repo
462460
const owner = selectedRepo?.owner || (toolInput?.owner as string) || "";
@@ -714,7 +712,7 @@ function CreateIssueApp() {
714712
labels: false,
715713
assignees: false,
716714
milestone: false,
717-
type: hasExplicitIssueType && toolInput?.type === null,
715+
type: false,
718716
issueFields: false,
719717
};
720718
setExistingIssueData(null);
@@ -724,7 +722,6 @@ function CreateIssueApp() {
724722
setSelectedAssignees([]);
725723
setSelectedMilestone(null);
726724
setSelectedIssueType(null);
727-
setIssueTypeChanged(hasExplicitIssueType && toolInput?.type === null);
728725
setCurrentState("open");
729726
setStateReason("completed");
730727
setDuplicateOf("");
@@ -753,7 +750,7 @@ function CreateIssueApp() {
753750
} else {
754751
setSelectedRepo(null);
755752
}
756-
}, [toolInput, hasExplicitIssueType]);
753+
}, [toolInput]);
757754

758755
// Load existing issue data when in update mode
759756
useEffect(() => {
@@ -803,7 +800,7 @@ function CreateIssueApp() {
803800

804801
// Pre-fill issue type immediately from issue data
805802
const issueTypeName = issueData.type?.name || (typeof issueData.type === 'string' ? issueData.type : null);
806-
if (issueTypeName && !prefillApplied.current.type && !hasExplicitIssueType) {
803+
if (issueTypeName && !prefillApplied.current.type) {
807804
setSelectedIssueType({ id: issueTypeName, text: issueTypeName });
808805
prefillApplied.current.type = true;
809806
}
@@ -832,7 +829,7 @@ function CreateIssueApp() {
832829
};
833830

834831
loadExistingIssue();
835-
}, [isUpdateMode, owner, repo, issueNumber, app, callTool, existingIssueData, hasExplicitIssueType]);
832+
}, [isUpdateMode, owner, repo, issueNumber, app, callTool, existingIssueData]);
836833

837834
// Apply existing labels when available labels load
838835
useEffect(() => {
@@ -1035,12 +1032,6 @@ function CreateIssueApp() {
10351032
}
10361033
if (selectedIssueType) {
10371034
params.type = selectedIssueType.text;
1038-
} else if (issueTypeChanged) {
1039-
if (isUpdateMode) {
1040-
params.type = null;
1041-
} else {
1042-
delete params.type;
1043-
}
10441035
}
10451036

10461037
if (requestedState) {
@@ -1124,7 +1115,6 @@ function CreateIssueApp() {
11241115
selectedAssignees,
11251116
selectedMilestone,
11261117
selectedIssueType,
1127-
issueTypeChanged,
11281118
isUpdateMode,
11291119
issueNumber,
11301120
stateReason,
@@ -1543,10 +1533,7 @@ function CreateIssueApp() {
15431533
<>
15441534
{selectedIssueType && (
15451535
<ActionList.Item
1546-
onSelect={() => {
1547-
setSelectedIssueType(null);
1548-
setIssueTypeChanged(true);
1549-
}}
1536+
onSelect={() => setSelectedIssueType(null)}
15501537
>
15511538
Clear selection
15521539
</ActionList.Item>
@@ -1555,10 +1542,7 @@ function CreateIssueApp() {
15551542
<ActionList.Item
15561543
key={type.id}
15571544
selected={selectedIssueType?.id === type.id}
1558-
onSelect={() => {
1559-
setSelectedIssueType(type);
1560-
setIssueTypeChanged(true);
1561-
}}
1545+
onSelect={() => setSelectedIssueType(type)}
15621546
>
15631547
{type.text}
15641548
</ActionList.Item>

0 commit comments

Comments
 (0)