Deploys a VirtualMCPServer configuration locally for manual testing and verification
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Fix and improve this skill with Tessl
tessl review fix ./.claude/skills/deploying-vmcp-locally/SKILL.mdThis skill helps you deploy and test VirtualMCPServer configurations in a local Kind cluster for manual verification.
Before using this skill, ensure you have:
If no Kind cluster exists, create one with the ToolHive operator:
# From the toolhive repository root
task kind-with-toolhive-operatorThis creates a Kind cluster named toolhive with:
If you need to test local code changes:
# Set up cluster with e2e port mappings
task kind-setup-e2e
# Install CRDs
task operator-install-crds
# Build and deploy local operator image
task operator-deploy-localApply the YAML configuration you want to test:
kubectl apply -f <path-to-vmcp-yaml> --kubeconfig kconfig.yamlCheck the VirtualMCPServer status:
# List all VirtualMCPServers
kubectl get virtualmcpserver --kubeconfig kconfig.yaml
# Get detailed status
kubectl get virtualmcpserver <name> -o yaml --kubeconfig kconfig.yaml
# Check operator logs for issues
kubectl logs -n toolhive-system -l app.kubernetes.io/name=thv-operator --kubeconfig kconfig.yamlFor NodePort service type (useful for local testing):
# Get the NodePort
kubectl get svc vmcp-<name> -o jsonpath='{.spec.ports[0].nodePort}' --kubeconfig kconfig.yaml
# Test the endpoint (port will be on localhost when using kind-setup-e2e)
curl http://localhost:<nodeport>/mcpFor ClusterIP (default), use port-forward:
kubectl port-forward svc/vmcp-<name> 4483:4483 --kubeconfig kconfig.yaml
curl http://localhost:4483/mcpUse an MCP client to verify tool discovery and execution:
# Initialize MCP session
curl -X POST http://localhost:<port>/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}, "id": 1}'
# List tools
curl -X POST http://localhost:<port>/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 2}'When done testing:
# Remove specific resources
kubectl delete -f <path-to-vmcp-yaml> --kubeconfig kconfig.yaml
# Or destroy the entire cluster
task kind-destroyReference example configurations are in examples/operator/virtual-mcps/:
| File | Description |
|---|---|
vmcp_simple_discovered.yaml | Basic discovered mode configuration |
vmcp_conflict_resolution.yaml | Tool conflict handling strategies |
vmcp_inline_incoming_auth.yaml | Inline authentication configuration |
vmcp_production_full.yaml | Full production configuration |
composite_tool_simple.yaml | Simple composite tool workflow |
composite_tool_complex.yaml | Complex multi-step workflows |
composite_tool_with_elicitations.yaml | Workflows with user prompts |
Check that:
kubectl describe virtualmcpserver <name> --kubeconfig kconfig.yaml
kubectl get mcpgroup --kubeconfig kconfig.yaml
kubectl get mcpserver --kubeconfig kconfig.yamlVerify backend servers have the correct groupRef:
kubectl get mcpserver -o custom-columns=NAME:.metadata.name,GROUP:.spec.groupRef --kubeconfig kconfig.yamlFor testing, use anonymous auth:
incomingAuth:
type: anonymous
authzConfig:
type: inline
inline:
policies:
- 'permit(principal, action, resource);'stacklok/toolhive
bb62674
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.