Skip to content

Commit c36d550

Browse files
authored
Upgrade mcp-go to v0.31.0 (#54)
- Change tool annotation type from bool to *bool - Change the way we fetch arguments to new method
1 parent 7628a23 commit c36d550

File tree

3 files changed

+87
-75
lines changed

3 files changed

+87
-75
lines changed

src/cmd/root.go

Lines changed: 84 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,20 @@ var rootCmd = &cobra.Command{
122122

123123
client := NewGraphClient(version)
124124

125+
trueValue := true
126+
falseValue := false
127+
125128
// Register Teams
126129
s.AddTool(
127130
mcp.NewTool(
128131
"teams",
129132
mcp.WithDescription("Get all the team names, identifiers and metadata for the OpsLevel account. Teams are owners of other objects in OpsLevel. Only use this if you need to search all teams."),
130133
mcp.WithToolAnnotation(mcp.ToolAnnotation{
131134
Title: "Teams in OpsLevel",
132-
ReadOnlyHint: true,
133-
DestructiveHint: false,
134-
IdempotentHint: true,
135-
OpenWorldHint: true,
135+
ReadOnlyHint: &trueValue,
136+
DestructiveHint: &falseValue,
137+
IdempotentHint: &trueValue,
138+
OpenWorldHint: &trueValue,
136139
}),
137140
),
138141
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -147,10 +150,10 @@ var rootCmd = &cobra.Command{
147150
mcp.WithDescription("Get all the user names, e-mail addresses and metadata for the OpsLevel account. Users are the people in OpsLevel. Only use this if you need to search all users."),
148151
mcp.WithToolAnnotation(mcp.ToolAnnotation{
149152
Title: "Users in OpsLevel",
150-
ReadOnlyHint: true,
151-
DestructiveHint: false,
152-
IdempotentHint: true,
153-
OpenWorldHint: true,
153+
ReadOnlyHint: &trueValue,
154+
DestructiveHint: &falseValue,
155+
IdempotentHint: &trueValue,
156+
OpenWorldHint: &trueValue,
154157
}),
155158
),
156159
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -166,10 +169,10 @@ var rootCmd = &cobra.Command{
166169

167170
mcp.WithToolAnnotation(mcp.ToolAnnotation{
168171
Title: "Actions in OpsLevel",
169-
ReadOnlyHint: true,
170-
DestructiveHint: false,
171-
IdempotentHint: true,
172-
OpenWorldHint: true,
172+
ReadOnlyHint: &trueValue,
173+
DestructiveHint: &falseValue,
174+
IdempotentHint: &trueValue,
175+
OpenWorldHint: &trueValue,
173176
}),
174177
),
175178
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -185,10 +188,10 @@ var rootCmd = &cobra.Command{
185188

186189
mcp.WithToolAnnotation(mcp.ToolAnnotation{
187190
Title: "Filters in OpsLevel",
188-
ReadOnlyHint: true,
189-
DestructiveHint: false,
190-
IdempotentHint: true,
191-
OpenWorldHint: true,
191+
ReadOnlyHint: &trueValue,
192+
DestructiveHint: &falseValue,
193+
IdempotentHint: &trueValue,
194+
OpenWorldHint: &trueValue,
192195
}),
193196
),
194197
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -203,10 +206,10 @@ var rootCmd = &cobra.Command{
203206
mcp.WithDescription("Get all the components in the OpsLevel account. Components are objects in OpsLevel that represent things like apis, libraries, services, frontends, backends, etc. Use this tool to list what components are in the catalog, what team is the owner, what primary coding language is used, and what primary framework is used. It also includes its rubric level, corresponding to the maturity of the component; a higher index is better. A level is achieved by passing all checks tied to that same level. The Lifecycle field indicates the stage of the component (e.g., Alpha, Beta, GA, Decommissioned). The Tier field represents the importance and criticality of the component, with Tier 1 being the most critical (customer-facing with high impact) and Tier 4 being of least importance."),
204207
mcp.WithToolAnnotation(mcp.ToolAnnotation{
205208
Title: "Components in OpsLevel",
206-
ReadOnlyHint: true,
207-
DestructiveHint: false,
208-
IdempotentHint: true,
209-
OpenWorldHint: true,
209+
ReadOnlyHint: &trueValue,
210+
DestructiveHint: &falseValue,
211+
IdempotentHint: &trueValue,
212+
OpenWorldHint: &trueValue,
210213
}),
211214
),
212215
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -238,10 +241,10 @@ var rootCmd = &cobra.Command{
238241
mcp.WithDescription("Get all the infrastructure in the OpsLevel account. Infrastructure are objects in OpsLevel that represent cloud provider resources like vpc, databases, caches, networks, vms, etc."),
239242
mcp.WithToolAnnotation(mcp.ToolAnnotation{
240243
Title: "Infrastructure in OpsLevel",
241-
ReadOnlyHint: true,
242-
DestructiveHint: false,
243-
IdempotentHint: true,
244-
OpenWorldHint: true,
244+
ReadOnlyHint: &trueValue,
245+
DestructiveHint: &falseValue,
246+
IdempotentHint: &trueValue,
247+
OpenWorldHint: &trueValue,
245248
}),
246249
),
247250
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -270,10 +273,10 @@ var rootCmd = &cobra.Command{
270273
mcp.WithDescription("Get all the domains in the OpsLevel account. Domains are comprised of child Systems which contain Components. Used to represent large business units or verticals within OpsLevel."),
271274
mcp.WithToolAnnotation(mcp.ToolAnnotation{
272275
Title: "Domains in OpsLevel",
273-
ReadOnlyHint: true,
274-
DestructiveHint: false,
275-
IdempotentHint: true,
276-
OpenWorldHint: true,
276+
ReadOnlyHint: &trueValue,
277+
DestructiveHint: &falseValue,
278+
IdempotentHint: &trueValue,
279+
OpenWorldHint: &trueValue,
277280
}),
278281
),
279282
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -288,10 +291,10 @@ var rootCmd = &cobra.Command{
288291
mcp.WithDescription("Get all the systems in the OpsLevel account. Systems are made up of Components that combine to form a unified whole or function. eg a 'Checkout' System that combines a cart and payment component."),
289292
mcp.WithToolAnnotation(mcp.ToolAnnotation{
290293
Title: "Systems in OpsLevel",
291-
ReadOnlyHint: true,
292-
DestructiveHint: false,
293-
IdempotentHint: true,
294-
OpenWorldHint: true,
294+
ReadOnlyHint: &trueValue,
295+
DestructiveHint: &falseValue,
296+
IdempotentHint: &trueValue,
297+
OpenWorldHint: &trueValue,
295298
}),
296299
),
297300
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -308,15 +311,21 @@ var rootCmd = &cobra.Command{
308311
mcp.WithString("identifier", mcp.Required(), mcp.Description("The ID or alias of the resource.")),
309312
mcp.WithToolAnnotation(mcp.ToolAnnotation{
310313
Title: "Resource Details in OpsLevel",
311-
ReadOnlyHint: true,
312-
DestructiveHint: false,
313-
IdempotentHint: true,
314-
OpenWorldHint: true,
314+
ReadOnlyHint: &trueValue,
315+
DestructiveHint: &falseValue,
316+
IdempotentHint: &trueValue,
317+
OpenWorldHint: &trueValue,
315318
}),
316319
),
317320
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
318-
resourceTypeString := req.Params.Arguments["resourceType"].(string)
319-
identifier := req.Params.Arguments["identifier"].(string)
321+
resourceTypeString, err := req.RequireString("resourceType")
322+
if err != nil {
323+
return nil, err
324+
}
325+
identifier, err := req.RequireString("identifier")
326+
if err != nil {
327+
return nil, err
328+
}
320329
resourceType := opslevel.AliasOwnerTypeEnum(resourceTypeString)
321330
resp, err := client.GetAliasableResource(resourceType, identifier)
322331
switch v := resp.(type) {
@@ -338,17 +347,14 @@ var rootCmd = &cobra.Command{
338347
mcp.WithString("searchTerm", mcp.Description("To filter documents with.")),
339348
mcp.WithToolAnnotation(mcp.ToolAnnotation{
340349
Title: "Documents in OpsLevel",
341-
ReadOnlyHint: true,
342-
DestructiveHint: false,
343-
IdempotentHint: true,
344-
OpenWorldHint: true,
350+
ReadOnlyHint: &trueValue,
351+
DestructiveHint: &falseValue,
352+
IdempotentHint: &trueValue,
353+
OpenWorldHint: &trueValue,
345354
}),
346355
),
347356
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
348-
searchTerm := ""
349-
if req.Params.Arguments["searchTerm"] != nil {
350-
searchTerm = req.Params.Arguments["searchTerm"].(string)
351-
}
357+
searchTerm := req.GetString("searchTerm", "")
352358
variables := getListDocumentPayloadVariables(searchTerm)
353359
resp, err := client.ListDocuments(&variables)
354360
return newToolResult(resp.Nodes, err)
@@ -361,14 +367,17 @@ var rootCmd = &cobra.Command{
361367
mcp.WithString("id", mcp.Required(), mcp.Description("The id of the document to fetch.")),
362368
mcp.WithToolAnnotation(mcp.ToolAnnotation{
363369
Title: "Document in OpsLevel",
364-
ReadOnlyHint: true,
365-
DestructiveHint: false,
366-
IdempotentHint: true,
367-
OpenWorldHint: true,
370+
ReadOnlyHint: &trueValue,
371+
DestructiveHint: &falseValue,
372+
IdempotentHint: &trueValue,
373+
OpenWorldHint: &trueValue,
368374
}),
369375
),
370376
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
371-
id := req.Params.Arguments["id"].(string)
377+
id, err := req.RequireString("id")
378+
if err != nil {
379+
return nil, err
380+
}
372381
resp, err := client.GetDocument(opslevel.ID(id))
373382
return newToolResult(resp, err)
374383
})
@@ -381,22 +390,23 @@ var rootCmd = &cobra.Command{
381390
mcp.WithString("searchTerm", mcp.Description("To filter documents with.")),
382391
mcp.WithToolAnnotation(mcp.ToolAnnotation{
383392
Title: "Documents for Service in OpsLevel",
384-
ReadOnlyHint: true,
385-
DestructiveHint: false,
386-
IdempotentHint: true,
387-
OpenWorldHint: true,
393+
ReadOnlyHint: &trueValue,
394+
DestructiveHint: &falseValue,
395+
IdempotentHint: &trueValue,
396+
OpenWorldHint: &trueValue,
388397
}),
389398
),
390399
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
400+
serviceId, err := req.RequireString("serviceId")
401+
if err != nil {
402+
return nil, err
403+
}
391404
service := opslevel.Service{
392405
ServiceId: opslevel.ServiceId{
393-
Id: opslevel.ID(req.Params.Arguments["serviceId"].(string)),
406+
Id: opslevel.ID(serviceId),
394407
},
395408
}
396-
searchTerm := ""
397-
if req.Params.Arguments["searchTerm"] != nil {
398-
searchTerm = req.Params.Arguments["searchTerm"].(string)
399-
}
409+
searchTerm := req.GetString("searchTerm", "")
400410
variables := getListDocumentPayloadVariables(searchTerm)
401411
resp, err := service.GetDocuments(client, &variables)
402412
return newToolResult(resp, err)
@@ -409,10 +419,10 @@ var rootCmd = &cobra.Command{
409419
mcp.WithDescription("Get all the checks in the OpsLevel account. Checks provide a foundation for evaluating the maturity of software components, allowing for the definition and enforcement of criteria that ensure components are built and maintained according to best practices. Check priority is determined by level index, not level name—lower index means higher priority."),
410420
mcp.WithToolAnnotation(mcp.ToolAnnotation{
411421
Title: "Checks in OpsLevel",
412-
ReadOnlyHint: true,
413-
DestructiveHint: false,
414-
IdempotentHint: true,
415-
OpenWorldHint: true,
422+
ReadOnlyHint: &trueValue,
423+
DestructiveHint: &falseValue,
424+
IdempotentHint: &trueValue,
425+
OpenWorldHint: &trueValue,
416426
}),
417427
),
418428
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -444,19 +454,23 @@ var rootCmd = &cobra.Command{
444454
mcp.WithString("serviceId", mcp.Required(), mcp.Description("The id of the service to fetch.")),
445455
mcp.WithToolAnnotation(mcp.ToolAnnotation{
446456
Title: "Rubric of Checks for Component",
447-
ReadOnlyHint: true,
448-
DestructiveHint: false,
449-
IdempotentHint: true,
450-
OpenWorldHint: true,
457+
ReadOnlyHint: &trueValue,
458+
DestructiveHint: &falseValue,
459+
IdempotentHint: &trueValue,
460+
OpenWorldHint: &trueValue,
451461
}),
452462
),
453463
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
454-
service, err := client.GetService(req.Params.Arguments["serviceId"].(string))
464+
serviceId, err := req.RequireString("serviceId")
465+
if err != nil {
466+
return nil, err
467+
}
468+
service, err := client.GetService(serviceId)
455469
if err != nil {
456470
return nil, err
457471
}
458472
if service.Id == "" {
459-
return nil, fmt.Errorf("service with id %s not found", req.Params.Arguments["serviceId"].(string))
473+
return nil, fmt.Errorf("service with id %s not found", serviceId)
460474
}
461475

462476
stats, err := service.GetServiceStats(client)

src/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.24
55
toolchain go1.24.2
66

77
require (
8-
github.com/mark3labs/mcp-go v0.23.1
8+
github.com/mark3labs/mcp-go v0.31.0
99
github.com/opslevel/opslevel-go/v2025 v2025.5.28
1010
github.com/relvacode/iso8601 v1.6.0
1111
github.com/rs/zerolog v1.34.0

src/go.sum

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
6262
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
6363
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
6464
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
65-
github.com/mark3labs/mcp-go v0.23.1 h1:RzTzZ5kJ+HxwnutKA4rll8N/pKV6Wh5dhCmiJUu5S9I=
66-
github.com/mark3labs/mcp-go v0.23.1/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
65+
github.com/mark3labs/mcp-go v0.31.0 h1:4UxSV8aM770OPmTvaVe/b1rA2oZAjBMhGBfUgOGut+4=
66+
github.com/mark3labs/mcp-go v0.31.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
6767
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
6868
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
6969
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
@@ -79,8 +79,6 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
7979
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
8080
github.com/opslevel/moredefaults v0.0.0-20240529152742-17d1318a3c12 h1:OQZ3W8kbyCcdS8QUWFTnZd6xtdkfhdckc7Paro7nXio=
8181
github.com/opslevel/moredefaults v0.0.0-20240529152742-17d1318a3c12/go.mod h1:g2GSXVP6LO+5+AIsnMRPN+BeV86OXuFRTX7HXCDtYeI=
82-
github.com/opslevel/opslevel-go/v2025 v2025.5.28 h1:LCkgLakF0MWIHMmgQHr3ldNjcO8CB4fLcs/LnRZXnHU=
83-
github.com/opslevel/opslevel-go/v2025 v2025.5.28/go.mod h1:QiYGhFPwJj3V4efdiY3gqWlU0ZFMcJDiWPnQkPYKSYA=
8482
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
8583
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
8684
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

0 commit comments

Comments
 (0)