Skip to content

Conversation

@jerm-dro
Copy link
Contributor

@jerm-dro jerm-dro commented Dec 9, 2025

Summary

Fixes #2921

This PR updates the VirtualMCPServer CRD's WorkflowStep.Arguments field to support non-string value types (integers, booleans, arrays, objects). Previously, the field was defined as map[string]string, which prevented passing typed values to backend MCP tools even though the internal vmcp runtime expects map[string]any.

Problem

When defining composite tools in a VirtualMCPServer, users could not specify non-string arguments:

steps:
  - id: search
    tool: backend.search
    arguments:
      query: "{{ .params.query }}"
      max_results: 10        # ❌ This was converted to string "10"
      include_metadata: true # ❌ This was converted to string "true"

The type mismatch between the CRD (map[string]string) and the runtime (map[string]any) caused numeric and boolean values to be incorrectly converted to strings.

Solution

Changed WorkflowStep.Arguments from map[string]string to *runtime.RawExtension, which is the Kubernetes-native way to store arbitrary JSON in CRDs. This preserves the original types through the entire pipeline.

Changes

CRD Type Definition (cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go):

// Before
Arguments map[string]string `json:"arguments,omitempty"`

// After
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
Arguments *runtime.RawExtension `json:"arguments,omitempty"`

Converter (cmd/thv-operator/pkg/vmcpconfig/converter.go):

  • Updated convertArguments to unmarshal RawExtension into map[string]any
  • Added proper error handling for invalid JSON

Webhook Validation:

  • Updated template validation to handle the new argument type (virtualmcpcompositetooldefinition_webhook.go)
  • Add composite tool validation to virtualmcpserver_webhook.go by factoring out a reusable function from the step above.

Tests:

  • Added TestConvertCompositeTools_NonStringArguments unit test for the converter
  • Added TestVMCPServer_CompositeToolNonStringArguments integration test
  • Updated existing tests to use the new type

@github-actions github-actions bot added the size/M Medium PR: 300-599 lines changed label Dec 9, 2025
@jerm-dro jerm-dro force-pushed the jerm/arguments-supports-types branch from 9da5fb9 to 5cd8e58 Compare December 9, 2025 19:35
@github-actions github-actions bot added size/M Medium PR: 300-599 lines changed and removed size/M Medium PR: 300-599 lines changed labels Dec 9, 2025
@codecov
Copy link

codecov bot commented Dec 9, 2025

Codecov Report

❌ Patch coverage is 83.33333% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 56.01%. Comparing base (71de38f) to head (ebd3951).

Files with missing lines Patch % Lines
...lpha1/virtualmcpcompositetooldefinition_webhook.go 69.23% 3 Missing and 1 partial ⚠️
cmd/thv-operator/pkg/vmcpconfig/converter.go 87.09% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2971      +/-   ##
==========================================
+ Coverage   56.00%   56.01%   +0.01%     
==========================================
  Files         328      328              
  Lines       32314    32337      +23     
==========================================
+ Hits        18096    18115      +19     
- Misses      12673    12675       +2     
- Partials     1545     1547       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the VirtualMCPServer and VirtualMCPCompositeToolDefinition CRDs to support non-string argument types in composite tool workflow steps. Previously, the WorkflowStep.Arguments field was defined as map[string]string, which forced all argument values to be strings even when the backend MCP tools expected typed values (integers, booleans, arrays, objects). The PR changes the field type to *runtime.RawExtension, the Kubernetes-native way to preserve arbitrary JSON types in CRDs.

Key Changes:

  • Changed WorkflowStep.Arguments from map[string]string to *runtime.RawExtension to preserve value types
  • Updated converter logic to unmarshal RawExtension into map[string]any with proper error handling
  • Updated webhook validation in VirtualMCPCompositeToolDefinition to validate Arguments JSON and template syntax
  • Added comprehensive unit and integration tests for non-string argument types

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go Updated WorkflowStep.Arguments field type to *runtime.RawExtension with kubebuilder markers
cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go Auto-generated deepcopy method updated to handle RawExtension
cmd/thv-operator/api/v1alpha1/virtualmcpcompositetooldefinition_webhook.go Updated template validation to unmarshal Arguments JSON and validate string values
cmd/thv-operator/api/v1alpha1/virtualmcpcompositetooldefinition_webhook_test.go Updated tests to use RawExtension for Arguments
cmd/thv-operator/pkg/vmcpconfig/converter.go Updated convertArguments to unmarshal RawExtension to map[string]any with error handling
cmd/thv-operator/pkg/vmcpconfig/converter_test.go Added comprehensive tests for non-string arguments including error cases
cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go Updated controller test to use RawExtension for Arguments
test/integration/vmcp/vmcp_integration_test.go Added integration test verifying non-string arguments flow through to backend tools
test/e2e/thv-operator/virtualmcp/virtualmcp_composite_sequential_test.go Updated E2E test to marshal Arguments as JSON for RawExtension
test/e2e/thv-operator/virtualmcp/virtualmcp_composite_parallel_test.go Updated E2E test to marshal Arguments as JSON for RawExtension
deploy/charts/operator-crds/crds/toolhive.stacklok.dev_virtualmcpservers.yaml Updated CRD schema to use object type with preserve-unknown-fields
deploy/charts/operator-crds/crds/toolhive.stacklok.dev_virtualmcpcompositetooldefinitions.yaml Updated CRD schema to use object type with preserve-unknown-fields
deploy/charts/operator-crds/Chart.yaml Bumped chart version to 0.0.78
deploy/charts/operator-crds/README.md Updated version badge to 0.0.78
docs/operator/crd-api.md Updated API documentation to describe RawExtension type and template support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions github-actions bot added size/M Medium PR: 300-599 lines changed and removed size/M Medium PR: 300-599 lines changed labels Dec 9, 2025
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
@jerm-dro jerm-dro force-pushed the jerm/arguments-supports-types branch from 5dac0dc to b4e3b6e Compare December 9, 2025 21:54
@github-actions github-actions bot added size/M Medium PR: 300-599 lines changed and removed size/M Medium PR: 300-599 lines changed labels Dec 9, 2025
@github-actions github-actions bot removed the size/M Medium PR: 300-599 lines changed label Dec 9, 2025
@github-actions github-actions bot added the size/M Medium PR: 300-599 lines changed label Dec 9, 2025
@jerm-dro jerm-dro marked this pull request as ready for review December 9, 2025 22:57
@jerm-dro jerm-dro requested review from JAORMX and tgrunnagle December 9, 2025 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Medium PR: 300-599 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VirtualMCPServer CRD: Support non-string argument types in composite tool steps

2 participants