Skip to main content

Overview

Bifrost can connect to any MCP-compatible server to discover and execute tools. Each connection is called an MCP Client in Bifrost terminology.

Connection Types

Bifrost supports three connection protocols, each with different authentication options:
TypeDescriptionBest ForAuth Support
STDIOSpawns a subprocess and communicates via stdin/stdoutLocal tools, CLI utilities, scriptsNone
HTTPSends requests to an HTTP endpointRemote APIs, microservices, cloud functionsHeaders, OAuth 2.0
SSEServer-Sent Events for persistent connectionsReal-time data, streaming toolsHeaders, OAuth 2.0

STDIO Connections

STDIO connections launch external processes and communicate via standard input/output. Best for local tools and scripts.
{
  "name": "filesystem",
  "connection_type": "stdio",
  "stdio_config": {
    "command": "npx",
    "args": ["-y", "@anthropic/mcp-filesystem"],
    "envs": ["HOME", "PATH"]
  },
  "tools_to_execute": ["*"]
}
Use Cases:
  • Local filesystem operations
  • Python/Node.js MCP servers
  • CLI utilities and scripts
  • Database tools with local credentials
Docker Users: When running Bifrost in Docker, STDIO connections may not work if the required commands (e.g., npx, python) are not installed in the container. For STDIO-based MCP servers, build a custom Docker image that includes the necessary dependencies, or use HTTP/SSE connections to externally hosted MCP servers.

HTTP Connections

HTTP connections communicate with MCP servers via HTTP requests. Ideal for remote services and microservices. HTTP connections support two authentication methods:
  • Header-based authentication: Static headers (API keys, custom tokens)
  • OAuth 2.0: Dynamic token-based authentication with automatic token refresh

Header-Based Authentication

Use static headers for API keys and custom authentication tokens:
{
  "name": "web-search",
  "connection_type": "http",
  "connection_string": "https://mcp-server.example.com/mcp",
  "auth_type": "headers",
  "headers": {
    "Authorization": "Bearer your-api-key",
    "X-Custom-Header": "value"
  },
  "tools_to_execute": ["*"]
}
Use Cases:
  • Static API keys
  • Bearer token authentication
  • Custom header-based auth schemes

OAuth 2.0 Authentication

Use OAuth 2.0 for secure, user-based authentication with automatic token refresh:
{
  "name": "web-search",
  "connection_type": "http",
  "connection_string": "https://mcp-server.example.com/mcp",
  "auth_type": "oauth",
  "oauth_config": {
    "client_id": "your-client-id",
    "client_secret": "your-client-secret",
    "authorize_url": "https://auth.example.com/authorize",
    "token_url": "https://auth.example.com/token",
    "scopes": ["read", "write"]
  },
  "tools_to_execute": ["*"]
}
Features:
  • Automatic token refresh before expiration
  • PKCE support for public clients
  • Dynamic client registration (RFC 7591)
  • OAuth discovery from server URLs
→ Learn more about OAuth authentication → Use Cases:
  • User-delegated access
  • Third-party service integrations
  • Secure credential management
  • Compliance with OAuth 2.0 standards
Overall HTTP Use Cases:
  • Remote API integrations
  • Cloud-hosted MCP services
  • Microservice architectures
  • Third-party tool providers

SSE Connections

Server-Sent Events (SSE) connections provide real-time, persistent connections to MCP servers. Like HTTP connections, SSE supports both header-based and OAuth authentication.

Header-Based Authentication

{
  "name": "live-data",
  "connection_type": "sse",
  "connection_string": "https://stream.example.com/mcp/sse",
  "auth_type": "headers",
  "headers": {
    "Authorization": "Bearer your-api-key"
  },
  "tools_to_execute": ["*"]
}

OAuth 2.0 Authentication

{
  "name": "live-data",
  "connection_type": "sse",
  "connection_string": "https://stream.example.com/mcp/sse",
  "auth_type": "oauth",
  "oauth_config": {
    "client_id": "your-client-id",
    "authorize_url": "https://auth.example.com/authorize",
    "token_url": "https://auth.example.com/token",
    "scopes": ["stream:read"]
  },
  "tools_to_execute": ["*"]
}
Use Cases:
  • Real-time market data
  • Live system monitoring
  • Event-driven workflows
  • User-authenticated streaming connections
→ Learn more about OAuth authentication →

Gateway Setup

Adding an MCP Client

  1. Navigate to MCP Gateway in the sidebar - you’ll see a table of all registered servers
MCP Servers Table
  1. Click New MCP Server button to open the creation form
  2. Fill in the connection details:
Add MCP Client Form
Fields:
  • Name: Unique identifier (no spaces or hyphens, ASCII only)
  • Connection Type: STDIO, HTTP, or SSE
  • For STDIO: Command, arguments, and environment variables
  • For HTTP/SSE: Connection URL
  1. Click Create to connect

Viewing and Managing Connected Tools

Once connected, click on any client row to open the configuration sheet:
MCP Client Configuration and Tools
Here you can:
  • View all discovered tools with their descriptions and parameters
  • Enable/disable individual tools via toggle switches
  • Configure auto-execution for specific tools
  • Edit custom headers for HTTP/SSE connections
  • View the full connection configuration as JSON

Go SDK Setup

Configure MCP in your Bifrost initialization:
package main

import (
    "context"
    bifrost "github.com/maximhq/bifrost/core"
    "github.com/maximhq/bifrost/core/schemas"
)

func main() {
    mcpConfig := &schemas.MCPConfig{
        ClientConfigs: []schemas.MCPClientConfig{
            {
                Name:             "filesystem",
                ConnectionType:   schemas.MCPConnectionTypeSTDIO,
                IsPingAvailable:  true,  // Use lightweight ping for health checks
                StdioConfig: &schemas.MCPStdioConfig{
                    Command: "npx",
                    Args:    []string{"-y", "@anthropic/mcp-filesystem"},
                    Envs:    []string{"HOME", "PATH"},
                },
                ToolsToExecute: []string{"*"},
            },
            {
                Name:             "web_search",
                ConnectionType:   schemas.MCPConnectionTypeHTTP,
                ConnectionString: bifrost.Ptr("http://localhost:3001/mcp"),
                IsPingAvailable:  false,  // Use listTools for health checks
                ToolsToExecute:   []string{"search", "fetch_url"},
            },
        },
    }

    client, err := bifrost.Init(context.Background(), schemas.BifrostConfig{
        Account:   account,
        MCPConfig: mcpConfig,
        Logger:    bifrost.NewDefaultLogger(schemas.LogLevelInfo),
    })
    if err != nil {
        panic(err)
    }
}

Tools To Execute Semantics

The ToolsToExecute field controls which tools from the client are available:
ValueBehavior
["*"]All tools from this client are included
[] or nilNo tools included (deny-by-default)
["tool1", "tool2"]Only specified tools are included

Tools To Auto Execute (Agent Mode)

The ToolsToAutoExecute field controls which tools can be automatically executed in Agent Mode:
ValueBehavior
["*"]All tools are auto-executed
[] or nilNo tools are auto-executed (manual approval required)
["tool1", "tool2"]Only specified tools are auto-executed
A tool must be in both ToolsToExecute and ToolsToAutoExecute to be auto-executed. If a tool is in ToolsToAutoExecute but not in ToolsToExecute, it will be skipped.
Example configuration:
{
    Name:           "filesystem",
    ConnectionType: schemas.MCPConnectionTypeSTDIO,
    StdioConfig: &schemas.MCPStdioConfig{
        Command: "npx",
        Args:    []string{"-y", "@anthropic/mcp-filesystem"},
    },
    ToolsToExecute:     []string{"*"},                              // All tools available
    ToolsToAutoExecute: []string{"read_file", "list_directory"},    // Only these auto-execute
}

Environment Variables

Use environment variables for sensitive configuration values: Gateway (config.json):
{
  "name": "secure_api",
  "connection_type": "http",
  "connection_string": "env.SECURE_MCP_URL"
}
Go SDK:
{
    Name:             "secure_api",
    ConnectionType:   schemas.MCPConnectionTypeHTTP,
    ConnectionString: bifrost.Ptr(os.Getenv("SECURE_MCP_URL")),
}
Environment variables are:
  • Automatically resolved during client connection
  • Redacted in API responses and UI for security
  • Validated at startup to ensure all required variables are set

Client State Management

Connection States

StateDescription
connectedClient is active and tools are available
connectingClient is establishing connection
disconnectedClient lost connection but can be reconnected
errorClient configuration or connection failed

Managing Clients at Runtime

Reconnect a client:
curl -X POST http://localhost:8080/api/mcp/client/{id}/reconnect
Edit client configuration:
curl -X PUT http://localhost:8080/api/mcp/client/{id} \
  -H "Content-Type: application/json" \
  -d '{
    "name": "filesystem",
    "connection_type": "stdio",
    "stdio_config": {
      "command": "npx",
      "args": ["-y", "@anthropic/mcp-filesystem"]
    },
    "tools_to_execute": ["read_file", "list_directory"]
  }'
Remove a client:
curl -X DELETE http://localhost:8080/api/mcp/client/{id}

Health Monitoring

Bifrost automatically monitors MCP client health with periodic checks every 10 seconds by default.

Health Check Methods

By default, Bifrost uses the lightweight ping method for health checks. However, you can configure the health check method based on your MCP server’s capabilities:
MethodWhen to UseOverheadFallback
Ping (default)Server supports MCP ping protocolMinimalBest for most servers
ListToolsServer doesn’t support ping, or you need heavier checksHigherMore resource-intensive

Configuring Health Check Method

You can toggle the is_ping_available setting for each client:

Via Web UI

  1. Navigate to MCP Gateway and select a server
  2. In the configuration panel, toggle “Ping Available for Health Check”
  3. Enable: Uses lightweight ping for health checks
  4. Disable: Uses listTools method for health checks instead
Ping Available Toggle

Via API

curl -X PUT http://localhost:8080/api/mcp/client/{id} \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my_server",
    "is_ping_available": false
  }'

Via config.json

{
  "mcp": {
    "client_configs": [
      {
        "name": "filesystem",
        "connection_type": "stdio",
        "is_ping_available": true,
        "stdio_config": {
          "command": "npx",
          "args": ["-y", "@anthropic/mcp-filesystem"]
        }
      }
    ]
  }
}

Via Go SDK

err := client.EditMCPClient(context.Background(), schemas.MCPClientConfig{
    ID:               "filesystem",
    Name:             "filesystem",
    IsPingAvailable:  false,  // Use listTools instead of ping
    ToolsToExecute:   []string{"*"},
})

Health Check Behavior

When a client disconnects:
  1. State changes to disconnected
  2. Tools from that client become unavailable
  3. You can reconnect via API or UI
Note: Changing is_ping_available takes effect immediately without requiring a client reconnection.

Connection Resilience and Retry Logic

Bifrost automatically implements exponential backoff retry logic to handle transient network failures and temporary service unavailability. This ensures that brief connection issues don’t immediately cause tool unavailability.
Important: Bifrost only retries on transient errors (network failures, timeouts, temporary service unavailability). Permanent errors like authentication failures, configuration errors, and missing commands fail immediately without retry.

Automatic Retry Strategy

Bifrost retries failed operations using the following strategy, as implemented by ExecuteWithRetry and DefaultRetryConfig in the MCP layer:
ParameterValueDescription
Max Retries (DefaultRetryConfig.MaxRetries)5Retries after the initial attempt (6 attempts total)
Initial Backoff (DefaultRetryConfig.InitialBackoff)1 secondStarting backoff duration before doubling
Max Backoff (DefaultRetryConfig.MaxBackoff)30 secondsMaximum wait time between retries
Backoff Multiplier2xExponential growth between attempts
Backoff Progression (matches ExecuteWithRetry with DefaultRetryConfig):
  • Attempt 1: Initial attempt (no wait)
  • Attempt 2: Wait 1s, then retry (and double backoff to 2s)
  • Attempt 3: Wait 2s, then retry (and double backoff to 4s)
  • Attempt 4: Wait 4s, then retry (and double backoff to 8s)
  • Attempt 5: Wait 8s, then retry (and double backoff to 16s)
  • Attempt 6: Wait 16s, then retry (backoff capped at 30s max)

Error Classification

Bifrost intelligently classifies errors as either transient (retryable) or permanent (fail immediately): Transient Errors (Retried):
  • Connection timeouts or refused connections
  • Network unreachable errors
  • DNS resolution failures
  • HTTP 5xx errors (500, 502, 503, 504)
  • HTTP 429 (Too Many Requests)
  • I/O errors and broken pipes
  • Temporary service unavailability
Permanent Errors (Fail Immediately - No Retry):
  • Context deadline exceeded or cancelled - Retrying won’t help if time limit is reached
  • Authentication failures (401, 403)
  • Authorization denied
  • Configuration errors (invalid auth, invalid config)
  • File or command not found (e.g., “command not found: npx”)
  • Bad request errors (400, 405, 422)
  • Command execution permission denied
  • Invalid credentials

What Operations Are Retried

Bifrost applies retry logic to these critical operations:
  1. Connection Creation - Establishing initial connection to the MCP server (with error classification)
  2. Transport Start - Starting the transport layer (STDIO, HTTP, SSE)
  3. Client Initialization - Initializing the MCP client protocol
  4. Tool Discovery - Retrieving available tools from the server
  5. Automatic Reconnection - When health checks detect disconnection

Reconnection on Health Check Failure

When a client reaches 5 consecutive health check failures:
  1. Client state changes to disconnected
  2. Bifrost automatically attempts reconnection in the background
  3. Reconnection uses the same exponential backoff retry logic
  4. Once reconnected, health checks resume normal operation
  5. Tools become available again without manual intervention
This automatic reconnection happens asynchronously and doesn’t block other operations.

Manual Reconnection

You can also trigger manual reconnection at any time:
curl -X POST http://localhost:8080/api/mcp/client/{id}/reconnect
Manual reconnection also uses the retry logic for robustness.

Benefits

  • Handles transient failures: Brief network hiccups won’t cause tool unavailability
  • Prevents server overload: Exponential backoff prevents hammering servers
  • Automatic recovery: Disconnected clients reconnect automatically
  • Production-ready: No manual intervention needed for temporary issues
  • Transparent logging: Detailed retry attempts logged for debugging

Naming Conventions

MCP client names have specific requirements:
  • Must contain only ASCII characters
  • Cannot contain hyphens (-) or spaces
  • Cannot start with a number
  • Must be unique across all clients
Valid names: filesystem, web_search, myAPI, tool123 Invalid names: my-tools, web search, 123tools, datos-api

Next Steps