WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ See the [DEVELOPMENT.md](DEVELOPMENT.md) file for more information.

- **Go Code**:
- Follow the [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments)
- Use the official MCP SDK patterns: `github.com/modelcontextprotocol/go-sdk`
- Run `make lint` before submitting your changes
- Ensure all tests pass with `make test`
- Add tests for new functionality
- Follow MCP specification for tool implementations

#### Commit Guidelines

Expand Down
30 changes: 26 additions & 4 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ package category

import (
"context"
"github.com/mark3labs/mcp-go/pkg/mcp"
"github.com/modelcontextprotocol/go-sdk/src/go/mcp"
)

type Tools struct {
Expand All @@ -169,11 +169,33 @@ func NewTools() *Tools {
}

func (t *Tools) RegisterTools(server *mcp.Server) {
server.RegisterTool("tool_name", t.handleTool)
tool := mcp.NewTool("tool_name",
mcp.WithDescription("Description of what this tool does"),
mcp.WithString("param1",
mcp.Required(),
mcp.Description("Description of parameter 1"),
),
mcp.WithBool("param2",
mcp.Description("Optional boolean parameter"),
),
)
server.AddTool(tool, t.handleTool)
}

func (t *Tools) handleTool(ctx context.Context, params map[string]interface{}) (*mcp.ToolResult, error) {
// implementation
func (t *Tools) handleTool(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Parse required parameters with type safety
param1, err := request.RequireString("param1")
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}

// Parse optional parameters
param2, _ := request.GetBool("param2")

// Tool implementation logic here
result := fmt.Sprintf("Processing %s with flag %v", param1, param2)

return mcp.NewToolResultText(result), nil
}
```

Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,12 @@ $(LOCALBIN):
mkdir -p $(LOCALBIN)

GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
GOLANGCI_LINT_VERSION ?= v1.63.4
GOLANGCI_LINT_VERSION ?= v2.5.0

.PHONY: golangci-lint
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary
Expand Down
94 changes: 84 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,32 @@ For a quickstart guide on how to run KAgent tools using AgentGateway, please ref

## Architecture

The Go tools are implemented as a single MCP server that exposes all available tools through the MCP protocol.
Each tool category is implemented in its own Go file for better organization and maintainability.
The Go tools are implemented as a single MCP server that exposes all available tools through the Model Context Protocol (MCP). Built using the official `github.com/modelcontextprotocol/go-sdk`, the server provides comprehensive Kubernetes, cloud-native, and observability functionality through a unified interface.

### MCP SDK Integration

KAgent Tools leverages the official Model Context Protocol SDK:
- **Official SDK**: Uses `github.com/modelcontextprotocol/go-sdk` for MCP compliance
- **Type Safety**: Strongly-typed parameter validation and parsing
- **JSON Schema**: Automatic schema generation for tool parameters
- **Multiple Transports**: Support for stdio, HTTP, and SSE transports
- **Error Handling**: Standardized error responses following MCP specification
- **Tool Discovery**: Automatic tool registration and capability advertisement

### Package Structure

Each tool category is implemented in its own Go package under `pkg/` for better organization and maintainability:

```
pkg/
├── k8s/ # Kubernetes operations
├── helm/ # Helm package management
├── istio/ # Istio service mesh
├── argo/ # Argo Rollouts
├── cilium/ # Cilium CNI
├── prometheus/ # Prometheus monitoring
└── utils/ # Common utilities
```

## Tool Categories

Expand Down Expand Up @@ -183,10 +207,20 @@ go build -o kagent-tools .

### Running
```bash
./kagent-tools
# Run with stdio transport (default)
./kagent-tools --stdio

# Run with HTTP transport
./kagent-tools --http --port 8084

# Run with custom kubeconfig
./kagent-tools --stdio --kubeconfig ~/.kube/config
```

The server runs using sse transport for MCP communication.
The server supports multiple MCP transports:
- **Stdio**: For direct integration with MCP clients
- **HTTP**: For web-based integrations and debugging
- **SSE**: Server-Sent Events for real-time communication

### Testing
```bash
Expand All @@ -213,11 +247,13 @@ The tools use a common `runCommand` function that:
- Handles timeouts and cancellation

### MCP Integration
All tools are properly integrated with the MCP protocol:
- Use proper parameter parsing with `mcp.ParseString`, `mcp.ParseBool`, etc.
- Return results using `mcp.NewToolResultText` or `mcp.NewToolResultError`
- Include comprehensive tool descriptions and parameter documentation
- Support required and optional parameters
All tools are properly integrated with the official MCP SDK:
- Built using `github.com/modelcontextprotocol/go-sdk`
- Use type-safe parameter parsing with `request.RequireString()`, `request.RequireBool()`, etc.
- Return results using `mcp.NewToolResultText()` or `mcp.NewToolResultError()`
- Include comprehensive tool descriptions and JSON schema parameter validation
- Support required and optional parameters with proper validation
- Follow MCP specification for error handling and result formatting

## Migration from Python

Expand All @@ -239,9 +275,47 @@ This Go implementation provides feature parity with the original Python tools wh

Tools can be configured through environment variables:
- `KUBECONFIG`: Kubernetes configuration file path
- `PROMETHEUS_URL`: Default Prometheus server URL
- `PROMETHEUS_URL`: Default Prometheus server URL (default: http://localhost:9090)
- `GRAFANA_URL`: Default Grafana server URL
- `GRAFANA_API_KEY`: Default Grafana API key
- `LOG_LEVEL`: Logging level (debug, info, warn, error)

## Example Usage

### With MCP Clients

Once connected to an MCP client, you can use natural language to interact with the tools:

```
"List all pods in the default namespace"
→ Uses kubectl_get tool with resource_type="pods", namespace="default"

"Scale the nginx deployment to 3 replicas"
→ Uses kubectl_scale tool with resource_type="deployment", resource_name="nginx", replicas=3

"Show me the Prometheus query for CPU usage"
→ Uses prometheus_query tool with appropriate PromQL query

"Install the nginx helm chart"
→ Uses helm_install tool with chart="nginx"
```

### Direct HTTP API

When running with HTTP transport, you can also interact directly:

```bash
# Check server health
curl http://localhost:8084/health

# Get server metrics
curl http://localhost:8084/metrics

# List available tools (when MCP endpoint is implemented)
curl -X POST http://localhost:8084/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
```

## Error Handling and Debugging

Expand Down
70 changes: 46 additions & 24 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ import (
"github.com/kagent-dev/tools/pkg/k8s"
"github.com/kagent-dev/tools/pkg/prometheus"
"github.com/kagent-dev/tools/pkg/utils"
"github.com/modelcontextprotocol/go-sdk/mcp"
"github.com/spf13/cobra"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"

"github.com/mark3labs/mcp-go/server"
)

var (
Expand Down Expand Up @@ -122,13 +121,13 @@ func run(cmd *cobra.Command, args []string) {

logger.Get().Info("Starting "+Name, "version", Version, "git_commit", GitCommit, "build_date", BuildDate)

mcp := server.NewMCPServer(
Name,
Version,
)
mcpServer := mcp.NewServer(&mcp.Implementation{
Name: Name,
Version: Version,
}, nil)

// Register tools
registerMCP(mcp, tools, *kubeconfig)
registerMCP(mcpServer, tools, *kubeconfig)

// Create wait group for server goroutines
var wg sync.WaitGroup
Expand All @@ -145,12 +144,15 @@ func run(cmd *cobra.Command, args []string) {
if stdio {
go func() {
defer wg.Done()
runStdioServer(ctx, mcp)
runStdioServer(ctx, mcpServer)
}()
} else {
sseServer := server.NewStreamableHTTPServer(mcp,
server.WithHeartbeatInterval(30*time.Second),
)
// TODO: Implement new SDK HTTP transport
// The new SDK should provide HTTP transport capabilities
// This needs to be updated once the correct HTTP transport pattern is identified
// sseServer := server.NewStreamableHTTPServer(mcpServer,
// server.WithHeartbeatInterval(30*time.Second),
// )

// Create a mux to handle different routes
mux := http.NewServeMux()
Expand All @@ -175,10 +177,18 @@ func run(cmd *cobra.Command, args []string) {
}
})

// Handle all other routes with the MCP server wrapped in telemetry middleware
mux.Handle("/", telemetry.HTTPMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sseServer.ServeHTTP(w, r)
})))
// TODO: Handle MCP routes with new SDK HTTP transport
// mux.Handle("/", telemetry.HTTPMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// sseServer.ServeHTTP(w, r)
// })))

// Placeholder: Add MCP routes here once HTTP transport is implemented
mux.HandleFunc("/mcp", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotImplemented)
if err := writeResponse(w, []byte("MCP HTTP transport not yet implemented with new SDK")); err != nil {
logger.Get().Error("Failed to write MCP response", "error", err)
}
})

httpServer = &http.Server{
Addr: fmt.Sprintf(":%d", port),
Expand Down Expand Up @@ -276,22 +286,32 @@ func generateRuntimeMetrics() string {
return metrics.String()
}

func runStdioServer(ctx context.Context, mcp *server.MCPServer) {
func runStdioServer(ctx context.Context, mcpServer *mcp.Server) {
logger.Get().Info("Running KAgent Tools Server STDIO:", "tools", strings.Join(tools, ","))
stdioServer := server.NewStdioServer(mcp)
if err := stdioServer.Listen(ctx, os.Stdin, os.Stdout); err != nil {
logger.Get().Info("Stdio server stopped", "error", err)
}

// TODO: Implement proper stdio transport from new SDK
// The new SDK should provide a stdio transport pattern
// This needs to be researched and implemented correctly

// Placeholder implementation - this will not work and needs to be replaced
// with the correct new SDK stdio transport pattern
logger.Get().Error("Stdio transport not yet implemented with new SDK")

// Example of what the new pattern might look like (needs verification):
// stdioTransport := mcp.NewStdioTransport(os.Stdin, os.Stdout)
// if _, err := mcpServer.Connect(ctx, stdioTransport, nil); err != nil {
// logger.Get().Error("Failed to connect stdio transport", "error", err)
// }
}

func registerMCP(mcp *server.MCPServer, enabledToolProviders []string, kubeconfig string) {
func registerMCP(mcpServer *mcp.Server, enabledToolProviders []string, kubeconfig string) {
// A map to hold tool providers and their registration functions
toolProviderMap := map[string]func(*server.MCPServer){
toolProviderMap := map[string]func(*mcp.Server) error{
"argo": argo.RegisterTools,
"cilium": cilium.RegisterTools,
"helm": helm.RegisterTools,
"istio": istio.RegisterTools,
"k8s": func(s *server.MCPServer) { k8s.RegisterTools(s, nil, kubeconfig) },
"k8s": func(s *mcp.Server) error { return k8s.RegisterTools(s, nil, kubeconfig) },
"prometheus": prometheus.RegisterTools,
"utils": utils.RegisterTools,
}
Expand All @@ -304,7 +324,9 @@ func registerMCP(mcp *server.MCPServer, enabledToolProviders []string, kubeconfi
}
for _, toolProviderName := range enabledToolProviders {
if registerFunc, ok := toolProviderMap[toolProviderName]; ok {
registerFunc(mcp)
if err := registerFunc(mcpServer); err != nil {
logger.Get().Error("Failed to register tool provider", "provider", toolProviderName, "error", err)
}
} else {
logger.Get().Error("Unknown tool specified", "provider", toolProviderName)
}
Expand Down
33 changes: 27 additions & 6 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ To learn more about agentgateway, see [AgentGateway](https://agentgateway.dev/do
5. open http://localhost:15000/ui

```bash
# Install KAgent Tools
curl -sL https://raw.githubusercontent.com/kagent-dev/tools/refs/heads/main/scripts/install.sh | bash
curl -sL https://raw.githubusercontent.com/kagent-dev/tools/refs/heads/main/scripts/agentgateway-config-tools.yaml

# Download AgentGateway configuration
curl -sL https://raw.githubusercontent.com/kagent-dev/tools/refs/heads/main/scripts/agentgateway-config-tools.yaml -o agentgateway-config-tools.yaml

# Install AgentGateway
curl -sL https://raw.githubusercontent.com/agentgateway/agentgateway/refs/heads/main/common/scripts/get-agentproxy | bash

# Add to PATH and run
export PATH=$PATH:$HOME/.local/bin/
agentgateway -f agentgateway-config-tools.yaml
```
Expand Down Expand Up @@ -55,24 +61,39 @@ make run-agentgateway

### Running KAgent Tools using Cursor MCP


1. Download the agentgateway binary and install it.
```
1. Install KAgent Tools:
```bash
curl -sL https://raw.githubusercontent.com/kagent-dev/tools/refs/heads/main/scripts/install.sh | bash
```

2. Create `.cursor/mcp.json`
2. Create `.cursor/mcp.json` in your project root:

```json
{
"mcpServers": {
"kagent-tools": {
"command": "kagent-tools",
"args": ["--stdio", "--kubeconfig", "~/.kube/config"]
"args": ["--stdio", "--kubeconfig", "~/.kube/config"],
"env": {
"LOG_LEVEL": "info"
}
}
}
}
```

3. Restart Cursor and the KAgent Tools will be available through the MCP interface.

### Available Tools

Once connected, you'll have access to all KAgent tool categories:
- **Kubernetes**: `kubectl_get`, `kubectl_describe`, `kubectl_logs`, `kubectl_apply`, etc.
- **Helm**: `helm_list`, `helm_install`, `helm_upgrade`, etc.
- **Istio**: `istio_proxy_status`, `istio_analyze`, `istio_install`, etc.
- **Argo Rollouts**: `promote_rollout`, `pause_rollout`, `set_rollout_image`, etc.
- **Cilium**: `cilium_status_and_version`, `install_cilium`, `upgrade_cilium`, etc.
- **Prometheus**: `prometheus_query`, `prometheus_range_query`, `prometheus_labels`, etc.
- **Utils**: `shell`, `current_date_time`, etc.



Loading
Loading