aggregator

package
v0.6.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2025 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package aggregator provides capability aggregation for Virtual MCP Server.

This package discovers backend MCP servers, queries their capabilities, resolves naming conflicts, and merges them into a unified view. The aggregation process has three stages: query, conflict resolution, and merging.

Package aggregator provides capability aggregation for Virtual MCP Server.

This file contains the factory function for creating conflict resolvers and shared helper functions used by multiple resolver implementations.

Package aggregator provides platform-specific backend discovery implementations.

This file contains:

  • Unified backend discoverer implementation (works with both CLI and Kubernetes)
  • Factory function to create BackendDiscoverer based on runtime environment
  • WorkloadDiscoverer interface and implementations are in pkg/vmcp/workloads

The BackendDiscoverer interface is defined in aggregator.go.

Package aggregator provides capability aggregation for Virtual MCP Server.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoBackendsFound indicates no backends were discovered.
	ErrNoBackendsFound = fmt.Errorf("no backends found in group")

	// ErrBackendQueryFailed indicates a backend query failed.
	ErrBackendQueryFailed = fmt.Errorf("failed to query backend capabilities")

	// ErrUnresolvedConflicts indicates conflicts exist without resolution.
	ErrUnresolvedConflicts = fmt.Errorf("unresolved capability name conflicts")

	// ErrInvalidConflictStrategy indicates an unknown conflict resolution strategy.
	ErrInvalidConflictStrategy = fmt.Errorf("invalid conflict resolution strategy")
)

Common aggregation errors.

Functions

This section is empty.

Types

type AggregatedCapabilities

type AggregatedCapabilities struct {
	// Tools are the aggregated backend tools (ready to expose to clients).
	Tools []vmcp.Tool

	// CompositeTools are the composite workflow tools defined in vMCP configuration.
	// These are separate from backend tools and orchestrate multi-step workflows.
	CompositeTools []vmcp.Tool

	// Resources are the aggregated resources.
	Resources []vmcp.Resource

	// Prompts are the aggregated prompts.
	Prompts []vmcp.Prompt

	// SupportsLogging indicates if logging is supported.
	SupportsLogging bool

	// SupportsSampling indicates if sampling is supported.
	SupportsSampling bool

	// RoutingTable maps capabilities to their backend targets.
	RoutingTable *vmcp.RoutingTable

	// Metadata contains aggregation statistics and info.
	Metadata *AggregationMetadata
}

AggregatedCapabilities is the final unified view of all backend capabilities. This is what gets exposed to MCP clients via tools/list, resources/list, prompts/list.

type AggregationMetadata

type AggregationMetadata struct {
	// BackendCount is the number of backends aggregated.
	BackendCount int

	// ToolCount is the total number of tools.
	ToolCount int

	// ResourceCount is the total number of resources.
	ResourceCount int

	// PromptCount is the total number of prompts.
	PromptCount int

	// ConflictStrategy is the strategy used for conflict resolution.
	ConflictStrategy vmcp.ConflictResolutionStrategy
}

AggregationMetadata contains information about the aggregation process.

type Aggregator

type Aggregator interface {
	// QueryCapabilities queries a backend for its MCP capabilities.
	// Returns the raw capabilities (tools, resources, prompts) from the backend.
	QueryCapabilities(ctx context.Context, backend vmcp.Backend) (*BackendCapabilities, error)

	// QueryAllCapabilities queries all backends for their capabilities in parallel.
	// Handles backend failures gracefully (logs and continues with remaining backends).
	QueryAllCapabilities(ctx context.Context, backends []vmcp.Backend) (map[string]*BackendCapabilities, error)

	// ResolveConflicts applies conflict resolution strategy to handle
	// duplicate capability names across backends.
	ResolveConflicts(ctx context.Context, capabilities map[string]*BackendCapabilities) (*ResolvedCapabilities, error)

	// MergeCapabilities creates the final unified capability view and routing table.
	// Uses the backend registry to populate full BackendTarget information for routing.
	MergeCapabilities(
		ctx context.Context,
		resolved *ResolvedCapabilities,
		registry vmcp.BackendRegistry,
	) (*AggregatedCapabilities, error)

	// AggregateCapabilities is a convenience method that performs the full aggregation pipeline:
	// 1. Query all backends
	// 2. Resolve conflicts
	// 3. Merge into final view
	AggregateCapabilities(ctx context.Context, backends []vmcp.Backend) (*AggregatedCapabilities, error)
}

Aggregator aggregates capabilities from discovered backends into a unified view. This is the core of the virtual MCP server's capability management.

The aggregation process has three stages:

  1. Query: Fetch capabilities from each backend
  2. Conflict Resolution: Handle duplicate tool/resource/prompt names
  3. Merging: Create final unified capability view and routing table

func NewDefaultAggregator

func NewDefaultAggregator(
	backendClient vmcp.BackendClient,
	conflictResolver ConflictResolver,
	workloadConfigs []*config.WorkloadToolConfig,
) Aggregator

NewDefaultAggregator creates a new default aggregator implementation. conflictResolver handles tool name conflicts across backends. workloadConfigs specifies per-backend tool filtering and overrides.

type BackendCapabilities

type BackendCapabilities struct {
	// BackendID identifies the source backend.
	BackendID string

	// Tools are the tools exposed by this backend.
	Tools []vmcp.Tool

	// Resources are the resources exposed by this backend.
	Resources []vmcp.Resource

	// Prompts are the prompts exposed by this backend.
	Prompts []vmcp.Prompt

	// SupportsLogging indicates if the backend supports MCP logging.
	SupportsLogging bool

	// SupportsSampling indicates if the backend supports MCP sampling.
	SupportsSampling bool
}

BackendCapabilities contains the raw capabilities from a single backend.

type BackendDiscoverer

type BackendDiscoverer interface {
	// Discover finds all backend workloads in the specified group.
	// Returns only healthy/running backends.
	// The groupRef format is platform-specific (group name for CLI, MCPGroup name for K8s).
	Discover(ctx context.Context, groupRef string) ([]vmcp.Backend, error)
}

BackendDiscoverer discovers backend MCP server workloads. This abstraction enables different discovery mechanisms for CLI (Docker/Podman) and Kubernetes (Pods/Services).

func NewBackendDiscoverer added in v0.6.6

func NewBackendDiscoverer(
	ctx context.Context,
	groupsManager groups.Manager,
	authConfig *config.OutgoingAuthConfig,
) (BackendDiscoverer, error)

NewBackendDiscoverer creates a unified BackendDiscoverer based on the runtime environment. It automatically detects whether to use CLI (Docker/Podman) or Kubernetes workloads and creates the appropriate WorkloadDiscoverer implementation.

Parameters:

  • ctx: Context for creating managers
  • groupsManager: Manager for group operations (must already be initialized)
  • authConfig: Outgoing authentication configuration for discovered backends

Returns:

  • BackendDiscoverer: A unified discoverer that works with both CLI and Kubernetes workloads
  • error: If manager creation fails

func NewBackendDiscovererWithManager added in v0.6.6

func NewBackendDiscovererWithManager(
	workloadManager workloads.Discoverer,
	groupsManager groups.Manager,
	authConfig *config.OutgoingAuthConfig,
) BackendDiscoverer

NewBackendDiscovererWithManager creates a unified BackendDiscoverer with a pre-configured WorkloadDiscoverer. This is useful for testing or when you already have a workload manager.

func NewUnifiedBackendDiscoverer added in v0.6.6

func NewUnifiedBackendDiscoverer(
	workloadsManager workloads.Discoverer,
	groupsManager groups.Manager,
	authConfig *config.OutgoingAuthConfig,
) BackendDiscoverer

NewUnifiedBackendDiscoverer creates a unified backend discoverer that works with both CLI and Kubernetes workloads through the WorkloadDiscoverer interface.

The authConfig parameter configures authentication for discovered backends. If nil, backends will have no authentication configured.

type ConflictResolver

type ConflictResolver interface {
	// ResolveToolConflicts resolves tool name conflicts using the configured strategy.
	ResolveToolConflicts(ctx context.Context, tools map[string][]vmcp.Tool) (map[string]*ResolvedTool, error)
}

ConflictResolver handles tool name conflicts across backends.

func NewConflictResolver added in v0.5.2

func NewConflictResolver(aggregationConfig *config.AggregationConfig) (ConflictResolver, error)

NewConflictResolver creates the appropriate conflict resolver based on configuration.

type ManualConflictResolver added in v0.5.2

type ManualConflictResolver struct {
	// Overrides maps (backendID, originalToolName) to the resolved configuration.
	// Key format: "backendID:toolName"
	Overrides map[string]*config.ToolOverride
}

ManualConflictResolver implements manual conflict resolution. It requires explicit overrides for ALL conflicts and fails startup if any are unresolved.

func NewManualConflictResolver added in v0.5.2

func NewManualConflictResolver(workloadConfigs []*config.WorkloadToolConfig) (*ManualConflictResolver, error)

NewManualConflictResolver creates a new manual conflict resolver. Note: This resolver validates that overrides don't create NEW conflicts. If two tools are both overridden to the same name, ResolveToolConflicts will return an error ("collision after override").

func (*ManualConflictResolver) ResolveToolConflicts added in v0.5.2

func (r *ManualConflictResolver) ResolveToolConflicts(
	_ context.Context,
	toolsByBackend map[string][]vmcp.Tool,
) (map[string]*ResolvedTool, error)

ResolveToolConflicts applies manual conflict resolution with validation. Returns an error if any conflicts exist without explicit overrides.

type PrefixConflictResolver added in v0.5.2

type PrefixConflictResolver struct {
	// PrefixFormat defines how to format the prefix.
	// Supported placeholders:
	//   {workload} - just the workload name
	//   {workload}_ - workload with underscore
	//   {workload}. - workload with dot
	// Can also be a custom static prefix like "backend_"
	PrefixFormat string
}

PrefixConflictResolver implements automatic tool name prefixing to resolve conflicts. All tools are prefixed with their workload identifier according to a configurable format.

func NewPrefixConflictResolver added in v0.5.2

func NewPrefixConflictResolver(prefixFormat string) *PrefixConflictResolver

NewPrefixConflictResolver creates a new prefix-based conflict resolver.

func (*PrefixConflictResolver) ResolveToolConflicts added in v0.5.2

func (r *PrefixConflictResolver) ResolveToolConflicts(
	_ context.Context,
	toolsByBackend map[string][]vmcp.Tool,
) (map[string]*ResolvedTool, error)

ResolveToolConflicts applies prefix strategy to all tools. Returns a map of resolved tool names to ResolvedTool structs.

type PriorityConflictResolver added in v0.5.2

type PriorityConflictResolver struct {
	// PriorityOrder defines the priority of backends (first has highest priority).
	PriorityOrder []string
	// contains filtered or unexported fields
}

PriorityConflictResolver implements priority-based conflict resolution. The first backend in the priority order wins; conflicting tools from lower-priority backends are dropped.

For backends not in the priority list, conflicts are resolved using prefix strategy as a fallback (prevents data loss).

func NewPriorityConflictResolver added in v0.5.2

func NewPriorityConflictResolver(priorityOrder []string) (*PriorityConflictResolver, error)

NewPriorityConflictResolver creates a new priority-based conflict resolver.

func (*PriorityConflictResolver) ResolveToolConflicts added in v0.5.2

func (r *PriorityConflictResolver) ResolveToolConflicts(
	_ context.Context,
	toolsByBackend map[string][]vmcp.Tool,
) (map[string]*ResolvedTool, error)

ResolveToolConflicts applies priority strategy to resolve conflicts. Returns a map of resolved tool names to ResolvedTool structs.

type ResolvedCapabilities

type ResolvedCapabilities struct {
	// Tools are the conflict-resolved tools.
	// Map key is the resolved tool name, value contains original name and backend.
	Tools map[string]*ResolvedTool

	// Resources are passed through (conflicts rare, namespaced by URI).
	Resources []vmcp.Resource

	// Prompts are passed through (conflicts rare, namespaced by name).
	Prompts []vmcp.Prompt

	// SupportsLogging is true if any backend supports logging.
	SupportsLogging bool

	// SupportsSampling is true if any backend supports sampling.
	SupportsSampling bool
}

ResolvedCapabilities contains capabilities after conflict resolution. Tool names are now unique (after prefixing, priority, or manual resolution).

type ResolvedTool

type ResolvedTool struct {
	// ResolvedName is the final name exposed to clients (after conflict resolution).
	ResolvedName string

	// OriginalName is the tool's name in the backend.
	OriginalName string

	// Description is the tool description (may be overridden).
	Description string

	// InputSchema is the JSON Schema for parameters.
	InputSchema map[string]any

	// BackendID identifies the backend providing this tool.
	BackendID string

	// ConflictResolutionApplied indicates which strategy was used.
	ConflictResolutionApplied vmcp.ConflictResolutionStrategy
}

ResolvedTool represents a tool after conflict resolution.

type ToolFilter

type ToolFilter interface {
	// FilterTools returns only the tools that should be included.
	FilterTools(ctx context.Context, tools []vmcp.Tool) ([]vmcp.Tool, error)
}

ToolFilter filters tools from a backend based on configuration. This reuses ToolHive's existing mcp.WithToolsFilter() middleware.

type ToolOverride

type ToolOverride interface {
	// ApplyOverrides modifies tool names and descriptions.
	ApplyOverrides(ctx context.Context, tools []vmcp.Tool) ([]vmcp.Tool, error)
}

ToolOverride applies renames and description updates to tools. This reuses ToolHive's existing mcp.WithToolsOverride() middleware.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL