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:
Type Description Best For Auth Support STDIO Spawns a subprocess and communicates via stdin/stdout Local tools, CLI utilities, scripts None HTTP Sends requests to an HTTP endpoint Remote APIs, microservices, cloud functions Headers, OAuth 2.0 SSE Server-Sent Events for persistent connections Real-time data, streaming tools Headers, 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
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.
{
"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
Navigate to MCP Gateway in the sidebar - you’ll see a table of all registered servers
Click New MCP Server button to open the creation form
Fill in the connection details:
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
Click Create to connect
Once connected, click on any client row to open the configuration sheet: 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
Add STDIO Client curl -X POST http://localhost:8080/api/mcp/client \
-H "Content-Type: application/json" \
-d '{
"name": "filesystem",
"connection_type": "stdio",
"stdio_config": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem"],
"envs": ["HOME", "PATH"]
},
"tools_to_execute": ["*"]
}'
Add HTTP Client curl -X POST http://localhost:8080/api/mcp/client \
-H "Content-Type: application/json" \
-d '{
"name": "web_search",
"connection_type": "http",
"connection_string": "http://localhost:3001/mcp",
"tools_to_execute": ["*"]
}'
Add SSE Client curl -X POST http://localhost:8080/api/mcp/client \
-H "Content-Type: application/json" \
-d '{
"name": "realtime_data",
"connection_type": "sse",
"connection_string": "https://api.example.com/mcp/sse",
"tools_to_execute": ["*"]
}'
List All Clients curl http://localhost:8080/api/mcp/clients
Response: [
{
"config" : {
"id" : "abc123" ,
"name" : "filesystem" ,
"connection_type" : "stdio" ,
"stdio_config" : {
"command" : "npx" ,
"args" : [ "-y" , "@anthropic/mcp-filesystem" ]
}
},
"tools" : [
{ "name" : "read_file" , "description" : "Read contents of a file" },
{ "name" : "write_file" , "description" : "Write contents to a file" },
{ "name" : "list_directory" , "description" : "List directory contents" }
],
"state" : "connected"
}
]
Configure MCP clients in your config.json: {
"mcp" : {
"client_configs" : [
{
"name" : "filesystem" ,
"connection_type" : "stdio" ,
"is_ping_available" : true ,
"stdio_config" : {
"command" : "npx" ,
"args" : [ "-y" , "@anthropic/mcp-filesystem" ],
"envs" : [ "HOME" , "PATH" ]
},
"tools_to_execute" : [ "*" ]
},
{
"name" : "web_search" ,
"connection_type" : "http" ,
"connection_string" : "env.WEB_SEARCH_MCP_URL" ,
"is_ping_available" : false ,
"tools_to_execute" : [ "search" , "fetch_url" ]
},
{
"name" : "database" ,
"connection_type" : "sse" ,
"connection_string" : "https://db-mcp.example.com/sse" ,
"is_ping_available" : true ,
"tools_to_execute" : []
}
]
}
}
Use env.VARIABLE_NAME syntax to reference environment variables for sensitive values like URLs with API keys.
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 )
}
}
The ToolsToExecute field controls which tools from the client are available:
Value Behavior ["*"]All tools from this client are included [] or nilNo tools included (deny-by-default) ["tool1", "tool2"]Only specified tools are included
The ToolsToAutoExecute field controls which tools can be automatically executed in Agent Mode :
Value Behavior ["*"]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
State Description 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}
// Get all connected clients
clients , err := client . GetMCPClients ()
for _ , mcpClient := range clients {
fmt . Printf ( "Client: %s , State: %s , Tools: %d \n " ,
mcpClient . Config . Name ,
mcpClient . State ,
len ( mcpClient . Tools ))
}
// Reconnect a disconnected client
err = client . ReconnectMCPClient ( "filesystem" )
// Add new client at runtime
err = client . AddMCPClient ( schemas . MCPClientConfig {
Name : "new_client" ,
ConnectionType : schemas . MCPConnectionTypeHTTP ,
ConnectionString : bifrost . Ptr ( "http://localhost:3002/mcp" ),
ToolsToExecute : [] string { "*" },
})
// Remove a client
err = client . RemoveMCPClient ( "old_client" )
// Edit client tools
err = client . EditMCPClientTools ( "filesystem" , [] string { "read_file" , "list_directory" })
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:
Method When to Use Overhead Fallback Ping (default)Server supports MCP ping protocol Minimal Best for most servers ListTools Server doesn’t support ping, or you need heavier checks Higher More resource-intensive
Configuring Health Check Method
You can toggle the is_ping_available setting for each client:
Via Web UI
Navigate to MCP Gateway and select a server
In the configuration panel, toggle “Ping Available for Health Check”
Enable: Uses lightweight ping for health checks
Disable: Uses listTools method for health checks instead
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:
State changes to disconnected
Tools from that client become unavailable
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:
Parameter Value Description Max Retries (DefaultRetryConfig.MaxRetries)5 Retries after the initial attempt (6 attempts total) Initial Backoff (DefaultRetryConfig.InitialBackoff)1 second Starting backoff duration before doubling Max Backoff (DefaultRetryConfig.MaxBackoff)30 seconds Maximum wait time between retries Backoff Multiplier 2x Exponential 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:
Connection Creation - Establishing initial connection to the MCP server (with error classification)
Transport Start - Starting the transport layer (STDIO, HTTP, SSE)
Client Initialization - Initializing the MCP client protocol
Tool Discovery - Retrieving available tools from the server
Automatic Reconnection - When health checks detect disconnection
Reconnection on Health Check Failure
When a client reaches 5 consecutive health check failures:
Client state changes to disconnected
Bifrost automatically attempts reconnection in the background
Reconnection uses the same exponential backoff retry logic
Once reconnected, health checks resume normal operation
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. // Reconnect with automatic retry logic
err := client . ReconnectMCPClient ( "filesystem" )
if err != nil {
log . Printf ( "Reconnection failed after retries: %v " , err )
}
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
Tool Execution Learn how to execute tools from connected MCP servers
Agent Mode Enable autonomous tool execution with auto-approval