Files
bifrost/examples/mcps/go-test-server/main.go
Beyhan Oğur 880f412e2c first commit
2026-04-26 21:52:23 +03:00

382 lines
10 KiB
Go

package main
import (
"context"
"crypto/md5"
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"net/url"
"os"
"strings"
"github.com/google/uuid"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
func main() {
// Create MCP server
s := server.NewMCPServer(
"go-test-server",
"1.0.0",
server.WithToolCapabilities(true),
)
// Register all tools
registerStringTransformTool(s)
registerJSONValidateTool(s)
registerUUIDGenerateTool(s)
registerHashTool(s)
registerEncodeTool(s)
registerDecodeTool(s)
// Start STDIO server
if err := server.ServeStdio(s); err != nil {
fmt.Fprintf(os.Stderr, "Server error: %v\n", err)
os.Exit(1)
}
}
// ============================================================================
// TOOL 1: string_transform
// ============================================================================
func registerStringTransformTool(s *server.MCPServer) {
tool := mcp.NewTool("string_transform",
mcp.WithDescription("Performs string transformations: uppercase, lowercase, reverse, title"),
mcp.WithString("input",
mcp.Required(),
mcp.Description("The input string to transform"),
),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("The operation to perform"),
mcp.Enum("uppercase", "lowercase", "reverse", "title"),
),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var args struct {
Input string `json:"input"`
Operation string `json:"operation"`
}
// Get arguments using the proper method
argsInterface := request.GetArguments()
// Marshal and unmarshal to convert to our struct
argsBytes, err := json.Marshal(argsInterface)
if err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil
}
if err := json.Unmarshal(argsBytes, &args); err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Invalid arguments: %v", err)), nil
}
var result string
switch args.Operation {
case "uppercase":
result = strings.ToUpper(args.Input)
case "lowercase":
result = strings.ToLower(args.Input)
case "reverse":
runes := []rune(args.Input)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
result = string(runes)
case "title":
result = strings.Title(strings.ToLower(args.Input))
default:
return mcp.NewToolResultError(fmt.Sprintf("Unknown operation: %s", args.Operation)), nil
}
response := map[string]string{
"input": args.Input,
"operation": args.Operation,
"result": result,
}
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 2: json_validate
// ============================================================================
func registerJSONValidateTool(s *server.MCPServer) {
tool := mcp.NewTool("json_validate",
mcp.WithDescription("Validates if a string is valid JSON"),
mcp.WithString("json_string",
mcp.Required(),
mcp.Description("The JSON string to validate"),
),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var args struct {
JSONString string `json:"json_string"`
}
// Get arguments using the proper method
argsInterface := request.GetArguments()
// Marshal and unmarshal to convert to our struct
argsBytes, err := json.Marshal(argsInterface)
if err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil
}
if err := json.Unmarshal(argsBytes, &args); err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Invalid arguments: %v", err)), nil
}
var jsonData interface{}
err = json.Unmarshal([]byte(args.JSONString), &jsonData)
response := map[string]interface{}{
"valid": err == nil,
}
if err != nil {
response["error"] = err.Error()
} else {
response["parsed"] = jsonData
}
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 3: uuid_generate
// ============================================================================
func registerUUIDGenerateTool(s *server.MCPServer) {
tool := mcp.NewTool("uuid_generate",
mcp.WithDescription("Generates a random UUID v4"),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
id := uuid.New()
response := map[string]string{
"uuid": id.String(),
}
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 4: hash
// ============================================================================
func registerHashTool(s *server.MCPServer) {
tool := mcp.NewTool("hash",
mcp.WithDescription("Computes hash of input string using specified algorithm"),
mcp.WithString("input",
mcp.Required(),
mcp.Description("The input string to hash"),
),
mcp.WithString("algorithm",
mcp.Required(),
mcp.Description("The hash algorithm to use"),
mcp.Enum("md5", "sha256", "sha512"),
),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var args struct {
Input string `json:"input"`
Algorithm string `json:"algorithm"`
}
// Get arguments using the proper method
argsInterface := request.GetArguments()
// Marshal and unmarshal to convert to our struct
argsBytes, err := json.Marshal(argsInterface)
if err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil
}
if err := json.Unmarshal(argsBytes, &args); err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Invalid arguments: %v", err)), nil
}
var hashResult string
switch args.Algorithm {
case "md5":
hash := md5.Sum([]byte(args.Input))
hashResult = hex.EncodeToString(hash[:])
case "sha256":
hash := sha256.Sum256([]byte(args.Input))
hashResult = hex.EncodeToString(hash[:])
case "sha512":
hash := sha512.Sum512([]byte(args.Input))
hashResult = hex.EncodeToString(hash[:])
default:
return mcp.NewToolResultError(fmt.Sprintf("Unknown algorithm: %s", args.Algorithm)), nil
}
response := map[string]string{
"input": args.Input,
"algorithm": args.Algorithm,
"hash": hashResult,
}
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 5: encode
// ============================================================================
func registerEncodeTool(s *server.MCPServer) {
tool := mcp.NewTool("encode",
mcp.WithDescription("Encodes input string using specified encoding"),
mcp.WithString("input",
mcp.Required(),
mcp.Description("The input string to encode"),
),
mcp.WithString("encoding",
mcp.Required(),
mcp.Description("The encoding to use"),
mcp.Enum("base64", "hex", "url"),
),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var args struct {
Input string `json:"input"`
Encoding string `json:"encoding"`
}
// Get arguments using the proper method
argsInterface := request.GetArguments()
// Marshal and unmarshal to convert to our struct
argsBytes, err := json.Marshal(argsInterface)
if err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil
}
if err := json.Unmarshal(argsBytes, &args); err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Invalid arguments: %v", err)), nil
}
var encoded string
switch args.Encoding {
case "base64":
encoded = base64.StdEncoding.EncodeToString([]byte(args.Input))
case "hex":
encoded = hex.EncodeToString([]byte(args.Input))
case "url":
encoded = url.QueryEscape(args.Input)
default:
return mcp.NewToolResultError(fmt.Sprintf("Unknown encoding: %s", args.Encoding)), nil
}
response := map[string]string{
"input": args.Input,
"encoding": args.Encoding,
"encoded": encoded,
}
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}
// ============================================================================
// TOOL 6: decode
// ============================================================================
func registerDecodeTool(s *server.MCPServer) {
tool := mcp.NewTool("decode",
mcp.WithDescription("Decodes input string using specified encoding"),
mcp.WithString("input",
mcp.Required(),
mcp.Description("The encoded input string to decode"),
),
mcp.WithString("encoding",
mcp.Required(),
mcp.Description("The encoding to use for decoding"),
mcp.Enum("base64", "hex", "url"),
),
)
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var args struct {
Input string `json:"input"`
Encoding string `json:"encoding"`
}
// Get arguments using the proper method
argsInterface := request.GetArguments()
// Marshal and unmarshal to convert to our struct
argsBytes, err := json.Marshal(argsInterface)
if err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil
}
if err := json.Unmarshal(argsBytes, &args); err != nil {
return mcp.NewToolResultError(fmt.Sprintf("Invalid arguments: %v", err)), nil
}
var decoded string
var decodeErr error
switch args.Encoding {
case "base64":
decodedBytes, err := base64.StdEncoding.DecodeString(args.Input)
if err != nil {
decodeErr = err
} else {
decoded = string(decodedBytes)
}
case "hex":
decodedBytes, err := hex.DecodeString(args.Input)
if err != nil {
decodeErr = err
} else {
decoded = string(decodedBytes)
}
case "url":
var err error
decoded, err = url.QueryUnescape(args.Input)
if err != nil {
decodeErr = err
}
default:
return mcp.NewToolResultError(fmt.Sprintf("Unknown encoding: %s", args.Encoding)), nil
}
if decodeErr != nil {
return mcp.NewToolResultError(fmt.Sprintf("Decode error: %v", decodeErr)), nil
}
response := map[string]string{
"input": args.Input,
"encoding": args.Encoding,
"decoded": decoded,
}
jsonResult, _ := json.Marshal(response)
return mcp.NewToolResultText(string(jsonResult)), nil
})
}