From 54fac0041941e17bcbc8eddc940badf595421531 Mon Sep 17 00:00:00 2001 From: Sam Morrow Date: Wed, 17 Dec 2025 11:03:03 +0100 Subject: [PATCH] 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 --- CONTRIBUTING.md | 1 + cmd/github-mcp-server/generate_docs.go | 47 ++++++++ docs/remote-server.md | 12 +- docs/toolsets-and-icons.md | 160 +++++++++++++++++++++++++ pkg/github/tools.go | 29 +++++ 5 files changed, 244 insertions(+), 5 deletions(-) create mode 100644 docs/toolsets-and-icons.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9bbf555e..6c16cd27 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,6 +40,7 @@ These are one time installations required to be able to test your changes locall - Update snapshots and run tests: `UPDATE_TOOLSNAPS=true go test ./...` - Update readme documentation: `script/generate-docs` - If renaming a tool, add a deprecation alias (see [Tool Renaming Guide](docs/tool-renaming.md)) + - For toolset and icon configuration, see [Toolsets and Icons Guide](docs/toolsets-and-icons.md) 6. Push to your fork and [submit a pull request][pr] targeting the `main` branch 7. Pat yourself on the back and wait for your pull request to be reviewed and merged. diff --git a/cmd/github-mcp-server/generate_docs.go b/cmd/github-mcp-server/generate_docs.go index 7c8eff59..3ee60476 100644 --- a/cmd/github-mcp-server/generate_docs.go +++ b/cmd/github-mcp-server/generate_docs.go @@ -101,6 +101,13 @@ func generateRemoteServerDocs(docsPath string) error { return err } + // Also generate remote-only toolsets section + remoteOnlyDoc := generateRemoteOnlyToolsetsDoc() + updatedContent, err = replaceSection(updatedContent, "START AUTOMATED REMOTE TOOLSETS", "END AUTOMATED REMOTE TOOLSETS", remoteOnlyDoc) + if err != nil { + return err + } + return os.WriteFile(docsPath, []byte(updatedContent), 0600) //#nosec G306 } @@ -373,6 +380,46 @@ func generateRemoteToolsetsDoc() string { return strings.TrimSuffix(buf.String(), "\n") } +func generateRemoteOnlyToolsetsDoc() string { + var buf strings.Builder + + // Generate table header (with icon column) + buf.WriteString("| | Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) |\n") + buf.WriteString("| --- | ---- | ----------- | ------- | ------------------------- | -------------- | ----------------------------------- |\n") + + // Use RemoteOnlyToolsets from github package + for _, ts := range github.RemoteOnlyToolsets() { + idStr := string(ts.ID) + + formattedName := formatToolsetName(idStr) + apiURL := fmt.Sprintf("https://api.githubcopilot.com/mcp/x/%s", idStr) + readonlyURL := fmt.Sprintf("https://api.githubcopilot.com/mcp/x/%s/readonly", idStr) + + // Create install config JSON (URL encoded) + installConfig := url.QueryEscape(fmt.Sprintf(`{"type": "http","url": "%s"}`, apiURL)) + readonlyConfig := url.QueryEscape(fmt.Sprintf(`{"type": "http","url": "%s"}`, readonlyURL)) + + // Fix URL encoding to use %20 instead of + for spaces + installConfig = strings.ReplaceAll(installConfig, "+", "%20") + readonlyConfig = strings.ReplaceAll(readonlyConfig, "+", "%20") + + installLink := fmt.Sprintf("[Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-%s&config=%s)", idStr, installConfig) + readonlyInstallLink := fmt.Sprintf("[Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-%s&config=%s)", idStr, readonlyConfig) + + icon := octiconImg(ts.Icon, "../") + fmt.Fprintf(&buf, "| %s | %s | %s | %s | %s | [read-only](%s) | %s |\n", + icon, + formattedName, + ts.Description, + apiURL, + installLink, + readonlyURL, + readonlyInstallLink, + ) + } + + return strings.TrimSuffix(buf.String(), "\n") +} func generateDeprecatedAliasesDocs(docsPath string) error { // Read the current file content, err := os.ReadFile(docsPath) //#nosec G304 diff --git a/docs/remote-server.md b/docs/remote-server.md index f4521bf8..5e768dbc 100644 --- a/docs/remote-server.md +++ b/docs/remote-server.md @@ -43,11 +43,13 @@ Below is a table of available toolsets for the remote GitHub MCP Server. Each to These toolsets are only available in the remote GitHub MCP Server and are not included in the local MCP server. -| Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) | -| -------------------- | --------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 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) | -| 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) | -| 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) | + +| | Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) | +| --- | ---- | ----------- | ------- | ------------------------- | -------------- | ----------------------------------- | +| copilot | 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) | +| copilot | 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) | +| book | 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) | + ### Optional Headers diff --git a/docs/toolsets-and-icons.md b/docs/toolsets-and-icons.md new file mode 100644 index 00000000..7328a420 --- /dev/null +++ b/docs/toolsets-and-icons.md @@ -0,0 +1,160 @@ +# Toolsets and Icons + +This document explains how to work with toolsets and icons in the GitHub MCP Server. + +## Toolset Overview + +Toolsets are logical groupings of related tools. Each toolset has metadata defined in `pkg/github/tools.go`: + +```go +ToolsetMetadataRepos = inventory.ToolsetMetadata{ + ID: "repos", + Description: "GitHub Repository related tools", + Default: true, + Icon: "repo", +} +``` + +### Toolset Fields + +| Field | Type | Description | +|-------|------|-------------| +| `ID` | `ToolsetID` | Unique identifier used in URLs and CLI flags (e.g., `repos`, `issues`) | +| `Description` | `string` | Human-readable description shown in documentation | +| `Default` | `bool` | Whether this toolset is enabled by default | +| `Icon` | `string` | Octicon name for visual representation in MCP clients | + +## Adding Icons to Toolsets + +Icons help users quickly identify toolsets in MCP-compatible clients. We use [Primer Octicons](https://primer.style/foundations/icons) for all icons. + +### Step 1: Choose an Octicon + +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`). + +### Step 2: Add the Icon Files + +Icons are stored as PNG files in `pkg/octicons/icons/` with light and dark theme variants: + +``` +pkg/octicons/icons/ +├── repo-light.png # For light theme +├── repo-dark.png # For dark theme +├── issue-opened-light.png +├── issue-opened-dark.png +└── ... +``` + +Icon files should be 20x20 pixels in size. + +### Step 3: Update the Toolset Metadata + +Add or update the `Icon` field in the toolset definition: + +```go +// In pkg/github/tools.go +ToolsetMetadataRepos = inventory.ToolsetMetadata{ + ID: "repos", + Description: "GitHub Repository related tools", + Default: true, + Icon: "repo", // Add this line +} +``` + +### Step 4: Regenerate Documentation + +Run the documentation generator to update all markdown files: + +```bash +go run ./cmd/github-mcp-server generate-docs +``` + +This updates icons in: +- `README.md` - Toolsets table and tool section headers +- `docs/remote-server.md` - Remote toolsets table + +## Remote-Only Toolsets + +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: + +```go +// Remote-only toolsets +ToolsetMetadataCopilot = inventory.ToolsetMetadata{ + ID: "copilot", + Description: "Copilot related tools", + Icon: "copilot", +} +``` + +The `RemoteOnlyToolsets()` function returns the list of these toolsets for documentation generation. + +To add a new remote-only toolset: + +1. Add the metadata definition in `pkg/github/tools.go` +2. Add it to the slice returned by `RemoteOnlyToolsets()` +3. Regenerate documentation + +## Tool Icon Inheritance + +Individual tools inherit icons from their parent toolset. When a tool is registered with a toolset, its icons are automatically set: + +```go +// In pkg/inventory/server_tool.go +toolCopy.Icons = tool.Toolset.Icons() +``` + +This means you only need to set the icon once on the toolset, and all tools in that toolset will display the same icon. + +## How Icons Work in MCP + +The MCP protocol supports tool icons via the `icons` field. We provide icons in two formats: + +1. **Data URIs** - Base64-encoded PNG images embedded in the tool definition +2. **Light/Dark variants** - Both theme variants are provided for proper display + +The `octicons.Icons()` function generates the MCP-compatible icon objects: + +```go +// Returns []mcp.Icon with both light and dark variants +icons := octicons.Icons("repo") +``` + +## Existing Toolset Icons + +| Toolset | Octicon Name | +|---------|--------------| +| Context | `person` | +| Repositories | `repo` | +| Issues | `issue-opened` | +| Pull Requests | `git-pull-request` | +| Git | `git-branch` | +| Users | `people` | +| Organizations | `organization` | +| Actions | `workflow` | +| Code Security | `codescan` | +| Secret Protection | `shield-lock` | +| Dependabot | `dependabot` | +| Discussions | `comment-discussion` | +| Gists | `logo-gist` | +| Security Advisories | `shield` | +| Projects | `project` | +| Labels | `tag` | +| Stargazers | `star` | +| Notifications | `bell` | +| Dynamic | `tools` | +| Copilot | `copilot` | +| Support Search | `book` | + +## Troubleshooting + +### Icons not appearing in documentation + +1. Ensure PNG files exist in `pkg/octicons/icons/` with `-light.png` and `-dark.png` suffixes +2. Run `go run ./cmd/github-mcp-server generate-docs` to regenerate +3. Check that the `Icon` field is set on the toolset metadata + +### Icons not appearing in MCP clients + +1. Verify the client supports MCP tool icons +2. Check that the octicons package is properly generating base64 data URIs +3. Ensure the icon name matches a file in `pkg/octicons/icons/` diff --git a/pkg/github/tools.go b/pkg/github/tools.go index 48298afb..10877adf 100644 --- a/pkg/github/tools.go +++ b/pkg/github/tools.go @@ -132,6 +132,24 @@ var ( Description: "GitHub Labels related tools", Icon: "tag", } + + // Remote-only toolsets - these are only available in the remote MCP server + // but are documented here for consistency and to enable automated documentation. + ToolsetMetadataCopilot = inventory.ToolsetMetadata{ + ID: "copilot", + Description: "Copilot related tools", + Icon: "copilot", + } + ToolsetMetadataCopilotSpaces = inventory.ToolsetMetadata{ + ID: "copilot_spaces", + Description: "Copilot Spaces tools", + Icon: "copilot", + } + ToolsetMetadataSupportSearch = inventory.ToolsetMetadata{ + ID: "github_support_docs_search", + Description: "Retrieve documentation to answer GitHub product and support questions. Topics include: GitHub Actions Workflows, Authentication, ...", + Icon: "book", + } ) // AllTools returns all tools with their embedded toolset metadata. @@ -428,3 +446,14 @@ func GetDefaultToolsetIDs() []string { } return result } + +// RemoteOnlyToolsets returns toolset metadata for toolsets that are only +// available in the remote MCP server. These are documented but not registered +// in the local server. +func RemoteOnlyToolsets() []inventory.ToolsetMetadata { + return []inventory.ToolsetMetadata{ + ToolsetMetadataCopilot, + ToolsetMetadataCopilotSpaces, + ToolsetMetadataSupportSearch, + } +}