Skip to content

Configuration

OpalServe v3 supports three operating modes: local (single developer), team-server (centralized hub), and team-client (connect to a hub). This page covers every configuration option.

Config File Locations

OpalServe uses cosmiconfig and searches for config in this order:

  1. opalserve.config.ts / .js / .mjs / .cjs
  2. opalserve.config.json
  3. .opalserverc / .opalserverc.json / .opalserverc.yaml
  4. opalserve key in package.json
  5. ~/.opalserve/config.json (global fallback)

The opalserve init wizard writes to option 5 by default. You can override the config path with --config:

bash
opalserve start --config ./my-config.json

Operating Modes

Local Mode (Default)

For individual developers. Runs everything on your machine. No auth required.

json
{
  "mode": "local",
  "servers": [],
  "gateway": { "port": 3456 },
  "storage": { "path": "~/.opalserve/data.db" }
}

Team Server Mode

For the team admin. Runs a centralized OpalServe instance that team members connect to. Requires auth configuration.

json
{
  "mode": "team-server",
  "servers": [
    {
      "name": "github",
      "transport": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-github"],
        "env": { "GITHUB_TOKEN": "ghp_xxx" }
      }
    }
  ],
  "gateway": {
    "port": 3456,
    "host": "0.0.0.0"
  },
  "auth": {
    "enabled": true,
    "jwtSecret": "your-secure-random-secret",
    "apiKeys": true,
    "sessionTtl": 86400
  },
  "team": {
    "name": "Acme Engineering",
    "maxUsers": 50,
    "allowSignup": false,
    "defaultRole": "developer"
  },
  "storage": {
    "path": "/var/lib/opalserve/data.db"
  },
  "rateLimiting": {
    "enabled": true,
    "windowMs": 60000,
    "maxRequests": 100
  },
  "logging": {
    "level": "info"
  }
}

Team Client Mode

For developers connecting to a team server. Minimal config — just the server URL and credentials.

json
{
  "mode": "team-client",
  "teamServer": {
    "url": "https://opalserve.internal.company.com",
    "apiKey": "osk_abc123..."
  },
  "gateway": {
    "port": 3456
  }
}

Login instead of manual config

You do not need to write the team-client config by hand. Use the CLI:

bash
opalserve login https://opalserve.internal.company.com

This stores your credentials securely and sets the mode to team-client automatically.

Full Config Reference

Top-Level Fields

FieldTypeDefaultDescription
modestring"local"Operating mode: local, team-server, or team-client
serversServer[][]MCP servers to connect to (local and team-server modes)
gatewayobject{}HTTP API and gateway settings
authobject{}Authentication configuration (team-server mode)
teamobject{}Team settings (team-server mode)
teamServerobject{}Remote server connection (team-client mode)
storageobject{}Database storage settings
rateLimitingobject{}Rate limiting configuration
loggingobject{}Log level and output
knowledgeBaseobject{}Knowledge base settings

Server Configuration

Each entry in the servers array defines an MCP server to connect to.

FieldTypeDefaultDescription
namestringrequiredUnique name (lowercase, hyphens allowed)
transportTransportrequiredTransport configuration (see below)
enabledbooleantrueWhether to connect on startup
tagsstring[][]Tags for organization and filtering
autoConnectbooleantrueAuto-connect when opalserve start runs
descriptionstring""Human-readable description (shown in dashboard)

Transport Types

stdio — Launch a local process:

json
{
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"],
  "env": {},
  "cwd": "/optional/working/dir"
}

sse — Connect to a remote SSE endpoint:

json
{
  "type": "sse",
  "url": "https://my-mcp-server.example.com/sse",
  "headers": { "Authorization": "Bearer token" }
}

streamable-http — Connect to a Streamable HTTP endpoint:

json
{
  "type": "streamable-http",
  "url": "https://my-mcp-server.example.com/mcp",
  "headers": {}
}

Gateway Configuration

FieldTypeDefaultDescription
portnumber3456HTTP API port
hoststring127.0.0.1Bind address. Use 0.0.0.0 for team-server mode
corsstring[]["*"]Allowed CORS origins
trustProxybooleanfalseTrust reverse proxy headers (X-Forwarded-For)

Auth Configuration

FieldTypeDefaultDescription
enabledbooleanfalseEnable JWT authentication
jwtSecretstringSecret for signing JWT tokens. Required if auth is enabled
apiKeysbooleantrueAllow API key authentication
sessionTtlnumber86400Session lifetime in seconds (default: 24 hours)
bcryptRoundsnumber12Bcrypt cost factor for password hashing

Keep your JWT secret secure

The jwtSecret should be a cryptographically random string of at least 32 characters. Never commit it to version control. Use environment variables instead:

bash
export OPALSERVE_JWT_SECRET=$(openssl rand -hex 32)

Team Configuration

FieldTypeDefaultDescription
namestring""Team or organization name
maxUsersnumber100Maximum number of user accounts
allowSignupbooleanfalseAllow self-registration (default: invite only)
defaultRolestring"developer"Default role for new users: admin, developer, viewer
inviteExpirynumber604800Invite link expiry in seconds (default: 7 days)

Team Server Connection (Client Mode)

FieldTypeDefaultDescription
urlstringrequiredURL of the team server
apiKeystringAPI key for authentication
syncIntervalnumber300How often to sync server list, in seconds
fallbackToLocalbooleantrueUse local servers if team server is unreachable

Storage Configuration

FieldTypeDefaultDescription
pathstring~/.opalserve/data.dbSQLite database path
walModebooleantrueEnable WAL mode for better concurrent performance

Rate Limiting

FieldTypeDefaultDescription
enabledbooleanfalseEnable rate limiting
windowMsnumber60000Time window in milliseconds
maxRequestsnumber100Max requests per window per user
toolCallLimitnumber50Max tool calls per window per user

Knowledge Base

FieldTypeDefaultDescription
enabledbooleantrueEnable the knowledge base
maxDocumentSizenumber1048576Max document size in bytes (default: 1MB)
maxDocumentsnumber1000Max documents in the knowledge base
chunkSizenumber512Token chunk size for indexing
chunkOverlapnumber64Overlap between chunks

Logging

FieldTypeDefaultDescription
levelstring"info"Log level: silent, error, warn, info, debug, trace

Environment Variable Overrides

Any config field can be overridden with an environment variable. These take priority over the config file.

VariableOverridesExample
OPALSERVE_MODEmodeteam-server
OPALSERVE_PORTgateway.port8080
OPALSERVE_HOSTgateway.host0.0.0.0
OPALSERVE_JWT_SECRETauth.jwtSecretyour-secret
OPALSERVE_LOG_LEVELlogging.leveldebug
OPALSERVE_DB_PATHstorage.path/var/lib/opalserve/data.db
OPALSERVE_TEAM_SERVER_URLteamServer.urlhttps://opalserve.company.com
GITHUB_TOKENGitHub server envghp_xxx
SLACK_BOT_TOKENSlack server envxoxb-xxx

Example: Full Team Server Config

json
{
  "mode": "team-server",
  "servers": [
    {
      "name": "github",
      "description": "GitHub repositories and issues",
      "transport": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-github"],
        "env": { "GITHUB_TOKEN": "ghp_xxx" }
      },
      "tags": ["code", "github"]
    },
    {
      "name": "slack",
      "description": "Slack workspace",
      "transport": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-slack"],
        "env": { "SLACK_BOT_TOKEN": "xoxb-xxx" }
      },
      "tags": ["communication"]
    },
    {
      "name": "docs",
      "description": "Engineering documentation",
      "transport": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/opt/docs"]
      },
      "tags": ["docs"]
    }
  ],
  "gateway": {
    "port": 3456,
    "host": "0.0.0.0",
    "cors": ["https://dashboard.company.com"],
    "trustProxy": true
  },
  "auth": {
    "enabled": true,
    "jwtSecret": "use-env-variable-instead",
    "apiKeys": true,
    "sessionTtl": 86400
  },
  "team": {
    "name": "Acme Engineering",
    "maxUsers": 50,
    "allowSignup": false,
    "defaultRole": "developer"
  },
  "storage": {
    "path": "/var/lib/opalserve/data.db"
  },
  "rateLimiting": {
    "enabled": true,
    "windowMs": 60000,
    "maxRequests": 100,
    "toolCallLimit": 50
  },
  "knowledgeBase": {
    "enabled": true,
    "maxDocuments": 500,
    "chunkSize": 512
  },
  "logging": {
    "level": "info"
  }
}

Released under the MIT License.