Skip to content

Commit 7b12928

Browse files
committed
deps: bump github.com/mark3labs/mcp-go from v0.8.5 to v0.11.2
1 parent fa4c472 commit 7b12928

File tree

8 files changed

+100
-79
lines changed

8 files changed

+100
-79
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/manusa/kubernetes-mcp-server
33
go 1.23.5
44

55
require (
6-
github.com/mark3labs/mcp-go v0.8.5
6+
github.com/mark3labs/mcp-go v0.11.2
77
github.com/spf13/afero v1.12.0
88
github.com/spf13/cobra v1.8.1
99
github.com/spf13/viper v1.19.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
6969
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
7070
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
7171
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
72-
github.com/mark3labs/mcp-go v0.8.5 h1:s5oRwQfs83Jim3ZAcQMyUQNHzCEVIuGD12GV8vhJqqc=
73-
github.com/mark3labs/mcp-go v0.8.5/go.mod h1:cjMlBU0cv/cj9kjlgmRhoJ5JREdS7YX83xeIG9Ko/jE=
72+
github.com/mark3labs/mcp-go v0.11.2 h1:mCxWFUTrcXOtJIn9t7F8bxAL8rpE/ZZTTnx3PU/VNdA=
73+
github.com/mark3labs/mcp-go v0.11.2/go.mod h1:cjMlBU0cv/cj9kjlgmRhoJ5JREdS7YX83xeIG9Ko/jE=
7474
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
7575
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
7676
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=

pkg/mcp/common_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ import (
1313
apiextensionsv1spec "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1414
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
1515
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
"k8s.io/apimachinery/pkg/runtime/schema"
17+
"k8s.io/apimachinery/pkg/runtime/serializer"
1618
"k8s.io/apimachinery/pkg/watch"
1719
"k8s.io/client-go/kubernetes"
1820
"k8s.io/client-go/rest"
21+
"k8s.io/client-go/scale"
1922
"k8s.io/client-go/tools/clientcmd"
2023
"k8s.io/client-go/tools/clientcmd/api"
2124
toolswatch "k8s.io/client-go/tools/watch"
@@ -193,6 +196,18 @@ func (c *mcpContext) newKubernetesClient() *kubernetes.Clientset {
193196
return kubernetes.NewForConfigOrDie(envTestRestConfig)
194197
}
195198

199+
func (c *mcpContext) newRestClient(groupVersion *schema.GroupVersion) *rest.RESTClient {
200+
config := *envTestRestConfig
201+
config.GroupVersion = groupVersion
202+
config.APIPath = "/api"
203+
config.NegotiatedSerializer = serializer.NewCodecFactory(scale.NewScaleConverter().Scheme()).WithoutConversion()
204+
rc, err := rest.RESTClientFor(&config)
205+
if err != nil {
206+
panic(err)
207+
}
208+
return rc
209+
}
210+
196211
// newApiExtensionsClient creates a new ApiExtensions client with the envTest kubeconfig
197212
func (c *mcpContext) newApiExtensionsClient() *apiextensionsv1.ApiextensionsV1Client {
198213
return apiextensionsv1.NewForConfigOrDie(envTestRestConfig)

pkg/mcp/configuration_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mcp
22

33
import (
4+
"github.com/mark3labs/mcp-go/mcp"
45
v1 "k8s.io/client-go/tools/clientcmd/api/v1"
56
"sigs.k8s.io/yaml"
67
"testing"
@@ -16,7 +17,7 @@ func TestConfigurationView(t *testing.T) {
1617
}
1718
})
1819
var decoded *v1.Config
19-
err = yaml.Unmarshal([]byte(toolResult.Content[0].(map[string]interface{})["text"].(string)), &decoded)
20+
err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
2021
t.Run("configuration_view has yaml content", func(t *testing.T) {
2122
if err != nil {
2223
t.Fatalf("invalid tool result content %v", err)

pkg/mcp/mcp.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func NewSever() (*Server, error) {
2020
version.Version,
2121
server.WithResourceCapabilities(true, true),
2222
server.WithPromptCapabilities(true),
23+
server.WithToolCapabilities(true),
2324
server.WithLogging(),
2425
),
2526
}
@@ -51,7 +52,7 @@ func NewTextResult(content string, err error) *mcp.CallToolResult {
5152
if err != nil {
5253
return &mcp.CallToolResult{
5354
IsError: true,
54-
Content: []interface{}{
55+
Content: []mcp.Content{
5556
mcp.TextContent{
5657
Type: "text",
5758
Text: err.Error(),
@@ -60,7 +61,7 @@ func NewTextResult(content string, err error) *mcp.CallToolResult {
6061
}
6162
}
6263
return &mcp.CallToolResult{
63-
Content: []interface{}{
64+
Content: []mcp.Content{
6465
mcp.TextContent{
6566
Type: "text",
6667
Text: content,

pkg/mcp/pods.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ func (s *Server) podsLog(ctx context.Context, ctr mcp.CallToolRequest) (*mcp.Cal
106106
ret, err := s.k.PodsLog(ctx, ns.(string), name.(string))
107107
if err != nil {
108108
return NewTextResult("", fmt.Errorf("failed to get pod %s log in namespace %s: %v", name, ns, err)), nil
109+
} else if ret == "" {
110+
ret = fmt.Sprintf("The pod %s in namespace %s has not logged any message yet", name, ns)
109111
}
110112
return NewTextResult(ret, err), nil
111113
}

pkg/mcp/pods_test.go

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mcp
22

33
import (
4+
"github.com/mark3labs/mcp-go/mcp"
45
corev1 "k8s.io/api/core/v1"
56
rbacv1 "k8s.io/api/rbac/v1"
67
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,7 +28,7 @@ func TestPodsListInAllNamespaces(t *testing.T) {
2728
}
2829
})
2930
var decoded []unstructured.Unstructured
30-
err = yaml.Unmarshal([]byte(toolResult.Content[0].(map[string]interface{})["text"].(string)), &decoded)
31+
err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
3132
t.Run("pods_list has yaml content", func(t *testing.T) {
3233
if err != nil {
3334
t.Fatalf("invalid tool result content %v", err)
@@ -102,7 +103,7 @@ func TestPodsListInAllNamespacesUnauthorized(t *testing.T) {
102103
}
103104
})
104105
var decoded []unstructured.Unstructured
105-
err = yaml.Unmarshal([]byte(toolResult.Content[0].(map[string]interface{})["text"].(string)), &decoded)
106+
err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
106107
t.Run("pods_list has yaml content", func(t *testing.T) {
107108
if err != nil {
108109
t.Fatalf("invalid tool result content %v", err)
@@ -137,8 +138,8 @@ func TestPodsListInNamespace(t *testing.T) {
137138
t.Fatalf("call tool should fail")
138139
return
139140
}
140-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to list pods in namespace, missing argument namespace" {
141-
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
141+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to list pods in namespace, missing argument namespace" {
142+
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
142143
return
143144
}
144145
})
@@ -156,7 +157,7 @@ func TestPodsListInNamespace(t *testing.T) {
156157
}
157158
})
158159
var decoded []unstructured.Unstructured
159-
err = yaml.Unmarshal([]byte(toolResult.Content[0].(map[string]interface{})["text"].(string)), &decoded)
160+
err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
160161
t.Run("pods_list_in_namespace has yaml content", func(t *testing.T) {
161162
if err != nil {
162163
t.Fatalf("invalid tool result content %v", err)
@@ -197,8 +198,8 @@ func TestPodsGet(t *testing.T) {
197198
t.Fatalf("call tool should fail")
198199
return
199200
}
200-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to get pod, missing argument name" {
201-
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
201+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to get pod, missing argument name" {
202+
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
202203
return
203204
}
204205
})
@@ -208,8 +209,8 @@ func TestPodsGet(t *testing.T) {
208209
t.Fatalf("call tool should fail")
209210
return
210211
}
211-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to get pod not-found in namespace : pods \"not-found\" not found" {
212-
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
212+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to get pod not-found in namespace : pods \"not-found\" not found" {
213+
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
213214
return
214215
}
215216
})
@@ -227,7 +228,7 @@ func TestPodsGet(t *testing.T) {
227228
}
228229
})
229230
var decodedNilNamespace unstructured.Unstructured
230-
err = yaml.Unmarshal([]byte(podsGetNilNamespace.Content[0].(map[string]interface{})["text"].(string)), &decodedNilNamespace)
231+
err = yaml.Unmarshal([]byte(podsGetNilNamespace.Content[0].(mcp.TextContent).Text), &decodedNilNamespace)
231232
t.Run("pods_get with name and nil namespace has yaml content", func(t *testing.T) {
232233
if err != nil {
233234
t.Fatalf("invalid tool result content %v", err)
@@ -265,7 +266,7 @@ func TestPodsGet(t *testing.T) {
265266
}
266267
})
267268
var decodedInNamespace unstructured.Unstructured
268-
err = yaml.Unmarshal([]byte(podsGetInNamespace.Content[0].(map[string]interface{})["text"].(string)), &decodedInNamespace)
269+
err = yaml.Unmarshal([]byte(podsGetInNamespace.Content[0].(mcp.TextContent).Text), &decodedInNamespace)
269270
t.Run("pods_get with name and namespace has yaml content", func(t *testing.T) {
270271
if err != nil {
271272
t.Fatalf("invalid tool result content %v", err)
@@ -295,8 +296,8 @@ func TestPodsDelete(t *testing.T) {
295296
t.Errorf("call tool should fail")
296297
return
297298
}
298-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to delete pod, missing argument name" {
299-
t.Errorf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
299+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to delete pod, missing argument name" {
300+
t.Errorf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
300301
return
301302
}
302303
})
@@ -306,8 +307,8 @@ func TestPodsDelete(t *testing.T) {
306307
t.Errorf("call tool should fail")
307308
return
308309
}
309-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to delete pod not-found in namespace : pods \"not-found\" not found" {
310-
t.Errorf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
310+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to delete pod not-found in namespace : pods \"not-found\" not found" {
311+
t.Errorf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
311312
return
312313
}
313314
})
@@ -329,8 +330,8 @@ func TestPodsDelete(t *testing.T) {
329330
t.Errorf("call tool failed")
330331
return
331332
}
332-
if podsDeleteNilNamespace.Content[0].(map[string]interface{})["text"].(string) != "Pod deleted successfully" {
333-
t.Errorf("invalid tool result content, got %v", podsDeleteNilNamespace.Content[0].(map[string]interface{})["text"].(string))
333+
if podsDeleteNilNamespace.Content[0].(mcp.TextContent).Text != "Pod deleted successfully" {
334+
t.Errorf("invalid tool result content, got %v", podsDeleteNilNamespace.Content[0].(mcp.TextContent).Text)
334335
return
335336
}
336337
})
@@ -359,8 +360,8 @@ func TestPodsDelete(t *testing.T) {
359360
t.Errorf("call tool failed")
360361
return
361362
}
362-
if podsDeleteInNamespace.Content[0].(map[string]interface{})["text"].(string) != "Pod deleted successfully" {
363-
t.Errorf("invalid tool result content, got %v", podsDeleteInNamespace.Content[0].(map[string]interface{})["text"].(string))
363+
if podsDeleteInNamespace.Content[0].(mcp.TextContent).Text != "Pod deleted successfully" {
364+
t.Errorf("invalid tool result content, got %v", podsDeleteInNamespace.Content[0].(mcp.TextContent).Text)
364365
return
365366
}
366367
})
@@ -396,8 +397,8 @@ func TestPodsDelete(t *testing.T) {
396397
t.Errorf("call tool failed")
397398
return
398399
}
399-
if podsDeleteManaged.Content[0].(map[string]interface{})["text"].(string) != "Pod deleted successfully" {
400-
t.Errorf("invalid tool result content, got %v", podsDeleteManaged.Content[0].(map[string]interface{})["text"].(string))
400+
if podsDeleteManaged.Content[0].(mcp.TextContent).Text != "Pod deleted successfully" {
401+
t.Errorf("invalid tool result content, got %v", podsDeleteManaged.Content[0].(mcp.TextContent).Text)
401402
return
402403
}
403404
})
@@ -451,8 +452,8 @@ func TestPodsDeleteInOpenShift(t *testing.T) {
451452
t.Errorf("call tool failed")
452453
return
453454
}
454-
if podsDeleteManagedOpenShift.Content[0].(map[string]interface{})["text"].(string) != "Pod deleted successfully" {
455-
t.Errorf("invalid tool result content, got %v", podsDeleteManagedOpenShift.Content[0].(map[string]interface{})["text"].(string))
455+
if podsDeleteManagedOpenShift.Content[0].(mcp.TextContent).Text != "Pod deleted successfully" {
456+
t.Errorf("invalid tool result content, got %v", podsDeleteManagedOpenShift.Content[0].(mcp.TextContent).Text)
456457
return
457458
}
458459
})
@@ -482,8 +483,8 @@ func TestPodsLog(t *testing.T) {
482483
t.Fatalf("call tool should fail")
483484
return
484485
}
485-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to get pod log, missing argument name" {
486-
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
486+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to get pod log, missing argument name" {
487+
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
487488
return
488489
}
489490
})
@@ -493,8 +494,8 @@ func TestPodsLog(t *testing.T) {
493494
t.Fatalf("call tool should fail")
494495
return
495496
}
496-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to get pod not-found log in namespace : pods \"not-found\" not found" {
497-
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
497+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to get pod not-found log in namespace : pods \"not-found\" not found" {
498+
t.Fatalf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
498499
return
499500
}
500501
})
@@ -537,8 +538,8 @@ func TestPodsRun(t *testing.T) {
537538
t.Errorf("call tool should fail")
538539
return
539540
}
540-
if toolResult.Content[0].(map[string]interface{})["text"].(string) != "failed to run pod, missing argument image" {
541-
t.Errorf("invalid error message, got %v", toolResult.Content[0].(map[string]interface{})["text"].(string))
541+
if toolResult.Content[0].(mcp.TextContent).Text != "failed to run pod, missing argument image" {
542+
t.Errorf("invalid error message, got %v", toolResult.Content[0].(mcp.TextContent).Text)
542543
return
543544
}
544545
})
@@ -554,7 +555,7 @@ func TestPodsRun(t *testing.T) {
554555
}
555556
})
556557
var decodedNilNamespace []unstructured.Unstructured
557-
err = yaml.Unmarshal([]byte(podsRunNilNamespace.Content[0].(map[string]interface{})["text"].(string)), &decodedNilNamespace)
558+
err = yaml.Unmarshal([]byte(podsRunNilNamespace.Content[0].(mcp.TextContent).Text), &decodedNilNamespace)
558559
t.Run("pods_run with image and nil namespace has yaml content", func(t *testing.T) {
559560
if err != nil {
560561
t.Errorf("invalid tool result content %v", err)
@@ -622,7 +623,7 @@ func TestPodsRun(t *testing.T) {
622623
}
623624
})
624625
var decodedNamespaceAndPort []unstructured.Unstructured
625-
err = yaml.Unmarshal([]byte(podsRunNamespaceAndPort.Content[0].(map[string]interface{})["text"].(string)), &decodedNamespaceAndPort)
626+
err = yaml.Unmarshal([]byte(podsRunNamespaceAndPort.Content[0].(mcp.TextContent).Text), &decodedNamespaceAndPort)
626627
t.Run("pods_run with image, namespace, and port has yaml content", func(t *testing.T) {
627628
if err != nil {
628629
t.Errorf("invalid tool result content %v", err)
@@ -692,7 +693,7 @@ func TestPodsRunInOpenShift(t *testing.T) {
692693
return
693694
}
694695
var decodedPodServiceRoute []unstructured.Unstructured
695-
err = yaml.Unmarshal([]byte(podsRunInOpenShift.Content[0].(map[string]interface{})["text"].(string)), &decodedPodServiceRoute)
696+
err = yaml.Unmarshal([]byte(podsRunInOpenShift.Content[0].(mcp.TextContent).Text), &decodedPodServiceRoute)
696697
if err != nil {
697698
t.Errorf("invalid tool result content %v", err)
698699
return

0 commit comments

Comments
 (0)