You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add explicit show_ui parameter to UI-enabled write tools
Today the server decides whether to route issue_write and create_pull_request
through the MCP App form using two implicit signals: _ui_submitted (set by
the form on submit) and a heuristic that bypasses the form when the call
carries any parameter the form cannot represent (labels, assignees,
issue_fields, state, reviewers, etc.). The model had no first-class,
documented way to say "execute directly, do not show a form".
Add a show_ui boolean parameter to the input schema of IssueWrite,
LegacyIssueWrite, and CreatePullRequest. It defaults to true and is
visible only to clients that advertise MCP App UI support: the strip
happens per-request in inventory.ToolsForRegistration via a new
stripUIOnlySchemaProperties helper, gated by the same predicate that
already strips _meta.ui (shouldStripMCPAppsMetadata). The two strips share
one decision so the schema and metadata stay in lock-step.
Form-routing predicate becomes:
MCPApps FF on && client supports UI &&
!_ui_submitted && show_ui && !hasNonFormParams
show_ui=false is a new explicit way for the model to opt out. The existing
non-form-param auto-bypass stays as a safety net, and the React forms keep
sending _ui_submitted=true on submit unchanged. get_me is out of scope
because its UI is pure client-side card rendering with no server-side
gating to replace.
The current strip gate ("strip when FF is off OR capability explicitly
absent") mirrors today's _meta.ui behavior exactly, including the
"capability unknown" case. For stdio that means UI-capable schemas are
exposed to any FF-enabled client. The handler-side clientSupportsUI check
still gates form execution at call time, so it is functionally a no-op for
non-UI stdio clients. A separate follow-up will tighten the gate to
"strip on unknown too" and wire an InitializedHandler in stdio to
re-register the un-stripped surface only after a UI-capable client has
advertised; the two changes must ship together to avoid breaking stdio.
docs/feature-flags.md and docs/insiders-features.md include an unrelated
"reviewers" description update picked up by script/generate-docs from
commit 2bd162a ("fix: support team pull request reviewers"), which
updated the source schema but did not regenerate docs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
-`show_ui`: Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like reviewers) and the user has already confirmed the action. (boolean, optional)
-`show_ui`: Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like labels, assignees, milestone, type, or state changes) and the user has already confirmed the action. (boolean, optional)
69
71
-`state`: New state (string, optional)
70
72
-`state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
-`show_ui`: Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like reviewers) and the user has already confirmed the action. (boolean, optional)
41
42
-`title`: PR title (string, required)
42
43
43
44
-**get_me** - Get my user profile
@@ -60,6 +61,7 @@ The list below is generated from the Go source. It covers tool **inventory and s
60
61
-`milestone`: Milestone number (number, optional)
61
62
-`owner`: Repository owner (string, required)
62
63
-`repo`: Repository name (string, required)
64
+
-`show_ui`: Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like labels, assignees, milestone, type, or state changes) and the user has already confirmed the action. (boolean, optional)
63
65
-`state`: New state (string, optional)
64
66
-`state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
Copy file name to clipboardExpand all lines: pkg/github/__toolsnaps__/create_pull_request.snap
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -42,6 +42,10 @@
42
42
"description": "Repository name",
43
43
"type": "string"
44
44
},
45
+
"show_ui": {
46
+
"description": "Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like reviewers) and the user has already confirmed the action.",
Copy file name to clipboardExpand all lines: pkg/github/__toolsnaps__/issue_write.snap
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -60,6 +60,10 @@
60
60
"description": "Repository name",
61
61
"type": "string"
62
62
},
63
+
"show_ui": {
64
+
"description": "Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like labels, assignees, milestone, type, or state changes) and the user has already confirmed the action.",
Copy file name to clipboardExpand all lines: pkg/github/__toolsnaps__/issue_write_ff_remote_mcp_issue_fields.snap
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -96,6 +96,10 @@
96
96
"description": "Repository name",
97
97
"type": "string"
98
98
},
99
+
"show_ui": {
100
+
"description": "Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like labels, assignees, milestone, type, issue_fields, or state changes) and the user has already confirmed the action.",
Copy file name to clipboardExpand all lines: pkg/github/issues.go
+41-10Lines changed: 41 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -1774,6 +1774,7 @@ var issueWriteFormParams = map[string]struct{}{
1774
1774
"title": {},
1775
1775
"body": {},
1776
1776
"issue_number": {},
1777
+
"show_ui": {},
1777
1778
"_ui_submitted": {},
1778
1779
}
1779
1780
@@ -1918,6 +1919,15 @@ Options are:
1918
1919
Required: []string{"field_name"},
1919
1920
},
1920
1921
},
1922
+
// show_ui is hidden from clients that do not advertise MCP App
1923
+
// UI support. The strip happens per-request in
1924
+
// inventory.ToolsForRegistration; it is present in the static
1925
+
// schema (and therefore in toolsnaps / README) so the UI-capable
1926
+
// surface is fully documented.
1927
+
"show_ui": {
1928
+
Type: "boolean",
1929
+
Description: "Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like labels, assignees, milestone, type, issue_fields, or state changes) and the user has already confirmed the action.",
1930
+
},
1921
1931
},
1922
1932
Required: []string{"method", "owner", "repo"},
1923
1933
},
@@ -1939,13 +1949,19 @@ Options are:
1939
1949
}
1940
1950
1941
1951
// When MCP Apps are enabled and the client supports UI, route the
1942
-
// call to the interactive form unless it is itself a form submission
1943
-
// (the UI sends _ui_submitted=true) or it carries parameters the form
1944
-
// cannot represent (e.g. labels, assignees or issue_fields). Those
1945
-
// must be applied directly so their values aren't silently dropped.
1952
+
// call to the interactive form unless:
1953
+
// - it is itself a form submission (the UI sends _ui_submitted=true),
1954
+
// - the caller explicitly asked to skip the UI (show_ui=false), or
1955
+
// - it carries parameters the form cannot represent (e.g. labels,
1956
+
// assignees or issue_fields). Those must be applied directly so
Description: "Issue number that this issue is a duplicate of. Only used when state_reason is 'duplicate'.",
2152
2168
},
2169
+
// show_ui is hidden from clients that do not advertise MCP App
2170
+
// UI support. The strip happens per-request in
2171
+
// inventory.ToolsForRegistration; it is present in the static
2172
+
// schema (and therefore in toolsnaps / README) so the UI-capable
2173
+
// surface is fully documented.
2174
+
"show_ui": {
2175
+
Type: "boolean",
2176
+
Description: "Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like labels, assignees, milestone, type, or state changes) and the user has already confirmed the action.",
2177
+
},
2153
2178
},
2154
2179
Required: []string{"method", "owner", "repo"},
2155
2180
},
@@ -2171,13 +2196,19 @@ Options are:
2171
2196
}
2172
2197
2173
2198
// When MCP Apps are enabled and the client supports UI, route the
2174
-
// call to the interactive form unless it is itself a form submission
2175
-
// (the UI sends _ui_submitted=true) or it carries parameters the form
2176
-
// cannot represent (e.g. labels, assignees or issue_fields). Those
2177
-
// must be applied directly so their values aren't silently dropped.
2199
+
// call to the interactive form unless:
2200
+
// - it is itself a form submission (the UI sends _ui_submitted=true),
2201
+
// - the caller explicitly asked to skip the UI (show_ui=false), or
2202
+
// - it carries parameters the form cannot represent (e.g. labels,
2203
+
// assignees or issue_fields). Those must be applied directly so
// show_ui is hidden from clients that do not advertise MCP App
632
+
// UI support. The strip happens per-request in
633
+
// inventory.ToolsForRegistration; it is present in the static
634
+
// schema (and therefore in toolsnaps / README) so the UI-capable
635
+
// surface is fully documented.
636
+
"show_ui": {
637
+
Type: "boolean",
638
+
Description: "Whether to render the MCP App form instead of executing the request immediately. Defaults to true. Set to false to skip the form and execute directly — useful when you have all required values (especially ones the form does not collect, like reviewers) and the user has already confirmed the action.",
returnutils.NewToolResultText(fmt.Sprintf("Ready to create a pull request in %s/%s. IMPORTANT: The PR has NOT been created yet. Do NOT tell the user the PR was created. The user MUST click Submit in the form to create it.", owner, repo)), nil, nil
0 commit comments