> ## Documentation Index
> Fetch the complete documentation index at: https://ibm-d95bab6e.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration Reference

> Complete guide to configuring the IBM i MCP Server with environment variables, authentication modes, and deployment options.

The IBM i MCP Server is configured through environment variables that control transport, authentication, logging, and IBM i connection settings. This guide covers all configuration options with examples and best practices.

<Warning>
  Always use a `.env` file for local development and secure environment variable management in production. Never commit sensitive credentials to version control.
</Warning>

***

## Loading Your Configuration

Before starting the server, set the `MCP_SERVER_CONFIG` environment variable to point to your configuration file:

<Tabs>
  <Tab title="NPM Package">
    ```bash theme={null}
    # Point to your .env file
    export MCP_SERVER_CONFIG=.env

    # Start the server - it will automatically load the config
    npx -y @ibm/ibmi-mcp-server@latest --transport http
    ```

    The server loads the file specified by `MCP_SERVER_CONFIG` on startup.
  </Tab>

  <Tab title="Build from Source">
    ```bash theme={null}
    # Point to your .env file (from repository root)
    export MCP_SERVER_CONFIG=.env

    # Or use relative path from server directory
    export MCP_SERVER_CONFIG=../.env

    # Start the server
    cd packages/server
    npm run start:http
    ```
  </Tab>
</Tabs>

<Note>
  **How it works:** The `MCP_SERVER_CONFIG` environment variable tells the server where to find your configuration file. Without it, you'd need to pass each variable individually as environment variables. CLI arguments (like `--transport http`) override values in the config file.
</Note>

***

## Minimal Working Configuration

**Start here** if you're setting up for the first time. This minimal configuration is sufficient to get the server running:

```bash theme={null}
# Required: IBM i Connection
DB2i_HOST=your-ibmi-system.com
DB2i_USER=your-username
DB2i_PASS=your-password
DB2i_PORT=8076

# Default SQL tools
TOOLS_YAML_PATH=tools

# Recommended: Basic Server Settings
MCP_TRANSPORT_TYPE=http
MCP_HTTP_PORT=3010
MCP_LOG_LEVEL=info
```

<Accordion title="What do these variables do?">
  | Variable             | Purpose                             | When to Change                         |
  | -------------------- | ----------------------------------- | -------------------------------------- |
  | `DB2i_HOST`          | IBM i hostname where Mapepire runs  | Always set to your IBM i system        |
  | `DB2i_USER`          | IBM i user profile                  | Set to your credentials                |
  | `DB2i_PASS`          | IBM i password                      | Set to your credentials                |
  | `DB2i_PORT`          | Mapepire daemon port                | Only if you changed Mapepire's default |
  | `TOOLS_YAML_PATH`    | Location of SQL tool definitions    | Change if using custom tools           |
  | `MCP_TRANSPORT_TYPE` | How clients connect (http or stdio) | Use `http` for most cases              |
  | `MCP_HTTP_PORT`      | Port for HTTP server                | Change if 3010 is in use               |
  | `MCP_LOG_LEVEL`      | Logging detail                      | Use `debug` for troubleshooting        |
</Accordion>

<Info>
  **What's next?** This minimal config gets you started. Add [authentication](#authentication-configuration), [observability](#observability--monitoring), and [SQL tools configuration](#sql-tools-configuration) as your needs grow.
</Info>

***

## Quick Setup

Create your configuration file from the template:

```bash theme={null}
cp .env.example .env
```

Then edit `.env` with your IBM i connection details using the minimal configuration above.

<Tip>
  For a step-by-step walkthrough, see the [Quick Start Guide](/quickstart). For production deployment, refer to the [Production Deployment](/deployment/production) guide.
</Tip>

***

## Core Server Configuration

Below is the reference for core server configuration options. Each section includes detailed explanations, examples, and guidance on when to use specific settings.

***

### Server Transport

**How clients connect to your MCP server.** The transport type determines whether clients connect via standard input/output (stdio) for local processes or HTTP for remote/web-based connections. Most production deployments use HTTP transport for flexibility and multi-client support.

| Variable              | Description                            | Default     | Example                                   |
| --------------------- | -------------------------------------- | ----------- | ----------------------------------------- |
| `MCP_TRANSPORT_TYPE`  | Server transport mode                  | `stdio`     | `http`                                    |
| `MCP_HTTP_PORT`       | HTTP server port                       | `3010`      | `3010`                                    |
| `MCP_HTTP_HOST`       | HTTP server host                       | `127.0.0.1` | `0.0.0.0`                                 |
| `MCP_ALLOWED_ORIGINS` | CORS allowed origins (comma-separated) | (none)      | `http://localhost:3000,https://myapp.com` |

<Tabs>
  <Tab title="HTTP Transport (Recommended)">
    ```bash theme={null}
    MCP_TRANSPORT_TYPE=http
    MCP_HTTP_PORT=3010
    MCP_HTTP_HOST=127.0.0.1
    MCP_ALLOWED_ORIGINS=http://localhost:3000
    ```

    **Use for**: Web applications, REST APIs, development with browser-based tools
  </Tab>

  <Tab title="Stdio Transport">
    ```bash theme={null}
    MCP_TRANSPORT_TYPE=stdio
    ```

    **Use for**: CLI tools, MCP Inspector, direct process communication
  </Tab>
</Tabs>

### Session Management (HTTP Only)

**Control how HTTP connections maintain state.** Session modes determine whether the server maintains persistent connections (stateful) or treats each request independently (stateless). The `auto` mode intelligently detects client capabilities and chooses the optimal strategy.

| Variable           | Description           | Default | Options                         |
| ------------------ | --------------------- | ------- | ------------------------------- |
| `MCP_SESSION_MODE` | Session handling mode | `auto`  | `stateless`, `stateful`, `auto` |

<Info>
  **Session Modes**:

  * `auto`: Automatically detects client capabilities (recommended)
  * `stateful`: Maintains persistent sessions with connection state
  * `stateless`: Each request is independent, no session state
</Info>

### Rate Limiting (HTTP Only)

**Control request rate limiting for the HTTP transport.** Rate limiting prevents abuse and manages server load. For agentic AI workflows that make many parallel tool calls (e.g., [Agno AgentOS](https://agno.com)), you can increase the limit or disable rate limiting entirely.

| Variable                      | Description                     | Default           | Example |
| ----------------------------- | ------------------------------- | ----------------- | ------- |
| `MCP_RATE_LIMIT_ENABLED`      | Enable or disable rate limiting | `true`            | `false` |
| `MCP_RATE_LIMIT_MAX_REQUESTS` | Max requests per window         | `100`             | `1000`  |
| `MCP_RATE_LIMIT_WINDOW_MS`    | Window duration (ms)            | `900000` (15 min) | `60000` |
| `MCP_RATE_LIMIT_SKIP_DEV`     | Skip in development mode        | `false`           | `true`  |

<Tabs>
  <Tab title="Default">
    ```bash theme={null}
    MCP_RATE_LIMIT_ENABLED=true
    MCP_RATE_LIMIT_MAX_REQUESTS=100
    MCP_RATE_LIMIT_WINDOW_MS=900000
    ```

    **Use for**: Standard deployments with moderate request volumes
  </Tab>

  <Tab title="Agentic Workflows">
    ```bash theme={null}
    MCP_RATE_LIMIT_ENABLED=true
    MCP_RATE_LIMIT_MAX_REQUESTS=1000
    MCP_RATE_LIMIT_WINDOW_MS=60000
    ```

    **Use for**: AI agents (Agno, LangChain, etc.) making many parallel tool calls per turn
  </Tab>

  <Tab title="Disabled">
    ```bash theme={null}
    MCP_RATE_LIMIT_ENABLED=false
    ```

    **Use for**: Trusted internal networks, development environments, Docker Compose setups with controlled access
  </Tab>
</Tabs>

<Info>
  **Docker / Reverse Proxy**: The server reads `X-Forwarded-For` and `X-Real-IP` headers for client identification. When these headers are absent (e.g., behind Docker without proxy header forwarding), the server falls back to the TCP socket's remote address. Configure your reverse proxy to forward these headers for accurate per-client rate limiting.
</Info>

### Connection Pool Timeouts

**Control automatic cleanup of idle database connections and query timeouts.** In cloud deployments (Railway, Heroku, etc.), reverse proxies silently kill idle TCP connections. The Mapepire connection pool may still report as initialized, but queries sent over a dead WebSocket will hang indefinitely. These settings prevent that by proactively closing idle pools and aborting stale queries.

| Variable                    | Description                                                                               | Default          | Example |
| --------------------------- | ----------------------------------------------------------------------------------------- | ---------------- | ------- |
| `MCP_POOL_IDLE_TIMEOUT_MS`  | Idle timeout for connection pools (ms). Pools are closed after this period of inactivity. | `300000` (5 min) | `60000` |
| `MCP_POOL_QUERY_TIMEOUT_MS` | Query execution timeout (ms). Queries are aborted if they exceed this duration.           | `30000` (30s)    | `60000` |

<Tabs>
  <Tab title="Default">
    ```bash theme={null}
    MCP_POOL_IDLE_TIMEOUT_MS=300000
    MCP_POOL_QUERY_TIMEOUT_MS=30000
    ```

    **Use for**: Most deployments — 5-minute idle timeout and 30-second query timeout
  </Tab>

  <Tab title="Cloud Deployment">
    ```bash theme={null}
    MCP_POOL_IDLE_TIMEOUT_MS=60000
    MCP_POOL_QUERY_TIMEOUT_MS=30000
    ```

    **Use for**: Cloud platforms with aggressive proxy timeouts (Railway, Heroku, etc.)
  </Tab>

  <Tab title="Disabled">
    ```bash theme={null}
    MCP_POOL_IDLE_TIMEOUT_MS=0
    MCP_POOL_QUERY_TIMEOUT_MS=0
    ```

    **Use for**: Stable network environments where connections are long-lived and reliable
  </Tab>
</Tabs>

<Info>
  **How it works:** The idle timer checks pools at an interval of `max(10s, timeout/2)`. When a pool exceeds the idle timeout, it is closed automatically. The next query triggers a transparent re-initialization through the existing lazy-init path — no manual intervention needed. The query timeout uses `Promise.race()` to abort queries on stale connections, marking the pool unhealthy so it is re-created on the next request.
</Info>

<Warning>
  **Setting `MCP_POOL_QUERY_TIMEOUT_MS=0` disables query timeouts entirely.** This means queries on dead connections will hang until the client's own timeout fires. Only disable this in trusted, stable network environments.
</Warning>

### Pagination

**Controls the per-fetch page size and the safety ceiling used when SQL tools paginate large result sets.** `fetchAllRows: true` tools and the built-in `execute_sql` tool share these values. YAML tools override per-call via `rowsToFetch`; these env vars govern the defaults.

| Variable                            | Description                                                                                                                                | Default | Example  |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------- | -------- |
| `IBMI_PAGINATION_DEFAULT_PAGE_SIZE` | Rows per `fetchMore` call when a tool paginates without specifying its own page size.                                                      | `1000`  | `500`    |
| `IBMI_PAGINATION_MAX_ROWS`          | Hard upper bound on total rows from a single paginated tool call. Pagination stops and flags the result as truncated once this is reached. | `30000` | `100000` |

<Info>
  **Why these defaults:** At 1000 rows/fetch, the server makes at most 30 round-trips before hitting the 30,000-row ceiling — around 3 seconds of tail latency on a healthy WebSocket link. The ceiling itself is the practical LLM-ingestion limit: 30k rows typically serialize to 3-6M tokens, already beyond most context windows. Operators running bulk CLI exports can raise `IBMI_PAGINATION_MAX_ROWS`; LLM-facing deployments rarely should.
</Info>

## Authentication Configuration

### Choosing an Authentication Mode

**Which auth mode should you use?** Select based on your deployment scenario:

<AccordionGroup>
  <Accordion title="Development & Testing → Use 'none'" icon="flask">
    **No authentication, shared credentials**

    **Benefits:**

    * Quick setup for local development
    * Ideal for testing and prototyping
    * No additional configuration required

    **Limitations:**

    * **Never use in production environments**
    * No per-user tracking or authorities
    * Security risk for networked deployments

    **Setup:** Simply set `MCP_AUTH_MODE=none` in your `.env` file
  </Accordion>

  <Accordion title="Production with Multiple Users → Use 'ibmi'" icon="users">
    **Per-user IBM i authentication with RSA encryption**

    **Benefits:**

    * Each user connects with their own IBM i credentials
    * Respects individual IBM i object authorities
    * Full audit trail per user
    * Enterprise-grade security

    **Requirements:**

    * RSA keypair generation (public/private keys)
    * IBM i HTTP authentication endpoints enabled
    * Per-user credential management

    **Setup:** Requires `IBMI_AUTH_PRIVATE_KEY_PATH`, `IBMI_AUTH_PUBLIC_KEY_PATH`, and `IBMI_HTTP_AUTH_ENABLED=true`
  </Accordion>

  <Accordion title="Custom SSO / Identity Provider → Use 'oauth'" icon="building">
    **External OAuth/OIDC authentication**

    **Benefits:**

    * Integrate with existing enterprise auth systems
    * Support for SSO (Single Sign-On)
    * Centralized identity management
    * Industry-standard OAuth 2.0 / OIDC protocols

    **Requirements:**

    * OAuth provider configuration (issuer URL, audience)
    * Token validation infrastructure
    * External identity provider setup

    **Setup:** Configure `OAUTH_ISSUER_URL` and `OAUTH_AUDIENCE` for your identity provider
  </Accordion>

  <Accordion title="Custom Token System → Use 'jwt'" icon="key">
    **JSON Web Token authentication**

    **Benefits:**

    * Custom authentication logic and workflows
    * Token-based stateless auth
    * Flexible integration with existing systems
    * Control over token generation and validation

    **Requirements:**

    * You manage token generation and signing
    * Shared secret key (minimum 32 characters)
    * Custom token issuance logic

    **Setup:** Set `MCP_AUTH_SECRET_KEY` with a secure secret (min 32 chars)
  </Accordion>
</AccordionGroup>

### Authentication Mode Configuration

| Variable        | Description         | Default | Options                        |
| --------------- | ------------------- | ------- | ------------------------------ |
| `MCP_AUTH_MODE` | Authentication mode | `none`  | `none`, `jwt`, `oauth`, `ibmi` |

<Tabs>
  <Tab title="No Authentication">
    ```bash theme={null}
    MCP_AUTH_MODE=none
    ```

    **Use for**: Development, internal networks, trusted environments
  </Tab>

  <Tab title="JWT Authentication">
    ```bash theme={null}
    MCP_AUTH_MODE=jwt
    MCP_AUTH_SECRET_KEY=your-secret-key-min-32-chars
    ```

    **Use for**: Custom authentication systems, token-based auth
  </Tab>

  <Tab title="OAuth Authentication">
    ```bash theme={null}
    MCP_AUTH_MODE=oauth
    OAUTH_ISSUER_URL=https://your-auth-server.com
    OAUTH_AUDIENCE=ibmi-mcp-server
    ```

    **Use for**: Enterprise SSO, external identity providers
  </Tab>

  <Tab title="IBM i Authentication">
    ```bash theme={null}
    MCP_AUTH_MODE=ibmi
    IBMI_HTTP_AUTH_ENABLED=true
    IBMI_AUTH_KEY_ID=development
    IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
    IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
    ```

    **Use for**: Per-user IBM i credentials, connection pooling
  </Tab>
</Tabs>

### IBM i Authentication Settings

| Variable                             | Description                      | Default | Example               |
| ------------------------------------ | -------------------------------- | ------- | --------------------- |
| `IBMI_HTTP_AUTH_ENABLED`             | Enable IBM i HTTP auth endpoints | `false` | `true`                |
| `IBMI_AUTH_ALLOW_HTTP`               | Allow HTTP for auth (dev only)   | `false` | `true`                |
| `IBMI_AUTH_TOKEN_EXPIRY_SECONDS`     | Token lifetime in seconds        | `3600`  | `7200`                |
| `IBMI_AUTH_CLEANUP_INTERVAL_SECONDS` | Token cleanup interval           | `300`   | `600`                 |
| `IBMI_AUTH_MAX_CONCURRENT_SESSIONS`  | Max concurrent sessions          | `100`   | `50`                  |
| `IBMI_AUTH_KEY_ID`                   | Key identifier for encryption    | (none)  | `production`          |
| `IBMI_AUTH_PRIVATE_KEY_PATH`         | Path to RSA private key          | (none)  | `secrets/private.pem` |
| `IBMI_AUTH_PUBLIC_KEY_PATH`          | Path to RSA public key           | (none)  | `secrets/public.pem`  |

<Card title="IBM i Authentication Guide →" icon="key" href="/server-config/ibmi-auth">
  **Complete setup guide**: For detailed instructions on IBM i HTTP authentication including RSA key generation, token management, security best practices, and troubleshooting, see the [IBM i Authentication](/server-config/ibmi-auth) page.
</Card>

### Setting Up RSA Encryption Keys

**IBM i authentication requires RSA keypairs to protect credentials during transmission.** The authentication flow uses RSA and AES encryption to securely exchange IBM i credentials between clients and the server.

<Steps>
  <Step title="Create Secrets Directory">
    Create a dedicated directory for storing encryption keys:

    ```bash theme={null}
    mkdir -p secrets
    ```

    <Tip>
      Store the `secrets/` directory outside of version control. Add it to your `.gitignore` file.
    </Tip>
  </Step>

  <Step title="Generate RSA Private Key">
    Generate a 2048-bit RSA private key:

    ```bash theme={null}
    openssl genpkey -algorithm RSA \
      -out secrets/private.pem \
      -pkeyopt rsa_keygen_bits:2048
    ```

    **What this does:**

    * Creates a new RSA private key with 2048-bit encryption strength
    * Saves it to `secrets/private.pem`
    * This key will be used by the server to decrypt credentials sent by clients
  </Step>

  <Step title="Extract Public Key">
    Extract the corresponding public key from the private key:

    ```bash theme={null}
    openssl rsa -pubout \
      -in secrets/private.pem \
      -out secrets/public.pem
    ```

    **What this does:**

    * Derives the public key from your private key
    * Saves it to `secrets/public.pem`
    * Clients use this public key to encrypt credentials before sending them to the server
  </Step>

  <Step title="Set Secure File Permissions">
    Restrict access to your private key:

    ```bash theme={null}
    # Make private key readable only by owner
    chmod 600 secrets/private.pem

    # Public key can be more permissive
    chmod 644 secrets/public.pem
    ```

    <Warning>
      **Critical Security Step**: The private key (`private.pem`) must be protected. Anyone with access to this file can decrypt client credentials.
    </Warning>
  </Step>

  <Step title="Configure Environment Variables">
    Add the keypair paths to your `.env` file:

    ```bash theme={null}
    # IBM i Authentication Keys
    IBMI_AUTH_KEY_ID=production
    IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
    IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
    ```

    **Key Configuration:**

    * `IBMI_AUTH_KEY_ID`: Identifier for this keypair (used for key rotation)
    * `IBMI_AUTH_PRIVATE_KEY_PATH`: Path to your private key file
    * `IBMI_AUTH_PUBLIC_KEY_PATH`: Path to your public key file
  </Step>
</Steps>

**How the Encryption Works:**

1. **Client requests public key** from server (`/api/v1/auth/public-key`)
2. **Client generates** a random AES-256-GCM session key
3. **Client encrypts** IBM i credentials with the session key
4. **Client encrypts** the session key with the server's RSA public key
5. **Server decrypts** the session key using its RSA private key
6. **Server decrypts** the credentials using the session key
7. **Server authenticates** against IBM i and issues an access token

<Note>
  **Key Rotation**: To rotate keys, generate a new keypair with a different `IBMI_AUTH_KEY_ID`. The server can support multiple keypairs simultaneously, allowing gradual migration without service interruption.
</Note>

**Security Best Practices:**

<AccordionGroup>
  <Accordion title="Production Deployment" icon="shield-check">
    * **Always use HTTPS**: Set `IBMI_AUTH_ALLOW_HTTP=false`
    * **Rotate keys regularly**: Generate new keypairs every 90-180 days
    * **Use strong key sizes**: 2048-bit minimum, 4096-bit recommended for high-security environments
    * **Monitor key access**: Enable file auditing on the `secrets/` directory
    * **Backup keys securely**: Store encrypted backups in a secrets management system
  </Accordion>

  <Accordion title="File Permissions" icon="lock">
    * **Private key**: `chmod 600 secrets/private.pem` (owner read/write only)
    * **Public key**: `chmod 644 secrets/public.pem` (world-readable is safe)
    * **Secrets directory**: `chmod 700 secrets/` (owner access only)
    * **Owner**: Ensure files are owned by the service account running the MCP server
  </Accordion>

  <Accordion title="Version Control" icon="code-branch">
    * **Never commit keys**: Add `secrets/` to `.gitignore`
    * **Never commit `.env`**: Environment files often contain paths to secrets
    * **Use environment-specific keys**: Different keypairs for dev/staging/production
    * **Document setup process**: Include key generation in deployment documentation
  </Accordion>

  <Accordion title="Secrets Management" icon="vault">
    For production environments, consider using a secrets management system:

    * **AWS Secrets Manager**: Store keys in encrypted AWS vault
    * **HashiCorp Vault**: Centralized secrets management with audit logs
    * **Azure Key Vault**: Microsoft's cloud-based secrets storage
    * **Kubernetes Secrets**: For containerized deployments

    Update `IBMI_AUTH_PRIVATE_KEY_PATH` to reference the mounted secret location.
  </Accordion>
</AccordionGroup>

## IBM i Database Connection

**Connect to IBM i DB2 for i databases via Mapepire.** These settings configure the connection to your IBM i system through the Mapepire database server. The server uses these credentials to execute SQL tools and access DB2 for i data. All connections are pooled for efficiency and support both shared (development) and per-user (production) authentication modes.

### Connection Settings

| Variable                   | Description                                                  | Default | Example                         | Security Impact                             |
| -------------------------- | ------------------------------------------------------------ | ------- | ------------------------------- | ------------------------------------------- |
| `DB2i_HOST`                | IBM i host (Mapepire daemon)                                 | (none)  | `my-ibmi-system.company.com`    | Use hostname, not `127.0.0.1` in Docker     |
| `DB2i_USER`                | IBM i user profile                                           | (none)  | `MYUSER`                        | Shared credentials (dev only)               |
| `DB2i_PASS`                | IBM i user password                                          | (none)  | `mypassword`                    | Never commit to version control             |
| `DB2i_PORT`                | Mapepire daemon port                                         | `8076`  | `8076`                          | Ensure firewall allows this port            |
| `DB2i_IGNORE_UNAUTHORIZED` | Skip TLS certificate verification                            | `true`  | `false`                         | ⚠️ **High Risk**: Set `false` in production |
| `DB2i_JDBC_OPTIONS`        | Mapepire JDBC options ([syntax](#db2i-jdbc-options-env-var)) | (none)  | `naming=system;date format=iso` | `key ring password` redacted from logs      |

<Warning>
  **Security Alert**: `DB2i_IGNORE_UNAUTHORIZED=true` disables TLS certificate verification, making connections vulnerable to man-in-the-middle attacks.

  **Use this setting:**

  * ✅ Development with self-signed Mapepire certificates
  * ❌ Production environments (use proper TLS certificates)
</Warning>

<Tabs>
  <Tab title="Development">
    ```bash theme={null}
    DB2i_HOST=dev-ibmi.company.com
    DB2i_USER=DEVUSER
    DB2i_PASS=devpassword
    DB2i_PORT=8076
    DB2i_IGNORE_UNAUTHORIZED=true
    ```
  </Tab>

  <Tab title="Production">
    ```bash theme={null}
    DB2i_HOST=prod-ibmi.company.com
    DB2i_USER=PRODUSER
    DB2i_PASS=${SECURE_PASSWORD}
    DB2i_PORT=8076
    DB2i_IGNORE_UNAUTHORIZED=false
    ```
  </Tab>
</Tabs>

<Note>
  **IBM i Requirements**:

  * User profile must have appropriate database authorities
  * Access to QSYS2 system services
  * Mapepire daemon must be running on the specified port
</Note>

### DB2i\_JDBC\_OPTIONS Env Var

**Forward any [mapepire JDBC option](https://javadoc.io/static/net.sf.jt400/jt400/21.0.0/com/ibm/as400/access/doc-files/JDBCProperties.html) to the underlying driver via a single environment variable.** The `DB2i_JDBC_OPTIONS` env var accepts a semicolon-separated list of `key=value` pairs modeled on DB2 JDBC URL syntax — letting you set library list, naming convention, date format, and any other JDBC property without editing YAML.

```bash theme={null}
DB2i_JDBC_OPTIONS='naming=system;date format=iso;libraries=MYLIB,DEVDATA'
```

#### Format Rules

| Rule             | Behavior                                                           |
| ---------------- | ------------------------------------------------------------------ |
| Outer separator  | `;` splits pairs; empty segments are ignored                       |
| Inner separator  | First `=` in each pair splits key/value (values may contain `=`)   |
| Whitespace       | Trimmed around both key and value                                  |
| Arrays           | Only `libraries` is array-valued; comma-split within a single pair |
| Types            | All other values forwarded as strings — no boolean/number coercion |
| Keys with spaces | Work unquoted: `date format=iso` is valid                          |
| Malformed pairs  | A non-empty segment with no `=` throws a clear error at startup    |

<Tabs>
  <Tab title="Library List">
    ```bash theme={null}
    DB2i_JDBC_OPTIONS='libraries=MYLIB,DEVDATA,QGPL'
    ```

    **Use for**: Resolving unqualified object names. Comma-split within the single `libraries=` pair.
  </Tab>

  <Tab title="Date Format">
    ```bash theme={null}
    DB2i_JDBC_OPTIONS='date format=iso'
    ```

    **Output**: `SELECT CHAR(CURRENT_DATE)` → `2026-04-17`

    **Other values**: `usa` (`04/17/2026`), `eur` (`17.04.2026`), `jis` (`2026-04-17`), `mdy`, `dmy`, `ymd`, `julian`

    <Warning>
      **Job default caveat**: If `date format` is unset, the driver inherits the connected job's `DATFMT` system value — which may produce **two-digit years** (e.g., `04/17/26`). Set `date format=iso` explicitly for unambiguous date serialization.
    </Warning>
  </Tab>

  <Tab title="Combined Options">
    ```bash theme={null}
    DB2i_JDBC_OPTIONS='naming=system;date format=iso;libraries=REPORTS,SALESDATA,QGPL'
    ```

    **Use for**: Reporting or audit pipelines that need a specific library list, legacy slash-notation naming, and ISO date format.
  </Tab>
</Tabs>

#### Precedence and YAML Interaction

`DB2i_JDBC_OPTIONS` is **shallow-merged over** the `jdbc-options` field in each YAML source. Env values win on per-key collisions; YAML-only keys are preserved.

| Scenario                          | Result                                    |
| --------------------------------- | ----------------------------------------- |
| Only YAML sets `jdbc-options`     | YAML values flow through unchanged        |
| Only env sets `DB2i_JDBC_OPTIONS` | Env values apply to every source          |
| Both set the same key             | **Env wins** for that key                 |
| Both set different keys           | Both apply (shallow merge, union of keys) |

<Info>
  **Why env overrides YAML**: Operators can enforce a fleet-wide JDBC configuration (for example, forcing `naming=system` or a standard library list across all environments) without editing per-deployment YAML files.
</Info>

**Example merge:**

```yaml theme={null}
# YAML source
jdbc-options:
  libraries: [YAMLLIB]
  naming: sql
  date format: iso
```

```bash theme={null}
# Env var
DB2i_JDBC_OPTIONS='libraries=ENVLIB;naming=system'
```

```yaml theme={null}
# Effective JDBC options sent to mapepire
libraries: [ENVLIB]      # env wins
naming: system           # env wins
date format: iso         # YAML only, preserved
```

#### Security: Log Redaction

The server logs **only** the `libraries` field at pool initialization. Other JDBC fields — including potentially sensitive values like `key ring password`, `proxy server`, and `trace` — are **intentionally excluded** from every log level to prevent credential leakage.

<Note>
  If you need to verify that a non-`libraries` option took effect, inspect driver behavior directly (for example, run `SELECT CHAR(CURRENT_DATE)` to confirm `date format`) rather than searching the logs.
</Note>

See the [YAML Sources Reference → JDBC Options](/sql-tools/sources#jdbc-options) for per-source configuration in YAML.

## SQL Tools Configuration

**Load and manage YAML-defined SQL tools.** These settings control how the server discovers, loads, and reloads SQL tool definitions from YAML configuration files. You can load tools from individual files, entire directories, or use glob patterns to organize tools into logical groups (toolsets) for different use cases.

<Warning>
  **Path Requirements:**

  * `TOOLS_YAML_PATH` in `.env` files should use **absolute paths** to avoid issues when the server is started from different directories
  * For relative paths, use the `--tools` CLI argument instead: `npx -y @ibm/ibmi-mcp-server@latest --tools ./tools`
  * CLI arguments override environment variables, so `--tools` always takes precedence over `TOOLS_YAML_PATH`
</Warning>

For detailed information on creating SQL tools, see the [SQL Tools Overview](/sql-tools/overview) and [Building SQL Tools](/sql-tools/building-tools) guides.

### YAML Tool Settings

| Variable                       | Description                         | Default | Example                  |
| ------------------------------ | ----------------------------------- | ------- | ------------------------ |
| `TOOLS_YAML_PATH`              | Path to YAML tool definitions       | (none)  | `tools`                  |
| `SELECTED_TOOLSETS`            | Comma-separated toolset names       | (none)  | `performance,monitoring` |
| `YAML_AUTO_RELOAD`             | Auto-reload tools when files change | `true`  | `false`                  |
| `YAML_MERGE_ARRAYS`            | Merge arrays when combining files   | `true`  | `true`                   |
| `YAML_ALLOW_DUPLICATE_TOOLS`   | Allow duplicate tool names          | `false` | `true`                   |
| `YAML_ALLOW_DUPLICATE_SOURCES` | Allow duplicate source names        | `false` | `true`                   |
| `YAML_VALIDATE_MERGED`         | Validate merged configuration       | `true`  | `false`                  |

<Accordion title="YAML Configuration Examples">
  **Single File**:

  ```bash theme={null}
  TOOLS_YAML_PATH=tools/system-tools.yaml
  ```

  **Directory (loads all .yaml files)**:

  ```bash theme={null}
  TOOLS_YAML_PATH=tools
  ```

  **Specific Toolsets**:

  ```bash theme={null}
  TOOLS_YAML_PATH=tools
  SELECTED_TOOLSETS=performance,security,monitoring
  ```

  **Glob Pattern**:

  ```bash theme={null}
  TOOLS_YAML_PATH=configs/**/*.yaml
  ```
</Accordion>

## Built-in Tools

**Control access to compiled SQL tools.** The server includes built-in tools for schema discovery, query validation, and SQL execution. All are **disabled by default** (except `describe_sql_object`) and must be explicitly enabled via CLI flags or environment variables.

| Tool                    | Status                 | Purpose                                          | CLI Flag          | Env Variable                |
| ----------------------- | ---------------------- | ------------------------------------------------ | ----------------- | --------------------------- |
| `describe_sql_object`   | ✅ Always enabled       | Generate DDL for database objects                | —                 | —                           |
| `list_schemas`          | Disabled by default    | List available schemas/libraries                 | `--builtin-tools` | `IBMI_ENABLE_DEFAULT_TOOLS` |
| `list_tables_in_schema` | Disabled by default    | List tables, views, physical files               | `--builtin-tools` | `IBMI_ENABLE_DEFAULT_TOOLS` |
| `get_table_columns`     | Disabled by default    | Get column metadata for a table                  | `--builtin-tools` | `IBMI_ENABLE_DEFAULT_TOOLS` |
| `get_related_objects`   | Disabled by default    | Find dependent objects                           | `--builtin-tools` | `IBMI_ENABLE_DEFAULT_TOOLS` |
| `validate_query`        | Disabled by default    | Validate SQL syntax and verify objects           | `--builtin-tools` | `IBMI_ENABLE_DEFAULT_TOOLS` |
| `execute_sql`           | ⚠️ Disabled by default | Execute ad-hoc SQL queries (readonly by default) | `--execute-sql`   | `IBMI_ENABLE_EXECUTE_SQL`   |

<Tip>
  Use `--builtin-tools --execute-sql` together for the full text-to-SQL workflow. Use `--builtin-tools` alone to let agents discover schema while routing queries through curated YAML tools. See the [Built-in Tools Reference](/sql-tools/built-in-tools) for complete parameter and response documentation.
</Tip>

### Configuration Variables

| Variable                    | Description                                 | Default | Options         |
| --------------------------- | ------------------------------------------- | ------- | --------------- |
| `IBMI_ENABLE_DEFAULT_TOOLS` | Enable schema discovery tools               | `false` | `true`, `false` |
| `IBMI_ENABLE_EXECUTE_SQL`   | Enable ad-hoc SQL execution                 | `false` | `true`, `false` |
| `IBMI_EXECUTE_SQL_READONLY` | Control readonly mode (only SELECT queries) | `true`  | `true`, `false` |

<Warning>
  **Security**: `execute_sql` allows clients to run ad-hoc SQL queries. By default (`IBMI_EXECUTE_SQL_READONLY=true`), only SELECT queries are allowed. Set `IBMI_EXECUTE_SQL_READONLY=false` to enable write operations (INSERT, UPDATE, DELETE). Enable only in development or trusted environments. Production deployments should use YAML-defined tools for controlled query access.
</Warning>

<Tabs>
  <Tab title="Full Workflow (CLI)">
    ```bash theme={null}
    # Schema discovery + query execution
    npx -y @ibm/ibmi-mcp-server@latest --builtin-tools --execute-sql --transport http
    ```

    **Use for**: Development with full text-to-SQL capability
  </Tab>

  <Tab title="Schema Discovery Only">
    ```bash theme={null}
    # Agents explore schema but can't run arbitrary SQL
    npx -y @ibm/ibmi-mcp-server@latest --builtin-tools --tools ./tools
    ```

    **Use for**: Production with curated YAML tools + schema exploration
  </Tab>

  <Tab title="Write Mode (Opt-in)">
    ```bash theme={null}
    IBMI_EXECUTE_SQL_READONLY=false
    npx -y @ibm/ibmi-mcp-server@latest --builtin-tools --execute-sql
    ```

    **Use for**: Development when write operations are explicitly needed

    ⚠️ **Warning**: Only use in trusted environments with proper authentication
  </Tab>

  <Tab title="YAML Tools Only (Default)">
    ```bash theme={null}
    npx -y @ibm/ibmi-mcp-server@latest --tools ./tools
    ```

    **Use for**: Production with curated YAML tools for controlled access
  </Tab>
</Tabs>

**Tool Capabilities:**

<AccordionGroup>
  <Accordion title="Schema Discovery Tools (--builtin-tools)" icon="magnifying-glass">
    Five read-only tools that query IBM i system catalog views:

    * **list\_schemas**: Browse available schemas via `QSYS2.SYSSCHEMAS`
    * **list\_tables\_in\_schema**: Find tables, views, physical files via `QSYS2.SYSTABLES`
    * **get\_table\_columns**: Inspect column metadata via `QSYS2.SYSCOLUMNS2`
    * **get\_related\_objects**: Dependency analysis via `SYSTOOLS.RELATED_OBJECTS`
    * **validate\_query**: Multi-step SQL validation via `QSYS2.PARSE_STATEMENT`

    All are safe, read-only catalog queries with zero risk to data.
  </Accordion>

  <Accordion title="describe_sql_object (Always Available)" icon="database">
    Generates SQL DDL for IBM i database objects using `QSYS2.GENERATE_SQL`:

    * **Input**: Object name, library, type (TABLE, VIEW, INDEX, etc.)
    * **Output**: Complete DDL with constraints, indexes, and properties
    * **Security**: Read-only, describes objects without modification
    * **Use case**: Schema discovery, documentation, AI context
  </Accordion>

  <Accordion title="execute_sql (--execute-sql)" icon="code">
    Executes ad-hoc SQL queries with multi-layered security controls:

    * **Readonly by default**: Only SELECT/QUERY statements allowed when `IBMI_EXECUTE_SQL_READONLY=true` (default)
    * **Write operations opt-in**: Set `IBMI_EXECUTE_SQL_READONLY=false` to enable INSERT, UPDATE, DELETE, etc.
    * **PARSE\_STATEMENT validation**: Uses IBM i's native SQL parser (`QSYS2.PARSE_STATEMENT`) for authoritative statement type detection
    * **AST/Regex validation**: Fast pattern matching to catch dangerous SQL keywords
    * **Fail-closed security**: All validation failures result in query rejection
    * **Query length limit**: Maximum 10,000 characters per query
    * **Use case**: Development exploration, debugging queries, ad-hoc data analysis
  </Accordion>
</AccordionGroup>

<Note>
  **Built-in vs YAML Tools**:

  * **Built-in tools**: Compiled TypeScript, controlled by feature flags, runtime validation with PARSE\_STATEMENT
  * **YAML tools**: User-defined, curated queries with parameters, explicit query control
  * **Security**: Built-in tools use IBM i's SQL parser for defense-in-depth; YAML tools use explicit query whitelisting
  * **Recommendation**: Use YAML tools in production for explicit query control and parameterization

  See [SQL Tools Overview](/sql-tools/overview) for creating YAML tools.
</Note>

***

## Observability & Monitoring

**Track server performance, debug issues, and monitor operations.** Observability features help you understand server behavior through logging, distributed tracing (OpenTelemetry), and performance metrics. These settings are crucial for production deployments and troubleshooting.

### Server Settings

**Basic server identification and environment configuration.** These variables set the server's identity in logs and telemetry data, control the runtime environment, and determine where log files are stored.

| Variable             | Description                             | Default         | Example              |
| -------------------- | --------------------------------------- | --------------- | -------------------- |
| `MCP_SERVER_NAME`    | Server name identifier for MCP protocol | Package name    | `ibmi-mcp-dev`       |
| `MCP_SERVER_VERSION` | Server version for MCP protocol         | Package version | `1.9.1`              |
| `NODE_ENV`           | Node environment                        | `development`   | `production`, `test` |

### Logging Configuration

**Control log output, verbosity, and file storage.** The server uses Pino for structured logging with automatic log rotation, level-specific log files, and support for both console and file outputs. Logs help you debug issues, track server behavior, and comply with audit requirements.

#### Log Settings

| Variable        | Description                    | Default                   | Options                                                                 |
| --------------- | ------------------------------ | ------------------------- | ----------------------------------------------------------------------- |
| `MCP_LOG_LEVEL` | Logging verbosity level        | `info`                    | `debug`, `info`, `notice`, `warning`, `error`, `crit`, `alert`, `emerg` |
| `LOGS_DIR`      | Directory for log files        | `~/.ibmi-mcp-server/logs` | Any absolute, relative, or `~/` path                                    |
| `NO_COLOR`      | Disable colored console output | (none)                    | `1` to disable colors                                                   |
| `FORCE_COLOR`   | Force disable colored output   | (none)                    | `0` to disable colors                                                   |

<Info>
  **Log Levels Explained**:

  * `debug`: Detailed diagnostic information (verbose)
  * `info`: General informational messages (recommended)
  * `notice`: Significant events worth noting
  * `warning`: Warning conditions that should be addressed
  * `error`: Error conditions that need attention
  * `crit`, `alert`, `emerg`: Critical system failures
</Info>

#### Log Directory Configuration

**Where logs are stored depends on how you specify the path:**

<Tabs>
  <Tab title="Default (OS-Standard)">
    ```bash theme={null}
    # No LOGS_DIR specified - uses OS-standard location
    # Logs will be written to: ~/.ibmi-mcp-server/logs/
    ```

    **Default location**: `~/.ibmi-mcp-server/logs/`

    **Use for**: Production with `npx`, user-specific installations

    **Benefits**:

    * Works consistently with `npx @ibm/ibmi-mcp-server`
    * Persists across package updates
    * Doesn't require write permissions to npm cache
    * Follows OS conventions for user data
  </Tab>

  <Tab title="Absolute Path">
    ```bash theme={null}
    # Absolute path - exact location specified
    LOGS_DIR=/var/log/ibmi-mcp-server
    ```

    **Use for**: System-wide installations, production servers

    **Examples**:

    * `/var/log/ibmi-mcp-server` - System logs directory
    * `/opt/ibmi-mcp/logs` - Custom application directory
    * `/app/logs` - Docker container path
  </Tab>

  <Tab title="Relative Path">
    ```bash theme={null}
    # Relative to current working directory (process.cwd())
    LOGS_DIR=./logs
    ```

    **Resolves relative to**: Directory where you run the server

    **Use for**: Local development, project-specific logs

    **Examples**:

    * `./logs` - Logs in current directory
    * `../shared-logs` - Logs in parent directory
    * `data/logs` - Logs in data subdirectory
  </Tab>

  <Tab title="Tilde Expansion">
    ```bash theme={null}
    # User home directory expansion
    LOGS_DIR=~/my-project/logs
    ```

    **Expands to**: Your home directory + path

    **Use for**: User-specific custom locations

    **Examples**:

    * `~/ibmi-mcp-logs` → `/Users/username/ibmi-mcp-logs`
    * `~/projects/mcp/logs` → `/Users/username/projects/mcp/logs`
  </Tab>
</Tabs>

<Warning>
  **Path Resolution:**

  * Absolute paths (`/var/log/...`) are used as-is
  * Relative paths (`./logs`) resolve from **current working directory**, not package location
  * Tilde paths (`~/logs`) expand to your home directory
  * When using `npx`, relative paths resolve from where you run the command
</Warning>

#### Log Files Created

The server creates **6 log files** with automatic rotation:

| File               | Content                  | Rotation      |
| ------------------ | ------------------------ | ------------- |
| `combined.log`     | All info+ level logs     | Daily or 10MB |
| `error.log`        | Error+ level logs only   | Daily or 10MB |
| `warn.log`         | Warning+ level logs only | Daily or 10MB |
| `info.log`         | Info+ level logs only    | Daily or 10MB |
| `debug.log`        | Debug+ level logs only   | Daily or 10MB |
| `interactions.log` | MCP interaction tracking | Daily or 10MB |

**Rotation behavior:**

* Logs rotate when they reach **10MB** OR at **midnight daily** (whichever comes first)
* Rotated files are numbered sequentially: `combined.log.1`, `combined.log.2`, etc.
* **Current file + 5 historical versions** are kept (6 total files per log level)
* When the 7th file would be created, the oldest file is automatically deleted
* Daily rotation re-uses the existing file if still within the same day

<Accordion title="Log File Examples">
  **Directory structure:**

  ```bash theme={null}
  ~/.ibmi-mcp-server/logs/
  ├── combined.log       # Current log (being written to)
  ├── combined.log.1     # Most recent rotation (yesterday or 10MB ago)
  ├── combined.log.2     # 2nd most recent
  ├── combined.log.3     # 3rd most recent
  ├── combined.log.4     # 4th most recent
  ├── combined.log.5     # 5th most recent (oldest kept)
  ├── error.log          # Current error log
  ├── error.log.1        # Recent error rotation
  ├── warn.log           # Current warning log
  ├── info.log           # Current info log
  ├── debug.log          # Current debug log
  └── interactions.log   # Current interaction log
  ```

  **Note**: Once `combined.log.6` would be created, `combined.log.5` is deleted and files shift: `.4` → `.5`, `.3` → `.4`, etc.

  **Sample log entry (JSON format):**

  ```json theme={null}
  {
    "level": "info",
    "time": "2024-12-17T16:30:45.123Z",
    "pid": 12345,
    "env": "production",
    "version": "0.1.2",
    "msg": "Connection pool initialized successfully",
    "operation": "InitializePool",
    "requestId": "req_abc123"
  }
  ```
</Accordion>

#### Console Output & Colors

**Console behavior depends on environment and transport mode:**

<AccordionGroup>
  <Accordion title="HTTP Transport (Colored)" icon="palette">
    In development with HTTP transport, console logs are **colored and pretty-printed** to stderr:

    ```bash theme={null}
    MCP_TRANSPORT_TYPE=http
    MCP_LOG_LEVEL=debug
    ```

    **Output**: Human-readable colored logs to `stderr`

    **Disable colors**: Set `NO_COLOR=1` or `FORCE_COLOR=0`
  </Accordion>

  <Accordion title="STDIO Transport (Plain)" icon="terminal">
    With STDIO transport, console logs are **plain JSON** to stderr (MCP spec requirement):

    ```bash theme={null}
    MCP_TRANSPORT_TYPE=stdio
    ```

    **Output**: Structured JSON to `stderr` (no colors, no pretty-printing)

    **Why**: MCP protocol requires clean JSON-RPC on `stdout` with no ANSI codes
  </Accordion>

  <Accordion title="Production (JSON)" icon="server">
    In production, logs are **structured JSON** regardless of transport:

    ```bash theme={null}
    NODE_ENV=production
    ```

    **Output**: JSON to `stderr` and log files
  </Accordion>
</AccordionGroup>

<Note>
  **NO\_COLOR Support**: The server respects the [NO\_COLOR](https://no-color.org/) environment variable standard. Set `NO_COLOR=1` to disable all colored output, useful for CI/CD pipelines and log aggregation systems.
</Note>

#### Session Correlation with OpenTelemetry

**How to correlate logs across server restarts:**

Since logs now append across server sessions (rather than creating timestamped files), use **structured logging fields** to filter by session:

<CodeGroup>
  ```json Example: Filter by Request ID theme={null}
  {
    "requestId": "req_abc123",
    "operation": "ExecuteQuery",
    "msg": "Query executed successfully"
  }
  ```

  ```json Example: Filter by Trace ID (OpenTelemetry) theme={null}
  {
    "traceId": "d4e5f6a7b8c9d0e1",
    "spanId": "a1b2c3d4e5f6",
    "msg": "Processing MCP tool request"
  }
  ```
</CodeGroup>

**Best practice**: Enable OpenTelemetry for distributed tracing across restarts:

```bash theme={null}
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
```

This adds `traceId` and `spanId` to every log entry, making it easy to:

* Filter logs by specific server sessions
* Correlate requests across services
* Track performance over time
* Debug issues with full request context

### OpenTelemetry

**Enable distributed tracing and metrics collection.** OpenTelemetry (OTel) provides enterprise-grade observability by tracking every request through the system, measuring performance, and exporting telemetry data to monitoring platforms like Jaeger, Zipkin, or cloud providers. Essential for production monitoring and performance optimization.

| Variable                              | Description                       | Default           | Example                                |
| ------------------------------------- | --------------------------------- | ----------------- | -------------------------------------- |
| `OTEL_ENABLED`                        | Enable OpenTelemetry              | `false`           | `true`                                 |
| `OTEL_SERVICE_NAME`                   | Service name for telemetry data   | `ibmi-mcp-server` | `production-mcp`                       |
| `OTEL_SERVICE_VERSION`                | Service version for telemetry     | Package version   | `1.9.1`                                |
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`  | OTLP endpoint for trace export    | (none)            | `http://localhost:4318/v1/traces`      |
| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | OTLP endpoint for metrics export  | (none)            | `http://localhost:4318/v1/metrics`     |
| `OTEL_TRACES_SAMPLER_ARG`             | Trace sampling ratio (0.0 to 1.0) | `1.0`             | `0.1`                                  |
| `OTEL_LOG_LEVEL`                      | OTel diagnostic log level         | `INFO`            | `DEBUG`                                |
| `OTEL_RESOURCE_ATTRIBUTES`            | Resource attributes               | (none)            | `environment=production,version=1.0.0` |

<Note>
  **Supported OTEL\_LOG\_LEVEL values**: `NONE`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `VERBOSE`, `ALL`
</Note>

<Tabs>
  <Tab title="Jaeger">
    ```bash theme={null}
    OTEL_ENABLED=true
    OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:14268/api/traces
    OTEL_SERVICE_NAME=ibmi-mcp-server
    ```
  </Tab>

  <Tab title="OTLP Collector">
    ```bash theme={null}
    OTEL_ENABLED=true
    OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://otel-collector:4318/v1/traces
    OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://otel-collector:4318/v1/metrics
    ```
  </Tab>
</Tabs>

## Environment-Specific Examples

<Accordion title="Development Environment">
  ```bash theme={null}
  # Transport
  MCP_TRANSPORT_TYPE=http
  MCP_HTTP_PORT=3010
  MCP_HTTP_HOST=127.0.0.1
  MCP_SESSION_MODE=auto

  # Authentication (disabled for development)
  MCP_AUTH_MODE=none

  # IBM i Connection
  DB2i_HOST=dev-ibmi.company.com
  DB2i_USER=DEVUSER
  DB2i_PASS=devpassword
  DB2i_PORT=8076
  DB2i_IGNORE_UNAUTHORIZED=true

  # Tools
  TOOLS_YAML_PATH=tools
  YAML_AUTO_RELOAD=true

  # Logging
  MCP_LOG_LEVEL=debug
  LOG_FORMAT=text

  # Observability (optional)
  OTEL_ENABLED=false
  ```
</Accordion>

<Accordion title="Production Environment">
  ```bash theme={null}
  # Transport
  MCP_TRANSPORT_TYPE=http
  MCP_HTTP_PORT=3010
  MCP_HTTP_HOST=0.0.0.0
  MCP_SESSION_MODE=stateful
  MCP_ALLOWED_ORIGINS=https://myapp.company.com

  # Authentication
  MCP_AUTH_MODE=ibmi
  IBMI_HTTP_AUTH_ENABLED=true
  IBMI_AUTH_KEY_ID=production
  IBMI_AUTH_PRIVATE_KEY_PATH=/app/secrets/private.pem
  IBMI_AUTH_PUBLIC_KEY_PATH=/app/secrets/public.pem
  IBMI_AUTH_ALLOW_HTTP=false
  IBMI_AUTH_TOKEN_EXPIRY_SECONDS=7200

  # IBM i Connection
  DB2i_HOST=prod-ibmi.company.com
  DB2i_USER=${IBM_USER}
  DB2i_PASS=${IBM_PASS}
  DB2i_PORT=8076
  DB2i_IGNORE_UNAUTHORIZED=false

  # Connection Pool Timeouts (recommended for cloud deployments)
  MCP_POOL_IDLE_TIMEOUT_MS=300000
  MCP_POOL_QUERY_TIMEOUT_MS=30000

  # Tools
  TOOLS_YAML_PATH=/app/configs
  SELECTED_TOOLSETS=production,monitoring
  YAML_AUTO_RELOAD=false

  # Logging
  MCP_LOG_LEVEL=info
  LOG_FORMAT=json

  # Observability
  OTEL_ENABLED=true
  OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://traces.company.com/v1/traces
  OTEL_SERVICE_NAME=ibmi-mcp-production
  ```
</Accordion>

<Accordion title="Docker Compose">
  ```yaml theme={null}
  version: '3.8'
  services:
    ibmi-mcp-server:
      build: .
      environment:
        MCP_TRANSPORT_TYPE: http
        MCP_HTTP_PORT: 3010
        MCP_AUTH_MODE: ibmi
        IBMI_HTTP_AUTH_ENABLED: "true"
        DB2i_HOST: ${DB2i_HOST}
        DB2i_USER: ${DB2i_USER}
        DB2i_PASS: ${DB2i_PASS}
        TOOLS_YAML_PATH: /app/configs
        OTEL_ENABLED: "true"
        MCP_RATE_LIMIT_MAX_REQUESTS: "1000"  # Higher limit for agentic workflows
        MCP_POOL_IDLE_TIMEOUT_MS: "300000"
        MCP_POOL_QUERY_TIMEOUT_MS: "30000"
      ports:
        - "3010:3010"
      volumes:
        - ./configs:/app/configs:ro
        - ./secrets:/app/secrets:ro
  ```
</Accordion>

<Tip>
  For additional security considerations and IBM i authority requirements, see the [Authentication](/api/auth-endpoints) and [Production Deployment](/deployment/production) guides.
</Tip>
