Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
67a4793
PoC full flow (hello world example)
tommaso-moro Jan 7, 2026
7d2b463
add avatar resource domain
tommaso-moro Jan 7, 2026
7606aec
add postmessage logic and richer UI
tommaso-moro Jan 7, 2026
02ce9bf
add create issue ui
tommaso-moro Jan 15, 2026
d53ff41
update ui for issue creatioon
tommaso-moro Jan 15, 2026
e3d5db7
fix
tommaso-moro Jan 15, 2026
b149642
ignore banner
tommaso-moro Jan 15, 2026
92aabf2
update docs after rebase
mattdholloway Feb 2, 2026
8b55d08
update toolsnap for get_me
mattdholloway Feb 2, 2026
06270c7
new UI changes
mattdholloway Feb 2, 2026
a770719
update docs
mattdholloway Feb 2, 2026
23de0bc
update workflows that need ui build
mattdholloway Feb 2, 2026
e2a8582
add UI diff
mattdholloway Feb 2, 2026
5bb6228
fix build ui step for windows runners to use git bash
mattdholloway Feb 2, 2026
157ba4d
fix UI diff
mattdholloway Feb 2, 2026
c927390
refactor issue creation UI
mattdholloway Feb 3, 2026
6d0eda6
add AvatarWithFallback component and update UserCard to use it; enhan…
mattdholloway Feb 3, 2026
2b0d8cc
fix formatting of button labels
mattdholloway Feb 3, 2026
b8dc0d5
add create pull request functionality with UI support and insiders
mattdholloway Feb 3, 2026
2d186da
update docs
mattdholloway Feb 3, 2026
072f5c4
add test for insiders mode handling in ServerTool schema
mattdholloway Feb 3, 2026
adc1053
remove `show_ui` param for now
mattdholloway Feb 4, 2026
ee0a440
make insiders mode metadata stripping generic
mattdholloway Feb 4, 2026
2b8f062
remove ui diff
mattdholloway Feb 4, 2026
6070471
Merge branch 'main' into mcp-ui-apps-3
mattdholloway Feb 4, 2026
d0f0334
Merge branch 'mcp-ui-apps-3' of https://github.com/github/github-mcp-…
mattdholloway Feb 4, 2026
37da563
fix CI
mattdholloway Feb 4, 2026
8b23e49
remove redundant mention of old app name
mattdholloway Feb 4, 2026
12af958
add node types to fix ide issues for ts code
mattdholloway Feb 4, 2026
e61c2d2
remove unused TriangleDownIcon import
mattdholloway Feb 4, 2026
54ce61d
update @primer/behaviors and electron-to-chromium versions in package…
mattdholloway Feb 4, 2026
03aad7f
add check to ensure base and head are not the same when creating a ne…
mattdholloway Feb 4, 2026
ad09947
remove old show_ui
mattdholloway Feb 4, 2026
d5e263e
fix gitignore for dist so builds dont break
mattdholloway Feb 4, 2026
dca4d52
add tests for insiders mode handling and metadata stripping in Server…
mattdholloway Feb 4, 2026
932750c
remove unused state and components from CreatePRApp
mattdholloway Feb 4, 2026
16469f8
fix ui build
mattdholloway Feb 4, 2026
d0085a7
update docker build to fix npm issue
mattdholloway Feb 4, 2026
7ce5e08
remove reference to show_ui
mattdholloway Feb 4, 2026
3413b71
Merge branch 'main' into mcp-ui-apps-3
mattdholloway Feb 5, 2026
e20cef3
allow insiders to work for non-ui features
mattdholloway Feb 5, 2026
8a0edfb
formalise insiders inventory support
mattdholloway Feb 5, 2026
d564d98
update docs
mattdholloway Feb 5, 2026
f034e19
fix overflow issues and replace pull request dropdown with matching U…
mattdholloway Feb 5, 2026
934e83d
fix createpullrequest test
mattdholloway Feb 5, 2026
a1922b2
consolidate fetching tools under `ui_get` tool to remove toolset deps
mattdholloway Feb 5, 2026
a47064d
fix issue data prefill in issue_write form
mattdholloway Feb 5, 2026
be4c4c7
fix link component when updating issue
mattdholloway Feb 5, 2026
69579b2
fix avatar URL
mattdholloway Feb 5, 2026
b2164a1
fix broken issue update logic
mattdholloway Feb 5, 2026
fcefcaa
remove dbg
mattdholloway Feb 5, 2026
826b518
Merge remote-tracking branch 'origin/main' into mcp-ui-apps-3
mattdholloway Feb 6, 2026
8fa72ad
fix for new GetFlags
mattdholloway Feb 6, 2026
00b9213
revert to original required fields for create_pull_request
mattdholloway Feb 6, 2026
922fa9f
fix for UI form submission
mattdholloway Feb 6, 2026
a2dcb30
Merge branch 'main' into mcp-ui-apps-3
mattdholloway Feb 9, 2026
24174b9
Simplify MCP App UIs for basic branch
mattdholloway Feb 9, 2026
4dc0d47
Fix header spacing in issue-write and pr-write UIs
mattdholloway Feb 9, 2026
4994f84
fix UI spacing
mattdholloway Feb 9, 2026
fce0c3d
Revert "Simplify MCP App UIs for basic branch"
mattdholloway Feb 9, 2026
c8cf1e9
Merge remote-tracking branch 'origin/main' into mcp-ui-apps-advanced
mattdholloway Feb 13, 2026
5cc9623
Undo dependency downgrades in ui/package-lock.json
mattdholloway Feb 13, 2026
a9bcd2b
Update ui/src/apps/pr-write/App.tsx
mattdholloway Feb 13, 2026
8432a54
Update ui/src/apps/issue-write/App.tsx
mattdholloway Feb 13, 2026
c8848f5
Implement pagination for uiGetBranches (#2012)
Copilot Feb 13, 2026
e021022
Merge branch 'main' into mcp-ui-apps-advanced
mattdholloway Feb 17, 2026
5de74d8
Merge branch 'main' into mcp-ui-apps-advanced
mattdholloway Feb 17, 2026
d0e6c0b
Merge branch 'main' into mcp-ui-apps-advanced
mattdholloway Feb 20, 2026
6c529d0
Merge branch 'main' into mcp-ui-apps-advanced
mattdholloway Mar 2, 2026
096ecbb
Merge branch 'main' into mcp-ui-apps-advanced
mattdholloway Apr 1, 2026
3ea342a
Merge branch 'main' into mcp-ui-apps-advanced
mattdholloway Apr 28, 2026
46c7267
update to new insiders feature flag func
mattdholloway Apr 28, 2026
0a0b7da
ensure transient state is reset on successive tool calls
mattdholloway Apr 29, 2026
2a65fd3
Merge remote-tracking branch 'origin/main' into mcp-ui-apps-advanced
Copilot Jun 1, 2026
489e188
Mark ui_get as app-only visibility
mattdholloway Jun 1, 2026
5698568
Update ui_get toolsnap for app-only visibility
mattdholloway Jun 1, 2026
b5b87d5
Assert ui_get declares app-only visibility
mattdholloway Jun 1, 2026
f310291
Add ui_get to insiders feature docs
mattdholloway Jun 1, 2026
d9292e9
Address ui_get review feedback
mattdholloway Jun 1, 2026
13bb1b0
Fix repo reset and stale base-branch in MCP App views
mattdholloway Jun 1, 2026
6f6e826
Potential fix for pull request finding
mattdholloway Jun 1, 2026
19f5c11
Fix issue-write repo owner mapping and clear stale UI state on reset
mattdholloway Jun 1, 2026
3e11e38
Merge remote-tracking branch 'origin/main' into mcp-ui-apps-advanced
Copilot Jun 1, 2026
064c9cc
Merge remote-tracking branch 'origin/main' into mcp-ui-apps-advanced
Copilot Jun 1, 2026
064250e
Merge branch 'main' into mcp-ui-apps-advanced
mattdholloway Jun 2, 2026
3f9e68f
Merge remote-tracking branch 'origin/main' into mcp-ui-apps-advanced
Copilot Jun 3, 2026
0eccc22
feat: add pull request editing functionality with reviewers support
mattdholloway Jun 9, 2026
d9be621
feat: implement interactive form handling for issue and pull request …
mattdholloway Jun 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,7 @@ The following sets of tools are available:
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
- `owner`: Repository owner (string, required)
- `repo`: Repository name (string, required)
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
- `title`: PR title (string, required)

- **list_pull_requests** - List pull requests
Expand Down
24 changes: 23 additions & 1 deletion docs/feature-flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ runtime behavior (such as output formatting) won't appear here.
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
- `owner`: Repository owner (string, required)
- `repo`: Repository name (string, required)
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
- `title`: PR title (string, required)

- **get_me** - Get my user profile
Expand Down Expand Up @@ -71,6 +72,27 @@ runtime behavior (such as output formatting) won't appear here.
- `title`: Issue title (string, optional)
- `type`: Type of this issue. Only use if the repository has issue types configured. Use list_issue_types tool to get valid type values for the organization. If the repository doesn't support issue types, omit this parameter. (string, optional)

- **ui_get** - Get UI data
- **Required OAuth Scopes**: `repo`, `read:org`
- **Accepted OAuth Scopes**: `admin:org`, `read:org`, `repo`, `write:org`
- `method`: The type of data to fetch (string, required)
- `owner`: Repository owner (required for all methods) (string, required)
- `repo`: Repository name (required for labels, assignees, milestones, branches, issue fields, reviewers) (string, optional)

- **update_pull_request** - Edit pull request
- **Required OAuth Scopes**: `repo`
- **MCP App UI**: `ui://github-mcp-server/pr-edit`
- `base`: New base branch name (string, optional)
- `body`: New description (string, optional)
- `draft`: Mark pull request as draft (true) or ready for review (false) (boolean, optional)
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
- `owner`: Repository owner (string, required)
- `pullNumber`: Pull request number to update (number, required)
- `repo`: Repository name (string, required)
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
- `state`: New state (string, optional)
- `title`: New title (string, optional)

### `remote_mcp_issue_fields`

- **issue_write** - Create or update issue
Expand Down Expand Up @@ -240,7 +262,7 @@ runtime behavior (such as output formatting) won't appear here.
- `owner`: Repository owner (username or organization) (string, required)
- `pullNumber`: The pull request number (number, required)
- `repo`: Repository name (string, required)
- `reviewers`: GitHub usernames to request reviews from (string[], required)
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], required)

- **resolve_review_thread** - Resolve Review Thread
- **Required OAuth Scopes**: `repo`
Expand Down
22 changes: 22 additions & 0 deletions docs/insiders-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ The list below is generated from the Go source. It covers tool **inventory and s
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
- `owner`: Repository owner (string, required)
- `repo`: Repository name (string, required)
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
- `title`: PR title (string, required)

- **get_me** - Get my user profile
Expand Down Expand Up @@ -65,6 +66,27 @@ The list below is generated from the Go source. It covers tool **inventory and s
- `title`: Issue title (string, optional)
- `type`: Type of this issue. Only use if the repository has issue types configured. Use list_issue_types tool to get valid type values for the organization. If the repository doesn't support issue types, omit this parameter. (string, optional)

- **ui_get** - Get UI data
- **Required OAuth Scopes**: `repo`, `read:org`
- **Accepted OAuth Scopes**: `admin:org`, `read:org`, `repo`, `write:org`
- `method`: The type of data to fetch (string, required)
- `owner`: Repository owner (required for all methods) (string, required)
- `repo`: Repository name (required for labels, assignees, milestones, branches, issue fields, reviewers) (string, optional)

- **update_pull_request** - Edit pull request
- **Required OAuth Scopes**: `repo`
- **MCP App UI**: `ui://github-mcp-server/pr-edit`
- `base`: New base branch name (string, optional)
- `body`: New description (string, optional)
- `draft`: Mark pull request as draft (true) or ready for review (false) (boolean, optional)
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
- `owner`: Repository owner (string, required)
- `pullNumber`: Pull request number to update (number, required)
- `repo`: Repository name (string, required)
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
- `state`: New state (string, optional)
- `title`: New title (string, optional)

### `remote_mcp_issue_fields`

- **issue_write** - Create or update issue
Expand Down
7 changes: 7 additions & 0 deletions pkg/github/__toolsnaps__/create_pull_request.snap
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
"description": "Repository name",
"type": "string"
},
"reviewers": {
"description": "GitHub usernames or ORG/team-slug team reviewers to request reviews from",
"items": {
"type": "string"
},
"type": "array"
},
"title": {
"description": "PR title",
"type": "string"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@
"type": "object"
},
"name": "request_pull_request_reviewers"
}
}
45 changes: 45 additions & 0 deletions pkg/github/__toolsnaps__/ui_get.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"_meta": {
"ui": {
"visibility": [
"app"
]
}
},
"annotations": {
"readOnlyHint": true,
"title": "Get UI data"
},
"description": "Fetch UI data for MCP Apps (labels, assignees, milestones, issue types, branches, issue fields, reviewers).",
"inputSchema": {
"properties": {
"method": {
"description": "The type of data to fetch",
"enum": [
"labels",
"assignees",
"milestones",
"issue_types",
"branches",
"issue_fields",
"reviewers"
],
"type": "string"
},
"owner": {
"description": "Repository owner (required for all methods)",
"type": "string"
},
"repo": {
"description": "Repository name (required for labels, assignees, milestones, branches, issue fields, reviewers)",
"type": "string"
}
},
"required": [
"method",
"owner"
],
"type": "object"
},
"name": "ui_get"
}
11 changes: 10 additions & 1 deletion pkg/github/__toolsnaps__/update_pull_request.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
{
"_meta": {
"ui": {
"resourceUri": "ui://github-mcp-server/pr-edit",
"visibility": [
"model",
"app"
]
}
},
"annotations": {
"title": "Edit pull request"
},
Expand Down Expand Up @@ -61,4 +70,4 @@
"type": "object"
},
"name": "update_pull_request"
}
}
53 changes: 44 additions & 9 deletions pkg/github/issues.go
Original file line number Diff line number Diff line change
Expand Up @@ -1764,8 +1764,7 @@ func searchIssuesHandler(ctx context.Context, deps ToolDependencies, args map[st
const IssueWriteUIResourceURI = "ui://github-mcp-server/issue-write"

// issueWriteFormParams are the parameters the issue_write MCP App form collects
// and re-sends on submit. The form only supports title/body editing (plus the
// routing/identity fields), so any other parameter present on a call cannot be
// and re-sends on submit. Any other parameter present on a call cannot be
// represented by the form.
var issueWriteFormParams = map[string]struct{}{
"method": {},
Expand All @@ -1774,12 +1773,16 @@ var issueWriteFormParams = map[string]struct{}{
"title": {},
"body": {},
"issue_number": {},
"issue_fields": {},
"state": {},
"state_reason": {},
"duplicate_of": {},
"_ui_submitted": {},
}

// issueWriteHasNonFormParams reports whether the call carries any parameter the
// issue_write MCP App form cannot represent (anything outside issueWriteFormParams,
// e.g. labels, assignees, issue_fields or a state change). Such calls must bypass
// e.g. labels, assignees, milestones or issue types). Such calls must bypass
// the UI form and execute directly so the supplied values aren't silently dropped.
func issueWriteHasNonFormParams(args map[string]any) bool {
for key, value := range args {
Expand All @@ -1793,6 +1796,36 @@ func issueWriteHasNonFormParams(args map[string]any) bool {
return false
}

// issueWriteAwaitingFormResult builds the "awaiting form submission" stub
// returned when issue_write hands off to the MCP App form. The body is shared
// by IssueWrite and LegacyIssueWrite. The result is marked IsError=true so
// agents that bail on error don't claim success or chain dependent tool calls
// while the user is still interacting with the form; the host renders the UI
// regardless because rendering is keyed off the tool's _meta.ui resourceUri.
func issueWriteAwaitingFormResult(method, owner, repo string, issueNumber int) *mcp.CallToolResult {
var msg string
if method == "update" {
msg = fmt.Sprintf(
"An interactive form has been shown to the user for editing issue #%d in %s/%s. "+
"STOP — do not call any other tools, do not respond as if the issue was updated, "+
"and do not claim the operation succeeded. The issue has NOT been updated yet; "+
"only the form was rendered. Wait silently for the user to review and click Submit. "+
"When they do, the real result will be delivered to your context automatically.",
issueNumber, owner, repo,
)
} else {
msg = fmt.Sprintf(
"An interactive form has been shown to the user for creating a new issue in %s/%s. "+
"STOP — do not call any other tools, do not respond as if the issue was created, "+
"and do not claim the operation succeeded. The issue has NOT been created yet; "+
"only the form was rendered. Wait silently for the user to review and click Submit. "+
"When they do, the real result will be delivered to your context automatically.",
owner, repo,
)
}
return utils.NewToolResultAwaitingFormSubmission(msg)
}

// IssueWrite is the FeatureFlagIssueFields-enabled variant of issue_write
// (with the issue_fields parameter). LegacyIssueWrite is served when the flag
// is off. Both register under the tool name "issue_write"; exactly one is
Expand Down Expand Up @@ -1946,14 +1979,15 @@ Options are:
uiSubmitted, _ := OptionalParam[bool](args, "_ui_submitted")

if deps.IsFeatureEnabled(ctx, MCPAppsFeatureFlag) && clientSupportsUI(ctx, req) && !uiSubmitted && !issueWriteHasNonFormParams(args) {
issueNumber := 0
if method == "update" {
issueNumber, numErr := RequiredInt(args, "issue_number")
n, numErr := RequiredInt(args, "issue_number")
if numErr != nil {
return utils.NewToolResultError("issue_number is required for update method"), nil, nil
}
return utils.NewToolResultText(fmt.Sprintf("Ready to update issue #%d in %s/%s. IMPORTANT: The issue has NOT been updated yet. Do NOT tell the user the issue was updated. The user MUST click Submit in the form to update it.", issueNumber, owner, repo)), nil, nil
issueNumber = n
}
return utils.NewToolResultText(fmt.Sprintf("Ready to create an issue in %s/%s. IMPORTANT: The issue has NOT been created yet. Do NOT tell the user the issue was created. The user MUST click Submit in the form to create it.", owner, repo)), nil, nil
return issueWriteAwaitingFormResult(method, owner, repo, issueNumber), nil, nil
}

title, err := OptionalParam[string](args, "title")
Expand Down Expand Up @@ -2178,14 +2212,15 @@ Options are:
uiSubmitted, _ := OptionalParam[bool](args, "_ui_submitted")

if deps.IsFeatureEnabled(ctx, MCPAppsFeatureFlag) && clientSupportsUI(ctx, req) && !uiSubmitted && !issueWriteHasNonFormParams(args) {
issueNumber := 0
if method == "update" {
issueNumber, numErr := RequiredInt(args, "issue_number")
n, numErr := RequiredInt(args, "issue_number")
if numErr != nil {
return utils.NewToolResultError("issue_number is required for update method"), nil, nil
}
return utils.NewToolResultText(fmt.Sprintf("Ready to update issue #%d in %s/%s. IMPORTANT: The issue has NOT been updated yet. Do NOT tell the user the issue was updated. The user MUST click Submit in the form to update it.", issueNumber, owner, repo)), nil, nil
issueNumber = n
}
return utils.NewToolResultText(fmt.Sprintf("Ready to create an issue in %s/%s. IMPORTANT: The issue has NOT been created yet. Do NOT tell the user the issue was created. The user MUST click Submit in the form to create it.", owner, repo)), nil, nil
return issueWriteAwaitingFormResult(method, owner, repo, issueNumber), nil, nil
}

title, err := OptionalParam[string](args, "title")
Expand Down
Loading
Loading