Skip to content

Commit b22bc12

Browse files
committed
simplify code
1 parent e79b7b3 commit b22bc12

7 files changed

Lines changed: 208 additions & 695 deletions

File tree

pkg/vmcp/client/client.go

Lines changed: 6 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ package client
99

1010
import (
1111
"context"
12-
"encoding/json"
1312
"errors"
1413
"fmt"
1514
"io"
1615
"net"
1716
"net/http"
18-
"strings"
1917
"time"
2018

2119
"github.com/mark3labs/mcp-go/client"
@@ -28,6 +26,7 @@ import (
2826
vmcpauth "github.com/stacklok/toolhive/pkg/vmcp/auth"
2927
authtypes "github.com/stacklok/toolhive/pkg/vmcp/auth/types"
3028
"github.com/stacklok/toolhive/pkg/vmcp/conversion"
29+
"github.com/stacklok/toolhive/pkg/versions"
3130
)
3231

3332
const (
@@ -329,7 +328,7 @@ func initializeClient(ctx context.Context, c *client.Client) (*mcp.ServerCapabil
329328
ProtocolVersion: mcp.LATEST_PROTOCOL_VERSION,
330329
ClientInfo: mcp.Implementation{
331330
Name: "toolhive-vmcp",
332-
Version: "0.1.0",
331+
Version: versions.Version,
333332
},
334333
Capabilities: mcp.ClientCapabilities{
335334
// Virtual MCP acts as a client to backends
@@ -386,13 +385,6 @@ func queryPrompts(ctx context.Context, c *client.Client, supported bool, backend
386385
return &mcp.ListPromptsResult{Prompts: []mcp.Prompt{}}, nil
387386
}
388387

389-
// convertContent converts a single mcp.Content item to vmcp.Content.
390-
// Delegates to the shared conversion package; kept here for backward compatibility
391-
// with tests that call it directly.
392-
func convertContent(content mcp.Content) vmcp.Content {
393-
return conversion.ConvertMCPContent(content)
394-
}
395-
396388
// ListCapabilities queries a backend for its MCP capabilities.
397389
// Returns tools, resources, and prompts exposed by the backend.
398390
// Only queries capabilities that the server advertises during initialization.
@@ -445,25 +437,10 @@ func (h *httpBackendClient) ListCapabilities(ctx context.Context, target *vmcp.B
445437

446438
// Convert tools
447439
for i, tool := range toolsResp.Tools {
448-
// Use a JSON round-trip to capture all schema fields (type, properties,
449-
// required, $defs, additionalProperties, etc.) rather than enumerating
450-
// them manually. This is forward-safe: any fields the SDK adds in future
451-
// versions are preserved automatically.
452-
inputSchema := make(map[string]any)
453-
if b, err := json.Marshal(tool.InputSchema); err == nil {
454-
if jsonErr := json.Unmarshal(b, &inputSchema); jsonErr != nil {
455-
logger.Debugf("Failed to decode tool input schema for %s; using type-only fallback: %v", tool.Name, jsonErr)
456-
inputSchema = map[string]any{"type": tool.InputSchema.Type}
457-
}
458-
} else {
459-
logger.Debugf("Failed to encode tool input schema for %s; using type-only fallback: %v", tool.Name, err)
460-
inputSchema = map[string]any{"type": tool.InputSchema.Type}
461-
}
462-
463440
capabilities.Tools[i] = vmcp.Tool{
464441
Name: tool.Name,
465442
Description: tool.Description,
466-
InputSchema: inputSchema,
443+
InputSchema: conversion.ConvertToolInputSchema(tool.InputSchema),
467444
BackendID: target.WorkloadID,
468445
}
469446
}
@@ -702,11 +679,7 @@ func (h *httpBackendClient) GetPrompt(
702679
logger.Debugf("Translating prompt name: %s (client-facing) → %s (backend)", name, backendPromptName)
703680
}
704681

705-
// Convert map[string]any to map[string]string
706-
stringArgs := make(map[string]string)
707-
for k, v := range arguments {
708-
stringArgs[k] = fmt.Sprintf("%v", v)
709-
}
682+
stringArgs := conversion.ConvertPromptArguments(arguments)
710683

711684
result, err := c.GetPrompt(ctx, mcp.GetPromptRequest{
712685
Params: mcp.GetPromptParams{
@@ -718,27 +691,9 @@ func (h *httpBackendClient) GetPrompt(
718691
return nil, fmt.Errorf("prompt get failed on backend %s: %w", target.WorkloadID, err)
719692
}
720693

721-
// Concatenate all prompt messages into a single string.
722-
// MCP prompts return messages with role and multi-modal content; only text
723-
// chunks are captured (non-text content is silently discarded — Phase 1 limitation).
724-
var sb strings.Builder
725-
for _, msg := range result.Messages {
726-
if msg.Role != "" {
727-
fmt.Fprintf(&sb, "[%s] ", msg.Role)
728-
}
729-
if textContent, ok := mcp.AsTextContent(msg.Content); ok {
730-
sb.WriteString(textContent.Text)
731-
sb.WriteByte('\n')
732-
}
733-
}
734-
prompt := sb.String()
735-
736-
// Extract _meta field from backend response
737-
meta := conversion.FromMCPMeta(result.Meta)
738-
739694
return &vmcp.PromptGetResult{
740-
Messages: prompt,
695+
Messages: conversion.ConvertPromptMessages(result.Messages),
741696
Description: result.Description,
742-
Meta: meta,
697+
Meta: conversion.FromMCPMeta(result.Meta),
743698
}, nil
744699
}

0 commit comments

Comments
 (0)