Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions .github/workflows/configs/withpostgresmcpclientsinconfig/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
{
"$schema": "https://www.getbifrost.ai/schema",
"client": {
"allow_direct_keys": false,
"allowed_origins": [
"*"
],
"disable_content_logging": false,
"drop_excess_requests": false,
"enable_governance": true,
"enable_litellm_fallbacks": false,
"enable_logging": true,
"enforce_governance_header": true,
"initial_pool_size": 300,
"log_retention_days": 365,
"max_request_body_size_mb": 100
},
"config_store": {
"enabled": true,
"type": "postgres",
"config": {
"host": "localhost",
"port": "5432",
"user": "bifrost",
"password": "bifrost_password",
"db_name": "bifrost",
"ssl_mode": "disable"
}
},
"logs_store": {
"enabled": true,
"type": "postgres",
"config": {
"host": "localhost",
"port": "5432",
"user": "bifrost",
"password": "bifrost_password",
"db_name": "bifrost",
"ssl_mode": "disable"
}
},
"mcp": {
"client_configs": [
{
"id": "weather-mcp-server",
"name": "WeatherService",
"connection_type": "http",
"http_url": "http://localhost:8080/mcp",
"is_enabled": true
},
{
"id": "calendar-mcp-server",
"name": "CalendarService",
"connection_type": "http",
"http_url": "http://localhost:8081/mcp",
"is_enabled": true
}
]
},
"governance": {
"auth_config": {
"admin_password": "env.BIFROST_ADMIN_PASSWORD",
"admin_username": "env.BIFROST_ADMIN_USERNAME",
"disable_auth_on_inference": true,
"is_enabled": false
},
"virtual_keys": [
{
"id": "vk-ai-portal-prod",
"is_active": true,
"name": "ai-portal-production-key",
"description": "Virtual key for AI portal with MCP access to weather and calendar services",
"value": "env.BIFROST_VK_AI_PORTAL",
"mcp_configs": [
{
"mcp_client_name": "WeatherService",
"tools_to_execute": [
"*"
]
},
{
"mcp_client_name": "CalendarService",
"tools_to_execute": [
"get_events",
"create_event"
]
}
],
"provider_configs": [
{
"provider": "openai",
"weight": 1.0
}
]
},
{
"id": "vk-internal-tools",
"is_active": true,
"name": "internal-tools-key",
"description": "Virtual key for internal tools with limited MCP access",
"value": "env.BIFROST_VK_INTERNAL",
"mcp_configs": [
{
"mcp_client_name": "WeatherService",
"tools_to_execute": [
"get_current_weather"
]
}
],
"provider_configs": [
{
"provider": "openai",
"weight": 1.0
}
]
}
]
},
"plugins": [
{
"config": {
"is_vk_mandatory": true
},
"enabled": true,
"name": "governance"
}
],
"providers": {
"openai": {
"keys": [
{
"name": "openai-primary",
"value": "env.OPENAI_API_KEY",
"weight": 1
}
]
}
}
}
1 change: 1 addition & 0 deletions .github/workflows/scripts/release-bifrost-http.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ CONFIGS_TO_TEST=(
"withdynamicplugin"
"withobservability"
"withsemanticcache"
"withpostgresmcpclientsinconfig"
)
Comment thread
akshaydeo marked this conversation as resolved.

TEST_BINARY="../tmp/bifrost-http"
Expand Down
139 changes: 139 additions & 0 deletions examples/configs/withpostgresmcpclientsinconfig/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
{
"$schema": "https://www.getbifrost.ai/schema",
"client": {
"allow_direct_keys": false,
"allowed_origins": [
"*"
],
"disable_content_logging": false,
"drop_excess_requests": false,
"enable_governance": true,
"enable_litellm_fallbacks": false,
"enable_logging": true,
"enforce_governance_header": true,
"initial_pool_size": 300,
"log_retention_days": 365,
"max_request_body_size_mb": 100
},
"config_store": {
"enabled": true,
"type": "postgres",
"config": {
"host": "localhost",
"port": "5432",
"user": "bifrost",
"password": "bifrost_password",
"db_name": "bifrost",
"ssl_mode": "disable"
}
},
"logs_store": {
"enabled": true,
"type": "postgres",
"config": {
"host": "localhost",
"port": "5432",
"user": "bifrost",
"password": "bifrost_password",
"db_name": "bifrost",
"ssl_mode": "disable"
}
},
"mcp": {
"client_configs": [
{
"id": "weather-mcp-server",
"name": "WeatherService",
"connection_type": "http",
"http_url": "http://localhost:8080/mcp",
"is_enabled": true
},
{
"id": "calendar-mcp-server",
"name": "CalendarService",
"connection_type": "http",
"http_url": "http://localhost:8081/mcp",
"is_enabled": true
}
]
},
"governance": {
"auth_config": {
"admin_password": "env.BIFROST_ADMIN_PASSWORD",
"admin_username": "env.BIFROST_ADMIN_USERNAME",
"disable_auth_on_inference": true,
"is_enabled": false
},
"virtual_keys": [
{
"id": "vk-ai-portal-prod",
"is_active": true,
"name": "ai-portal-production-key",
"description": "Virtual key for AI portal with MCP access to weather and calendar services",
"value": "env.BIFROST_VK_AI_PORTAL",
"mcp_configs": [
{
"mcp_client_name": "WeatherService",
"tools_to_execute": [
"*"
]
},
{
"mcp_client_name": "CalendarService",
"tools_to_execute": [
"get_events",
"create_event"
]
}
],
"provider_configs": [
{
"provider": "openai",
"weight": 1.0
}
]
},
{
"id": "vk-internal-tools",
"is_active": true,
"name": "internal-tools-key",
"description": "Virtual key for internal tools with limited MCP access",
"value": "env.BIFROST_VK_INTERNAL",
"mcp_configs": [
{
"mcp_client_name": "WeatherService",
"tools_to_execute": [
"get_current_weather"
]
}
],
"provider_configs": [
{
"provider": "openai",
"weight": 1.0
}
]
}
]
},
"plugins": [
{
"config": {
"is_vk_mandatory": true
},
"enabled": true,
"name": "governance"
}
],
"providers": {
"openai": {
"keys": [
{
"name": "openai-primary",
"value": "env.OPENAI_API_KEY",
"weight": 1
}
]
}
}
}
31 changes: 31 additions & 0 deletions framework/configstore/tables/virtualkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,44 @@ type TableVirtualKeyMCPConfig struct {
MCPClientID uint `gorm:"not null;uniqueIndex:idx_vk_mcpclient" json:"mcp_client_id"`
MCPClient TableMCPClient `gorm:"foreignKey:MCPClientID" json:"mcp_client"`
ToolsToExecute []string `gorm:"type:text;serializer:json" json:"tools_to_execute"`

// MCPClientName is used during config file parsing to resolve the MCP client by name.
// This field is not persisted to the database - it's only used to capture
// "mcp_client_name" from config.json and then resolve it to MCPClientID.
MCPClientName string `gorm:"-" json:"-"`
}

// TableName sets the table name for each model
func (TableVirtualKeyMCPConfig) TableName() string {
return "governance_virtual_key_mcp_configs"
}

// UnmarshalJSON custom unmarshaller to handle both "mcp_client_id" (database format)
// and "mcp_client_name" (config file format) for MCP client references.
func (mc *TableVirtualKeyMCPConfig) UnmarshalJSON(data []byte) error {
// Temporary struct to capture all fields including mcp_client_name
type Alias TableVirtualKeyMCPConfig
type TempMCPConfig struct {
Alias
MCPClientName string `json:"mcp_client_name"` // Config file format: MCP client name
}

var temp TempMCPConfig
if err := json.Unmarshal(data, &temp); err != nil {
return err
}

// Copy all standard fields
*mc = TableVirtualKeyMCPConfig(temp.Alias)

// Capture mcp_client_name for later resolution to MCPClientID
if temp.MCPClientName != "" {
mc.MCPClientName = temp.MCPClientName
}

return nil
}

// TableVirtualKey represents a virtual key with budget, rate limits, and team/customer association
type TableVirtualKey struct {
ID string `gorm:"primaryKey;type:varchar(255)" json:"id"`
Expand Down
Loading