Skip to content

Commit 39bcacd

Browse files
Upgrade MCP Go SDK to v1.2.0-pre.1 and add Octicon icons to tools
- 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.
1 parent 689a040 commit 39bcacd

File tree

5 files changed

+69
-6
lines changed

5 files changed

+69
-6
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ require (
3636
github.com/go-viper/mapstructure/v2 v2.4.0
3737
github.com/google/go-querystring v1.1.0 // indirect
3838
github.com/inconshreveable/mousetrap v1.1.0 // indirect
39-
github.com/modelcontextprotocol/go-sdk v1.1.0
39+
github.com/modelcontextprotocol/go-sdk v1.2.0-pre.1
4040
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
4141
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
4242
github.com/rogpeppe/go-internal v1.13.1 // indirect

go.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrK
1717
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
1818
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
1919
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
20+
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
21+
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
2022
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
2123
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
2224
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
@@ -55,8 +57,8 @@ github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwX
5557
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
5658
github.com/migueleliasweb/go-github-mock v1.3.0 h1:2sVP9JEMB2ubQw1IKto3/fzF51oFC6eVWOOFDgQoq88=
5759
github.com/migueleliasweb/go-github-mock v1.3.0/go.mod h1:ipQhV8fTcj/G6m7BKzin08GaJ/3B5/SonRAkgrk0zCY=
58-
github.com/modelcontextprotocol/go-sdk v1.1.0 h1:Qjayg53dnKC4UZ+792W21e4BpwEZBzwgRW6LrjLWSwA=
59-
github.com/modelcontextprotocol/go-sdk v1.1.0/go.mod h1:6fM3LCm3yV7pAs8isnKLn07oKtB0MP9LHd3DfAcKw10=
60+
github.com/modelcontextprotocol/go-sdk v1.2.0-pre.1 h1:14+JrlEIFvUmbu5+iJzWPLk8CkpvegfKr42oXyjp3O4=
61+
github.com/modelcontextprotocol/go-sdk v1.2.0-pre.1/go.mod h1:6fM3LCm3yV7pAs8isnKLn07oKtB0MP9LHd3DfAcKw10=
6062
github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 h1:31Y+Yu373ymebRdJN1cWLLooHH8xAr0MhKTEJGV/87g=
6163
github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021/go.mod h1:WERUkUryfUWlrHnFSO/BEUZ+7Ns8aZy7iVOGewxKzcc=
6264
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=

pkg/github/server.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ func NewServer(version string, opts *mcp.ServerOptions) *mcp.Server {
2424
// Always advertise capabilities so clients know we support list_changed notifications.
2525
// This is important for dynamic toolsets mode where we start with few tools
2626
// and add more at runtime.
27-
opts.HasTools = true
28-
opts.HasResources = true
29-
opts.HasPrompts = true
27+
if opts.Capabilities == nil {
28+
opts.Capabilities = &mcp.ServerCapabilities{}
29+
}
30+
opts.Capabilities.Tools = &mcp.ToolCapabilities{ListChanged: true}
31+
opts.Capabilities.Resources = &mcp.ResourceCapabilities{ListChanged: true}
32+
opts.Capabilities.Prompts = &mcp.PromptCapabilities{ListChanged: true}
3033

3134
// Create a new MCP server
3235
s := mcp.NewServer(&mcp.Implementation{

pkg/github/tools.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,94 +16,117 @@ type GetGQLClientFn func(context.Context) (*githubv4.Client, error)
1616

1717
// Toolset metadata constants - these define all available toolsets and their descriptions.
1818
// Tools use these constants to declare which toolset they belong to.
19+
// Icons are Octicon names from https://primer.style/foundations/icons
1920
var (
2021
ToolsetMetadataAll = toolsets.ToolsetMetadata{
2122
ID: "all",
2223
Description: "Special toolset that enables all available toolsets",
24+
Icon: "apps",
2325
}
2426
ToolsetMetadataDefault = toolsets.ToolsetMetadata{
2527
ID: "default",
2628
Description: "Special toolset that enables the default toolset configuration. When no toolsets are specified, this is the set that is enabled",
29+
Icon: "check-circle",
2730
}
2831
ToolsetMetadataContext = toolsets.ToolsetMetadata{
2932
ID: "context",
3033
Description: "Tools that provide context about the current user and GitHub context you are operating in",
34+
Icon: "person",
3135
}
3236
ToolsetMetadataRepos = toolsets.ToolsetMetadata{
3337
ID: "repos",
3438
Description: "GitHub Repository related tools",
39+
Icon: "repo",
3540
}
3641
ToolsetMetadataGit = toolsets.ToolsetMetadata{
3742
ID: "git",
3843
Description: "GitHub Git API related tools for low-level Git operations",
44+
Icon: "git-branch",
3945
}
4046
ToolsetMetadataIssues = toolsets.ToolsetMetadata{
4147
ID: "issues",
4248
Description: "GitHub Issues related tools",
49+
Icon: "issue-opened",
4350
}
4451
ToolsetMetadataPullRequests = toolsets.ToolsetMetadata{
4552
ID: "pull_requests",
4653
Description: "GitHub Pull Request related tools",
54+
Icon: "git-pull-request",
4755
}
4856
ToolsetMetadataUsers = toolsets.ToolsetMetadata{
4957
ID: "users",
5058
Description: "GitHub User related tools",
59+
Icon: "people",
5160
}
5261
ToolsetMetadataOrgs = toolsets.ToolsetMetadata{
5362
ID: "orgs",
5463
Description: "GitHub Organization related tools",
64+
Icon: "organization",
5565
}
5666
ToolsetMetadataActions = toolsets.ToolsetMetadata{
5767
ID: "actions",
5868
Description: "GitHub Actions workflows and CI/CD operations",
69+
Icon: "play",
5970
}
6071
ToolsetMetadataCodeSecurity = toolsets.ToolsetMetadata{
6172
ID: "code_security",
6273
Description: "Code security related tools, such as GitHub Code Scanning",
74+
Icon: "codescan",
6375
}
6476
ToolsetMetadataSecretProtection = toolsets.ToolsetMetadata{
6577
ID: "secret_protection",
6678
Description: "Secret protection related tools, such as GitHub Secret Scanning",
79+
Icon: "key",
6780
}
6881
ToolsetMetadataDependabot = toolsets.ToolsetMetadata{
6982
ID: "dependabot",
7083
Description: "Dependabot tools",
84+
Icon: "dependabot",
7185
}
7286
ToolsetMetadataNotifications = toolsets.ToolsetMetadata{
7387
ID: "notifications",
7488
Description: "GitHub Notifications related tools",
89+
Icon: "bell",
7590
}
7691
ToolsetMetadataExperiments = toolsets.ToolsetMetadata{
7792
ID: "experiments",
7893
Description: "Experimental features that are not considered stable yet",
94+
Icon: "beaker",
7995
}
8096
ToolsetMetadataDiscussions = toolsets.ToolsetMetadata{
8197
ID: "discussions",
8298
Description: "GitHub Discussions related tools",
99+
Icon: "comment-discussion",
83100
}
84101
ToolsetMetadataGists = toolsets.ToolsetMetadata{
85102
ID: "gists",
86103
Description: "GitHub Gist related tools",
104+
Icon: "code",
87105
}
88106
ToolsetMetadataSecurityAdvisories = toolsets.ToolsetMetadata{
89107
ID: "security_advisories",
90108
Description: "Security advisories related tools",
109+
Icon: "shield",
91110
}
92111
ToolsetMetadataProjects = toolsets.ToolsetMetadata{
93112
ID: "projects",
94113
Description: "GitHub Projects related tools",
114+
Icon: "project",
95115
}
96116
ToolsetMetadataStargazers = toolsets.ToolsetMetadata{
97117
ID: "stargazers",
98118
Description: "GitHub Stargazers related tools",
119+
Icon: "star",
99120
}
100121
ToolsetMetadataDynamic = toolsets.ToolsetMetadata{
101122
ID: "dynamic",
102123
Description: "Discover GitHub MCP tools that can help achieve tasks by enabling additional sets of tools, you can control the enablement of any toolset to access its tools when this toolset is enabled.",
124+
Icon: "tools",
103125
}
104126
ToolsetLabels = toolsets.ToolsetMetadata{
105127
ID: "labels",
106128
Description: "GitHub Labels related tools",
129+
Icon: "tag",
107130
}
108131
)
109132

pkg/toolsets/server_tool.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package toolsets
33
import (
44
"context"
55
"encoding/json"
6+
"fmt"
67

78
"github.com/modelcontextprotocol/go-sdk/mcp"
89
)
@@ -24,6 +25,35 @@ type ToolsetMetadata struct {
2425
ID ToolsetID
2526
// Description provides a human-readable description of the toolset
2627
Description string
28+
// Icon is the name of the Octicon to use for tools in this toolset.
29+
// Use the base name without size suffix, e.g., "repo" not "repo-16".
30+
// See https://primer.style/foundations/icons for available icons.
31+
Icon string
32+
}
33+
34+
// OcticonURL returns the CDN URL for a GitHub Octicon SVG. Size should be 16 or 24.
35+
func OcticonURL(name string, size int) string {
36+
return fmt.Sprintf("https://raw.githubusercontent.com/primer/octicons/main/icons/%s-%d.svg", name, size)
37+
}
38+
39+
// Icons returns MCP Icon objects for this toolset, or nil if no icon is set.
40+
// Icons are provided in both 16x16 and 24x24 sizes.
41+
func (tm ToolsetMetadata) Icons() []mcp.Icon {
42+
if tm.Icon == "" {
43+
return nil
44+
}
45+
return []mcp.Icon{
46+
{
47+
Source: OcticonURL(tm.Icon, 16),
48+
MIMEType: "image/svg+xml",
49+
Sizes: []string{"16x16"},
50+
},
51+
{
52+
Source: OcticonURL(tm.Icon, 24),
53+
MIMEType: "image/svg+xml",
54+
Sizes: []string{"24x24"},
55+
},
56+
}
2757
}
2858

2959
// ServerTool represents an MCP tool with metadata and a handler generator function.
@@ -66,8 +96,13 @@ func (st *ServerTool) Handler(deps any) mcp.ToolHandler {
6696
}
6797

6898
// RegisterFunc registers the tool with the server using the provided dependencies.
99+
// Icons are automatically applied from the toolset metadata if not already set.
69100
func (st *ServerTool) RegisterFunc(s *mcp.Server, deps any) {
70101
handler := st.Handler(deps)
102+
// Apply icons from toolset metadata if tool doesn't have icons set
103+
if len(st.Tool.Icons) == 0 {
104+
st.Tool.Icons = st.Toolset.Icons()
105+
}
71106
s.AddTool(&st.Tool, handler)
72107
}
73108

0 commit comments

Comments
 (0)