diff --git a/src/cmd/mcp.go b/src/cmd/mcp.go index 42867063..f424035b 100644 --- a/src/cmd/mcp.go +++ b/src/cmd/mcp.go @@ -1,10 +1,12 @@ package cmd import ( + "context" "encoding/json" - mcp_golang "github.com/metoro-io/mcp-golang" - "github.com/metoro-io/mcp-golang/transport/stdio" + "github.com/mark3labs/mcp-go/mcp" + "github.com/mark3labs/mcp-go/server" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" ) @@ -25,152 +27,155 @@ var mcpCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { done := make(chan struct{}) - // transport := http.NewHTTPTransport("/mcp") - // transport.WithAddr(":8080") - // server := mcp_golang.NewServer(transport) - server := mcp_golang.NewServer(stdio.NewStdioServerTransport()) + s := server.NewMCPServer( + "OpsLevel", + "1.0.0", + ) // Register Teams - 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) { - client := getClientGQL() - resp, err := client.ListTeams(nil) - if err != nil { - return nil, err - } - data, err := json.Marshal(resp.Nodes) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } + s.AddTool( + mcp.NewTool("teams", + 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.")), + func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListTeams(nil) + if err != nil { + return nil, err + } + data, err := json.Marshal(resp.Nodes) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) // Register Users - 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) { - client := getClientGQL() - resp, err := client.ListUsers(nil) - if err != nil { - return nil, err - } - data, err := json.Marshal(resp.Nodes) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } + s.AddTool( + 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.")), + func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListUsers(nil) + if err != nil { + return nil, err + } + data, err := json.Marshal(resp.Nodes) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) // Register Actions - 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) { - client := getClientGQL() - resp, err := client.ListTriggerDefinitions(nil) - if err != nil { - return nil, err - } - data, err := json.Marshal(resp.Nodes) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } + s.AddTool( + mcp.NewTool("actions", mcp.WithDescription("Get all the information about actions the user can run in the opslevel account")), + func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListTriggerDefinitions(nil) + if err != nil { + return nil, err + } + data, err := json.Marshal(resp.Nodes) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) // Register Filters - 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) { - client := getClientGQL() - resp, err := client.ListFilters(nil) - if err != nil { - return nil, err - } - data, err := json.Marshal(resp.Nodes) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } + s.AddTool( + mcp.NewTool("filters", mcp.WithDescription("Get all the rubric filter names and which predicates they have for the opslevel account")), + func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListFilters(nil) + if err != nil { + return nil, err + } + data, err := json.Marshal(resp.Nodes) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) // Register Components - 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) { - client := getClientGQL() - resp, err := client.ListServices(nil) - if err != nil { - return nil, err - } - var components []LightweightComponent - for _, node := range resp.Nodes { - components = append(components, LightweightComponent{ - Id: string(node.Id), - Name: node.Name, - Owner: node.Owner.Alias, - URL: node.HtmlURL, - }) - } - data, err := json.Marshal(components) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } + s.AddTool( + mcp.NewTool("components", 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.")), + func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListServices(nil) + if err != nil { + return nil, err + } + var components []LightweightComponent + for _, node := range resp.Nodes { + components = append(components, LightweightComponent{ + Id: string(node.Id), + Name: node.Name, + Owner: node.Owner.Alias, + URL: node.HtmlURL, + }) + } + data, err := json.Marshal(components) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) // Register Infra - 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) { - client := getClientGQL() - resp, err := client.ListInfrastructure(nil) - if err != nil { - return nil, err - } - data, err := json.Marshal(resp.Nodes) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } + s.AddTool( + mcp.NewTool("infrastructure", 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.")), + func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListInfrastructure(nil) + if err != nil { + return nil, err + } + data, err := json.Marshal(resp.Nodes) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) // Register Domains - 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) { - client := getClientGQL() - resp, err := client.ListDomains(nil) - if err != nil { - return nil, err - } - data, err := json.Marshal(resp.Nodes) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } + s.AddTool( + mcp.NewTool("domains", mcp.WithDescription("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(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListDomains(nil) + if err != nil { + return nil, err + } + data, err := json.Marshal(resp.Nodes) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) // Register Systems - 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) { - client := getClientGQL() - resp, err := client.ListSystems(nil) - if err != nil { - return nil, err - } - data, err := json.Marshal(resp.Nodes) - if err != nil { - return nil, err - } - return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(string(data))), nil - }); err != nil { - panic(err) - } - - if err := server.Serve(); err != nil { + s.AddTool( + mcp.NewTool("systems", mcp.WithDescription("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(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + client := getClientGQL() + resp, err := client.ListSystems(nil) + if err != nil { + return nil, err + } + data, err := json.Marshal(resp.Nodes) + if err != nil { + return nil, err + } + return mcp.NewToolResultText(string(data)), nil + }) + + log.Info().Msg("Starting MCP server...") + if err := server.ServeStdio(s); err != nil { panic(err) } <-done + return nil }, } diff --git a/src/go.mod b/src/go.mod index 024bd901..e18b7bb4 100644 --- a/src/go.mod +++ b/src/go.mod @@ -11,7 +11,7 @@ require ( github.com/gosimple/slug v1.15.0 github.com/itchyny/gojq v0.12.17 github.com/manifoldco/promptui v0.9.0 - github.com/metoro-io/mcp-golang v0.9.0 + github.com/mark3labs/mcp-go v0.21.0 github.com/mitchellh/mapstructure v1.5.0 github.com/open-policy-agent/opa v0.67.1 github.com/opslevel/opslevel-go/v2024 v2024.12.24 @@ -32,9 +32,7 @@ require ( github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/ProtonMail/go-crypto v1.1.5 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect - github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/buger/jsonparser v1.1.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cloudflare/circl v1.6.0 // indirect @@ -61,12 +59,10 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hasura/go-graphql-client v0.13.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/jsonschema v0.12.0 // indirect github.com/itchyny/timefmt-go v0.1.6 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -88,15 +84,11 @@ require ( github.com/spf13/cast v1.7.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect - github.com/tidwall/gjson v1.18.0 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.1 // indirect - github.com/tidwall/sjson v1.2.5 // indirect - github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect go.opentelemetry.io/otel v1.29.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/sdk v1.29.0 // indirect diff --git a/src/go.sum b/src/go.sum index 8689142e..5462af5f 100644 --- a/src/go.sum +++ b/src/go.sum @@ -21,12 +21,8 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= -github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA= github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -153,15 +149,12 @@ github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= -github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/itchyny/gojq v0.12.17 h1:8av8eGduDb5+rvEdaOO+zQUjA04MS0m3Ps8HiD+fceg= github.com/itchyny/gojq v0.12.17/go.mod h1:WBrEMkgAfAGO1LUcGOckBl5O726KPp+OlkKug0I/FEY= github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= @@ -175,10 +168,10 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/mark3labs/mcp-go v0.21.0 h1:oyEtiXg8PnrVEFis9b1AwbiUWF2dTbyBP5yLo7SruXE= +github.com/mark3labs/mcp-go v0.21.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= @@ -186,8 +179,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/metoro-io/mcp-golang v0.9.0 h1:GpFENjieZ/KosTu7CE7tyGI/a2FhiG0nandR0d8B3rE= -github.com/metoro-io/mcp-golang v0.9.0/go.mod h1:ifLP9ZzKpN1UqFWNTpAHOqSvNkMK6b7d1FSZ5Lu0lN0= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -267,18 +258,6 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= -github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= @@ -287,6 +266,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg= github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=