🌐 AI搜索 & 代理 主页
Skip to content

Commit 316dde3

Browse files
Upgrade to MCP Go SDK v1.2.0-pre.1 and add Octicon icons to tools
This PR upgrades the MCP Go SDK from v1.1.0 to v1.2.0-pre.1 with SEP-973 support. Changes: - Upgrade go-sdk to v1.2.0-pre.1 (adds icons, tool validation, elicitation) - Add Icon field to ToolsetMetadata with Octicon names - Add OcticonURL() and ToolsetIcon() helpers for icon generation - Add SetIcons() and applyIcons() to Toolset for auto icon assignment - Add WithIcons() on ServerTool for manual icon setting - Configure Octicon icons for all toolsets (repo, issue-opened, etc.) - Icons provided in 16x16 and 24x24 SVG from Primer Octicons CDN
1 parent adaa6a1 commit 316dde3

File tree

4 files changed

+104
-10
lines changed

4 files changed

+104
-10
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/tools.go

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,96 +21,144 @@ type GetGQLClientFn func(context.Context) (*githubv4.Client, error)
2121
type ToolsetMetadata struct {
2222
ID string
2323
Description string
24+
// Icon is the name of the Octicon to use for this toolset (without size suffix, e.g., "repo" not "repo-16")
25+
Icon string
26+
}
27+
28+
// OcticonURL returns the URL for an Octicon SVG icon. Size should be 16 or 24.
29+
func OcticonURL(name string, size int) string {
30+
return fmt.Sprintf("https://raw.githubusercontent.com/primer/octicons/main/icons/%s-%d.svg", name, size)
31+
}
32+
33+
// ToolsetIcon creates an mcp.Icon for the toolset using Octicons
34+
func (tm ToolsetMetadata) ToolsetIcon() []mcp.Icon {
35+
if tm.Icon == "" {
36+
return nil
37+
}
38+
return []mcp.Icon{
39+
{
40+
Source: OcticonURL(tm.Icon, 16),
41+
MIMEType: "image/svg+xml",
42+
Sizes: []string{"16x16"},
43+
},
44+
{
45+
Source: OcticonURL(tm.Icon, 24),
46+
MIMEType: "image/svg+xml",
47+
Sizes: []string{"24x24"},
48+
},
49+
}
2450
}
2551

2652
var (
2753
ToolsetMetadataAll = ToolsetMetadata{
2854
ID: "all",
2955
Description: "Special toolset that enables all available toolsets",
56+
Icon: "apps",
3057
}
3158
ToolsetMetadataDefault = ToolsetMetadata{
3259
ID: "default",
3360
Description: "Special toolset that enables the default toolset configuration. When no toolsets are specified, this is the set that is enabled",
61+
Icon: "check-circle",
3462
}
3563
ToolsetMetadataContext = ToolsetMetadata{
3664
ID: "context",
3765
Description: "Tools that provide context about the current user and GitHub context you are operating in",
66+
Icon: "person",
3867
}
3968
ToolsetMetadataRepos = ToolsetMetadata{
4069
ID: "repos",
4170
Description: "GitHub Repository related tools",
71+
Icon: "repo",
4272
}
4373
ToolsetMetadataGit = ToolsetMetadata{
4474
ID: "git",
4575
Description: "GitHub Git API related tools for low-level Git operations",
76+
Icon: "git-branch",
4677
}
4778
ToolsetMetadataIssues = ToolsetMetadata{
4879
ID: "issues",
4980
Description: "GitHub Issues related tools",
81+
Icon: "issue-opened",
5082
}
5183
ToolsetMetadataPullRequests = ToolsetMetadata{
5284
ID: "pull_requests",
5385
Description: "GitHub Pull Request related tools",
86+
Icon: "git-pull-request",
5487
}
5588
ToolsetMetadataUsers = ToolsetMetadata{
5689
ID: "users",
5790
Description: "GitHub User related tools",
91+
Icon: "people",
5892
}
5993
ToolsetMetadataOrgs = ToolsetMetadata{
6094
ID: "orgs",
6195
Description: "GitHub Organization related tools",
96+
Icon: "organization",
6297
}
6398
ToolsetMetadataActions = ToolsetMetadata{
6499
ID: "actions",
65100
Description: "GitHub Actions workflows and CI/CD operations",
101+
Icon: "play",
66102
}
67103
ToolsetMetadataCodeSecurity = ToolsetMetadata{
68104
ID: "code_security",
69105
Description: "Code security related tools, such as GitHub Code Scanning",
106+
Icon: "codescan",
70107
}
71108
ToolsetMetadataSecretProtection = ToolsetMetadata{
72109
ID: "secret_protection",
73110
Description: "Secret protection related tools, such as GitHub Secret Scanning",
111+
Icon: "key",
74112
}
75113
ToolsetMetadataDependabot = ToolsetMetadata{
76114
ID: "dependabot",
77115
Description: "Dependabot tools",
116+
Icon: "dependabot",
78117
}
79118
ToolsetMetadataNotifications = ToolsetMetadata{
80119
ID: "notifications",
81120
Description: "GitHub Notifications related tools",
121+
Icon: "bell",
82122
}
83123
ToolsetMetadataExperiments = ToolsetMetadata{
84124
ID: "experiments",
85125
Description: "Experimental features that are not considered stable yet",
126+
Icon: "beaker",
86127
}
87128
ToolsetMetadataDiscussions = ToolsetMetadata{
88129
ID: "discussions",
89130
Description: "GitHub Discussions related tools",
131+
Icon: "comment-discussion",
90132
}
91133
ToolsetMetadataGists = ToolsetMetadata{
92134
ID: "gists",
93135
Description: "GitHub Gist related tools",
136+
Icon: "code",
94137
}
95138
ToolsetMetadataSecurityAdvisories = ToolsetMetadata{
96139
ID: "security_advisories",
97140
Description: "Security advisories related tools",
141+
Icon: "shield",
98142
}
99143
ToolsetMetadataProjects = ToolsetMetadata{
100144
ID: "projects",
101145
Description: "GitHub Projects related tools",
146+
Icon: "project",
102147
}
103148
ToolsetMetadataStargazers = ToolsetMetadata{
104149
ID: "stargazers",
105150
Description: "GitHub Stargazers related tools",
151+
Icon: "star",
106152
}
107153
ToolsetMetadataDynamic = ToolsetMetadata{
108154
ID: "dynamic",
109155
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.",
156+
Icon: "tools",
110157
}
111158
ToolsetLabels = ToolsetMetadata{
112159
ID: "labels",
113160
Description: "GitHub Labels related tools",
161+
Icon: "tag",
114162
}
115163
)
116164

@@ -166,6 +214,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
166214
// Define all available features with their default state (disabled)
167215
// Create toolsets
168216
repos := toolsets.NewToolset(ToolsetMetadataRepos.ID, ToolsetMetadataRepos.Description).
217+
SetIcons(ToolsetMetadataRepos.ToolsetIcon()).
169218
AddReadTools(
170219
toolsets.NewServerTool(SearchRepositories(getClient, t)),
171220
toolsets.NewServerTool(GetFileContents(getClient, getRawClient, t)),
@@ -195,10 +244,12 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
195244
toolsets.NewServerResourceTemplate(GetRepositoryResourcePrContent(getClient, getRawClient, t)),
196245
)
197246
git := toolsets.NewToolset(ToolsetMetadataGit.ID, ToolsetMetadataGit.Description).
247+
SetIcons(ToolsetMetadataGit.ToolsetIcon()).
198248
AddReadTools(
199249
toolsets.NewServerTool(GetRepositoryTree(getClient, t)),
200250
)
201251
issues := toolsets.NewToolset(ToolsetMetadataIssues.ID, ToolsetMetadataIssues.Description).
252+
SetIcons(ToolsetMetadataIssues.ToolsetIcon()).
202253
AddReadTools(
203254
toolsets.NewServerTool(IssueRead(getClient, getGQLClient, cache, t, flags)),
204255
toolsets.NewServerTool(SearchIssues(getClient, t)),
@@ -216,14 +267,17 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
216267
toolsets.NewServerPrompt(IssueToFixWorkflowPrompt(t)),
217268
)
218269
users := toolsets.NewToolset(ToolsetMetadataUsers.ID, ToolsetMetadataUsers.Description).
270+
SetIcons(ToolsetMetadataUsers.ToolsetIcon()).
219271
AddReadTools(
220272
toolsets.NewServerTool(SearchUsers(getClient, t)),
221273
)
222274
orgs := toolsets.NewToolset(ToolsetMetadataOrgs.ID, ToolsetMetadataOrgs.Description).
275+
SetIcons(ToolsetMetadataOrgs.ToolsetIcon()).
223276
AddReadTools(
224277
toolsets.NewServerTool(SearchOrgs(getClient, t)),
225278
)
226279
pullRequests := toolsets.NewToolset(ToolsetMetadataPullRequests.ID, ToolsetMetadataPullRequests.Description).
280+
SetIcons(ToolsetMetadataPullRequests.ToolsetIcon()).
227281
AddReadTools(
228282
toolsets.NewServerTool(PullRequestRead(getClient, cache, t, flags)),
229283
toolsets.NewServerTool(ListPullRequests(getClient, t)),
@@ -240,22 +294,26 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
240294
toolsets.NewServerTool(AddCommentToPendingReview(getGQLClient, t)),
241295
)
242296
codeSecurity := toolsets.NewToolset(ToolsetMetadataCodeSecurity.ID, ToolsetMetadataCodeSecurity.Description).
297+
SetIcons(ToolsetMetadataCodeSecurity.ToolsetIcon()).
243298
AddReadTools(
244299
toolsets.NewServerTool(GetCodeScanningAlert(getClient, t)),
245300
toolsets.NewServerTool(ListCodeScanningAlerts(getClient, t)),
246301
)
247302
secretProtection := toolsets.NewToolset(ToolsetMetadataSecretProtection.ID, ToolsetMetadataSecretProtection.Description).
303+
SetIcons(ToolsetMetadataSecretProtection.ToolsetIcon()).
248304
AddReadTools(
249305
toolsets.NewServerTool(GetSecretScanningAlert(getClient, t)),
250306
toolsets.NewServerTool(ListSecretScanningAlerts(getClient, t)),
251307
)
252308
dependabot := toolsets.NewToolset(ToolsetMetadataDependabot.ID, ToolsetMetadataDependabot.Description).
309+
SetIcons(ToolsetMetadataDependabot.ToolsetIcon()).
253310
AddReadTools(
254311
toolsets.NewServerTool(GetDependabotAlert(getClient, t)),
255312
toolsets.NewServerTool(ListDependabotAlerts(getClient, t)),
256313
)
257314

258315
notifications := toolsets.NewToolset(ToolsetMetadataNotifications.ID, ToolsetMetadataNotifications.Description).
316+
SetIcons(ToolsetMetadataNotifications.ToolsetIcon()).
259317
AddReadTools(
260318
toolsets.NewServerTool(ListNotifications(getClient, t)),
261319
toolsets.NewServerTool(GetNotificationDetails(getClient, t)),
@@ -268,6 +326,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
268326
)
269327

270328
discussions := toolsets.NewToolset(ToolsetMetadataDiscussions.ID, ToolsetMetadataDiscussions.Description).
329+
SetIcons(ToolsetMetadataDiscussions.ToolsetIcon()).
271330
AddReadTools(
272331
toolsets.NewServerTool(ListDiscussions(getGQLClient, t)),
273332
toolsets.NewServerTool(GetDiscussion(getGQLClient, t)),
@@ -276,6 +335,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
276335
)
277336

278337
actions := toolsets.NewToolset(ToolsetMetadataActions.ID, ToolsetMetadataActions.Description).
338+
SetIcons(ToolsetMetadataActions.ToolsetIcon()).
279339
AddReadTools(
280340
toolsets.NewServerTool(ListWorkflows(getClient, t)),
281341
toolsets.NewServerTool(ListWorkflowRuns(getClient, t)),
@@ -296,6 +356,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
296356
)
297357

298358
securityAdvisories := toolsets.NewToolset(ToolsetMetadataSecurityAdvisories.ID, ToolsetMetadataSecurityAdvisories.Description).
359+
SetIcons(ToolsetMetadataSecurityAdvisories.ToolsetIcon()).
299360
AddReadTools(
300361
toolsets.NewServerTool(ListGlobalSecurityAdvisories(getClient, t)),
301362
toolsets.NewServerTool(GetGlobalSecurityAdvisory(getClient, t)),
@@ -304,16 +365,19 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
304365
)
305366

306367
// // Keep experiments alive so the system doesn't error out when it's always enabled
307-
experiments := toolsets.NewToolset(ToolsetMetadataExperiments.ID, ToolsetMetadataExperiments.Description)
368+
experiments := toolsets.NewToolset(ToolsetMetadataExperiments.ID, ToolsetMetadataExperiments.Description).
369+
SetIcons(ToolsetMetadataExperiments.ToolsetIcon())
308370

309371
contextTools := toolsets.NewToolset(ToolsetMetadataContext.ID, ToolsetMetadataContext.Description).
372+
SetIcons(ToolsetMetadataContext.ToolsetIcon()).
310373
AddReadTools(
311374
toolsets.NewServerTool(GetMe(getClient, t)),
312375
toolsets.NewServerTool(GetTeams(getClient, getGQLClient, t)),
313376
toolsets.NewServerTool(GetTeamMembers(getGQLClient, t)),
314377
)
315378

316379
gists := toolsets.NewToolset(ToolsetMetadataGists.ID, ToolsetMetadataGists.Description).
380+
SetIcons(ToolsetMetadataGists.ToolsetIcon()).
317381
AddReadTools(
318382
toolsets.NewServerTool(ListGists(getClient, t)),
319383
toolsets.NewServerTool(GetGist(getClient, t)),
@@ -324,6 +388,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
324388
)
325389

326390
projects := toolsets.NewToolset(ToolsetMetadataProjects.ID, ToolsetMetadataProjects.Description).
391+
SetIcons(ToolsetMetadataProjects.ToolsetIcon()).
327392
AddReadTools(
328393
toolsets.NewServerTool(ListProjects(getClient, t)),
329394
toolsets.NewServerTool(GetProject(getClient, t)),
@@ -338,6 +403,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
338403
toolsets.NewServerTool(UpdateProjectItem(getClient, t)),
339404
)
340405
stargazers := toolsets.NewToolset(ToolsetMetadataStargazers.ID, ToolsetMetadataStargazers.Description).
406+
SetIcons(ToolsetMetadataStargazers.ToolsetIcon()).
341407
AddReadTools(
342408
toolsets.NewServerTool(ListStarredRepositories(getClient, t)),
343409
).
@@ -346,6 +412,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
346412
toolsets.NewServerTool(UnstarRepository(getClient, t)),
347413
)
348414
labels := toolsets.NewToolset(ToolsetLabels.ID, ToolsetLabels.Description).
415+
SetIcons(ToolsetLabels.ToolsetIcon()).
349416
AddReadTools(
350417
// get
351418
toolsets.NewServerTool(GetLabel(getGQLClient, t)),
@@ -390,6 +457,7 @@ func InitDynamicToolset(s *mcp.Server, tsg *toolsets.ToolsetGroup, t translation
390457
// Create a new dynamic toolset
391458
// Need to add the dynamic toolset last so it can be used to enable other toolsets
392459
dynamicToolSelection := toolsets.NewToolset(ToolsetMetadataDynamic.ID, ToolsetMetadataDynamic.Description).
460+
SetIcons(ToolsetMetadataDynamic.ToolsetIcon()).
393461
AddReadTools(
394462
toolsets.NewServerTool(ListAvailableToolsets(tsg, t)),
395463
toolsets.NewServerTool(GetToolsetsTools(tsg, t)),

pkg/toolsets/toolsets.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ type ServerTool struct {
3737
RegisterFunc func(s *mcp.Server)
3838
}
3939

40+
// WithIcons sets the icons on the tool and returns the modified ServerTool.
41+
func (st ServerTool) WithIcons(icons []mcp.Icon) ServerTool {
42+
st.Tool.Icons = icons
43+
return st
44+
}
45+
4046
func NewServerTool[In any, Out any](tool mcp.Tool, handler mcp.ToolHandlerFor[In, Out]) ServerTool {
4147
return ServerTool{Tool: tool, RegisterFunc: func(s *mcp.Server) {
4248
th := func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -86,6 +92,8 @@ type Toolset struct {
8692
readOnly bool
8793
writeTools []ServerTool
8894
readTools []ServerTool
95+
// icons are optional icons to apply to all tools in this toolset (if not already set)
96+
icons []mcp.Icon
8997
// resources are not tools, but the community seems to be moving towards namespaces as a broader concept
9098
// and in order to have multiple servers running concurrently, we want to avoid overlapping resources too.
9199
resourceTemplates []ServerResourceTemplate
@@ -170,10 +178,11 @@ func (t *Toolset) SetReadOnly() {
170178

171179
func (t *Toolset) AddWriteTools(tools ...ServerTool) *Toolset {
172180
// Silently ignore if the toolset is read-only to avoid any breach of that contract
173-
for _, tool := range tools {
174-
if tool.Tool.Annotations.ReadOnlyHint {
175-
panic(fmt.Sprintf("tool (%s) is incorrectly annotated as read-only", tool.Tool.Name))
181+
for i := range tools {
182+
if tools[i].Tool.Annotations.ReadOnlyHint {
183+
panic(fmt.Sprintf("tool (%s) is incorrectly annotated as read-only", tools[i].Tool.Name))
176184
}
185+
t.applyIcons(&tools[i])
177186
}
178187
if !t.readOnly {
179188
t.writeTools = append(t.writeTools, tools...)
@@ -182,10 +191,11 @@ func (t *Toolset) AddWriteTools(tools ...ServerTool) *Toolset {
182191
}
183192

184193
func (t *Toolset) AddReadTools(tools ...ServerTool) *Toolset {
185-
for _, tool := range tools {
186-
if !tool.Tool.Annotations.ReadOnlyHint {
187-
panic(fmt.Sprintf("tool (%s) must be annotated as read-only", tool.Tool.Name))
194+
for i := range tools {
195+
if !tools[i].Tool.Annotations.ReadOnlyHint {
196+
panic(fmt.Sprintf("tool (%s) must be annotated as read-only", tools[i].Tool.Name))
188197
}
198+
t.applyIcons(&tools[i])
189199
}
190200
t.readTools = append(t.readTools, tools...)
191201
return t
@@ -229,6 +239,20 @@ func NewToolset(name string, description string) *Toolset {
229239
}
230240
}
231241

242+
// SetIcons sets the default icons for all tools in this toolset.
243+
// Icons will be applied to tools that don't already have icons set.
244+
func (t *Toolset) SetIcons(icons []mcp.Icon) *Toolset {
245+
t.icons = icons
246+
return t
247+
}
248+
249+
// applyIcons applies the toolset's icons to a tool if it doesn't already have icons.
250+
func (t *Toolset) applyIcons(tool *ServerTool) {
251+
if len(tool.Tool.Icons) == 0 && len(t.icons) > 0 {
252+
tool.Tool.Icons = t.icons
253+
}
254+
}
255+
232256
func (tg *ToolsetGroup) IsEnabled(name string) bool {
233257
// If everythingOn is true, all features are enabled
234258
if tg.everythingOn {

0 commit comments

Comments
 (0)