-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Add Octicon icons to MCP tools #1603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: SamMorrowDrums/server-tool-refactor-toolsets
Are you sure you want to change the base?
Add Octicon icons to MCP tools #1603
Conversation
- Upgrade MCP Go SDK from v1.1.0 to v1.2.0-pre.1 for Icon support - Add Icon field to ToolsetMetadata for Octicon name assignment - Add OcticonURL() helper to generate CDN URLs for Octicon SVGs - Add Icons() method on ToolsetMetadata to generate MCP Icon objects - Apply icons automatically in RegisterFunc when tool is registered - Add icons to all 22 toolset metadata constants with appropriate Octicons - Update server.go to use new Capabilities API (fixes deprecation warnings) This demonstrates how the toolsets refactor makes adding new features simpler: icons are defined once in ToolsetMetadata and automatically applied to all tools in that toolset during registration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds Octicon icons to all MCP tools by upgrading the MCP Go SDK from v1.1.0 to v1.2.0-pre.1 and implementing icon infrastructure that automatically applies icons based on toolset metadata.
Key Changes
- Upgraded MCP Go SDK to v1.2.0-pre.1 to enable Icons field support
- Added icon infrastructure in
pkg/toolsets/server_tool.gowith automatic icon application during tool registration - Assigned appropriate Octicon icons to all 22 toolset metadata constants
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| go.mod | Upgraded modelcontextprotocol/go-sdk from v1.1.0 to v1.2.0-pre.1 |
| go.sum | Updated checksums for SDK upgrade and new golang-jwt/jwt/v5 dependency |
| pkg/github/server.go | Migrated from deprecated HasTools/HasResources/HasPrompts to new Capabilities API structure |
| pkg/toolsets/server_tool.go | Added Icon field to ToolsetMetadata, OcticonURL helper, Icons() method, and automatic icon application in RegisterFunc |
| pkg/github/tools.go | Assigned Octicon icon names to all 22 toolset metadata constants |
| } | ||
|
|
||
| // OcticonURL returns the CDN URL for a GitHub Octicon SVG. Size should be 16 or 24. | ||
| func OcticonURL(name string, size int) string { |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OcticonURL function does not validate the size parameter. According to the documentation comment, size should be 16 or 24, but any integer value will be accepted and used to construct the URL. While Icons() method currently only uses valid sizes (16 and 24), this function is exported and could be called by other packages with invalid values, resulting in broken URLs. Consider adding validation to ensure size is either 16 or 24.
| func OcticonURL(name string, size int) string { | |
| func OcticonURL(name string, size int) string { | |
| if size != 16 && size != 24 { | |
| return "" | |
| } |
| // Apply icons from toolset metadata if tool doesn't have icons set | ||
| if len(st.Tool.Icons) == 0 { | ||
| st.Tool.Icons = st.Toolset.Icons() | ||
| } | ||
| s.AddTool(&st.Tool, handler) |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RegisterFunc method mutates the Tool.Icons field on the ServerTool struct. This can cause unexpected behavior if the same ServerTool instance is registered multiple times or if the tool is accessed concurrently. Since ServerTool instances are typically defined as global variables, this mutation could lead to race conditions. Consider either making a copy of the tool before modifying it, or documenting that ServerTool instances should not be reused after registration.
| // Apply icons from toolset metadata if tool doesn't have icons set | |
| if len(st.Tool.Icons) == 0 { | |
| st.Tool.Icons = st.Toolset.Icons() | |
| } | |
| s.AddTool(&st.Tool, handler) | |
| // Make a shallow copy of the tool to avoid mutating the original | |
| toolCopy := st.Tool | |
| // Apply icons from toolset metadata if tool doesn't have icons set | |
| if len(toolCopy.Icons) == 0 { | |
| toolCopy.Icons = st.Toolset.Icons() | |
| } | |
| s.AddTool(&toolCopy, handler) |
| // OcticonURL returns the CDN URL for a GitHub Octicon SVG. Size should be 16 or 24. | ||
| func OcticonURL(name string, size int) string { | ||
| return fmt.Sprintf("https://raw.githubusercontent.com/primer/octicons/main/icons/%s-%d.svg", name, size) | ||
| } | ||
|
|
||
| // Icons returns MCP Icon objects for this toolset, or nil if no icon is set. | ||
| // Icons are provided in both 16x16 and 24x24 sizes. | ||
| func (tm ToolsetMetadata) Icons() []mcp.Icon { | ||
| if tm.Icon == "" { | ||
| return nil | ||
| } | ||
| return []mcp.Icon{ | ||
| { | ||
| Source: OcticonURL(tm.Icon, 16), | ||
| MIMEType: "image/svg+xml", | ||
| Sizes: []string{"16x16"}, | ||
| }, | ||
| { | ||
| Source: OcticonURL(tm.Icon, 24), | ||
| MIMEType: "image/svg+xml", | ||
| Sizes: []string{"24x24"}, | ||
| }, | ||
| } | ||
| } |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new icon infrastructure (OcticonURL function, Icons method, and icon assignment in RegisterFunc) lacks test coverage. Given that this is a new feature being added to a popular open-source repository, tests should be added to verify:
- OcticonURL generates correct URLs for valid sizes
- Icons() method returns correct icon objects with proper MIME types and sizes
- RegisterFunc correctly applies icons from metadata when not already set
- Icon field values in toolset metadata resolve to valid Octicon names
This is especially important since the PR description mentions that icons are served from GitHub's CDN, so broken icon names would result in 404 errors.
Summary
This PR adds Octicon icons to all MCP tools, using the new
Iconsfield added in MCP Go SDK v1.2.0-pre.1.Stacked on #1602 (toolsets refactor) - demonstrates how the refactored architecture makes adding new cross-cutting features simpler.
Changes
SDK Upgrade
Iconsfield on Tool struct)NewServer()to use newCapabilitiesAPI instead of deprecatedHasTools/HasResources/HasPromptsfieldsIcon Infrastructure (pkg/toolsets/server_tool.go)
Iconfield toToolsetMetadatafor storing Octicon nameOcticonURL(name, size)helper to generate CDN URLs for Octicon SVGsIcons()method onToolsetMetadatathat returns[]mcp.Icon(16x16 and 24x24 sizes)RegisterFunc()to automatically apply icons from toolset metadata when registering toolsIcon Assignments (pkg/github/tools.go)
All 22 toolset metadata constants now have appropriate Octicon icons:
repos→repo,issues→issue-opened,pull_requests→git-pull-requestactions→play,code_security→codescan,dependabot→dependabotnotifications→bell,discussions→comment-discussionWhy the Refactor Makes This Easier
Before refactor: Would need to call
SetIcons()on every toolset creation inDefaultToolsetGroup(), or modify each individual tool definition.After refactor: Simply add
Iconfield toToolsetMetadatain one place, and icons are automatically applied to all tools viaRegisterFunc(). The self-describing nature ofServerToolwith embeddedToolsetMetadataenables this clean architecture.Testing
raw.githubusercontent.com/primer/octicons/main/icons/Related