Skip to content

Commit 1d4f4fa

Browse files
authored
Merge branch 'main' into joannaakl-ai-triage-investigation
2 parents a7ccfba + 3366807 commit 1d4f4fa

8 files changed

Lines changed: 1151 additions & 0 deletions

‎docs/feature-flags.md‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,43 @@ end users. Insiders-only flags are not user-toggleable.
3737

3838
## Declaring tool availability
3939

40+
### Issue artifacts
41+
42+
Enable `--features=issue_artifacts` (or `GITHUB_FEATURES=issue_artifacts`) to
43+
expose `issue_artifact_read` (`method: list | get`) and `issue_artifact_write`
44+
(`method: create | update | delete`) in the `issues` toolset.
45+
This flag is **off by default**, including in Insiders mode. Read-only mode
46+
exposes only `issue_artifact_read`.
47+
48+
The MCP flag only exposes tools; it does not grant API access. The tools
49+
use the configured authenticated GitHub client and base URL without an
50+
endpoint-specific preview header. They declare `repo` in their OAuth challenge
51+
metadata; API access also depends on the token's permissions and repository
52+
access. API failures are returned explicitly; writes are not retried.
53+
54+
Artifact numbers are scoped to their owning issue, not global IDs. Updates
55+
preserve omitted fields, allow `body: ""` to clear the body, and cannot change
56+
type. Lists return one explicit `page`/`perPage` with bodies; request successive
57+
pages until fewer than `perPage` artifacts are returned. This works with or
58+
without REST `Link` headers; the tools do not expose those headers.
59+
Artifact names and bodies are sanitized as user-authored content.
60+
Both tools fail closed in lockdown mode because the reference artifact
61+
response does not identify authors for content-trust checks.
62+
63+
All methods require `owner`, `repo`, and `issue_number`. Get, update, and delete
64+
also require `artifact_number`. Create requires `type`, `name`, and `body`;
65+
an empty body is allowed. Update requires `name`, `body`, or both. Method-specific
66+
fields are rejected when used with another method.
67+
68+
Create and list's optional type filter support the existing REST API types:
69+
`generic`, `link`, `plan`, and `embedded_html`. For `embedded_html`, supply HTML
70+
source in `body`. Returned artifact types remain unrestricted for forward
71+
compatibility.
72+
73+
Get, create, and update return an `artifact` object. List returns a `list` object
74+
containing `artifacts`, `page`, and `perPage`; delete returns a `deleted` object
75+
containing `issue_number`, `artifact_number`, and a confirmation message.
76+
4077
Tools, resources, and prompts use `inventory.NewFeatureRule` when feature flags
4178
change whether they are available. Each rule declares the flags it references
4279
and evaluates them with a fail-closed `FeatureResolver`, so normal Go boolean
@@ -395,6 +432,30 @@ as output formatting) won't appear here.
395432
- 'blocked_by' - the subject issue is blocked by the related issue.
396433
- 'blocking' - the subject issue blocks the related issue. (string, required)
397434

435+
### `issue_artifacts`
436+
437+
- **issue_artifact_read** - Read issue artifacts
438+
- **OAuth Challenge Scopes**: `repo`
439+
- `artifact_number`: Required for get: positive issue-scoped artifact number, not its global ID (integer, optional)
440+
- `issue_number`: Positive issue number (integer, required)
441+
- `method`: (string, required)
442+
- `owner`: Repository owner (string, required)
443+
- `page`: For list only: page number, starting at 1 (default 1) (integer, optional)
444+
- `perPage`: For list only: results per page, from 1 to 100 (default 30) (integer, optional)
445+
- `repo`: Repository name (string, required)
446+
- `type`: (string, optional)
447+
448+
- **issue_artifact_write** - Write issue artifacts
449+
- **OAuth Challenge Scopes**: `repo`
450+
- `artifact_number`: Required for update and delete: positive issue-scoped artifact number, not its global ID (integer, optional)
451+
- `body`: Required for create, optional for update: artifact content (HTML source for embedded_html); an empty string clears it (string, optional)
452+
- `issue_number`: Positive issue number (integer, required)
453+
- `method`: (string, required)
454+
- `name`: Required for create, optional for update: nonempty artifact name (string, optional)
455+
- `owner`: Repository owner (string, required)
456+
- `repo`: Repository name (string, required)
457+
- `type`: (string, optional)
458+
398459
### `duplicate_detection`
399460

400461
- **find_duplicate** - Find duplicate issues
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
{
2+
"annotations": {
3+
"destructiveHint": false,
4+
"idempotentHint": false,
5+
"readOnlyHint": true,
6+
"title": "Read issue artifacts"
7+
},
8+
"description": "List or get GitHub issue artifacts including their bodies. Get requires artifact_number (issue-scoped, not its global ID). List accepts an optional type filter and page/perPage; request successive pages until a page contains fewer than perPage artifacts.",
9+
"icons": [
10+
{
11+
"mimeType": "image/png",
12+
"src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAC2UlEQVRIicWVMUyTaRjHf/+vVUpOJOdilOYoUvVreq2CDmLOwdlAS5xMbrrhBifjYG7QjYuJw108nZx1huLgYlw0QshxChUK2koxHHcuCmgsFfieG0or3kGPSoz/8X3f5/97nvfN8z7wmaVqm9FodFfR/EnMugy5giCAwYwgI9Ff9Hl9L9Lp1zUBgsGO+rqGwnlhF4CdwBSyAUwvS1G220zHBSFgHtmVxYWvfp2ZGSj8LyAcjgfZphTQZtAr7OdsZvSP9RIJR+LtQhcNusF+d1aUfPp05M8NAavmg8AOk3cmN56+s1Hpa7U/cviUYbcw3jgex9ZCKoBgsKM+0PDuAdBq2He5zOiTzZiXtc+NxRw598GeLRcWTuTz+UUAp3ygrqFwHmgzeWdqNQd4PpFOy/gedNQfaDz3UQXRaHRX0fNPGdzNZUZO12q+VuHIoV7g5Hu/1/IinX7tABTNnwR2SvRsxRzAzOsBGuuWfAkoX5FZFzCVHR95tFVAbiI9DEwj6wLwl5YVMTRYLTDsxjuRrgGYYz/kxkbvbXRWMOBB24cKYI9ks1X8hXQDaAaa5XG9WjImZgV71wI+m8qAv8y0t1pSmP0ITANTmHO2qqvRZDALlTdgHKyjWkx2YvQ2cHtTacMxYBhWK5DoF4TCkXj7Jg02VKsbOwI0Y+qvALZrOQXMC13cKkDSJWBuJUCqAhgbG3uF7IpBcn/k8KlPNQ+78U5QQuhy/vHjuQoAYPndwi9gw4bd2ufGYrWatxz8No50ExhaKsz9Vl6vAPL5/KKzoiTGG0fOg1oqCbvxTp/juw/M+zynu/yTwjoD58CBQ02ez/pAR4E+M69ntf3/o1Y3dqR050oAQz7P6Z6cfPRRw647MkOhUMAfaDyH+AloBKYNPRT292rQHoMOSp09J3TZlt5ezWazxX97VR3638RiX9ct+RImSyBcrDT0ETMyMp4ptRIgVX7QL6J/ALSUEwJ5rdg2AAAAAElFTkSuQmCC",
13+
"theme": "light"
14+
},
15+
{
16+
"mimeType": "image/png",
17+
"src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAABxElEQVRIibWVvW4TURCFv0vlNEDcIHAkKAERJOIKSjoUArwBPwUFFaKIIngAJARCPIgdh4cgRBYt6ZIAEYEqdhpEw0fhCbkKa68dxyNtsfNzzpnZu3NhwpYGBdUqcA+4A1wEZiK0DawD74FWSml3JAJ1CngGLAIngU1gFfgZKWeAG8AFoAu8At6mlH6VtqTOqJ/UP2pDnRuQO6c27VlbrQ0Dvq121Fulag7q5qPmW18SdSqUd9Qrw4Jn9bNR21YrRQkvYixDKy/AuB3jWjocqKpdtXFU8AxrOTqZzp2PgvnaMRDUA+tB7mypG+OCZ3hbahPgRPguAR9LihaicEu9WcKxClzOi/fU1wPAk7rjgX0uEfNG3cs7mJjtE+wA5/olpZQEHgNf6K2NJyW4NeD7v7c4WptjSc0svlMjdzyM2fbdOyOA7x/T+7mzGj9H8xgIWuquevpw4HmsivkxwBdC/WJRsBKLqqPOHgH8aqybtcJlF0m1WLndUToJ5V31q9r3NOYk7Wh1Wa0PyK3HzA3l/4H3uzIrwFNgCThF7/x/AH5EylngOnAe6AAvgXcppd9DEWRE08DdeIou/RVgJaXUGYQzUfsL+zmwV7BtIq0AAAAASUVORK5CYII=",
18+
"theme": "dark"
19+
}
20+
],
21+
"inputSchema": {
22+
"additionalProperties": false,
23+
"properties": {
24+
"artifact_number": {
25+
"description": "Required for get: positive issue-scoped artifact number, not its global ID",
26+
"minimum": 1,
27+
"type": "integer"
28+
},
29+
"issue_number": {
30+
"description": "Positive issue number",
31+
"minimum": 1,
32+
"type": "integer"
33+
},
34+
"method": {
35+
"enum": [
36+
"list",
37+
"get"
38+
],
39+
"type": "string"
40+
},
41+
"owner": {
42+
"description": "Repository owner",
43+
"minLength": 1,
44+
"type": "string",
45+
"x-mcp-header": "owner"
46+
},
47+
"page": {
48+
"description": "For list only: page number, starting at 1 (default 1)",
49+
"minimum": 1,
50+
"type": "integer"
51+
},
52+
"perPage": {
53+
"description": "For list only: results per page, from 1 to 100 (default 30)",
54+
"maximum": 100,
55+
"minimum": 1,
56+
"type": "integer"
57+
},
58+
"repo": {
59+
"description": "Repository name",
60+
"minLength": 1,
61+
"type": "string",
62+
"x-mcp-header": "repo"
63+
},
64+
"type": {
65+
"enum": [
66+
"generic",
67+
"link",
68+
"plan",
69+
"embedded_html"
70+
],
71+
"type": "string"
72+
}
73+
},
74+
"required": [
75+
"owner",
76+
"repo",
77+
"issue_number",
78+
"method"
79+
],
80+
"type": "object"
81+
},
82+
"name": "issue_artifact_read",
83+
"outputSchema": {
84+
"additionalProperties": false,
85+
"properties": {
86+
"artifact": {
87+
"additionalProperties": false,
88+
"description": "Artifact returned by get",
89+
"properties": {
90+
"body": {
91+
"type": "string"
92+
},
93+
"id": {
94+
"type": "integer"
95+
},
96+
"name": {
97+
"type": "string"
98+
},
99+
"number": {
100+
"type": "integer"
101+
},
102+
"type": {
103+
"type": "string"
104+
}
105+
},
106+
"required": [
107+
"id",
108+
"number",
109+
"type",
110+
"name",
111+
"body"
112+
],
113+
"type": [
114+
"null",
115+
"object"
116+
]
117+
},
118+
"list": {
119+
"additionalProperties": false,
120+
"description": "Page of artifacts returned by list",
121+
"properties": {
122+
"artifacts": {
123+
"items": {
124+
"additionalProperties": false,
125+
"properties": {
126+
"body": {
127+
"type": "string"
128+
},
129+
"id": {
130+
"type": "integer"
131+
},
132+
"name": {
133+
"type": "string"
134+
},
135+
"number": {
136+
"type": "integer"
137+
},
138+
"type": {
139+
"type": "string"
140+
}
141+
},
142+
"required": [
143+
"id",
144+
"number",
145+
"type",
146+
"name",
147+
"body"
148+
],
149+
"type": "object"
150+
},
151+
"type": [
152+
"null",
153+
"array"
154+
]
155+
},
156+
"page": {
157+
"type": "integer"
158+
},
159+
"perPage": {
160+
"type": "integer"
161+
}
162+
},
163+
"required": [
164+
"artifacts",
165+
"page",
166+
"perPage"
167+
],
168+
"type": [
169+
"null",
170+
"object"
171+
]
172+
}
173+
},
174+
"type": [
175+
"null",
176+
"object"
177+
]
178+
}
179+
}

0 commit comments

Comments
 (0)