Using STRONGLY_SERVICES in Your Code
All connected services are automatically available through the STRONGLY_SERVICES environment variable. This provides a unified interface for accessing databases, AI models, workflows, ML models, MCP servers, and more.
Overview
When you connect services during app deployment, the platform injects a JSON object containing all connection details:
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
Complete Structure
The STRONGLY_SERVICES JSON has the following top-level structure:
{
"version": "1.0.0",
"environment": "production",
"generated_at": "2025-01-15T10:30:00.000Z",
"services": {
"addons": { ... },
"datasources": { ... },
"aigateway": { ... },
"mlmodels": [ ... ],
"workflows": { ... },
"mcpservers": { ... }
},
"circuit_breaker": {
"enabled": true,
"failure_threshold": 5,
"timeout_seconds": 30,
"reset_timeout_seconds": 60
},
"monitoring": {
"metrics_endpoint": "https://app.strongly.ai/api/metrics",
"logs_endpoint": "https://app.strongly.ai/api/logs",
"tracing_endpoint": "https://app.strongly.ai/api/traces"
}
}
Service Categories
Add-ons (Managed Databases)
Platform-managed database instances organized by type. Each type contains an array of service instances.
Structure:
{
"services": {
"addons": {
"mongodb": [
{
"id": "addon-xyz123",
"name": "My MongoDB",
"type": "mongodb",
"category": "add-on",
"status": "active",
"version": "7.0",
"internal": false,
"connection": {
"connection_string": "mongodb://user:pass@addon-xyz123.addons.svc.cluster.local:27017/mydb",
"host": "addon-xyz123.addons.svc.cluster.local",
"port": 27017,
"database": "mydb"
},
"auth": {
"method": "username_password",
"credentials": {
"username": "admin",
"password": "decrypted-password"
}
},
"limits": {
"max_connections": 100,
"storage_gb": 10
},
"metadata": {
"tier": "standard",
"backup_enabled": false,
"region": "us-east-1"
}
}
],
"postgres": [
{
"id": "addon-abc456",
"name": "My PostgreSQL",
"type": "postgres",
"category": "add-on",
"status": "active",
"connection": {
"connection_string": "postgresql://user:pass@addon-abc456.addons.svc.cluster.local:5432/mydb",
"host": "addon-abc456.addons.svc.cluster.local",
"port": 5432,
"database": "mydb"
},
"auth": {
"method": "username_password",
"credentials": {
"username": "admin",
"password": "decrypted-password"
}
}
}
],
"redis": [
{
"id": "addon-red789",
"name": "My Redis",
"type": "redis",
"category": "add-on",
"status": "active",
"connection": {
"host": "addon-red789.addons.svc.cluster.local",
"port": 6379
},
"auth": {
"method": "username_password",
"credentials": {
"username": "default",
"password": "decrypted-password"
}
}
}
]
}
}
}
Supported addon types: mongodb, postgres, redis, rabbitmq, kafka, neo4j, milvus, greenplum, surrealdb
Data Sources (External Connections)
External data connections organized by type. Credentials are decrypted and provided directly.
Structure:
{
"services": {
"datasources": {
"s3": [
{
"id": "ds-s3-001",
"name": "Production Files",
"type": "s3",
"category": "data-source",
"status": "connected",
"connection": {
"bucket": "my-app-files",
"region": "us-east-1"
},
"auth": {
"method": "aws_access_key",
"credentials": {
"access_key_id": "AKIA...",
"secret_access_key": "..."
}
},
"metadata": {
"owner": "user123",
"tags": ["production"]
}
}
],
"mysql": [
{
"id": "ds-mysql-001",
"name": "Analytics DB",
"type": "mysql",
"category": "data-source",
"status": "connected",
"connection": {
"host": "analytics.example.com",
"port": 3306,
"database": "analytics"
},
"auth": {
"method": "username_password",
"credentials": {
"username": "app_user",
"password": "decrypted-password"
}
}
}
],
"snowflake": [
{
"id": "ds-sf-001",
"name": "Data Warehouse",
"type": "snowflake",
"category": "data-source",
"status": "connected",
"connection": {
"account": "xy12345.us-east-1",
"warehouse": "COMPUTE_WH",
"database": "ANALYTICS",
"region": "us-east-1"
},
"auth": {
"method": "username_password",
"credentials": {
"username": "app_user",
"password": "decrypted-password"
}
}
}
]
}
}
}
Supported datasource types: s3, mysql, mariadb, postgres, mongodb, bigquery, snowflake, redshift, dynamodb, elasticsearch, pinecone, gcs, minio, azure-blob, and many more.
AI Gateway
AI model endpoints with provider information and available models.
Structure:
{
"services": {
"aigateway": {
"id": "ai-gateway-001",
"status": "active",
"base_url": "http://ai-gateway.strongly.svc.cluster.local",
"providers": {
"openai": {
"enabled": true,
"base_url": "http://ai-gateway.strongly.svc.cluster.local",
"type": "third-party",
"models": [
{
"id": "model-abc123",
"name": "GPT-4o",
"display_name": "GPT-4o",
"type": "third-party",
"model_type": "multimodal",
"context_window": 128000,
"max_output_tokens": 4096
}
]
},
"self_hosted": {
"enabled": true,
"base_url": "http://llama.strongly.svc.cluster.local",
"type": "self-hosted",
"models": [
{
"id": "model-xyz789",
"name": "Llama 3.1 70B",
"display_name": "Llama 3.1 70B",
"type": "self-hosted",
"model_type": "chat",
"endpoint": "http://llama.strongly.svc.cluster.local"
}
]
}
},
"available_models": [
{
"_id": "model-abc123",
"vendor_model_id": "gpt-4o",
"vendor": "OpenAI",
"display_name": "GPT-4o",
"provider": "OpenAI",
"type": "third-party",
"model_type": "multimodal",
"context_window": 128000,
"max_output_tokens": 4096,
"capabilities": ["streaming"],
"status": "active"
},
{
"_id": "model-xyz789",
"vendor_model_id": "llama-3.1-70b",
"vendor": "Meta",
"display_name": "Llama 3.1 70B",
"provider": "Self-Hosted",
"type": "self-hosted",
"model_type": "chat",
"endpoint": "http://llama.strongly.svc.cluster.local",
"deployment_id": "deploy-xyz",
"instance_type": "g5.2xlarge"
}
],
"retry_policy": {
"max_retries": 3,
"backoff_multiplier": 2,
"initial_delay_ms": 1000
}
}
}
}
ML Models (Model Registry)
Traditional and AutoML models from the model registry.
Structure:
{
"services": {
"mlmodels": [
{
"id": "ml-model-001",
"name": "sales-predictor",
"display_name": "Sales Predictor",
"type": "traditional",
"framework": "XGBoost",
"problem_type": "Regression",
"status": "deployed",
"version": "1.0.0",
"accuracy": 0.95,
"endpoint": "http://ml-model-001.models.svc.cluster.local",
"deployment_id": "deploy-ml-001",
"instance_type": "m5.large",
"inference_time_ms": 15,
"size_mb": 120
}
]
}
}
Workflows
Workflow engine configuration and available REST API workflows.
Structure:
{
"services": {
"workflows": {
"engine": {
"id": "workflow-controller-001",
"status": "active",
"version": "2.0.0",
"api_endpoint": "http://workflow-controller:80/api/v1",
"webhook_endpoint": "http://workflow-controller:80/api/webhooks"
},
"available_workflows": [
{
"id": "wf-data-processor",
"name": "Data Processor",
"description": "Processes incoming data files",
"trigger_type": "rest_api",
"input_schema": {
"file_url": {
"type": "string",
"required": true,
"description": "URL of the file to process"
}
},
"endpoints": {
"proxy_url": "https://app.strongly.ai/api/workflows/wf-data-processor/execute",
"method": "POST"
},
"deployment": {
"pod_name": "wf-data-processor-abc123",
"environment": "production",
"namespace": "user-workflows"
}
}
],
"auth": {
"method": "api_key"
},
"limits": {
"max_concurrent_executions": 10,
"max_execution_time_seconds": 3600
}
}
}
}
MCP Servers
Model Context Protocol servers available to the application.
Structure:
{
"services": {
"mcpservers": {
"id": "mcp-servers-001",
"status": "active",
"available_servers": [
{
"id": "mcp-001",
"name": "Data Tools MCP",
"display_name": "Data Tools MCP",
"description": "MCP server providing data processing tools",
"endpoint": "http://mcp-001.apps.svc.cluster.local:8080",
"type": "mcp_server",
"status": "active",
"version": "1.0.0",
"capabilities": ["tools", "prompts"],
"configuration": {}
}
]
}
}
}
Usage Examples
Node.js / Express
MongoDB Add-on
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const { MongoClient } = require('mongodb');
// Get first MongoDB addon
const mongoAddons = services.services?.addons?.mongodb || [];
if (mongoAddons.length === 0) {
throw new Error('No MongoDB addon configured');
}
const mongoConfig = mongoAddons[0];
// Connect using connection string
const client = await MongoClient.connect(
mongoConfig.connection.connection_string
);
const db = client.db(mongoConfig.connection.database);
// Use the database
const users = await db.collection('users').find({ active: true }).toArray();
PostgreSQL Data Source
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const { Pool } = require('pg');
// Get first PostgreSQL datasource
const pgSources = services.services?.datasources?.postgres || [];
if (pgSources.length === 0) {
throw new Error('No PostgreSQL datasource configured');
}
const pgConfig = pgSources[0];
// Connect using connection details
const pool = new Pool({
host: pgConfig.connection.host,
port: pgConfig.connection.port,
database: pgConfig.connection.database,
user: pgConfig.auth?.credentials?.username,
password: pgConfig.auth?.credentials?.password,
max: 20
});
// Query data
const result = await pool.query('SELECT * FROM users WHERE active = $1', [true]);
AI Model (via AI Gateway)
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
// Get AI Gateway config
const aiGateway = services.services?.aigateway;
if (!aiGateway) {
throw new Error('No AI Gateway configured');
}
// Get the first available model
const models = aiGateway.available_models || [];
const model = models[0];
// Call via the AI Gateway base URL (OpenAI-compatible API)
const response = await fetch(`${aiGateway.base_url}/v1/chat/completions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Model-Id': model._id // Use Strongly model ID
},
body: JSON.stringify({
model: model.vendor_model_id, // e.g., 'gpt-4o'
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
})
});
const data = await response.json();
console.log(data.choices[0].message.content);
Workflow Trigger
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
// Get available workflows
const workflows = services.services?.workflows?.available_workflows || [];
const workflow = workflows.find(w => w.name === 'Data Processor');
if (!workflow) {
throw new Error('Workflow not found');
}
// Trigger workflow via proxy URL
const result = await fetch(workflow.endpoints.proxy_url, {
method: workflow.endpoints.method || 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
file_url: 'https://example.com/data.csv',
timestamp: new Date().toISOString()
})
});
const response = await result.json();
console.log('Workflow result:', response);
S3 Data Source
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const { S3Client, ListObjectsV2Command } = require('@aws-sdk/client-s3');
// Get first S3 datasource
const s3Sources = services.services?.datasources?.s3 || [];
if (s3Sources.length === 0) {
throw new Error('No S3 datasource configured');
}
const s3Config = s3Sources[0];
// Create S3 client
const s3Client = new S3Client({
region: s3Config.connection.region || 'us-east-1',
credentials: {
accessKeyId: s3Config.auth.credentials.access_key_id,
secretAccessKey: s3Config.auth.credentials.secret_access_key
}
});
// List objects
const response = await s3Client.send(new ListObjectsV2Command({
Bucket: s3Config.connection.bucket
}));
for (const obj of response.Contents || []) {
console.log(obj.Key);
}
Python / Flask
MongoDB Add-on
import os
import json
from pymongo import MongoClient
# Parse STRONGLY_SERVICES
services = json.loads(os.environ.get('STRONGLY_SERVICES', '{}'))
# Get first MongoDB addon
mongo_addons = services.get('services', {}).get('addons', {}).get('mongodb', [])
if not mongo_addons:
raise ValueError('No MongoDB addon configured')
mongo_config = mongo_addons[0]
# Connect using connection string
client = MongoClient(mongo_config['connection']['connection_string'])
db = client[mongo_config['connection']['database']]
# Use the database
users = list(db.users.find({'active': True}))
AI Model (via AI Gateway)
import os
import json
import requests
# Parse STRONGLY_SERVICES
services = json.loads(os.environ.get('STRONGLY_SERVICES', '{}'))
# Get AI Gateway config
ai_gateway = services.get('services', {}).get('aigateway', {})
if not ai_gateway:
raise ValueError('No AI Gateway configured')
# Get the first available model
models = ai_gateway.get('available_models', [])
model = models[0]
# Call via AI Gateway (OpenAI-compatible API)
response = requests.post(
f"{ai_gateway['base_url']}/v1/chat/completions",
headers={
'Content-Type': 'application/json',
'X-Model-Id': model['_id']
},
json={
'model': model['vendor_model_id'],
'max_tokens': 1024,
'messages': [
{'role': 'user', 'content': 'Hello, Claude!'}
]
}
)
data = response.json()
print(data['choices'][0]['message']['content'])
S3 Data Source
import os
import json
import boto3
# Parse STRONGLY_SERVICES
services = json.loads(os.environ.get('STRONGLY_SERVICES', '{}'))
# Get first S3 datasource
s3_sources = services.get('services', {}).get('datasources', {}).get('s3', [])
if not s3_sources:
raise ValueError('No S3 datasource configured')
s3_config = s3_sources[0]
# Create S3 client
s3_client = boto3.client(
's3',
region_name=s3_config['connection'].get('region', 'us-east-1'),
aws_access_key_id=s3_config['auth']['credentials']['access_key_id'],
aws_secret_access_key=s3_config['auth']['credentials']['secret_access_key']
)
# List objects
response = s3_client.list_objects_v2(Bucket=s3_config['connection']['bucket'])
for obj in response.get('Contents', []):
print(obj['Key'])
ML Model Inference
import os
import json
import requests
# Parse STRONGLY_SERVICES
services = json.loads(os.environ.get('STRONGLY_SERVICES', '{}'))
# Get ML models
ml_models = services.get('services', {}).get('mlmodels', [])
model = next((m for m in ml_models if m['name'] == 'sales-predictor'), None)
if model and model.get('endpoint'):
response = requests.post(
f"{model['endpoint']}/predict",
json={'features': [100, 200, 300]}
)
prediction = response.json()
print(f"Prediction: {prediction}")
React (Frontend)
For React apps, STRONGLY_SERVICES should be accessed via backend API, not directly in frontend code. However, you can inject specific values at build time:
// Backend API endpoint
const API_URL = process.env.REACT_APP_API_URL;
// Call backend which has access to STRONGLY_SERVICES
async function fetchData() {
const response = await fetch(`${API_URL}/api/data`);
return response.json();
}
Helper Functions
Service Lookup Helper
// services.js
class ServicesHelper {
constructor() {
this.data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
this.services = this.data.services || {};
}
// Get all addons of a specific type
getAddonsByType(type) {
return this.services.addons?.[type] || [];
}
// Get first addon of a specific type
getFirstAddon(type) {
const addons = this.getAddonsByType(type);
return addons.length > 0 ? addons[0] : null;
}
// Get all datasources of a specific type
getDataSourcesByType(type) {
return this.services.datasources?.[type] || [];
}
// Get AI Gateway config
getAIGateway() {
return this.services.aigateway || null;
}
// Get available AI models
getAvailableModels() {
return this.services.aigateway?.available_models || [];
}
// Get ML models
getMLModels() {
return this.services.mlmodels || [];
}
// Get available workflows
getWorkflows() {
return this.services.workflows?.available_workflows || [];
}
// Get MCP servers
getMCPServers() {
return this.services.mcpservers?.available_servers || [];
}
}
module.exports = new ServicesHelper();
Usage:
const services = require('./services');
// Get first MongoDB addon
const mongo = services.getFirstAddon('mongodb');
if (mongo) {
console.log('MongoDB connection:', mongo.connection.connection_string);
}
// Get all AI models
const models = services.getAvailableModels();
console.log(`${models.length} AI models available`);
Error Handling
Always handle missing or invalid service configurations:
const data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const services = data.services || {};
function getRequiredAddon(type) {
const addons = services.addons?.[type] || [];
if (addons.length === 0) {
throw new Error(`No ${type} addon found in STRONGLY_SERVICES`);
}
const addon = addons[0];
if (!addon.connection) {
throw new Error(`${type} addon missing connection details`);
}
return addon;
}
// Usage with error handling
try {
const mongoAddon = getRequiredAddon('mongodb');
const client = await MongoClient.connect(
mongoAddon.connection.connection_string
);
} catch (error) {
console.error('Failed to connect to addon:', error.message);
// Fallback or retry logic
}
Debugging
Log Service Configuration
const data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const services = data.services || {};
// Log available services (NEVER log in production - contains secrets!)
if (process.env.NODE_ENV === 'development') {
console.log('Version:', data.version);
console.log('Environment:', data.environment);
console.log('Addon types:', Object.keys(services.addons || {}));
console.log('Datasource types:', Object.keys(services.datasources || {}));
console.log('AI models:', (services.aigateway?.available_models || []).length);
console.log('ML models:', (services.mlmodels || []).length);
console.log('Workflows:', (services.workflows?.available_workflows || []).length);
console.log('MCP servers:', (services.mcpservers?.available_servers || []).length);
}
Validate Services on Startup
const data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const services = data.services || {};
function validateServices() {
const issues = [];
// Check for required addons
if (!services.addons?.mongodb?.length) {
issues.push('No MongoDB addon configured');
}
// Check for AI Gateway
if (!services.aigateway?.base_url) {
issues.push('No AI Gateway configured');
}
if (issues.length > 0) {
console.warn('Service validation warnings:', issues);
}
}
// Run on startup
validateServices();
Best Practices
- Parse Once: Parse
STRONGLY_SERVICESonce at startup, not on every request - Use Connection Pools: Reuse database connections across requests
- Handle Missing Services: Always check if services exist before using them
- Never Log Secrets: Don't log
STRONGLY_SERVICESin production - it contains decrypted credentials - Validate on Startup: Check required services are available at app start
- Use Helpers: Create helper functions for common service access patterns
- Access by Type: Services are organized by type (e.g.,
addons.mongodb,datasources.s3) - iterate arrays to find what you need