CyborgShell includes a lightweight CORS proxy (index.php) that enables browser-based applications to make API calls to services that don't support direct CORS requests. The proxy is optional - some AI providers work without it.
{
  // Claude Configuration
  "claude-proxy": "proxy/index.php?url=",
  "claude-jsonbearer": "Y",
  
  // OpenAI Configuration
  "openai-proxy": "proxy/index.php?url=",
  "openai-jsonbearer": "Y",
  
  // Gemini (no proxy needed)
  "gemini-jsonbearer": "N",
  
  // Ollama (no proxy needed)
  "ollama-jsonbearer": "N"
}| Setting | Values | Description | 
|---|---|---|
| {provider}-proxy | proxy/index.php?url=or empty | Relative path to proxy script. Leave empty for direct calls | 
| {provider}-jsonbearer | YorN | Y= Send API key in JSON body (required when using proxy)N= Send API key in headers or URL | 
The default configuration uses the public CORS proxy at cyborgshell.com/proxy/:
{
  "claude-proxy": "proxy/index.php?url=",
  "openai-proxy": "proxy/index.php?url="
}Note: When using the public proxy, your API keys pass through the proxy server. While the proxy is open source and auditable, for maximum security, self-host the proxy.
For complete privacy and control, host your own proxy:
Copy index.php from the CyborgShell repository to your web server:
# Example for Apache/PHP server
cp index.php /var/www/html/cors-proxy/Point to your proxy URL:
{
  "claude-proxy": "https://your-domain.com/cors-proxy/index.php?url=",
  "openai-proxy": "https://your-domain.com/cors-proxy/index.php?url="
}// Whitelist your domains (source)
$arrSourceWhitelist = array('yourdomain.com', 'localhost');
// Optional: Whitelist AI provider destinations
$arrDestinationWhitelist = array(
    'api.anthropic.com', 
    'api.openai.com'
);
// Enable logging for debugging
DEFINE('LOG_OUTPUT', 'TRUE');
DEFINE('FILE_ERRORLOG', '/var/log/cors-proxy.log');If you only use Gemini and/or Ollama, disable all proxies:
{
  "gemini-apikey": "your-key-here",
  "gemini-jsonbearer": "N",
  
  "ollama-endpoint": "http://localhost:11434/v1/chat/completions",
  "ollama-jsonbearer": "N"
}Authorization: Bearer headerExample Flow:
Browser → {request + api_key in JSON} → Proxy 
       → {request with Authorization header} → AI ProviderThe proxy includes several security features (edit in index.php):
// Security Settings
DEFINE('MAXFILESIZE', 1024);        // Max response size in KB
DEFINE('MAXTIMEOUT', 120);          // Request timeout in seconds
DEFINE('SSL_VERIFYPEER', false);    // SSL verification (set true for production)
DEFINE('LOG_OUTPUT', 'FALSE');      // Enable request logging
// Source Whitelist (who can use the proxy)
$arrSourceWhitelist = array(
    'cyborgshell.com', 
    'yourdomain.com', 
    'localhost'
);
// Destination Whitelist (which APIs can be called)
$arrDestinationWhitelist = array(
    'api.anthropic.com',
    'api.openai.com'
);{
  "claude-apikey": "sk-ant-api03-...",
  "claude-proxy": "https://proxy.yourcompany.com/index.php?url=",
  "claude-jsonbearer": "Y",
  
  "openai-apikey": "sk-proj-...",
  "openai-proxy": "https://proxy.yourcompany.com/index.php?url=",
  "openai-jsonbearer": "Y"
}{
  "claude-apikey": "sk-ant-api03-...",
  "claude-proxy": "proxy/index.php?url=",
  "claude-jsonbearer": "Y",
  
  "gemini-apikey": "AIzaSy...",
  "gemini-jsonbearer": "N"  // Direct, no proxy
}{
  "ollama-endpoint": "http://localhost:11434/v1/chat/completions",
  "ollama-jsonbearer": "N",
  "ollama-model": "llama3.2:latest"
}| Problem | Solution | 
|---|---|
| CORS errors with Claude or OpenAI | Verify proxy URL is correct and server is running | 
| 403 Permission Denied | Add your domain to $arrSourceWhitelistinindex.php | 
| 403 Host not allowed | Verify AI provider domain is in $arrDestinationWhitelist(or leave array empty to allow all) | 
DEFINE('LOG_OUTPUT', 'TRUE');
DEFINE('FILE_ERRORLOG', '/var/log/cors-proxy.log');Check logs for request details:
tail -f /var/log/cors-proxy.logDEFINE('SSL_VERIFYPEER', true);For zero external data transfer:
{
  "ollama-endpoint": "http://internal-server:11434/v1/chat/completions",
  "ollama-jsonbearer": "N"
}