Skip to content

Commit 9d1d671

Browse files
committed
Convert to mcp-go
1 parent 83f068a commit 9d1d671

3 files changed

Lines changed: 152 additions & 172 deletions

File tree

src/cmd/mcp.go

Lines changed: 146 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package cmd
22

33
import (
4+
"context"
45
"encoding/json"
5-
6-
mcp_golang "github.com/metoro-io/mcp-golang"
7-
"github.com/metoro-io/mcp-golang/transport/stdio"
6+
"github.com/mark3labs/mcp-go/mcp"
7+
"github.com/mark3labs/mcp-go/server"
8+
"github.com/rs/zerolog/log"
89
"github.com/spf13/cobra"
910
)
1011

@@ -28,149 +29,155 @@ var mcpCmd = &cobra.Command{
2829
// transport := http.NewHTTPTransport("/mcp")
2930
// transport.WithAddr(":8080")
3031
// server := mcp_golang.NewServer(transport)
31-
server := mcp_golang.NewServer(stdio.NewStdioServerTransport())
32+
s := server.NewMCPServer(
33+
"OpsLevel",
34+
"1.0.0",
35+
)
3236

3337
// Register Teams
34-
if err := server.RegisterTool("teams", "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.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
35-
client := getClientGQL()
36-
resp, err := client.ListTeams(nil)
37-
if err != nil {
38-
return nil, err
39-
}
40-
data, err := json.Marshal(resp.Nodes)
41-
if err != nil {
42-
return nil, err
43-
}
44-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
45-
}); err != nil {
46-
panic(err)
47-
}
38+
s.AddTool(
39+
mcp.NewTool("teams",
40+
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.")),
41+
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
42+
client := getClientGQL()
43+
resp, err := client.ListTeams(nil)
44+
if err != nil {
45+
return nil, err
46+
}
47+
data, err := json.Marshal(resp.Nodes)
48+
if err != nil {
49+
return nil, err
50+
}
51+
return mcp.NewToolResultText(string(data)), nil
52+
})
4853

4954
// Register Users
50-
if err := server.RegisterTool("users", "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.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
51-
client := getClientGQL()
52-
resp, err := client.ListUsers(nil)
53-
if err != nil {
54-
return nil, err
55-
}
56-
data, err := json.Marshal(resp.Nodes)
57-
if err != nil {
58-
return nil, err
59-
}
60-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
61-
}); err != nil {
62-
panic(err)
63-
}
64-
65-
// Register Actions
66-
if err := server.RegisterTool("actions", "Get all the information about actions the user can run in the opslevel account", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
67-
client := getClientGQL()
68-
resp, err := client.ListTriggerDefinitions(nil)
69-
if err != nil {
70-
return nil, err
71-
}
72-
data, err := json.Marshal(resp.Nodes)
73-
if err != nil {
74-
return nil, err
75-
}
76-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
77-
}); err != nil {
78-
panic(err)
79-
}
80-
81-
// Register Filters
82-
if err := server.RegisterTool("filters", "Get all the rubric filter names and which predicates they have for the opslevel account", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
83-
client := getClientGQL()
84-
resp, err := client.ListFilters(nil)
85-
if err != nil {
86-
return nil, err
87-
}
88-
data, err := json.Marshal(resp.Nodes)
89-
if err != nil {
90-
return nil, err
91-
}
92-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
93-
}); err != nil {
94-
panic(err)
95-
}
96-
97-
// Register Components
98-
if err := server.RegisterTool("components", "Get all the components in the opslevel account. Components are objects in opslevel that represent things like apis, libraries, services, frontends, backends, etc.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
99-
client := getClientGQL()
100-
resp, err := client.ListServices(nil)
101-
if err != nil {
102-
return nil, err
103-
}
104-
var components []LightweightComponent
105-
for _, node := range resp.Nodes {
106-
components = append(components, LightweightComponent{
107-
Id: string(node.Id),
108-
Name: node.Name,
109-
Owner: node.Owner.Alias,
110-
URL: node.HtmlURL,
111-
})
112-
}
113-
data, err := json.Marshal(components)
114-
if err != nil {
115-
return nil, err
116-
}
117-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
118-
}); err != nil {
119-
panic(err)
120-
}
121-
122-
// Register Infra
123-
if err := server.RegisterTool("infrastructure", "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.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
124-
client := getClientGQL()
125-
resp, err := client.ListInfrastructure(nil)
126-
if err != nil {
127-
return nil, err
128-
}
129-
data, err := json.Marshal(resp.Nodes)
130-
if err != nil {
131-
return nil, err
132-
}
133-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
134-
}); err != nil {
135-
panic(err)
136-
}
137-
138-
// Register Domains
139-
if err := server.RegisterTool("domains", "Get all the domains in the opslevel account. Domains are objects in opslevel that represent a top-level abstraction used to organize and categorize software systems.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
140-
client := getClientGQL()
141-
resp, err := client.ListDomains(nil)
142-
if err != nil {
143-
return nil, err
144-
}
145-
data, err := json.Marshal(resp.Nodes)
146-
if err != nil {
147-
return nil, err
148-
}
149-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
150-
}); err != nil {
151-
panic(err)
152-
}
153-
154-
// Register Systems
155-
if err := server.RegisterTool("systems", "Get all the systems in the opslevel account. Systems are objects in opslevel that represent a grouping of services or components that act together to serve a business function or process.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
156-
client := getClientGQL()
157-
resp, err := client.ListSystems(nil)
158-
if err != nil {
159-
return nil, err
160-
}
161-
data, err := json.Marshal(resp.Nodes)
162-
if err != nil {
163-
return nil, err
164-
}
165-
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
166-
}); err != nil {
167-
panic(err)
168-
}
169-
170-
if err := server.Serve(); err != nil {
55+
s.AddTool(
56+
mcp.NewTool("users", 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.")),
57+
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
58+
client := getClientGQL()
59+
resp, err := client.ListUsers(nil)
60+
if err != nil {
61+
return nil, err
62+
}
63+
data, err := json.Marshal(resp.Nodes)
64+
if err != nil {
65+
return nil, err
66+
}
67+
return mcp.NewToolResultText(string(data)), nil
68+
})
69+
//
70+
//// Register Actions
71+
//if err := server.RegisterTool("actions", "Get all the information about actions the user can run in the opslevel account", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
72+
// client := getClientGQL()
73+
// resp, err := client.ListTriggerDefinitions(nil)
74+
// if err != nil {
75+
// return nil, err
76+
// }
77+
// data, err := json.Marshal(resp.Nodes)
78+
// if err != nil {
79+
// return nil, err
80+
// }
81+
// return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
82+
//}); err != nil {
83+
// panic(err)
84+
//}
85+
//
86+
//// Register Filters
87+
//if err := server.RegisterTool("filters", "Get all the rubric filter names and which predicates they have for the opslevel account", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
88+
// client := getClientGQL()
89+
// resp, err := client.ListFilters(nil)
90+
// if err != nil {
91+
// return nil, err
92+
// }
93+
// data, err := json.Marshal(resp.Nodes)
94+
// if err != nil {
95+
// return nil, err
96+
// }
97+
// return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
98+
//}); err != nil {
99+
// panic(err)
100+
//}
101+
//
102+
//// Register Components
103+
//if err := server.RegisterTool("components", "Get all the components in the opslevel account. Components are objects in opslevel that represent things like apis, libraries, services, frontends, backends, etc.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
104+
// client := getClientGQL()
105+
// resp, err := client.ListServices(nil)
106+
// if err != nil {
107+
// return nil, err
108+
// }
109+
// var components []LightweightComponent
110+
// for _, node := range resp.Nodes {
111+
// components = append(components, LightweightComponent{
112+
// Id: string(node.Id),
113+
// Name: node.Name,
114+
// Owner: node.Owner.Alias,
115+
// URL: node.HtmlURL,
116+
// })
117+
// }
118+
// data, err := json.Marshal(components)
119+
// if err != nil {
120+
// return nil, err
121+
// }
122+
// return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
123+
//}); err != nil {
124+
// panic(err)
125+
//}
126+
//
127+
//// Register Infra
128+
//if err := server.RegisterTool("infrastructure", "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.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
129+
// client := getClientGQL()
130+
// resp, err := client.ListInfrastructure(nil)
131+
// if err != nil {
132+
// return nil, err
133+
// }
134+
// data, err := json.Marshal(resp.Nodes)
135+
// if err != nil {
136+
// return nil, err
137+
// }
138+
// return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
139+
//}); err != nil {
140+
// panic(err)
141+
//}
142+
//
143+
//// Register Domains
144+
//if err := server.RegisterTool("domains", "Get all the domains in the opslevel account. Domains are objects in opslevel that represent a top-level abstraction used to organize and categorize software systems.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
145+
// client := getClientGQL()
146+
// resp, err := client.ListDomains(nil)
147+
// if err != nil {
148+
// return nil, err
149+
// }
150+
// data, err := json.Marshal(resp.Nodes)
151+
// if err != nil {
152+
// return nil, err
153+
// }
154+
// return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
155+
//}); err != nil {
156+
// panic(err)
157+
//}
158+
//
159+
//// Register Systems
160+
//if err := server.RegisterTool("systems", "Get all the systems in the opslevel account. Systems are objects in opslevel that represent a grouping of services or components that act together to serve a business function or process.", func(args NullArguments) (*mcp_golang.ToolResponse, error) {
161+
// client := getClientGQL()
162+
// resp, err := client.ListSystems(nil)
163+
// if err != nil {
164+
// return nil, err
165+
// }
166+
// data, err := json.Marshal(resp.Nodes)
167+
// if err != nil {
168+
// return nil, err
169+
// }
170+
// return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil
171+
//}); err != nil {
172+
// panic(err)
173+
//}
174+
175+
log.Info().Msg("Starting MCP server...")
176+
if err := server.ServeStdio(s); err != nil {
171177
panic(err)
172178
}
173179
<-done
180+
174181
return nil
175182
},
176183
}

src/go.mod

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
github.com/gosimple/slug v1.15.0
1212
github.com/itchyny/gojq v0.12.17
1313
github.com/manifoldco/promptui v0.9.0
14-
github.com/metoro-io/mcp-golang v0.9.0
14+
github.com/mark3labs/mcp-go v0.21.0
1515
github.com/mitchellh/mapstructure v1.5.0
1616
github.com/open-policy-agent/opa v0.67.1
1717
github.com/opslevel/opslevel-go/v2024 v2024.12.24
@@ -32,9 +32,7 @@ require (
3232
github.com/OneOfOne/xxhash v1.2.8 // indirect
3333
github.com/ProtonMail/go-crypto v1.1.5 // indirect
3434
github.com/agnivade/levenshtein v1.1.1 // indirect
35-
github.com/bahlo/generic-list-go v0.2.0 // indirect
3635
github.com/beorn7/perks v1.0.1 // indirect
37-
github.com/buger/jsonparser v1.1.1 // indirect
3836
github.com/cespare/xxhash/v2 v2.3.0 // indirect
3937
github.com/chzyer/readline v1.5.1 // indirect
4038
github.com/cloudflare/circl v1.6.0 // indirect
@@ -61,12 +59,10 @@ require (
6159
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
6260
github.com/hasura/go-graphql-client v0.13.1 // indirect
6361
github.com/inconshreveable/mousetrap v1.1.0 // indirect
64-
github.com/invopop/jsonschema v0.12.0 // indirect
6562
github.com/itchyny/timefmt-go v0.1.6 // indirect
6663
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
6764
github.com/kevinburke/ssh_config v1.2.0 // indirect
6865
github.com/leodido/go-urn v1.4.0 // indirect
69-
github.com/mailru/easyjson v0.7.7 // indirect
7066
github.com/mattn/go-colorable v0.1.14 // indirect
7167
github.com/mattn/go-isatty v0.0.20 // indirect
7268
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
@@ -88,15 +84,11 @@ require (
8884
github.com/spf13/cast v1.7.1 // indirect
8985
github.com/subosito/gotenv v1.6.0 // indirect
9086
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
91-
github.com/tidwall/gjson v1.18.0 // indirect
92-
github.com/tidwall/match v1.1.1 // indirect
93-
github.com/tidwall/pretty v1.2.1 // indirect
94-
github.com/tidwall/sjson v1.2.5 // indirect
95-
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
9687
github.com/xanzy/ssh-agent v0.3.3 // indirect
9788
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
9889
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
9990
github.com/yashtewari/glob-intersection v0.2.0 // indirect
91+
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
10092
go.opentelemetry.io/otel v1.29.0 // indirect
10193
go.opentelemetry.io/otel/metric v1.29.0 // indirect
10294
go.opentelemetry.io/otel/sdk v1.29.0 // indirect

0 commit comments

Comments
 (0)