mcp

package
v1.7.3 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 26 Imported by: 3

Documentation

Index

Constants

View Source
const (
	ToolTypeListToolFiles   string = "listToolFiles"
	ToolTypeReadToolFile    string = "readToolFile"
	ToolTypeGetToolDocs     string = "getToolDocs"
	ToolTypeExecuteToolCode string = "executeToolCode"
)

CodeMode tool type constants

View Source
const (
	// Health check configuration
	DefaultHealthCheckInterval = 10 * time.Second // Interval between health checks
	DefaultHealthCheckTimeout  = 5 * time.Second  // Timeout for each health check
	MaxConsecutiveFailures     = 5                // Number of failures before marking as unhealthy
)
View Source
const (
	// MCP defaults and identifiers
	BifrostMCPVersion                   = "1.0.0"           // Version identifier for Bifrost
	BifrostMCPClientName                = "BifrostClient"   // Name for internal Bifrost MCP client
	BifrostMCPClientKey                 = "bifrostInternal" // Key for internal Bifrost client in clientMap
	MCPLogPrefix                        = "[Bifrost MCP]"   // Consistent logging prefix
	MCPClientConnectionEstablishTimeout = 30 * time.Second  // Timeout for MCP client connection establishment
)
View Source
const (
	// Tool sync configuration
	DefaultToolSyncInterval = 10 * time.Minute // Default interval for syncing tools from MCP servers
	ToolSyncTimeout         = 10 * time.Second // Timeout for each sync operation
)
View Source
const CodeModeLogPrefix = "[CODE MODE]"

CodeModeLogPrefix is the log prefix for code mode operations

Variables

View Source
var (
	ErrMCPToolTimeout    = errors.New("mcp tool call timed out")
	ErrMCPToolCallFailed = errors.New("mcp tool call failed")
)

Sentinels wrapped (%w) into wire-op errors so mcpErrorType classifies error.type via errors.Is, not message text. toolmanager.go wraps them at the CallTool site.

View Source
var DefaultRetryConfig = RetryConfig{
	MaxRetries:     5,
	InitialBackoff: 1 * time.Second,
	MaxBackoff:     30 * time.Second,
}

Functions

func ExecuteWithRetry added in v1.4.1

func ExecuteWithRetry(
	ctx context.Context,
	fn func() error,
	config RetryConfig,
	logger schemas.Logger,
) error

ExecuteWithRetry executes a function with exponential backoff retry logic. Only retries on transient errors; permanent errors (auth, config) fail immediately. It returns the error from the last attempt if all retries fail.

Parameters:

  • ctx: Context for cancellation
  • fn: Function to execute with retry logic
  • config: Retry configuration
  • logger: Logger for logging retries

Returns:

  • error: The last error if all retries failed, nil if successful

func FixArraySchemas added in v1.4.0

func FixArraySchemas(properties map[string]interface{}, logger schemas.Logger)

FixArraySchemas recursively fixes array schemas by ensuring they have an 'items' field. This prevents validation errors like "array schema missing items" when tools are registered. It handles nested arrays (array-of-array) and recurses into items regardless of type.

Parameters:

  • properties: The properties map to fix

func IsCodeModeTool added in v1.4.0

func IsCodeModeTool(toolName string) bool

IsCodeModeTool returns true if the given tool name is a code mode tool. This is a package-level helper function.

func ResolveToolSyncInterval added in v1.4.0

func ResolveToolSyncInterval(clientConfig *schemas.MCPClientConfig, globalInterval time.Duration) time.Duration

ResolveToolSyncInterval determines the effective tool sync interval for a client. Priority: per-client override > global setting > default

Per-client semantics:

  • Negative value: disabled for this client
  • Zero: use global setting
  • Positive value: use this interval

Returns 0 if sync is disabled for this client.

func ValidateMCPClientName added in v1.4.12

func ValidateMCPClientName(name string) error

ValidateMCPClientName validates an MCP client name. Names must be ASCII-only, cannot contain spaces or hyphens, and cannot start with a number.

Types

type AgentModeExecutor added in v1.4.0

type AgentModeExecutor struct {
	// contains filtered or unexported fields
}

func (*AgentModeExecutor) ExecuteAgentForChatRequest added in v1.4.0

func (a *AgentModeExecutor) ExecuteAgentForChatRequest(
	ctx *schemas.BifrostContext,
	maxAgentDepth int,
	originalReq *schemas.BifrostChatRequest,
	initialResponse *schemas.BifrostChatResponse,
	makeReq func(ctx *schemas.BifrostContext, req *schemas.BifrostChatRequest) (*schemas.BifrostChatResponse, *schemas.BifrostError),
	fetchNewRequestIDFunc func(ctx *schemas.BifrostContext) string,
	executeToolFunc MCPToolExecutor,
	clientManager ClientManager,
) (*schemas.BifrostChatResponse, *schemas.BifrostError)

ExecuteAgentForChatRequest handles the agent mode execution loop for Chat API. It orchestrates iterative tool execution up to the maximum depth, handling auto-executable and non-auto-executable tools appropriately.

Parameters:

  • ctx: Context for agent execution
  • maxAgentDepth: Maximum number of agent iterations allowed
  • originalReq: The original chat request
  • initialResponse: The initial chat response containing tool calls
  • makeReq: Function to make subsequent chat requests during agent execution
  • fetchNewRequestIDFunc: Optional function to generate unique request IDs for each iteration
  • executeToolFunc: Function to execute individual tool calls using unified MCP request/response
  • clientManager: Client manager for accessing MCP clients and tools

Returns:

  • *schemas.BifrostChatResponse: The final response after agent execution
  • *schemas.BifrostError: Any error that occurred during agent execution

func (*AgentModeExecutor) ExecuteAgentForResponsesRequest added in v1.4.0

func (a *AgentModeExecutor) ExecuteAgentForResponsesRequest(
	ctx *schemas.BifrostContext,
	maxAgentDepth int,
	originalReq *schemas.BifrostResponsesRequest,
	initialResponse *schemas.BifrostResponsesResponse,
	makeReq func(ctx *schemas.BifrostContext, req *schemas.BifrostResponsesRequest) (*schemas.BifrostResponsesResponse, *schemas.BifrostError),
	fetchNewRequestIDFunc func(ctx *schemas.BifrostContext) string,
	executeToolFunc MCPToolExecutor,
	clientManager ClientManager,
) (*schemas.BifrostResponsesResponse, *schemas.BifrostError)

ExecuteAgentForResponsesRequest handles the agent mode execution loop for Responses API. It orchestrates iterative tool execution up to the maximum depth, handling auto-executable and non-auto-executable tools appropriately.

Parameters:

  • ctx: Context for agent execution
  • maxAgentDepth: Maximum number of agent iterations allowed
  • originalReq: The original responses request
  • initialResponse: The initial responses response containing tool calls
  • makeReq: Function to make subsequent responses requests during agent execution
  • fetchNewRequestIDFunc: Optional function to generate unique request IDs for each iteration
  • executeToolFunc: Function to execute individual tool calls using unified MCP request/response
  • clientManager: Client manager for accessing MCP clients and tools

Returns:

  • *schemas.BifrostResponsesResponse: The final response after agent execution
  • *schemas.BifrostError: Any error that occurred during agent execution

type ClientHealthMonitor

type ClientHealthMonitor struct {
	// contains filtered or unexported fields
}

ClientHealthMonitor tracks the health status of an MCP client

func NewClientHealthMonitor

func NewClientHealthMonitor(
	manager *MCPManager,
	clientID string,
	interval time.Duration,
	isPingAvailable bool,
	logger schemas.Logger,
) *ClientHealthMonitor

NewClientHealthMonitor creates a new health monitor for an MCP client

func (*ClientHealthMonitor) Start

func (chm *ClientHealthMonitor) Start()

Start begins monitoring the client's health in a background goroutine

func (*ClientHealthMonitor) Stop

func (chm *ClientHealthMonitor) Stop()

Stop stops monitoring the client's health

type ClientManager

type ClientManager interface {
	GetClientByName(clientName string) *schemas.MCPClientState
	GetClientForTool(toolName string) *schemas.MCPClientState
	GetToolPerClient(ctx context.Context) map[string][]schemas.ChatTool
	GetPluginPipeline() PluginPipeline
	ReleasePluginPipeline(pipeline PluginPipeline)
	// AcquireClientConn returns a live upstream MCP client connection for the
	// given client state along with a release function the caller must invoke
	// (typically via defer). For shared-connection auth types the connection is
	// the persistent state.Conn and the release is a no-op; for per-user auth
	// types a fresh ephemeral connection is opened (with the caller-resolved
	// credentials) and closed on release. The credential-resolution error path
	// (e.g. *MCPUserOAuthRequiredError) surfaces here.
	AcquireClientConn(ctx *schemas.BifrostContext, state *schemas.MCPClientState) (*client.Client, func(), error)
	// RunWithPluginPipeline wraps an MCP wire operation in the canonical plugin
	// gate (PreMCPHooks → op → PostMCPHooks). It owns the tracing span,
	// MCPRequestType/ClientName/ToolName stamping, plugin log draining, and
	// short-circuit semantics. Use this from any call site that needs to invoke
	// an MCP tool/list/ping outside the gateway path — e.g. nested tool calls
	// from the Starlark codemode sandbox — to stay in sync with the gateway.
	RunWithPluginPipeline(ctx *schemas.BifrostContext, req *schemas.BifrostMCPRequest, op MCPOpFunc) (*schemas.BifrostMCPResponse, *schemas.BifrostError)
}

ClientManager interface for accessing MCP clients and tools

type ClientToolSyncer added in v1.4.0

type ClientToolSyncer struct {
	// contains filtered or unexported fields
}

ClientToolSyncer periodically syncs tools from an MCP server

func NewClientToolSyncer added in v1.4.0

func NewClientToolSyncer(
	manager *MCPManager,
	clientID string,
	clientName string,
	interval time.Duration,
	logger schemas.Logger,
) *ClientToolSyncer

NewClientToolSyncer creates a new tool syncer for an MCP client

func (*ClientToolSyncer) Start added in v1.4.0

func (cts *ClientToolSyncer) Start()

Start begins syncing tools in a background goroutine

func (*ClientToolSyncer) Stop added in v1.4.0

func (cts *ClientToolSyncer) Stop()

Stop stops syncing tools

type CodeMode added in v1.4.0

type CodeMode interface {
	// GetTools returns the code mode meta-tools (listToolFiles, readToolFile, getToolDocs, executeToolCode)
	// These tools are added to the available tools when a code mode client is connected.
	GetTools() []schemas.ChatTool

	// ExecuteTool handles a code mode tool call by name.
	// Returns the response message and any error that occurred.
	ExecuteTool(ctx *schemas.BifrostContext, toolCall schemas.ChatAssistantMessageToolCall) (*schemas.ChatMessage, error)

	// IsCodeModeTool returns true if the given tool name is a code mode tool.
	IsCodeModeTool(toolName string) bool

	// GetBindingLevel returns the current code mode binding level (server or tool).
	GetBindingLevel() schemas.CodeModeBindingLevel

	// UpdateConfig updates the code mode configuration atomically.
	UpdateConfig(config *CodeModeConfig)

	// SetDependencies sets the dependencies required for code execution.
	// This is called by MCPManager after construction to inject the dependencies
	// (ClientManager, plugin pipeline, etc.) that weren't available at CodeMode creation time.
	SetDependencies(deps *CodeModeDependencies)
}

CodeMode defines the interface for code execution environments. Implementations can provide different interpreters (Starlark, Lua, JavaScript, etc.) while maintaining the same tool interface for the ToolsManager.

type CodeModeConfig added in v1.4.0

type CodeModeConfig struct {
	// BindingLevel controls how tools are exposed in the VFS: "server" or "tool"
	BindingLevel schemas.CodeModeBindingLevel

	// ToolExecutionTimeout is the maximum time allowed for tool execution
	ToolExecutionTimeout time.Duration
}

CodeModeConfig holds the configuration for a CodeMode implementation.

func DefaultCodeModeConfig added in v1.4.0

func DefaultCodeModeConfig() *CodeModeConfig

DefaultCodeModeConfig returns the default configuration for CodeMode.

type CodeModeDependencies added in v1.4.0

type CodeModeDependencies struct {
	// ClientManager provides access to MCP clients and their tools
	ClientManager ClientManager

	// FetchNewRequestIDFunc generates unique request IDs for nested tool calls
	FetchNewRequestIDFunc func(ctx *schemas.BifrostContext) string

	// LogMutex protects concurrent access to logs during code execution
	LogMutex *sync.Mutex

	// CredentialStore resolves per-call credentials (Bearer tokens, headers)
	// and signals whether a client requires an ephemeral upstream connection.
	CredentialStore schemas.MCPCredentialStore
}

CodeModeDependencies holds the dependencies required by CodeMode implementations.

type HealthMonitorManager

type HealthMonitorManager struct {
	// contains filtered or unexported fields
}

HealthMonitorManager manages all client health monitors

func NewHealthMonitorManager

func NewHealthMonitorManager() *HealthMonitorManager

NewHealthMonitorManager creates a new health monitor manager

func (*HealthMonitorManager) StartMonitoring

func (hmm *HealthMonitorManager) StartMonitoring(monitor *ClientHealthMonitor)

StartMonitoring starts monitoring a specific client

func (*HealthMonitorManager) StopAll

func (hmm *HealthMonitorManager) StopAll()

StopAll stops all monitoring

func (*HealthMonitorManager) StopMonitoring

func (hmm *HealthMonitorManager) StopMonitoring(clientID string)

StopMonitoring stops monitoring a specific client

type MCPConnectOpFunc added in v1.5.10

type MCPConnectOpFunc func(preReq *schemas.BifrostMCPConnectRequest) (*schemas.BifrostMCPConnectResponse, error)

MCPConnectOpFunc is the closure each Connect call site provides to

. It receives the (possibly mutated) typed sub-request

that flowed through PreMCPConnectionHook plugins and performs the actual transport + initialize work (with internal retries), returning a typed sub-response.

type MCPManager

type MCPManager struct {
	// contains filtered or unexported fields
}

MCPManager manages MCP integration for Bifrost core. It provides a bridge between Bifrost and various MCP servers, supporting both local tool hosting and external MCP server connections.

func NewMCPManager

func NewMCPManager(ctx context.Context, config schemas.MCPConfig, credStore schemas.MCPCredentialStore, logger schemas.Logger, codeMode CodeMode) *MCPManager

NewMCPManager creates and initializes a new MCP manager instance.

Parameters:

  • ctx: Context for the MCP manager
  • config: MCP configuration including server port and client configs
  • credStore: CredentialStore that resolves per-call credentials (Bearer tokens, static headers, user-submitted headers) and signals whether each client requires an ephemeral upstream connection. Pass nil only in tests where credential resolution is irrelevant.
  • logger: Logger instance for structured logging (uses default if nil)
  • codeMode: Optional CodeMode implementation for code execution (e.g., Starlark). Pass nil if code mode is not needed. The CodeMode's dependencies will be injected automatically via SetDependencies after the manager is created.

Returns:

  • *MCPManager: Initialized manager instance

func (*MCPManager) AcquireClientConn added in v1.5.14

func (m *MCPManager) AcquireClientConn(ctx *schemas.BifrostContext, state *schemas.MCPClientState) (*client.Client, func(), error)

AcquireClientConn returns a live upstream MCP client connection for the given client state, along with a release function the caller must invoke (typically via defer).

For shared-connection auth types (none, headers, server_oauth) the connection is the persistent state.Conn and the release is a no-op — the caller MUST NOT close it.

For per-user auth types (per_user_oauth, …) a fresh ephemeral connection is opened per call. The opening is wrapped in the connect-plugin gate (runConnectWithPluginPipeline) just like AddClient/Reconnect does for shared connections — PreConnectionHook plugins observe the admin-configured static headers and may mutate them; credstore-resolved auth headers are layered on top AFTER the plugin gate, so the bearer token is never observable by plugins. Credential-resolution errors (including *MCPUserOAuthRequiredError) surface from this method without opening any connection.

func (*MCPManager) AddClient

func (m *MCPManager) AddClient(requestCtx context.Context, config *schemas.MCPClientConfig) error

AddClient adds a new MCP client to the manager. It validates the client configuration and establishes a connection. If connection fails, the client entry is retained in Disconnected state and a health monitor is started to automatically reconnect with exponential backoff.

Parameters:

  • config: MCP client configuration

Returns:

  • error: Any error that occurred during client addition or connection

AddClient adds a new MCP client using the provided context for request-scoped connect hooks. Existing transport lifetimes still use the manager context so persistent MCP connections are not tied to the caller.

func (*MCPManager) AddToolsToRequest

func (m *MCPManager) AddToolsToRequest(ctx *schemas.BifrostContext, req *schemas.BifrostRequest) *schemas.BifrostRequest

AddToolsToRequest parses available MCP tools from the context and adds them to the request. It respects context-based filtering for clients and tools, and returns the modified request with tools attached.

Parameters:

  • ctx: Context containing optional client/tool filtering keys
  • req: The Bifrost request to add tools to

Returns:

  • *schemas.BifrostRequest: The request with tools added

func (*MCPManager) CheckAndExecuteAgentForChatRequest

CheckAndExecuteAgentForChatRequest checks if the chat response contains tool calls, and if so, executes agent mode to handle the tool calls iteratively. If no tool calls are present, it returns the original response unchanged.

Agent mode enables autonomous tool execution where:

  1. Tool calls are automatically executed
  2. Results are fed back to the LLM
  3. The loop continues until no more tool calls are made or max depth is reached
  4. Non-auto-executable tools are returned to the caller

This method is available for both Chat Completions and Responses APIs. For Responses API, use CheckAndExecuteAgentForResponsesRequest().

Parameters:

  • ctx: Context for the agent execution
  • req: The original chat request
  • response: The initial chat response that may contain tool calls
  • makeReq: Function to make subsequent chat requests during agent execution

Returns:

  • *schemas.BifrostChatResponse: The final response after agent execution (or original if no tool calls)
  • *schemas.BifrostError: Any error that occurred during agent execution

func (*MCPManager) CheckAndExecuteAgentForResponsesRequest

CheckAndExecuteAgentForResponsesRequest checks if the responses response contains tool calls, and if so, executes agent mode to handle the tool calls iteratively. If no tool calls are present, it returns the original response unchanged.

Agent mode for Responses API works identically to Chat API:

  1. Detects tool calls in the response (function_call messages)
  2. Automatically executes tools in parallel when possible
  3. Feeds results back to the LLM in Responses API format
  4. Continues the loop until no more tool calls or max depth reached
  5. Returns non-auto-executable tools to the caller

Format Handling: This method automatically handles format conversions:

  • Responses tool calls (ResponsesToolMessage) are converted to Chat format for execution
  • Tool execution results are converted back to Responses format (ResponsesMessage)
  • All conversions use the adapters in agent_adaptors.go and converters in schemas/mux.go

This provides full feature parity between Chat Completions and Responses APIs for tool execution.

Parameters:

  • ctx: Context for the agent execution
  • req: The original responses request
  • response: The initial responses response that may contain tool calls
  • makeReq: Function to make subsequent responses requests during agent execution

Returns:

  • *schemas.BifrostResponsesResponse: The final response after agent execution (or original if no tool calls)
  • *schemas.BifrostError: Any error that occurred during agent execution

func (*MCPManager) Cleanup

func (m *MCPManager) Cleanup() error

Cleanup performs cleanup of all MCP resources including clients and local server. This function safely disconnects all MCP clients (HTTP, STDIO, and SSE) and cleans up the local MCP server. It handles proper cancellation of SSE contexts and closes all transport connections.

Returns:

  • error: Always returns nil, but maintains error interface for consistency

func (*MCPManager) ConnectConfiguredClients added in v1.5.22

func (m *MCPManager) ConnectConfiguredClients(ctx context.Context)

ConnectConfiguredClients dials the MCP clients supplied at construction time (MCPConfig.ClientConfigs). It is separated from NewMCPManager so the caller can run it only after all plugins are registered, ensuring every PreMCPConnectionHook participates in the connection. Safe to call once after construction; clients are dialed in parallel and a failed client is retained in the Disconnected state with a health monitor that recovers it automatically.

func (*MCPManager) DisableClient added in v1.5.8

func (m *MCPManager) DisableClient(id string) error

DisableClient shuts down a client's connection, health monitor, and tool syncer without removing it from the manager. The client entry is kept in clientMap with state MCPConnectionStateDisabled so it can be re-enabled later.

Parameters:

  • id: ID of the client to disable

Returns:

  • error: Any error that occurred during disable

func (*MCPManager) EnableClient added in v1.5.8

func (m *MCPManager) EnableClient(id string) error

EnableClient re-enables a previously disabled MCP client by reconnecting it and restarting its health monitor and tool syncer.

Parameters:

  • id: ID of the client to enable

Returns:

  • error: Any error that occurred during enable or connection

func (*MCPManager) ExecuteChatTool

ExecuteChatTool executes an MCP tool call and returns the result as a chat message. This is the canonical entry point for manual MCP tool execution in Chat format. Bifrost.ExecuteChatMCPTool delegates here.

func (*MCPManager) ExecuteResponsesTool

ExecuteResponsesTool executes an MCP tool call and returns the result as a responses message. Bifrost.ExecuteResponsesMCPTool delegates here.

func (*MCPManager) GetAvailableTools

func (m *MCPManager) GetAvailableTools(ctx *schemas.BifrostContext) []schemas.ChatTool

func (*MCPManager) GetClientByName

func (m *MCPManager) GetClientByName(clientName string) *schemas.MCPClientState

GetClientByName returns a client by name.

Parameters:

  • clientName: Name of the client to get

Returns:

  • *schemas.MCPClientState: Client state if found, nil otherwise

func (*MCPManager) GetClientForTool

func (m *MCPManager) GetClientForTool(toolName string) *schemas.MCPClientState

GetClientForTool safely finds a client that has the specified tool. Returns a copy of the client state to avoid data races. Callers should be aware that fields like Conn and ToolMap are still shared references and may be modified by other goroutines, but the struct itself is safe from concurrent modification.

func (*MCPManager) GetClients

func (m *MCPManager) GetClients() []schemas.MCPClientState

GetClients returns all MCP clients managed by the manager.

Returns:

  • []*schemas.MCPClientState: List of all MCP clients

func (*MCPManager) GetPluginPipeline added in v1.5.10

func (manager *MCPManager) GetPluginPipeline() PluginPipeline

GetPluginPipeline returns a plugin pipeline from the provider, or nil if no provider is configured.

func (*MCPManager) GetToolPerClient

func (m *MCPManager) GetToolPerClient(ctx context.Context) map[string][]schemas.ChatTool

GetToolPerClient returns all tools from connected MCP clients. Applies client filtering if specified in the context. Returns a map of client name to its available tools. Parameters:

  • ctx: Execution context

Returns:

  • map[string][]schemas.ChatTool: Map of client name to its available tools

func (*MCPManager) ReconnectClient

func (m *MCPManager) ReconnectClient(id string) error

ReconnectClient attempts to reconnect an MCP client if it is disconnected. It validates that the client exists and then establishes a new connection using the client's existing configuration. Retry logic is handled internally by connectToMCPClient (5 retries, 1-30 seconds per step).

Parameters:

  • id: ID of the client to reconnect

Returns:

  • error: Any error that occurred during reconnection

func (*MCPManager) RegisterTool

func (m *MCPManager) RegisterTool(name, description string, toolFunction MCPToolFunction[any], toolSchema schemas.ChatTool) error

RegisterTool registers a typed tool handler with the local MCP server. This is a convenience function that handles the conversion between typed Go handlers and the MCP protocol.

Type Parameters:

  • T: The expected argument type for the tool (must be JSON-deserializable)

Parameters:

  • name: Unique tool name
  • description: Human-readable tool description
  • handler: Typed function that handles tool execution
  • toolSchema: Bifrost tool schema for function calling

Returns:

  • error: Any registration error

Example:

type EchoArgs struct {
    Message string `json:"message"`
}

err := bifrost.RegisterMCPTool("echo", "Echo a message",
    func(args EchoArgs) (string, error) {
        return args.Message, nil
    }, toolSchema)

func (*MCPManager) ReleasePluginPipeline added in v1.5.10

func (manager *MCPManager) ReleasePluginPipeline(pipeline PluginPipeline)

ReleasePluginPipeline releases a plugin pipeline back to the pool via the configured release function.

func (*MCPManager) RemoveClient

func (m *MCPManager) RemoveClient(id string) error

RemoveClient removes an MCP client from the manager. It handles cleanup for all transport types (HTTP, STDIO, SSE).

Parameters:

  • id: ID of the client to remove

func (*MCPManager) RunWithPluginPipeline added in v1.5.14

func (m *MCPManager) RunWithPluginPipeline(
	ctx *schemas.BifrostContext,
	req *schemas.BifrostMCPRequest,
	op MCPOpFunc,
) (finalResponse *schemas.BifrostMCPResponse, finalError *schemas.BifrostError)

RunWithPluginPipeline wraps an MCP wire operation (connect / ping / list_tools / execute_tool) with the plugin pipeline. It is the single source of truth for the MCP plugin gate pattern — handleMCPToolExecution in core/bifrost.go calls into this same function, and the Starlark codemode sandbox calls into it via the ClientManager interface for nested tool calls.

  1. Acquire pipeline (no-op pass-through if none configured)
  2. Run PreMCPHooks — plugins may mutate the request or short-circuit
  3. On short-circuit: invoke PostMCPHooks with the short-circuit outcome, drain plugin logs, return
  4. Otherwise: invoke op with the mutated request, then run PostMCPHooks on the outcome (response or error), drain plugin logs, return

The op closure is responsible for reading mutated values from preReq's per-op sub-request struct (Headers, ConnectionString, ChatAssistantMessageToolCall, etc.) and using them for the actual wire call.

Returns *BifrostError so callers can preserve rich error fields (AllowFallbacks, MCPAuthRequired).

func (*MCPManager) SetClientTools added in v1.5.1

func (m *MCPManager) SetClientTools(clientID string, tools map[string]schemas.ChatTool, toolNameMapping map[string]string)

SetClientTools updates the tool map and name mapping for an existing client. This is used to populate tools discovered during per-user OAuth verification, where tool discovery happens separately from client creation.

Parameters:

  • clientID: ID of the client to update
  • tools: discovered tools keyed by prefixed name
  • toolNameMapping: mapping from sanitized tool names to original MCP names

func (*MCPManager) SetPluginPipeline added in v1.5.0

func (manager *MCPManager) SetPluginPipeline(provider func() PluginPipeline, release func(PluginPipeline))

SetPluginPipeline updates the plugin pipeline provider and release function on the manager's ToolsManager and CodeMode. Call this after attaching an externally-created MCPManager to a Bifrost instance so that nested tool calls in code mode can run through Bifrost's plugin hooks.

func (*MCPManager) UpdateClient added in v1.4.0

func (m *MCPManager) UpdateClient(id string, updatedConfig *schemas.MCPClientConfig) error

UpdateClient updates an existing MCP client's configuration and refreshes its tool list. It updates the client's execution config with new settings and retrieves updated tools from the MCP server if the client is connected. This method does not refresh the client's tool list. To refresh the client's tool list, use the ReconnectClient method.

Parameters:

  • id: ID of the client to edit
  • updatedConfig: Updated client configuration with new settings

Returns:

  • error: Any error that occurred during client update or tool retrieval

func (*MCPManager) UpdateClientConnection added in v1.5.8

func (m *MCPManager) UpdateClientConnection(id string, newConfig *schemas.MCPClientConfig) error

UpdateClientConnection updates auth-related fields (headers) for an existing MCP client by closing the current connection and establishing a new one so the new credentials are verified before being committed. Non-credential metadata (name, tools, etc.) is preserved from the current execution config.

On failure the clientMap entry is left in Disconnected state but its ExecutionConfig is restored to the previous value, allowing the health monitor to recover the client using the old credentials.

Parameters:

  • id: ID of the client whose credentials should be updated
  • newConfig: Partial config carrying the updated auth fields (Headers). All other fields are ignored and taken from the current execution config.

Returns:

  • error: Any connection error; nil on success

func (*MCPManager) UpdateToolManagerConfig

func (m *MCPManager) UpdateToolManagerConfig(config *schemas.MCPToolManagerConfig)

UpdateToolManagerConfig updates the configuration for the tool manager. This allows runtime updates to settings like execution timeout and max agent depth.

Parameters:

  • config: The new tool manager configuration to apply

func (*MCPManager) VerifyHeadersConnection added in v1.5.14

func (m *MCPManager) VerifyHeadersConnection(ctx context.Context, config *schemas.MCPClientConfig, userHeaders map[string]string) (map[string]schemas.ChatTool, map[string]string, error)

VerifyHeadersConnection creates a temporary MCP connection using the provided user-submitted header values to verify the server is reachable and discover available tools. The connection is closed after verification.

Used in two paths:

  • Admin test flow: admin enters sample values during MCP client creation, this runs an Initialize handshake against the upstream to validate the schema (PerUserHeaderKeys) + discover tools. The discovered tools then persist on the MCPClient row; the sample values are discarded.
  • User submission flow: an end user submits their own values via the workspace submit URL surfaced inline by MCPAuthRequiredError. The handler runs this before upserting the row so a bad submission returns 422 immediately instead of failing on the next tool call.

Parameters:

  • config: MCP client configuration (connection URL, name, PerUserHeaderKeys, etc.)
  • userHeaders: caller-supplied header_name → value map (must cover every PerUserHeaderKeys entry; the caller validates that before invoking).

Returns:

  • map[string]schemas.ChatTool: discovered tools keyed by prefixed name
  • map[string]string: tool name mapping (sanitized → original MCP name)
  • error: any error during verification

func (*MCPManager) VerifyPerUserOAuthConnection added in v1.5.1

func (m *MCPManager) VerifyPerUserOAuthConnection(ctx context.Context, config *schemas.MCPClientConfig, accessToken string) (map[string]schemas.ChatTool, map[string]string, error)

VerifyPerUserOAuthConnection creates a temporary MCP connection using the provided access token to verify the server is reachable and discover available tools. The connection is closed after verification. This is used during per-user OAuth client setup when the admin does a test login to validate the OAuth configuration before saving the MCP client.

Parameters:

  • config: MCP client configuration (connection URL, name, etc.)
  • accessToken: temporary OAuth access token from the admin's test login

Returns:

  • map[string]schemas.ChatTool: discovered tools keyed by prefixed name
  • map[string]string: tool name mapping (sanitized → original MCP name)
  • error: any error during verification

type MCPManagerInterface added in v1.4.0

type MCPManagerInterface interface {
	// Tool Operations
	// AddToolsToRequest parses available MCP tools and adds them to the request
	AddToolsToRequest(ctx *schemas.BifrostContext, req *schemas.BifrostRequest) *schemas.BifrostRequest

	// GetAvailableTools returns all available MCP tools for the given context
	GetAvailableTools(ctx *schemas.BifrostContext) []schemas.ChatTool

	// UpdateToolManagerConfig updates the configuration for the tool manager.
	// DisableAutoToolInject in the config controls auto injection — pass the
	// current value whenever only other fields change so it is never silently reset.
	UpdateToolManagerConfig(config *schemas.MCPToolManagerConfig)

	// Agent Mode Operations
	// CheckAndExecuteAgentForChatRequest handles agent mode for Chat Completions API.
	// Tool executions inside the agent loop go through the plugin gate internally —
	// callers no longer inject an executeTool function.
	CheckAndExecuteAgentForChatRequest(
		ctx *schemas.BifrostContext,
		req *schemas.BifrostChatRequest,
		response *schemas.BifrostChatResponse,
		makeReq func(ctx *schemas.BifrostContext, req *schemas.BifrostChatRequest) (*schemas.BifrostChatResponse, *schemas.BifrostError),
	) (*schemas.BifrostChatResponse, *schemas.BifrostError)

	// CheckAndExecuteAgentForResponsesRequest handles agent mode for Responses API.
	// Tool executions inside the agent loop go through the plugin gate internally.
	CheckAndExecuteAgentForResponsesRequest(
		ctx *schemas.BifrostContext,
		req *schemas.BifrostResponsesRequest,
		response *schemas.BifrostResponsesResponse,
		makeReq func(ctx *schemas.BifrostContext, req *schemas.BifrostResponsesRequest) (*schemas.BifrostResponsesResponse, *schemas.BifrostError),
	) (*schemas.BifrostResponsesResponse, *schemas.BifrostError)

	// ExecuteChatTool / ExecuteResponsesTool run a single MCP tool call through the
	// plugin gate and return the result in the appropriate API format. Bifrost's
	// ExecuteChatMCPTool / ExecuteResponsesMCPTool delegate here.
	ExecuteChatTool(ctx *schemas.BifrostContext, toolCall *schemas.ChatAssistantMessageToolCall) (*schemas.ChatMessage, *schemas.BifrostError)
	ExecuteResponsesTool(ctx *schemas.BifrostContext, toolCall *schemas.ResponsesToolMessage) (*schemas.ResponsesMessage, *schemas.BifrostError)

	// Client Management
	// GetClients returns all MCP clients
	GetClients() []schemas.MCPClientState

	// AddClient adds a new MCP client with the given configuration
	AddClient(ctx context.Context, config *schemas.MCPClientConfig) error

	// ConnectConfiguredClients dials all clients supplied at construction time.
	// Construction no longer connects; call this once all plugins are registered so
	// PreMCPConnectionHook sees the full plugin set.
	ConnectConfiguredClients(ctx context.Context)

	// RemoveClient removes an MCP client by ID
	RemoveClient(id string) error

	// UpdateClient updates an existing MCP client configuration
	UpdateClient(id string, updatedConfig *schemas.MCPClientConfig) error

	// UpdateClientConnection reconnects an existing MCP client using updated
	// auth-related connection fields (for example, headers and OAuth config).
	UpdateClientConnection(id string, newConfig *schemas.MCPClientConfig) error

	// ReconnectClient reconnects an MCP client by ID
	ReconnectClient(id string) error

	// DisableClient shuts down a client's connection and workers without removing it
	DisableClient(id string) error

	// EnableClient reconnects a disabled client and restarts its workers
	EnableClient(id string) error

	// VerifyHeadersConnection creates a temporary MCP connection using a set of
	// caller-supplied header values to verify connectivity and discover tools.
	// The connection is closed after verification.
	VerifyHeadersConnection(ctx context.Context, config *schemas.MCPClientConfig, userHeaders map[string]string) (map[string]schemas.ChatTool, map[string]string, error)

	// VerifyPerUserOAuthConnection creates a temporary MCP connection using a
	// test access token to verify connectivity and discover tools. The connection
	// is closed after verification.
	VerifyPerUserOAuthConnection(ctx context.Context, config *schemas.MCPClientConfig, accessToken string) (map[string]schemas.ChatTool, map[string]string, error)

	// SetClientTools updates the tool map and name mapping for an existing client.
	SetClientTools(clientID string, tools map[string]schemas.ChatTool, toolNameMapping map[string]string)

	// Tool Registration
	// RegisterTool registers a local tool with the MCP server
	RegisterTool(name, description string, toolFunction MCPToolFunction[any], toolSchema schemas.ChatTool) error

	// Lifecycle
	// Cleanup performs cleanup of all MCP resources
	Cleanup() error
}

MCPManagerInterface defines the interface for MCP management functionality. This interface allows different implementations to be used interchangeably in the Bifrost core.

type MCPOpFunc added in v1.5.10

type MCPOpFunc func(preReq *schemas.BifrostMCPRequest) (*schemas.BifrostMCPResponse, error)

MCPOpFunc is the closure each call site provides to RunWithPluginPipeline. It receives the (possibly mutated) request that flowed through PreHooks and is responsible for performing the wire call (including any internal retries) and building a BifrostMCPResponse from the outcome. The plain Go error returned here is wrapped into a BifrostError by the gate before being handed to PostMCPHooks.

type MCPToolExecutor added in v1.5.14

type MCPToolExecutor func(ctx *schemas.BifrostContext, request *schemas.BifrostMCPRequest) (*schemas.BifrostMCPResponse, error)

MCPToolExecutor is the per-call executor signature used by the agent loop. Callers (e.g. MCPManager.executeToolForAgent) handle client lifecycle internally — the agent itself is decoupled from connection management.

type MCPToolFunction

type MCPToolFunction[T any] func(args T) (string, error)

MCPToolFunction is a generic function type for handling tool calls with typed arguments. T represents the expected argument structure for the tool.

type PluginPipeline added in v1.4.0

type PluginPipeline interface {
	// Envelope pipeline (Ping / ListTools / ExecuteTool variants)
	RunMCPPreHooks(ctx *schemas.BifrostContext, req *schemas.BifrostMCPRequest) (*schemas.BifrostMCPRequest, *schemas.MCPPluginShortCircuit, int)
	RunMCPPostHooks(ctx *schemas.BifrostContext, mcpResp *schemas.BifrostMCPResponse, bifrostErr *schemas.BifrostError, runFrom int) (*schemas.BifrostMCPResponse, *schemas.BifrostError)

	// Typed Connect pipeline (MCPConnectionPlugin)
	RunMCPPreConnectionHooks(ctx *schemas.BifrostContext, req *schemas.BifrostMCPConnectRequest) (*schemas.BifrostMCPConnectRequest, *schemas.MCPConnectionShortCircuit, int)
	RunMCPPostConnectionHooks(ctx *schemas.BifrostContext, resp *schemas.BifrostMCPConnectResponse, bifrostErr *schemas.BifrostError, runFrom int) (*schemas.BifrostMCPConnectResponse, *schemas.BifrostError)
}

PluginPipeline represents the plugin execution pipeline interface This allows ToolsManager to run plugin hooks without direct dependency on Bifrost. Two parallel pipelines exist: the envelope-based MCP pipeline for Ping/ListTools/ ExecuteTool variants, and the typed Connect pipeline for MCPConnectionPlugin.

type RetryConfig added in v1.4.1

type RetryConfig struct {
	MaxRetries     int           // Maximum number of retry attempts (not including the initial attempt)
	InitialBackoff time.Duration // Initial backoff duration
	MaxBackoff     time.Duration // Maximum backoff duration
}

RetryConfig defines the retry behavior with exponential backoff

type ToolSyncManager added in v1.4.0

type ToolSyncManager struct {
	// contains filtered or unexported fields
}

ToolSyncManager manages all client tool syncers

func NewToolSyncManager added in v1.4.0

func NewToolSyncManager(globalInterval time.Duration) *ToolSyncManager

NewToolSyncManager creates a new tool sync manager

func (*ToolSyncManager) GetGlobalInterval added in v1.4.0

func (tsm *ToolSyncManager) GetGlobalInterval() time.Duration

GetGlobalInterval returns the global tool sync interval

func (*ToolSyncManager) StartSyncing added in v1.4.0

func (tsm *ToolSyncManager) StartSyncing(syncer *ClientToolSyncer)

StartSyncing starts syncing for a specific client

func (*ToolSyncManager) StopAll added in v1.4.0

func (tsm *ToolSyncManager) StopAll()

StopAll stops all syncing

func (*ToolSyncManager) StopSyncing added in v1.4.0

func (tsm *ToolSyncManager) StopSyncing(clientID string)

StopSyncing stops syncing for a specific client

type ToolsManager

type ToolsManager struct {
	// contains filtered or unexported fields
}

ToolsManager manages MCP tool execution and agent mode.

func NewToolsManager

func NewToolsManager(
	config *schemas.MCPToolManagerConfig,
	clientManager ClientManager,
	fetchNewRequestIDFunc func(ctx *schemas.BifrostContext) string,
	credStore schemas.MCPCredentialStore,
	logger schemas.Logger,
) *ToolsManager

NewToolsManager creates and initializes a new tools manager instance. It validates the configuration, sets defaults if needed, and initializes atomic values for thread-safe configuration updates.

Parameters:

  • config: Tool manager configuration with execution timeout and max agent depth
  • clientManager: Client manager interface for accessing MCP clients and tools
  • fetchNewRequestIDFunc: Optional function to generate unique request IDs for agent mode

Returns:

  • *ToolsManager: Initialized tools manager instance

func NewToolsManagerWithCodeMode added in v1.4.0

func NewToolsManagerWithCodeMode(
	config *schemas.MCPToolManagerConfig,
	clientManager ClientManager,
	fetchNewRequestIDFunc func(ctx *schemas.BifrostContext) string,
	codeMode CodeMode,
	credStore schemas.MCPCredentialStore,
	logger schemas.Logger,
) *ToolsManager

NewToolsManagerWithCodeMode creates a new tools manager with a custom CodeMode implementation. This allows using alternative code execution environments (e.g., Lua, JavaScript, WASM).

Parameters:

  • config: Tool manager configuration with execution timeout and max agent depth
  • clientManager: Client manager interface for accessing MCP clients and tools
  • fetchNewRequestIDFunc: Optional function to generate unique request IDs for agent mode
  • codeMode: Optional CodeMode implementation (if nil, must be set later via SetCodeMode)

Returns:

  • *ToolsManager: Initialized tools manager instance

func (*ToolsManager) ExecuteAgentForChatRequest

ExecuteAgentForChatRequest executes agent mode for a chat request, handling iterative tool calls up to the configured maximum depth. Tool executions inside the agent loop are dispatched through the executeTool callback the caller provides (typically MCPManager.executeToolForAgent, which routes through the plugin gate).

func (*ToolsManager) ExecuteAgentForResponsesRequest

ExecuteAgentForResponsesRequest mirrors ExecuteAgentForChatRequest for the Responses API.

func (*ToolsManager) ExecuteTool added in v1.4.0

func (m *ToolsManager) ExecuteTool(
	ctx *schemas.BifrostContext,
	request *schemas.BifrostMCPRequest,
	clientConn *client.Client,
	executionConfig *schemas.MCPClientConfig,
	toolNameMapping map[string]string,
) (*schemas.BifrostMCPResponse, error)

ExecuteTool executes a tool call and returns the result. This is the primary tool executor that works with both Chat Completions and Responses APIs.

Parameters:

  • ctx: Execution context
  • request: The MCP request containing the tool call (Chat or Responses format)
  • clientConn: The client connection for executing the tool
  • executionConfig: The MCP client configuration for execution context
  • toolNameMapping: Mapping of sanitized tool names to original MCP tool names for accurate logging and response metadata

Returns:

  • *schemas.BifrostMCPResponse: Tool execution result (Chat or Responses format)
  • error: Any execution error

func (*ToolsManager) GetAvailableTools

func (m *ToolsManager) GetAvailableTools(ctx *schemas.BifrostContext) []schemas.ChatTool

GetAvailableTools returns the available tools for the given context.

func (*ToolsManager) GetCodeMode added in v1.4.0

func (m *ToolsManager) GetCodeMode() CodeMode

GetCodeMode returns the current CodeMode implementation.

func (*ToolsManager) GetCodeModeBindingLevel

func (m *ToolsManager) GetCodeModeBindingLevel() schemas.CodeModeBindingLevel

GetCodeModeBindingLevel returns the current code mode binding level. This method is safe to call concurrently from multiple goroutines.

func (*ToolsManager) GetCodeModeDependencies added in v1.4.0

func (m *ToolsManager) GetCodeModeDependencies() *CodeModeDependencies

GetCodeModeDependencies returns the dependencies needed by CodeMode implementations. This is useful when constructing a CodeMode implementation externally.

func (*ToolsManager) ParseAndAddToolsToRequest

func (m *ToolsManager) ParseAndAddToolsToRequest(ctx *schemas.BifrostContext, req *schemas.BifrostRequest) *schemas.BifrostRequest

ParseAndAddToolsToRequest parses the available tools per client and adds them to the Bifrost request.

Parameters:

  • ctx: Execution context
  • req: Bifrost request
  • availableToolsPerClient: Map of client name to its available tools

Returns:

  • *schemas.BifrostRequest: Bifrost request with MCP tools added

func (*ToolsManager) SetCodeMode added in v1.4.0

func (m *ToolsManager) SetCodeMode(codeMode CodeMode)

SetCodeMode sets the CodeMode implementation for code execution. This should be called after construction if no CodeMode was provided to the constructor.

func (*ToolsManager) UpdateConfig

func (m *ToolsManager) UpdateConfig(config *schemas.MCPToolManagerConfig)

UpdateConfig updates tool manager configuration atomically. This method is safe to call concurrently from multiple goroutines.

Directories

Path Synopsis
codemode
starlark
Package starlark provides a Starlark-based implementation of the CodeMode interface.
Package starlark provides a Starlark-based implementation of the CodeMode interface.
Package credstore implements schemas.CredentialStore: it routes credential resolution for MCP tool execution by auth type.
Package credstore implements schemas.CredentialStore: it routes credential resolution for MCP tool execution by auth type.

Jump to

Keyboard shortcuts

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