Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Common terms used in this project:
- open source (not "open-source")
- large language model (LLM)
- Visual Studio Code ("VS Code" after first use)
- Virtual MCP Server (vMCP) - a feature of ToolHive that aggregates multiple MCP servers into a single endpoint; use "Virtual MCP Server (vMCP)" on first use, "vMCP" thereafter

Check this list for consistent use within the documentation. If you find inconsistencies, update the text to match the preferred term. If you find a term that is not listed here, consider adding it to the list for future reference.

Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Common terms used in this project:
- open source (not "open-source")
- large language model (LLM)
- Visual Studio Code ("VS Code" after first use)
- Virtual MCP Server (vMCP) - a feature of ToolHive that aggregates multiple MCP servers into a single endpoint; use "Virtual MCP Server (vMCP)" on first use, "vMCP" thereafter

Check this list for consistent use within the documentation. If you find inconsistencies, update the text to match the preferred term. If you find a term that is not listed here, consider adding it to the list for future reference.

Expand Down
5 changes: 5 additions & 0 deletions STYLE-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ all caps. Written out, it is lower-cased.
applications provide context to LLMs. MCP is an abbreviation, so it's written in
all caps. Written out, it is proper-cased.

**vMCP**: Virtual MCP Server, a feature of ToolHive that aggregates multiple MCP
servers into a single endpoint. It's written with a lowercase "v" followed by
"MC" in all caps and a capital "P" (not "VMCP" or "Vmcp"). Use "Virtual MCP
Server (vMCP)" on first use, "vMCP" thereafter.

**npm**: the registry for JavaScript packages (the "npm registry"), and the
default package manager for JavaScript. Since it's both the registry _and_ the
package manager, it may be useful to disambiguate "the npm registry". It's not
Expand Down
145 changes: 145 additions & 0 deletions docs/toolhive/concepts/vmcp.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
title: Understanding Virtual MCP Server
sidebar_label: Virtual MCP Server (vMCP)
description:
Learn what Virtual MCP Server does, why it exists, and when to use it.
---

This document explains Virtual MCP Server (vMCP), a feature of the ToolHive
Kubernetes Operator. You'll learn why it exists, when to use it, and how it
simplifies managing multiple MCP servers while enabling powerful multi-system
workflows.

## The problem vMCP solves

**Before vMCP**: Engineers manage 10+ separate MCP server connections, each with
its own authentication, manually coordinate multi-step workflows across systems,
and repeatedly configure the same parameters.

**With vMCP**: Connect once to a unified endpoint that aggregates all backend
MCP servers, execute complex multi-system workflows declaratively, and use
pre-configured tools with sensible defaults.

## Core value propositions

vMCP delivers four key benefits:

1. **Reduce complexity**: Many connections become one, dramatically simplifying
configuration
2. **Speed up workflows**: Parallel execution across systems instead of
sequential calls
3. **Improve security**: Centralized authentication and authorization with a
two-boundary model
4. **Enable reusability**: Define workflows once, use them everywhere

## Key capabilities

### Multi-server aggregation

Managing 10-20+ MCP server connections is overwhelming. Each server needs its
own configuration, authentication, and maintenance. vMCP aggregates all backend
MCP servers into one endpoint with automatic conflict resolution.

**Example scenario**: An engineering team needs access to 8 backend servers
(GitHub, Jira, Slack, Confluence, PagerDuty, Datadog, AWS, and internal company
docs). Instead of configuring 8 separate connections, they configure one vMCP
connection with SSO. This significantly reduces configuration complexity and
makes onboarding new team members much easier.

When multiple backend MCP servers have tools with the same name (for example,
both GitHub and Jira have `create_issue`), vMCP automatically prefixes them:
`github_create_issue`, `jira_create_issue`. You can also define custom names for
clarity.

### Multi-step workflows (composition)

Real-world tasks span multiple systems and require manual orchestration. vMCP
lets you define declarative workflows with parallel execution, conditionals,
error handling, and human-in-the-loop approval gates.

**Example scenario**: During an incident investigation, you need logs from your
logging system, metrics from your monitoring platform, traces from your tracing
service, and infrastructure status from your cloud provider. Without vMCP, an
engineer manually runs 4 commands sequentially and aggregates results. With
vMCP, you fetch all of this in parallel, automatically aggregate it into a
formatted report, and create a Jira ticket with all the data. This workflow is
reusable for every incident.

**Example scenario**: For an app deployment, merge the pull request, wait for
tests, ask a human for approval, deploy only if approved, and notify the team in
Slack. vMCP handles this entire flow declaratively, with automatic rollback on
deployment failure.

### Tool customization and overrides

Third-party MCP servers often have generic names, descriptions, and unrestricted
parameters. vMCP lets you filter, rename, and wrap tools without modifying the
upstream servers.

**Security policy enforcement**: You can restrict a fetch tool to internal
domains only (`*.company.com`), validate URLs before calling the backend, and
provide clear error messages for policy violations.

**Simplified interfaces**: A complex tool like AWS EC2 might have 20+
parameters, but your frontend team only needs 3. You can create a simplified
wrapper that uses instance names instead of IDs and pre-fills safe defaults for
all other parameters.

### Parameter defaults and pre-configuration

Generic servers require repetitive parameter specification. You always use the
same repo, channel, or database. vMCP lets you create specialized instances with
pre-configured defaults.

**Example scenario**: Without vMCP, every GitHub query requires specifying
`repo: stacklok/toolhive`. With vMCP, you pre-configure this default - engineers
never specify the repo parameter, and they can't accidentally query the wrong
repository. This eliminates hundreds of repetitive parameter entries per week.

**Example scenario**: Configure staging database as the default (safe for
development), while production queries require an explicit approval gate.
Connection details are centralized in vMCP configuration instead of scattered
across individual tool configurations.

### Authentication boundary separation

Different authentication is needed for clients versus backend MCP servers, and
managing credentials across multiple systems is complex. vMCP implements a
two-boundary auth model that separates these concerns.

**How it works**: Clients authenticate to vMCP using OAuth 2.1 authorization as
defined in the MCP specification. vMCP then handles authentication to each
backend MCP server independently. Revoking access is simple: disable the user in
your identity provider and all backend access is revoked instantly.

This approach provides single sign-on for users, centralized access control, and
a complete audit trail.

## When to use vMCP

### Good fit

- Teams managing 5+ MCP servers
- Tasks requiring coordination across multiple systems
- Centralized authentication and authorization requirements
- Workflows that should be reusable across the team
- Security policies that need centralized enforcement

### Not needed

- Single MCP server usage
- Simple, one-step operations
- No orchestration requirements

## Summary

vMCP transforms MCP from individual servers into a unified orchestration
platform. The use cases range from simple aggregation to complex workflows with
approval gates, making it valuable for teams managing multiple MCP servers.

## Related information

- [Deploy vMCP](../guides-vmcp/intro.mdx)
- [Configure authentication](../guides-vmcp/authentication.mdx)
- [Tool aggregation and conflict resolution](../guides-vmcp/tool-aggregation.mdx)
- [Composite tools and workflows](../guides-vmcp/composite-tools.mdx)
26 changes: 15 additions & 11 deletions docs/toolhive/guides-k8s/deploy-operator-helm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ chart. To install a specific version, append `--version <VERSION>` to the
command, for example:

```bash
helm upgrade --install toolhive-operator-crds oci://ghcr.io/stacklok/toolhive/toolhive-operator-crds --version 0.0.52
helm upgrade --install toolhive-operator-crds oci://ghcr.io/stacklok/toolhive/toolhive-operator-crds --version 0.0.73
```

## Install the operator
Expand All @@ -52,7 +52,7 @@ chart. To install a specific version, append `--version <VERSION>` to the
command, for example:

```bash
helm upgrade --install toolhive-operator oci://ghcr.io/stacklok/toolhive/toolhive-operator -n toolhive-system --create-namespace --version 0.3.7
helm upgrade --install toolhive-operator oci://ghcr.io/stacklok/toolhive/toolhive-operator -n toolhive-system --create-namespace --version 0.5.6
```

Verify the installation:
Expand Down Expand Up @@ -237,21 +237,23 @@ and then apply the CRDs using `kubectl`.
First, upgrade the CRD Helm chart to match your target operator version:

```bash
helm upgrade -i toolhive-operator-crds oci://ghcr.io/stacklok/toolhive/toolhive-operator-crds --version 0.0.52
helm upgrade -i toolhive-operator-crds oci://ghcr.io/stacklok/toolhive/toolhive-operator-crds --version 0.0.73
```

Then apply the CRDs from the same version tag:

```bash
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.52/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpexternalauthconfigs.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.52/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcptoolconfigs.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.52/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpremoteproxies.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.52/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpservers.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.52/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpgroups.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.52/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpregistries.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpexternalauthconfigs.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcptoolconfigs.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpremoteproxies.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpservers.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpgroups.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpregistries.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_virtualmcpcompositetooldefinitions.yaml
kubectl apply -f https://raw.githubusercontent.com/stacklok/toolhive/refs/tags/toolhive-operator-crds-0.0.73/deploy/charts/operator-crds/crds/toolhive.stacklok.dev_virtualmcpservers.yaml
```

Replace `0.0.52` in both commands with your target CRD version.
Replace `0.0.73` in both commands with your target CRD version.

### Upgrade the operator Helm release

Expand All @@ -267,7 +269,7 @@ This upgrades the operator to the latest version available in the OCI registry.
To upgrade to a specific version, add the `--version` flag:

```bash
helm upgrade -i toolhive-operator oci://ghcr.io/stacklok/toolhive/toolhive-operator -n toolhive-system --reuse-values --version 0.3.7
helm upgrade -i toolhive-operator oci://ghcr.io/stacklok/toolhive/toolhive-operator -n toolhive-system --reuse-values --version 0.5.6
```

If you have a custom `values.yaml` file, include it with the `-f` flag:
Expand Down Expand Up @@ -302,6 +304,8 @@ kubectl delete crd mcpremoteproxies.toolhive.stacklok.dev
kubectl delete crd mcpservers.toolhive.stacklok.dev
kubectl delete crd mcpgroups.toolhive.stacklok.dev
kubectl delete crd mcpregistries.toolhive.stacklok.dev
kubectl delete crd virtualmcpcompositetooldefinitions.toolhive.stacklok.dev
kubectl delete crd virtualmcpservers.toolhive.stacklok.dev
```

Finally, uninstall the CRD Helm chart metadata:
Expand Down
Loading