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
echo "ℹ️ **Note:** This job exercises the streamable-http transport against a shared server, with per-config settings supplied via X-MCP-* request headers." >> $GITHUB_STEP_SUMMARY
Copy file name to clipboardExpand all lines: docs/insiders-features.md
+57Lines changed: 57 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -42,3 +42,60 @@ MCP Apps requires a host that supports the [MCP Apps extension](https://modelcon
42
42
43
43
-**VS Code Insiders** — enable via the `chat.mcp.apps.enabled` setting
44
44
-**Visual Studio Code** — enable via the `chat.mcp.apps.enabled` setting
45
+
46
+
---
47
+
48
+
## CSV output for list tools
49
+
50
+
CSV output mode returns supported list tool responses as CSV instead of JSON. This is intended to reduce response context for agents when scanning or summarising lists of GitHub data.
51
+
52
+
CSV output applies only to tools in default toolsets whose names start with `list_`, such as `list_issues`, `list_pull_requests`, `list_commits`, and `list_branches`. It does not add new tools or expose a tool argument for selecting the format; the server controls the response format through the Insiders feature flag.
53
+
54
+
### Format
55
+
56
+
- Nested objects are flattened into dot-notation columns, for example `user.login`, `category.name`, or `head.ref`.
57
+
- Arrays are represented as compact single-cell values joined with `;`.
58
+
-`body` fields are whitespace-normalized so multiline Markdown does not expand a list response into many output lines.
59
+
- Response metadata present in wrapped responses, such as `pageInfo.*` and `totalCount`, is emitted as `#`-prefixed lines before the CSV rows, followed by a blank line. Tools that return a root JSON array do not include metadata preamble lines.
60
+
61
+
### Enabling CSV output
62
+
63
+
CSV output is enabled by Insiders Mode. For local development, it can also be enabled explicitly with the `csv_output` feature flag:
64
+
65
+
```bash
66
+
github-mcp-server stdio --features csv_output
67
+
```
68
+
69
+
Because this changes list tool response shape, clients that require JSON list responses should avoid enabling this feature.
70
+
71
+
---
72
+
73
+
## How feature flags are resolved
74
+
75
+
> [!NOTE]
76
+
> This section is for contributors. End users only need the table at the top of this page.
77
+
78
+
Insiders is a **meta feature flag** — the same shape as `default` or `all` for toolsets. It expands once at startup into a curated set of individual feature flags, and from that point on every code path keys off concrete flags, never `InsidersMode` directly. New experimental work should always get its own flag and then be added to the insiders expansion list, never folded into `insiders` as a catch-all.
79
+
80
+
### Resolution order
81
+
82
+
1.**User input.** Users may opt into specific features:
83
+
- Local server: `--features=<flag>,<flag>` CLI flag (or `GITHUB_FEATURES` env var).
2.**Allowlist filter.** User-supplied flags are filtered against [`AllowedFeatureFlags`](../pkg/github/feature_flags.go). Anything not on the allowlist is silently dropped — flags missing from the allowlist can only be turned on by remote-server feature management, not by end users.
86
+
3.**Insiders expansion.** If insiders mode is on (`--insiders`, `/insiders` route, or `X-MCP-Insiders: true`), every flag in [`InsidersFeatureFlags`](../pkg/github/feature_flags.go) is unioned in. The insiders expansion is **not** re-validated against the allowlist — insiders is a server-controlled switch that can reach internal-only flags.
87
+
4.**Server-side fallback (remote server only).** Any flag not yet decided falls back to the remote server's feature manager, which can roll a feature out independently of user input or insiders membership.
88
+
89
+
`AllowedFeatureFlags` and `InsidersFeatureFlags` are deliberately independent sets:
90
+
91
+
- A flag in **`AllowedFeatureFlags` only** is a regular opt-in: users can turn it on, but insiders does not auto-enable it. Granular issues/PRs flags work this way.
92
+
- A flag in **`InsidersFeatureFlags` only** is reachable through insiders (and remote-server rollouts), but cannot be enabled by user input. Internal-only experiments work this way.
93
+
- A flag in **both** is opt-in for end users *and* automatically on under insiders.
94
+
95
+
### Adding a new feature flag
96
+
97
+
1. Add a constant in `pkg/github/feature_flags.go`.
98
+
2. Add it to `AllowedFeatureFlags` if end users should be able to opt in via `--features` / `X-MCP-Features`.
99
+
3. Add it to `InsidersFeatureFlags` if insiders mode should turn it on automatically.
100
+
4. Gate the behavior on the concrete flag (`deps.IsFeatureEnabled(ctx, FeatureFlagX)`), never on `cfg.InsidersMode`. There is a `TestGitHubPackageDoesNotReadInsidersMode` guard test that fails if `pkg/github` reads `InsidersMode` directly.
101
+
5. The MCP-diff CI workflow picks up new entries in `AllowedFeatureFlags` automatically — see `.github/workflows/mcp-diff.yml`.
"description": "List issue fields for a repository or organization. Returns field definitions including name, type (text, number, date, single_select), and for single_select fields the list of valid option names. When repo is omitted, returns org-level fields directly.",
7
+
"inputSchema": {
8
+
"properties": {
9
+
"owner": {
10
+
"description": "The account owner of the repository or organization. The name is not case sensitive.",
11
+
"type": "string"
12
+
},
13
+
"repo": {
14
+
"description": "The name of the repository. When provided, returns fields for this specific repository (inherited from its organization). When omitted, returns org-level fields directly.",
Copy file name to clipboardExpand all lines: pkg/github/__toolsnaps__/list_issues.snap
+21Lines changed: 21 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -18,6 +18,27 @@
18
18
],
19
19
"type": "string"
20
20
},
21
+
"field_filters": {
22
+
"description": "Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date).",
23
+
"items": {
24
+
"properties": {
25
+
"field_name": {
26
+
"description": "Name of the custom field (e.g. \"Priority\"). Case-insensitive.",
27
+
"type": "string"
28
+
},
29
+
"value": {
30
+
"description": "Value to filter on. For single-select fields, the option name (e.g. \"P1\"). For dates, YYYY-MM-DD. For numbers, the numeric value as a string. For text, the text value.",
0 commit comments