Skip to content

Commit 54fac00

Browse files
Add remote-only toolsets with auto-generated documentation and icons guide
- Add ToolsetMetadataCopilot, ToolsetMetadataCopilotSpaces, ToolsetMetadataSupportSearch - Add RemoteOnlyToolsets() function to return remote-only toolset metadata - Update doc generator to auto-generate remote-only toolsets table with icons - Create docs/toolsets-and-icons.md explaining how to add icons to toolsets - Add link to icons guide in CONTRIBUTING.md
1 parent 3df07ae commit 54fac00

File tree

5 files changed

+244
-5
lines changed

5 files changed

+244
-5
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ These are one time installations required to be able to test your changes locall
4040
- Update snapshots and run tests: `UPDATE_TOOLSNAPS=true go test ./...`
4141
- Update readme documentation: `script/generate-docs`
4242
- If renaming a tool, add a deprecation alias (see [Tool Renaming Guide](docs/tool-renaming.md))
43+
- For toolset and icon configuration, see [Toolsets and Icons Guide](docs/toolsets-and-icons.md)
4344
6. Push to your fork and [submit a pull request][pr] targeting the `main` branch
4445
7. Pat yourself on the back and wait for your pull request to be reviewed and merged.
4546

cmd/github-mcp-server/generate_docs.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ func generateRemoteServerDocs(docsPath string) error {
101101
return err
102102
}
103103

104+
// Also generate remote-only toolsets section
105+
remoteOnlyDoc := generateRemoteOnlyToolsetsDoc()
106+
updatedContent, err = replaceSection(updatedContent, "START AUTOMATED REMOTE TOOLSETS", "END AUTOMATED REMOTE TOOLSETS", remoteOnlyDoc)
107+
if err != nil {
108+
return err
109+
}
110+
104111
return os.WriteFile(docsPath, []byte(updatedContent), 0600) //#nosec G306
105112
}
106113

@@ -373,6 +380,46 @@ func generateRemoteToolsetsDoc() string {
373380
return strings.TrimSuffix(buf.String(), "\n")
374381
}
375382

383+
func generateRemoteOnlyToolsetsDoc() string {
384+
var buf strings.Builder
385+
386+
// Generate table header (with icon column)
387+
buf.WriteString("| | Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) |\n")
388+
buf.WriteString("| --- | ---- | ----------- | ------- | ------------------------- | -------------- | ----------------------------------- |\n")
389+
390+
// Use RemoteOnlyToolsets from github package
391+
for _, ts := range github.RemoteOnlyToolsets() {
392+
idStr := string(ts.ID)
393+
394+
formattedName := formatToolsetName(idStr)
395+
apiURL := fmt.Sprintf("https://api.githubcopilot.com/mcp/x/%s", idStr)
396+
readonlyURL := fmt.Sprintf("https://api.githubcopilot.com/mcp/x/%s/readonly", idStr)
397+
398+
// Create install config JSON (URL encoded)
399+
installConfig := url.QueryEscape(fmt.Sprintf(`{"type": "http","url": "%s"}`, apiURL))
400+
readonlyConfig := url.QueryEscape(fmt.Sprintf(`{"type": "http","url": "%s"}`, readonlyURL))
401+
402+
// Fix URL encoding to use %20 instead of + for spaces
403+
installConfig = strings.ReplaceAll(installConfig, "+", "%20")
404+
readonlyConfig = strings.ReplaceAll(readonlyConfig, "+", "%20")
405+
406+
installLink := fmt.Sprintf("[Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-%s&config=%s)", idStr, installConfig)
407+
readonlyInstallLink := fmt.Sprintf("[Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-%s&config=%s)", idStr, readonlyConfig)
408+
409+
icon := octiconImg(ts.Icon, "../")
410+
fmt.Fprintf(&buf, "| %s | %s | %s | %s | %s | [read-only](%s) | %s |\n",
411+
icon,
412+
formattedName,
413+
ts.Description,
414+
apiURL,
415+
installLink,
416+
readonlyURL,
417+
readonlyInstallLink,
418+
)
419+
}
420+
421+
return strings.TrimSuffix(buf.String(), "\n")
422+
}
376423
func generateDeprecatedAliasesDocs(docsPath string) error {
377424
// Read the current file
378425
content, err := os.ReadFile(docsPath) //#nosec G304

docs/remote-server.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ Below is a table of available toolsets for the remote GitHub MCP Server. Each to
4343

4444
These toolsets are only available in the remote GitHub MCP Server and are not included in the local MCP server.
4545

46-
| Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) |
47-
| -------------------- | --------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
48-
| Copilot | Copilot related tools | https://api.githubcopilot.com/mcp/x/copilot | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/copilot/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot%2Freadonly%22%7D) |
49-
| Copilot Spaces | Copilot Spaces tools | https://api.githubcopilot.com/mcp/x/copilot_spaces | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot_spaces&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot_spaces%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/copilot_spaces/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot_spaces&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot_spaces%2Freadonly%22%7D) |
50-
| GitHub support docs search | Retrieve documentation to answer GitHub product and support questions. Topics include: GitHub Actions Workflows, Authentication, ... | https://api.githubcopilot.com/mcp/x/github_support_docs_search | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-support&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgithub_support_docs_search%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/github_support_docs_search/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-support&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgithub_support_docs_search%2Freadonly%22%7D) |
46+
<!-- START AUTOMATED REMOTE TOOLSETS -->
47+
| | Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) |
48+
| --- | ---- | ----------- | ------- | ------------------------- | -------------- | ----------------------------------- |
49+
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/copilot-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/copilot-light.png"><img src="../pkg/octicons/icons/copilot-light.png" width="20" height="20" alt="copilot"></picture> | Copilot | Copilot related tools | https://api.githubcopilot.com/mcp/x/copilot | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/copilot/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot%2Freadonly%22%7D) |
50+
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/copilot-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/copilot-light.png"><img src="../pkg/octicons/icons/copilot-light.png" width="20" height="20" alt="copilot"></picture> | Copilot Spaces | Copilot Spaces tools | https://api.githubcopilot.com/mcp/x/copilot_spaces | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot_spaces&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot_spaces%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/copilot_spaces/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot_spaces&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot_spaces%2Freadonly%22%7D) |
51+
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/book-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/book-light.png"><img src="../pkg/octicons/icons/book-light.png" width="20" height="20" alt="book"></picture> | Github Support Docs Search | Retrieve documentation to answer GitHub product and support questions. Topics include: GitHub Actions Workflows, Authentication, ... | https://api.githubcopilot.com/mcp/x/github_support_docs_search | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-github_support_docs_search&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgithub_support_docs_search%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/github_support_docs_search/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-github_support_docs_search&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgithub_support_docs_search%2Freadonly%22%7D) |
52+
<!-- END AUTOMATED REMOTE TOOLSETS -->
5153

5254
### Optional Headers
5355

docs/toolsets-and-icons.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Toolsets and Icons
2+
3+
This document explains how to work with toolsets and icons in the GitHub MCP Server.
4+
5+
## Toolset Overview
6+
7+
Toolsets are logical groupings of related tools. Each toolset has metadata defined in `pkg/github/tools.go`:
8+
9+
```go
10+
ToolsetMetadataRepos = inventory.ToolsetMetadata{
11+
ID: "repos",
12+
Description: "GitHub Repository related tools",
13+
Default: true,
14+
Icon: "repo",
15+
}
16+
```
17+
18+
### Toolset Fields
19+
20+
| Field | Type | Description |
21+
|-------|------|-------------|
22+
| `ID` | `ToolsetID` | Unique identifier used in URLs and CLI flags (e.g., `repos`, `issues`) |
23+
| `Description` | `string` | Human-readable description shown in documentation |
24+
| `Default` | `bool` | Whether this toolset is enabled by default |
25+
| `Icon` | `string` | Octicon name for visual representation in MCP clients |
26+
27+
## Adding Icons to Toolsets
28+
29+
Icons help users quickly identify toolsets in MCP-compatible clients. We use [Primer Octicons](https://primer.style/foundations/icons) for all icons.
30+
31+
### Step 1: Choose an Octicon
32+
33+
Browse the [Octicon gallery](https://primer.style/foundations/icons) and select an appropriate icon. Use the base name without size suffix (e.g., `repo` not `repo-16`).
34+
35+
### Step 2: Add the Icon Files
36+
37+
Icons are stored as PNG files in `pkg/octicons/icons/` with light and dark theme variants:
38+
39+
```
40+
pkg/octicons/icons/
41+
├── repo-light.png # For light theme
42+
├── repo-dark.png # For dark theme
43+
├── issue-opened-light.png
44+
├── issue-opened-dark.png
45+
└── ...
46+
```
47+
48+
Icon files should be 20x20 pixels in size.
49+
50+
### Step 3: Update the Toolset Metadata
51+
52+
Add or update the `Icon` field in the toolset definition:
53+
54+
```go
55+
// In pkg/github/tools.go
56+
ToolsetMetadataRepos = inventory.ToolsetMetadata{
57+
ID: "repos",
58+
Description: "GitHub Repository related tools",
59+
Default: true,
60+
Icon: "repo", // Add this line
61+
}
62+
```
63+
64+
### Step 4: Regenerate Documentation
65+
66+
Run the documentation generator to update all markdown files:
67+
68+
```bash
69+
go run ./cmd/github-mcp-server generate-docs
70+
```
71+
72+
This updates icons in:
73+
- `README.md` - Toolsets table and tool section headers
74+
- `docs/remote-server.md` - Remote toolsets table
75+
76+
## Remote-Only Toolsets
77+
78+
Some toolsets are only available in the remote GitHub MCP Server (hosted at `api.githubcopilot.com`). These are defined in `pkg/github/tools.go` with their icons, but are not registered with the local server:
79+
80+
```go
81+
// Remote-only toolsets
82+
ToolsetMetadataCopilot = inventory.ToolsetMetadata{
83+
ID: "copilot",
84+
Description: "Copilot related tools",
85+
Icon: "copilot",
86+
}
87+
```
88+
89+
The `RemoteOnlyToolsets()` function returns the list of these toolsets for documentation generation.
90+
91+
To add a new remote-only toolset:
92+
93+
1. Add the metadata definition in `pkg/github/tools.go`
94+
2. Add it to the slice returned by `RemoteOnlyToolsets()`
95+
3. Regenerate documentation
96+
97+
## Tool Icon Inheritance
98+
99+
Individual tools inherit icons from their parent toolset. When a tool is registered with a toolset, its icons are automatically set:
100+
101+
```go
102+
// In pkg/inventory/server_tool.go
103+
toolCopy.Icons = tool.Toolset.Icons()
104+
```
105+
106+
This means you only need to set the icon once on the toolset, and all tools in that toolset will display the same icon.
107+
108+
## How Icons Work in MCP
109+
110+
The MCP protocol supports tool icons via the `icons` field. We provide icons in two formats:
111+
112+
1. **Data URIs** - Base64-encoded PNG images embedded in the tool definition
113+
2. **Light/Dark variants** - Both theme variants are provided for proper display
114+
115+
The `octicons.Icons()` function generates the MCP-compatible icon objects:
116+
117+
```go
118+
// Returns []mcp.Icon with both light and dark variants
119+
icons := octicons.Icons("repo")
120+
```
121+
122+
## Existing Toolset Icons
123+
124+
| Toolset | Octicon Name |
125+
|---------|--------------|
126+
| Context | `person` |
127+
| Repositories | `repo` |
128+
| Issues | `issue-opened` |
129+
| Pull Requests | `git-pull-request` |
130+
| Git | `git-branch` |
131+
| Users | `people` |
132+
| Organizations | `organization` |
133+
| Actions | `workflow` |
134+
| Code Security | `codescan` |
135+
| Secret Protection | `shield-lock` |
136+
| Dependabot | `dependabot` |
137+
| Discussions | `comment-discussion` |
138+
| Gists | `logo-gist` |
139+
| Security Advisories | `shield` |
140+
| Projects | `project` |
141+
| Labels | `tag` |
142+
| Stargazers | `star` |
143+
| Notifications | `bell` |
144+
| Dynamic | `tools` |
145+
| Copilot | `copilot` |
146+
| Support Search | `book` |
147+
148+
## Troubleshooting
149+
150+
### Icons not appearing in documentation
151+
152+
1. Ensure PNG files exist in `pkg/octicons/icons/` with `-light.png` and `-dark.png` suffixes
153+
2. Run `go run ./cmd/github-mcp-server generate-docs` to regenerate
154+
3. Check that the `Icon` field is set on the toolset metadata
155+
156+
### Icons not appearing in MCP clients
157+
158+
1. Verify the client supports MCP tool icons
159+
2. Check that the octicons package is properly generating base64 data URIs
160+
3. Ensure the icon name matches a file in `pkg/octicons/icons/`

pkg/github/tools.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,24 @@ var (
132132
Description: "GitHub Labels related tools",
133133
Icon: "tag",
134134
}
135+
136+
// Remote-only toolsets - these are only available in the remote MCP server
137+
// but are documented here for consistency and to enable automated documentation.
138+
ToolsetMetadataCopilot = inventory.ToolsetMetadata{
139+
ID: "copilot",
140+
Description: "Copilot related tools",
141+
Icon: "copilot",
142+
}
143+
ToolsetMetadataCopilotSpaces = inventory.ToolsetMetadata{
144+
ID: "copilot_spaces",
145+
Description: "Copilot Spaces tools",
146+
Icon: "copilot",
147+
}
148+
ToolsetMetadataSupportSearch = inventory.ToolsetMetadata{
149+
ID: "github_support_docs_search",
150+
Description: "Retrieve documentation to answer GitHub product and support questions. Topics include: GitHub Actions Workflows, Authentication, ...",
151+
Icon: "book",
152+
}
135153
)
136154

137155
// AllTools returns all tools with their embedded toolset metadata.
@@ -428,3 +446,14 @@ func GetDefaultToolsetIDs() []string {
428446
}
429447
return result
430448
}
449+
450+
// RemoteOnlyToolsets returns toolset metadata for toolsets that are only
451+
// available in the remote MCP server. These are documented but not registered
452+
// in the local server.
453+
func RemoteOnlyToolsets() []inventory.ToolsetMetadata {
454+
return []inventory.ToolsetMetadata{
455+
ToolsetMetadataCopilot,
456+
ToolsetMetadataCopilotSpaces,
457+
ToolsetMetadataSupportSearch,
458+
}
459+
}

0 commit comments

Comments
 (0)