# Agent Development Overview
Source: https://ibm-d95bab6e.mintlify.app/agents/overview
Build specialized AI agents for IBM i systems using the MCP server and custom toolsets.
AI agents provide intelligent automation and assistance for IBM i system administration through natural language interfaces. The IBM i MCP server enables you to build **specialized agents** that focus on specific domains (performance monitoring, system discovery, security auditing) rather than monolithic agents attempting all tasks.
***
## Architecture Overview
The IBM i MCP server provides the foundation for building specialized agents. Agents connect to the MCP server, which exposes IBM i capabilities through SQL-based tools organized into **toolsets**. This architecture enables you to build focused agents that only see the tools they need.
```mermaid theme={null}
graph TB
subgraph agents["AI Agent Layer"]
direction TB
agent["๐ค AI AgentAgno/LangChain/LangGraph "]
nl["๐ฌ Natural language interface"]
memory["๐ง Persistent memory & context"]
end
subgraph filtering["FilteredMCPTools Layer"]
direction TB
filter["๐ FilteredMCPTools"]
annotations["๐ Annotation-based filtering"]
toolsets["๐ฆ Toolset selectionperformance, discovery, browse, search "]
end
subgraph mcp["IBM i MCP Server"]
direction TB
register["๐ Register SQL tools from YAML"]
validate["โ Validate parameters & security"]
format["๐ Format responses for AI"]
end
subgraph ibmi["IBM i System"]
direction TB
db2["โ Db2 for i"]
qsys2["โ QSYS2 Services"]
security["โ Security Model"]
sprocs["โ Stored Procedures"]
end
agents -->|Uses| filtering
filtering -->|HTTP/MCP Protocol| mcp
mcp -->|SQL Queries| ibmi
style agents fill:#e3f2fd,stroke:#1976d2,stroke-width:3px,color:#000
style filtering fill:#fff3e0,stroke:#f57c00,stroke-width:3px,color:#000
style mcp fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px,color:#000
style ibmi fill:#e8f5e9,stroke:#388e3c,stroke-width:3px,color:#000
style agent fill:#bbdefb,stroke:#1976d2,stroke-width:2px,color:#000
style nl fill:#bbdefb,stroke:#1976d2,stroke-width:2px,color:#000
style memory fill:#bbdefb,stroke:#1976d2,stroke-width:2px,color:#000
style filter fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#000
style annotations fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#000
style toolsets fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#000
style register fill:#e1bee7,stroke:#7b1fa2,stroke-width:2px,color:#000
style validate fill:#e1bee7,stroke:#7b1fa2,stroke-width:2px,color:#000
style format fill:#e1bee7,stroke:#7b1fa2,stroke-width:2px,color:#000
style db2 fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
style qsys2 fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
style security fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
style sprocs fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
```
### Three-Layer Design
**Your specialized agent** with natural language understanding, persistent memory, and domain-specific knowledge
**FilteredMCPTools** provides selective tool access based on annotations (toolsets, read-only, etc.)
**SQL tools as MCP tools** registered from YAML, validated, and formatted for AI consumption
***
## Building Specialized Agents with Toolsets
**Toolsets** are collections of related SQL tools that enable focused agent capabilities. Instead of giving an agent access to all 50+ tools, you configure it to use only the toolset(s) it needs.
### Example Toolsets
| Toolset | Purpose | When to Use |
| ----------------------- | ----------------------------- | -------------------------------------------------------------------- |
| **performance** | System performance monitoring | Agents that track CPU, memory, active jobs, and resource utilization |
| **sysadmin\_discovery** | High-level service discovery | Agents that explore available QSYS2 services and capabilities |
| **sysadmin\_browse** | Detailed service exploration | Agents that dive deep into specific schemas and service categories |
| **sysadmin\_search** | Targeted service search | Agents that find specific services by name or keyword |
**Why Toolsets?** Specialized agents are more reliable, performant, and secure than monolithic agents. A performance monitoring agent doesn't need access to security audit tools. A discovery agent doesn't need write operations. Toolsets enforce this separation.
### Creating Custom Toolsets
You define toolsets in your YAML tool configuration:
```yaml theme={null}
# tools/custom-tools.yaml
toolsets:
security_audit:
tools:
- get_failed_logins
- list_object_authorities
- check_password_expiry
database_health:
tools:
- table_sizes
- index_status
- query_performance
```
Your agent framework can then filter to these custom toolsets when connecting to the MCP server.
Learn how to define toolsets in YAML and use them with agents
***
## Agent Development Approach
Building an agent for IBM i follows this high-level process:
What specific IBM i domain will this agent handle? Performance? Security? Discovery?
Use existing toolsets or define custom ones in YAML based on your agent's needs
Connect your agent framework to the MCP server with toolset filters
Guide the agent on how to interpret user questions and use tools effectively
Verify the agent's reliability and deploy as a standalone service
**Multi-Agent Architecture**: IBM i's traditional separation of concerns translates well to specialized agents. Rather than one agent for "IBM i administration," build separate agents for performance monitoring, security auditing, database management, etc. Each agent becomes an expert in its domain.
***
## Framework Options
Pre-built integrations are available for popular agent frameworks:
Python agents with AgentOS, persistent memory, and evaluation tools
Google Agent Development Kit with Google AI and Vertex AI support
LangGraph-based agents with state management and workflows
Each integration includes example specialized agents demonstrating toolset filtering and domain-focused architectures.
***
## Next Steps
Understand how to create SQL tools and organize them into toolsets
Learn how to define and use toolsets for specialized agents
Start building agents with the recommended Agno framework
Explore pre-built specialized agents for performance, discovery, and more
**Architecture Philosophy**: The IBM i MCP server encourages **specialized agents** that handle specific domains rather than monolithic agents attempting all tasks. This separation of concerns aligns with IBM i's traditional design philosophy and provides better performance, security, and maintainability.
# Agent Integration
Source: https://ibm-d95bab6e.mintlify.app/cli/agent-integration
Use the IBM i CLI in AI agent workflows, shell scripts, and CI/CD pipelines with structured output and semantic exit codes.
The CLI is designed for programmatic use by AI agents, shell scripts, and automation pipelines. It provides structured JSON output, streaming, semantic exit codes, and dry-run capabilities for safe tool planning.
***
## Automatic JSON Output
When stdout is not a TTY (i.e., the CLI output is piped to another command), the CLI automatically switches to JSON output. Agents and scripts get structured data without specifying `--format json`:
```bash theme={null}
# Returns JSON automatically when piped
result=$(ibmi sql "SELECT COUNT(*) AS CNT FROM SAMPLE.EMPLOYEE")
count=$(echo "$result" | jq '.data[0].CNT')
echo "Employee count: $count"
```
***
## Exit Codes
The CLI uses semantic exit codes for programmatic error handling:
| Code | Name | Meaning |
| ---- | -------- | ------------------------------------------ |
| `0` | SUCCESS | Command completed successfully |
| `1` | GENERAL | Connection failure or unexpected error |
| `2` | USAGE | Invalid arguments or missing options |
| `3` | QUERY | SQL execution error |
| `4` | SECURITY | Read-only violation or forbidden operation |
| `5` | AUTH | Authentication failure |
### Exit Code Routing
Agents can branch logic based on exit codes:
```bash theme={null}
ibmi sql "SELECT 1 FROM SYSIBM.SYSDUMMY1" --system prod
case $? in
0) echo "Connection OK" ;;
1) echo "Connection failed โ check host/port" ;;
3) echo "SQL error โ check query syntax" ;;
5) echo "Auth failed โ check credentials" ;;
esac
```
### Error Codes in JSON
When output is JSON, errors include a machine-readable error code:
```json theme={null}
{
"ok": false,
"error": {
"code": "SQL_ERROR",
"message": "SQL0204 - BADTABLE not found in SAMPLE"
}
}
```
Error codes: `GENERAL_ERROR`, `USAGE_ERROR`, `CONNECTION_ERROR`, `QUERY_ERROR`, `SQL_ERROR`, `SECURITY_VIOLATION`, `AUTH_FAILURE`, `NOT_FOUND`, `TIMEOUT`
***
## NDJSON Streaming
Use `--stream` for newline-delimited JSON โ one object per row. This is ideal for incremental processing of large result sets:
```bash theme={null}
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --stream | while IFS= read -r row; do
name=$(echo "$row" | jq -r '.FIRSTNME')
echo "Processing: $name"
done
```
***
## Dry Run for Planning
Agents can use `--dry-run` to preview SQL without executing. This is useful for query planning and validation before committing to execution:
```bash theme={null}
# Preview SQL from a direct query
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE WHERE SALARY > 50000" --dry-run
# Preview resolved SQL from a YAML tool
ibmi tool monthly_report --schema SAMPLE --month 3 --dry-run --tools ./tools.yaml
```
Dry run requires no database connection, making it safe for agent planning steps.
***
## File Output
Write results directly to a file for pipeline processing:
```bash theme={null}
# Export query results to CSV
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --format csv --output /tmp/employees.csv
# Export to JSON
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --raw --output /tmp/employees.json
```
***
## Watch Mode for Monitoring
Repeatedly execute a command at a fixed interval. Useful for monitoring dashboards and alerting:
```bash theme={null}
# Monitor active jobs every 10 seconds
ibmi sql "SELECT JOB_NAME, CPU_TIME FROM TABLE(QSYS2.ACTIVE_JOB_INFO()) WHERE JOB_STATUS='RUN'" \
--watch 10
# Write monitoring data to a file
ibmi sql "SELECT * FROM TABLE(QSYS2.SYSTEM_STATUS())" \
--format csv --output /tmp/status.csv --watch 30
```
Press `Ctrl+C` to stop.
***
## Multi-System Workflows
Target different systems in sequence for cross-system operations:
```bash theme={null}
# Compare row counts across environments
dev_count=$(ibmi sql "SELECT COUNT(*) AS C FROM MYLIB.ORDERS" --system dev | jq '.data[0].C')
prod_count=$(ibmi sql "SELECT COUNT(*) AS C FROM MYLIB.ORDERS" --system prod | jq '.data[0].C')
echo "Dev: $dev_count, Prod: $prod_count"
```
***
## Example: Agent Script
A complete example of an AI agent using the CLI for a text-to-SQL workflow:
```bash theme={null}
#!/bin/bash
set -e
# Step 1: Discover available schemas
schemas=$(ibmi schemas --raw | jq -r '.data[].SCHEMA_NAME')
# Step 2: Find tables in target schema
tables=$(ibmi tables SAMPLE --raw | jq -r '.data[].TABLE_NAME')
# Step 3: Get column metadata for query planning
columns=$(ibmi columns SAMPLE EMPLOYEE --raw)
# Step 4: Validate the generated query (no execution)
ibmi validate "SELECT EMPNO, SALARY FROM SAMPLE.EMPLOYEE WHERE SALARY > 50000"
if [ $? -ne 0 ]; then
echo "Query validation failed"
exit 1
fi
# Step 5: Execute with confidence
ibmi sql "SELECT EMPNO, SALARY FROM SAMPLE.EMPLOYEE WHERE SALARY > 50000" --raw
```
# Command Reference
Source: https://ibm-d95bab6e.mintlify.app/cli/commands
Complete reference for all IBM i CLI commands, options, and usage examples.
All commands follow the pattern `ibmi [arguments] [options]`. [Global options](/cli/configuration#output-format-priority) (`--system`, `--format`, `--raw`, `--stream`, `--watch`, `--output`, `--tools`, `--no-color`) apply to every command.
***
## SQL Execution
### `ibmi sql [statement]`
Execute a SQL query against the target system.
```bash theme={null}
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE FETCH FIRST 10 ROWS ONLY"
ibmi sql --file query.sql
cat query.sql | ibmi sql
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --dry-run
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --format csv --output results.csv
ibmi sql "SELECT JOB_NAME FROM TABLE(QSYS2.ACTIVE_JOB_INFO())" --watch 5
```
| Option | Description | Default |
| -------------------------------- | ------------------------------------ | ----------------------- |
| `--file ` | Read SQL from a file | โ |
| `--limit ` | Maximum rows returned | system `maxRows` (5000) |
| `--read-only` / `--no-read-only` | Enforce or disable read-only mode | `--read-only` |
| `--dry-run` | Print resolved SQL without executing | โ |
**SQL source priority:** positional argument > `--file` > piped stdin.
Read-only mode is enabled by default. To execute INSERT, UPDATE, DELETE, or DDL statements, pass `--no-read-only` explicitly or set `readOnly: false` in your system config.
***
## Multi-System Execution
Run the same SQL query against multiple IBM i systems in parallel by passing a comma-separated list of system names to `--system`. Each system name must be defined in your [CLI configuration file](/cli/configuration#config-file-format) โ either the user-level config at `~/.ibmi/config.yaml` or a project-level `.ibmi/config.yaml`.
Multi-system execution requires named system connections. Ad-hoc `DB2i_*` environment variables only define a single system. See [Getting Started](/cli/getting-started#step-2-configure-a-system) for setup instructions and [Configuration](/cli/configuration#managing-systems) for managing multiple systems.
### Usage
```bash theme={null}
# Query two systems in parallel
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE FETCH FIRST 5 ROWS ONLY" --system dev,prod
# JSON output includes per-system metadata
ibmi sql "SELECT JOB_NAME, JOB_STATUS FROM TABLE(QSYS2.ACTIVE_JOB_INFO()) FETCH FIRST 10 ROWS ONLY" \
--system dev,prod --format json
# NDJSON streaming for pipeline consumption
ibmi sql "SELECT * FROM QSYS2.SYSTEM_STATUS_INFO" --system dev,prod --stream --format json
```
### Output format
Each row in the output includes a `SYSTEM` column identifying which system returned it. The JSON envelope includes a `systems` array with per-system row counts, timing, and any errors:
```json theme={null}
{
"ok": false,
"data": [
{ "SYSTEM": "dev", "EMPNO": "000010", "FIRSTNME": "CHRISTINE", ... },
{ "SYSTEM": "prod", "ERROR": "connect ECONNREFUSED ..." }
],
"systems": [
{ "system": "dev", "host": "dev.example.com", "rows": 5, "elapsed_ms": 413 },
{ "system": "prod", "host": "prod.example.com", "rows": 0, "error": "connect ECONNREFUSED ..." }
],
"meta": {
"total_rows": 5,
"systems_queried": 2,
"systems_ok": 1,
"systems_failed": 1
}
}
```
### Limitations
* `--watch` is not supported with multiple systems.
* If one system is unreachable, its results appear as an error row without affecting the other systems.
* All systems share the same `--limit` value. When no `--limit` is specified, the smallest `maxRows` across all target systems is used.
***
## Schema Discovery
### `ibmi schemas`
List available schemas (libraries) on the system.
```bash theme={null}
ibmi schemas
ibmi schemas --filter "MY%"
ibmi schemas --system-schemas # include Q* and SYS* schemas
ibmi schemas --limit 20 --offset 40 # pagination
```
| Option | Description | Default |
| -------------------- | --------------------------------------- | ------- |
| `--filter ` | SQL LIKE pattern to filter schema names | โ |
| `--system-schemas` | Include system schemas (Q\* and SYS\*) | `false` |
| `--limit ` | Rows per page | `50` |
| `--offset ` | Skip rows for pagination | `0` |
### `ibmi tables `
List tables, views, and physical files in a schema.
```bash theme={null}
ibmi tables SAMPLE
ibmi tables QSYS2 --filter "SYS%"
```
| Option | Description | Default |
| -------------------- | -------------------------------------- | ------- |
| `--filter ` | SQL LIKE pattern to filter table names | โ |
| `--limit ` | Rows per page | `50` |
| `--offset ` | Skip rows for pagination | `0` |
### `ibmi columns `
Get column metadata for a specific table.
```bash theme={null}
ibmi columns SAMPLE EMPLOYEE
```
Returns column name, data type, length, nullable, default value, description, and ordinal position.
### `ibmi related `
Discover objects that depend on a database file (views, indexes, triggers, foreign keys, logical files).
```bash theme={null}
ibmi related SAMPLE EMPLOYEE
ibmi related SAMPLE EMPLOYEE --type INDEX
```
| Option | Description | Default |
| --------------- | ------------------------------------------------------ | ------- |
| `--type ` | Filter by dependency type (e.g., INDEX, VIEW, TRIGGER) | โ |
### `ibmi describe `
Generate DDL (CREATE statements) for one or more SQL objects using `QSYS2.GENERATE_SQL`.
```bash theme={null}
# Single object
ibmi describe "SAMPLE.EMPLOYEE"
# Multiple objects (comma-separated)
ibmi describe "SAMPLE.EMPLOYEE,SAMPLE.DEPARTMENT"
# Explicit type for non-table objects
ibmi describe "QSYS2.SYSCOLUMNS" --type VIEW
# Unqualified name (defaults library to QSYS2)
ibmi describe "SYSCOLUMNS" --type VIEW
# JSON output
ibmi describe "SAMPLE.EMPLOYEE,SAMPLE.DEPARTMENT" --format json
```
| Option | Description | Default |
| --------------- | ----------- | ------- |
| `--type ` | Object type | `TABLE` |
**Valid `--type` values:** `ALIAS`, `CONSTRAINT`, `FUNCTION`, `INDEX`, `MASK`, `PERMISSION`, `PROCEDURE`, `SCHEMA`, `SEQUENCE`, `TABLE`, `TRIGGER`, `TYPE`, `VARIABLE`, `VIEW`, `XSR`
Objects are specified as `LIBRARY.OBJECT` or just `OBJECT` (defaults to `QSYS2`). When describing multiple objects, each is queried independently โ a failure on one object produces an `ERROR:` row without affecting the others.
***
### `ibmi validate ""`
Validate SQL syntax and verify referenced objects exist without executing the query.
```bash theme={null}
ibmi validate "SELECT * FROM SAMPLE.EMPLOYEE WHERE SALARY > 50000"
```
Uses `QSYS2.PARSE_STATEMENT` and cross-references tables, columns, and routines against the system catalog.
***
## YAML Tool Execution
### `ibmi tool `
Execute a YAML-defined SQL tool. Requires `--tools` to specify the YAML file(s).
```bash theme={null}
ibmi tool system_status --tools ./tools/performance/performance.yaml
ibmi tool active_job_info --limit 20 --tools ./tools/performance/performance.yaml
ibmi tool memory_pools --dry-run --tools ./tools/performance/performance.yaml
```
Each tool's YAML parameters are automatically converted to CLI flags. Parameter names are converted from `snake_case` to `--kebab-case`:
```yaml theme={null}
# YAML parameter: schema_name โ CLI flag: --schema-name
parameters:
- name: schema_name
type: string
required: true
```
| Option | Description |
| ----------- | -------------------------------------------------- |
| `--dry-run` | Show resolved SQL and parameters without executing |
### `ibmi tools`
List available tools from loaded YAML files.
```bash theme={null}
ibmi tools --tools ./tools/
ibmi tools --toolset work_management --tools ./tools/
ibmi tools show system_status --tools ./tools/
```
| Subcommand | Description |
| ------------- | --------------------------------------------- |
| *(default)* | List all available tools |
| `show ` | Show tool details (parameters, SQL statement) |
| Option | Description |
| ------------------ | ----------------------- |
| `--toolset ` | Filter tools by toolset |
### `ibmi toolsets`
List available toolsets from loaded YAML files.
```bash theme={null}
ibmi toolsets --tools ./tools/
```
***
## System Management
### `ibmi system `
Manage named system connections in `.ibmi/config.yaml`.
```bash theme={null}
ibmi system list # list all configured systems
ibmi system show dev # show system details
ibmi system add dev --host h --user u # add (prompts for missing fields)
ibmi system remove dev # remove a system
ibmi system default dev # set default system
ibmi system test dev # test connectivity
ibmi system test --all # test all systems
ibmi system config-path # show config file locations
```
| Subcommand | Description |
| ---------------- | ------------------------------------------- |
| `list` | Show all configured systems |
| `show ` | Display details for a specific system |
| `add ` | Add a new system connection |
| `remove ` | Remove a system connection |
| `default ` | Set the default system |
| `test [name]` | Test connectivity (`--all` for all systems) |
| `config-path` | Show config file locations |
***
## Shell Completions
### `ibmi completion [shell]`
Generate shell completion scripts for tab-completion of commands, options, and arguments.
```bash theme={null}
# Auto-detect shell
eval "$(ibmi completion)"
# Explicit shell
eval "$(ibmi completion bash)" # add to ~/.bashrc
eval "$(ibmi completion zsh)" # add to ~/.zshrc
ibmi completion fish | source # add to Fish config
```
Supports bash, zsh, and fish.
# Configuration
Source: https://ibm-d95bab6e.mintlify.app/cli/configuration
Configure multi-system connections, output defaults, and credential management for the IBM i CLI.
The CLI uses YAML configuration files to manage system connections. You can configure multiple IBM i systems, set a default, and switch between them with the `--system` flag.
***
## Config File Locations
The CLI loads configuration from two locations. Project-level config overrides user-level config:
| Scope | Path | Use Case |
| ----------- | ------------------------------------------------- | ---------------------------------------------- |
| **Project** | Nearest `.ibmi/config.yaml` walking up from `cwd` | Team-shared settings, project-specific systems |
| **User** | `~/.ibmi/config.yaml` | Personal systems, global defaults |
The CLI walks up the directory tree from your current working directory to find the nearest `.ibmi/config.yaml` โ similar to how `.gitignore` files work.
The `.ibmi/` directory is automatically added to `.gitignore` when you create your first system with `ibmi system add`. This prevents credentials from being committed to version control.
***
## Config File Format
```yaml theme={null}
# Default system to use when --system is not specified
default: dev
# Default output format (optional)
# Overrides TTY auto-detection when set
format: table # table | json | csv | markdown
# Named system connections
systems:
dev:
host: dev400.example.com
port: 8076
user: DEVUSER
password: ${DB2i_PASS}
readOnly: false
confirm: false
timeout: 60
maxRows: 5000
ignoreUnauthorized: true
prod:
host: prod400.example.com
port: 8076
user: ${PROD_USER}
password: ${PROD_PASS}
readOnly: true
confirm: true
```
### System Properties
| Property | Type | Default | Description |
| -------------------- | ------- | ---------- | ------------------------------------------ |
| `host` | string | *required* | IBM i hostname or IP address |
| `port` | number | `8076` | Mapepire port |
| `user` | string | *required* | IBM i user profile |
| `password` | string | โ | Password or `${ENV_VAR}` reference |
| `description` | string | โ | Human-readable label |
| `defaultSchema` | string | โ | Default schema for unqualified table names |
| `readOnly` | boolean | `true` | Restrict to SELECT statements |
| `confirm` | boolean | `false` | Prompt before executing write operations |
| `timeout` | number | `30` | Query timeout in seconds |
| `maxRows` | number | `5000` | Default row limit for queries |
| `ignoreUnauthorized` | boolean | `false` | Accept self-signed TLS certificates |
| `tools` | string | โ | Default YAML tool path for this system |
***
## Environment Variable Expansion
Use `${VAR_NAME}` syntax in config values to reference environment variables. These are expanded at load time:
```yaml theme={null}
systems:
dev:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
```
This lets you keep credentials in your shell environment or `.env` file rather than in the config file itself.
***
## System Resolution Order
When a command needs a system connection, the CLI resolves it in this priority order:
Explicit flag always wins.
```bash theme={null}
ibmi sql "SELECT 1 FROM SYSIBM.SYSDUMMY1" --system prod
```
Set in your shell or `.env` file.
```bash theme={null}
export IBMI_SYSTEM=prod
ibmi schemas
```
The `default:` key in your config file.
```yaml theme={null}
default: dev
```
If only one system is configured, it's used automatically.
Falls back to `DB2i_HOST`, `DB2i_USER`, `DB2i_PASS`, and `DB2i_PORT` from the environment. This provides zero-config compatibility with existing MCP server setups.
***
## Password Resolution
When a system connection requires authentication:
1. **Config `password` field** โ including `${ENV_VAR}` expansion
2. **Interactive prompt** โ if running in a TTY, prompts for password with hidden input
3. **Error** โ if non-interactive (piped) and no password is available
Password values are never logged, displayed in `--watch` headers, or included in error output.
***
## Managing Systems
Use `ibmi system` subcommands to manage connections:
```bash theme={null}
# Add a new system (interactive password prompt)
ibmi system add staging --host staging400.example.com --user STGUSER
# List all configured systems
ibmi system list
# Show details for a system
ibmi system show dev
# Set the default system
ibmi system default prod
# Test connectivity
ibmi system test dev
ibmi system test --all
# Remove a system
ibmi system remove staging
# Show config file locations
ibmi system config-path
```
***
## Output Format Priority
When determining the output format, the CLI checks in this order:
1. `--raw` flag (equivalent to `--format json`)
2. `--format ` flag
3. `format:` in config file
4. Auto-detect: `table` for TTY, `json` for piped output
Set a default in your config to always get consistent output:
```yaml theme={null}
format: table # always render tables, even when piped
```
# Getting Started
Source: https://ibm-d95bab6e.mintlify.app/cli/getting-started
Set up the IBM i CLI, configure your first system connection, and run your first query in under 5 minutes.
Get the `ibmi` CLI running and connected to your IBM i system.
***
## Prerequisites
* **Node.js 18+** installed on your development machine
* **Mapepire** running on your IBM i system ([Setup Guide](/setup-mapepire))
* IBM i hostname, username, and password
***
## Step 1: Install
```bash theme={null}
npm install -g @ibm/ibmi-cli
ibmi --help
```
```bash theme={null}
cd ibmi-mcp-server
npm install && npm run build && npm link -w @ibm/ibmi-cli
ibmi --help
```
***
## Step 2: Configure a System
You have two options for connecting to your IBM i system:
Create a named system connection stored in `.ibmi/config.yaml`:
```bash theme={null}
ibmi system add dev --host myhost.com --user MYUSER
```
You'll be prompted for a password interactively (hidden input). Or pass it via environment variable:
```bash theme={null}
ibmi system add dev --host myhost.com --user MYUSER --password '${DB2i_PASS}'
```
Test the connection:
```bash theme={null}
ibmi system test dev
```
You should see a success message confirming the connection to your IBM i system.
If you already have `DB2i_*` environment variables set (e.g., from your MCP server `.env` file), the CLI uses them automatically:
```bash theme={null}
export DB2i_HOST=myhost.com
export DB2i_USER=MYUSER
export DB2i_PASS=mypassword
export DB2i_PORT=8076
# No system config needed โ just run commands
ibmi schemas
```
Named system connections take priority over environment variables. See [Configuration](/cli/configuration) for the full resolution order.
***
## Step 3: Run Your First Query
```bash theme={null}
# List available schemas
ibmi schemas
# List tables in a schema
ibmi tables SAMPLE
# Run a SQL query
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE FETCH FIRST 5 ROWS ONLY"
```
You should see formatted table output like:
```
โโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโ
โ EMPNO โ FIRSTNME โ LASTNAME โ
โโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโค
โ 000010 โ CHRISTINE โ HAAS โ
โ 000020 โ MICHAEL โ THOMPSON โ
โ 000030 โ SALLY โ KWAN โ
โ 000050 โ JOHN โ GEYER โ
โ 000060 โ IRVING โ STERN โ
โโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโ
[dev] myhost.com ยท 5 rows ยท 0.12s
```
***
## Step 4: Explore
Try these commands to explore your IBM i system:
```bash theme={null}
# Get column metadata for a table
ibmi columns SAMPLE EMPLOYEE
# Validate SQL syntax before executing
ibmi validate "SELECT * FROM SAMPLE.EMPLOYEE WHERE SALARY > 50000"
# Find objects that depend on a database file
ibmi related SAMPLE EMPLOYEE
# Get JSON output instead of a table
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --raw
```
***
## Next Steps
Full reference for all commands, options, and examples
Multi-system config, output format defaults, and YAML tool paths
Table, JSON, CSV, markdown, and NDJSON streaming
Run YAML-defined SQL tools from the command line
# Output Formats
Source: https://ibm-d95bab6e.mintlify.app/cli/output-formats
Table, JSON, CSV, markdown, and NDJSON output formats for the IBM i CLI.
The CLI supports multiple output formats to suit different workflows โ interactive terminal use, scripting, data export, and AI agent integration.
***
## Format Selection
The output format is determined by this priority chain:
1. `--raw` flag (shorthand for `--format json`)
2. `--format ` flag (`table`, `json`, `csv`, `markdown`)
3. `format:` in `.ibmi/config.yaml`
4. **Auto-detect**: `table` when output is a TTY, `json` when piped
This means interactive terminal sessions default to human-readable tables, while piped commands automatically switch to machine-parseable JSON.
***
## Table (Default for TTY)
Formatted tables with box-drawing characters, column alignment, and a footer showing the system name, host, row count, and elapsed time.
```bash theme={null}
ibmi sql "SELECT EMPNO, FIRSTNME, LASTNAME FROM SAMPLE.EMPLOYEE FETCH FIRST 3 ROWS ONLY"
```
```
โโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโ
โ EMPNO โ FIRSTNME โ LASTNAME โ
โโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโค
โ 000010 โ CHRISTINE โ HAAS โ
โ 000020 โ MICHAEL โ THOMPSON โ
โ 000030 โ SALLY โ KWAN โ
โโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโ
[dev] myhost.com ยท 3 rows ยท 0.12s
```
***
## JSON
Structured JSON envelope with metadata. Default when output is piped to another command.
```bash theme={null}
ibmi sql "SELECT EMPNO, FIRSTNME FROM SAMPLE.EMPLOYEE FETCH FIRST 2 ROWS ONLY" --raw
```
```json theme={null}
{
"ok": true,
"system": "dev",
"host": "myhost.com",
"command": "execute_sql",
"data": [
{"EMPNO": "000010", "FIRSTNME": "CHRISTINE"},
{"EMPNO": "000020", "FIRSTNME": "MICHAEL"}
],
"meta": {
"rows": 2,
"hasMore": false,
"elapsed_ms": 120
}
}
```
On error:
```json theme={null}
{
"ok": false,
"error": {
"code": "SQL_ERROR",
"message": "SQL0204 - BADTABLE not found in SAMPLE"
}
}
```
***
## NDJSON (Streaming)
One JSON object per row, separated by newlines. Ideal for streaming processing and large result sets.
```bash theme={null}
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --stream
```
```
{"EMPNO":"000010","FIRSTNME":"CHRISTINE","LASTNAME":"HAAS"}
{"EMPNO":"000020","FIRSTNME":"MICHAEL","LASTNAME":"THOMPSON"}
{"EMPNO":"000030","FIRSTNME":"SALLY","LASTNAME":"KWAN"}
```
Process rows incrementally:
```bash theme={null}
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --stream | while IFS= read -r row; do
echo "$row" | jq '.EMPNO'
done
```
***
## CSV
Comma-separated values with a header row. Useful for data export and spreadsheet import.
```bash theme={null}
ibmi sql "SELECT EMPNO, FIRSTNME, LASTNAME FROM SAMPLE.EMPLOYEE" --format csv
```
```
EMPNO,FIRSTNME,LASTNAME
000010,CHRISTINE,HAAS
000020,MICHAEL,THOMPSON
000030,SALLY,KWAN
```
Export directly to a file:
```bash theme={null}
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --format csv --output employees.csv
```
***
## Markdown
Markdown-formatted table. Useful for documentation, reports, and chat tool output.
```bash theme={null}
ibmi sql "SELECT EMPNO, FIRSTNME, LASTNAME FROM SAMPLE.EMPLOYEE FETCH FIRST 3 ROWS ONLY" --format markdown
```
```markdown theme={null}
| EMPNO | FIRSTNME | LASTNAME |
|--------|-----------|----------|
| 000010 | CHRISTINE | HAAS |
| 000020 | MICHAEL | THOMPSON |
| 000030 | SALLY | KWAN |
```
***
## File Output
Write output to a file instead of stdout using `--output`:
```bash theme={null}
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --format csv --output /tmp/employees.csv
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE" --raw --output /tmp/employees.json
```
Combine with `--watch` to continuously update a file:
```bash theme={null}
ibmi sql "SELECT * FROM TABLE(QSYS2.ACTIVE_JOB_INFO()) WHERE JOB_STATUS='RUN'" \
--format csv --output /tmp/active-jobs.csv --watch 10
```
# IBM i CLI
Source: https://ibm-d95bab6e.mintlify.app/cli/overview
A lightweight command-line interface for querying, exploring, and managing IBM i systems directly from your terminal.
The `ibmi` CLI lets you interact with IBM i systems without starting the MCP server. Run SQL queries, explore schemas, execute YAML-defined tools, and manage multiple system connections โ all from your terminal.
***
## Why Use the CLI?
Query IBM i databases and explore schemas without configuring an MCP client or AI agent
Configure named connections and run queries against multiple systems in parallel with `--system dev,prod`
Structured JSON output, NDJSON streaming, semantic exit codes, and dry-run mode for AI agent integration
Execute any YAML-defined SQL tool as a CLI command with automatic parameter mapping
***
## Quick Example
```bash theme={null}
# Add a system connection
ibmi system add dev --host myhost.com --user MYUSER --password '${DB2i_PASS}'
# Run a query
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE FETCH FIRST 5 ROWS ONLY"
# Run the same query against multiple systems in parallel
ibmi sql "SELECT * FROM SAMPLE.EMPLOYEE FETCH FIRST 5 ROWS ONLY" --system dev,prod
# Explore schema metadata
ibmi schemas
ibmi tables SAMPLE
ibmi columns SAMPLE EMPLOYEE
# Generate DDL for one or more objects
ibmi describe "SAMPLE.EMPLOYEE"
ibmi describe "SAMPLE.EMPLOYEE,SAMPLE.DEPARTMENT"
# Execute a YAML tool
ibmi tool system_status --tools ./tools/performance/performance.yaml
```
If you already have `DB2i_HOST`, `DB2i_USER`, and `DB2i_PASS` environment variables set (from your MCP server `.env` file), the CLI picks them up automatically โ no additional configuration needed.
***
## How It Works
The CLI reuses the same tool logic functions that power the MCP server's built-in tools. When you run `ibmi schemas`, it calls the same `listSchemasLogic` function that the MCP server uses when an AI agent invokes the `list_schemas` tool. This means you get identical query behavior and results whether you're using the CLI directly or going through an MCP client.
For YAML-defined tools, the CLI loads tool definitions and dynamically converts YAML parameters into Commander.js options โ `snake_case` parameter names become `--kebab-case` flags automatically.
```mermaid theme={null}
graph LR
A[ibmi CLI] --> B[Tool Logic Functions]
C[MCP Server] --> B
B --> D[Mapepire Connection Pool]
D --> E[IBM i / Db2 for i]
```
***
## Installation
The CLI ships with the `@ibm/ibmi-mcp-server` package:
```bash theme={null}
# Run directly with npx
npx -y @ibm/ibmi-mcp-server@latest ibmi --help
# Or install globally
npm install -g @ibm/ibmi-mcp-server
ibmi --help
```
```bash theme={null}
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server
npm install
npm run build
npm link -w @ibm/ibmi-cli
ibmi --help
```
***
## Next Steps
Set up your first system connection and run your first query
Complete reference for all CLI commands and options
Multi-system config files, environment variables, and resolution chain
Use the CLI in scripts, pipelines, and AI agent workflows
# YAML Tool Execution
Source: https://ibm-d95bab6e.mintlify.app/cli/yaml-tools
Run YAML-defined SQL tools from the command line with automatic parameter mapping.
The CLI can execute any YAML-defined SQL tool as a command. Tool parameters are automatically converted to CLI flags, giving you a type-safe command-line interface for every tool in your YAML files.
***
## How It Works
When you run `ibmi tool `, the CLI:
1. Loads the YAML file(s) specified by `--tools`
2. Finds the tool by name
3. Converts its parameters to Commander.js options (`snake_case` becomes `--kebab-case`)
4. Validates required parameters and type constraints
5. Executes the SQL with bind parameters
6. Renders the result in the selected output format
***
## Running a Tool
```bash theme={null}
ibmi tool system_status --tools ./tools/performance/performance.yaml
```
Pass parameters as flags:
```bash theme={null}
ibmi tool active_job_info \
--limit 20 \
--tools ./tools/performance/performance.yaml
```
### Dry Run
Preview the resolved SQL and parameters without executing:
```bash theme={null}
ibmi tool active_job_info --limit 5 --dry-run --tools ./tools/performance/performance.yaml
```
```
-- Dry Run: active_job_info
-- Parameters: limit=5
SELECT CPU_TIME, A.* FROM
TABLE(QSYS2.ACTIVE_JOB_INFO(SUBSYSTEM_LIST_FILTER => 'QUSRWRK,QSYSWRK')) A
ORDER BY CPU_TIME DESC
FETCH FIRST ? ROWS ONLY
Bind values: [5]
```
***
## Discovering Tools
### List All Tools
```bash theme={null}
ibmi tools --tools ./tools/
```
### Filter by Toolset
```bash theme={null}
ibmi tools --toolset performance --tools ./tools/
```
### Show Tool Details
View a tool's description, parameters, and SQL statement:
```bash theme={null}
ibmi tools show system_status --tools ./tools/
```
### List Toolsets
```bash theme={null}
ibmi toolsets --tools ./tools/
```
***
## Parameter Mapping
YAML parameter definitions map directly to CLI flags:
| YAML Parameter | CLI Flag | Type Handling |
| ------------------- | --------------------- | ------------------------ |
| `name: schema_name` | `--schema-name` | Underscore to kebab-case |
| `type: string` | String value | Passed as-is |
| `type: integer` | Number value | Parsed and validated |
| `type: boolean` | Boolean flag | `--flag` or `--no-flag` |
| `required: true` | Required option | Error if missing |
| `default: 50` | Optional with default | Used when not specified |
### Example
Given this YAML tool definition:
```yaml theme={null}
tools:
find_employees:
source: ibmi-system
description: "Find employees by department"
parameters:
- name: department
type: string
required: true
description: "Department code"
- name: limit
type: integer
default: 50
minimum: 1
maximum: 500
statement: |
SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT
FROM SAMPLE.EMPLOYEE
WHERE WORKDEPT = :department
FETCH FIRST :limit ROWS ONLY
```
The CLI command would be:
```bash theme={null}
ibmi tool find_employees --department A00 --limit 10 --tools ./tools/custom.yaml
```
***
## Multiple YAML Files
Load tools from multiple files or directories:
```bash theme={null}
# Multiple files (comma-separated)
ibmi tools --tools ./tools/performance/performance.yaml,./tools/security/security-ops.yaml
# Entire directory
ibmi tools --tools ./tools/
```
When loading a directory, all `.yaml` and `.yml` files are loaded and merged. Tool names must be unique across all loaded files.
The `--tools` flag uses the same YAML format as the MCP server's `--tools` option. You can use the same tool files for both the CLI and the server.
# IBM Bob
Source: https://ibm-d95bab6e.mintlify.app/clients/bob
Configure IBM i MCP Server with IBM Bob, IBM's AI-powered development assistant
# IBM Bob Integration
IBM Bob is IBM's AI-powered development assistant and IDE designed for enterprise software development.
**Platform Support**: Windows, macOS, Linux
**Transport Modes**: Stdio (local) and HTTP (remote)
**MCP Client**: Built-in MCP client for connecting to MCP servers
## Prerequisites
Ensure you have IBM Bob installed and configured:
```bash theme={null}
# Verify Bob installation
bob --version
```
**Getting Bob**: IBM Bob is available to IBM employees and authorized partners. Visit the [IBM Bob product page](https://www.ibm.com/products/bob) for access information.
## Configuration File Location
Bob stores its MCP server configuration in:
**Location**: `~/.bob/mcp.json` or `%USERPROFILE%\.bob\mcp.json` (Windows)
**Benefits**:
* Available across all projects
* Personal configuration
* Not shared via version control
**Location**: `.bob/mcp.json` in your project root
**Benefits**:
* Shared with team via version control
* Project-specific MCP servers
* Consistent across team members
## Local (Stdio) Setup
Configure a local server that Bob will spawn and manage:
### Using Configuration File
Create or edit your MCP configuration file:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio",
"NODE_OPTIONS": "--no-deprecation"
}
}
}
}
```
**Important**:
* The `--tools` path must be an **absolute path**
* Replace credentials with your actual IBM i system details
* Ensure the user profile has appropriate database authorities
## Remote (HTTP) Setup
Connect to a remote IBM i MCP Server:
### Step 1: Start Remote Server
On your server machine, configure and start the MCP server with authentication:
```bash theme={null}
# Configure .env file
MCP_TRANSPORT_TYPE=http
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
# Start server
npm run start:http
```
### Step 2: Obtain Access Token
```bash theme={null}
# Generate access token
node get-access-token.js --verbose
# Copy the token from output
```
### Step 3: Configure Bob
Edit your MCP configuration file:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
**Production**: Replace `http://localhost:3010` with your production server URL and ensure HTTPS is enabled for secure communication.
## Environment Variable Expansion
Bob supports environment variable expansion for secure credential management:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "${IBMI_TOOLS_PATH}"],
"env": {
"DB2i_HOST": "${DB2i_HOST}",
"DB2i_USER": "${DB2i_USER}",
"DB2i_PASS": "${DB2i_PASS}",
"DB2i_PORT": "${DB2i_PORT:-8076}",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
**Supported syntax:**
* `${VAR}` - Expands to the value of environment variable `VAR`
* `${VAR:-default}` - Expands to `VAR` if set, otherwise uses `default`
## Testing the Connection
After configuration, restart Bob and verify the MCP server connection:
1. **Restart Bob**: Close and reopen the Bob IDE
2. **Check MCP status**: Look for MCP indicators in the Bob interface
3. **List available tools**: Ask Bob "What MCP tools are available?"
4. **Test a tool**: Try "Show me the IBM i system status using MCP"
## Troubleshooting
**Symptoms**: MCP server doesn't show up in Bob
**Solutions**:
* Verify JSON syntax in your MCP configuration file
* Check that `npx -y @ibm/ibmi-mcp-server@latest` works from terminal
* Ensure absolute paths are used for `--tools`
* Restart Bob completely
* Check Bob logs for MCP-related errors
**Symptoms**: Connection refused or 401 Unauthorized for remote connections
**Solutions**:
* Verify server is running: `curl http://localhost:3010/mcp`
* Check token is valid: verify token hasn't expired (default: 1 hour)
* Ensure `MCP_AUTH_MODE=ibmi` and `IBMI_HTTP_AUTH_ENABLED=true` on server
* Get a fresh token: `node get-access-token.js --verbose`
* Confirm Authorization header format: `Bearer TOKEN`
**Symptoms**: Server connects but no tools available
**Solutions**:
* Verify tools path exists and is absolute
* Check YAML files are valid in tools directory
* Ensure IBM i credentials are correct
* Verify Mapepire is running on IBM i (port 8076)
* Test tools: `npx -y @ibm/ibmi-mcp-server@latest --list-toolsets --tools /path`
**Symptoms**: Server starts but can't connect to IBM i
**Solutions**:
* Test IBM i connectivity: `ping your-ibmi-host`
* Verify Mapepire is running: `netstat -an | grep 8076`
* Check firewall allows port 8076
* Ensure DB2i credentials have appropriate authorities
* Verify hostname resolution
## Advanced Configuration
### Multiple IBM i Systems
Configure multiple server instances for different IBM i systems:
```json theme={null}
{
"mcpServers": {
"ibmi-dev": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/path/to/dev-tools"],
"env": {
"DB2i_HOST": "dev-ibmi.company.com",
"DB2i_USER": "DEVUSER",
"DB2i_PASS": "${DEV_PASSWORD}",
"MCP_TRANSPORT_TYPE": "stdio"
}
},
"ibmi-prod": {
"url": "https://prod-mcp.company.com/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer ${PROD_MCP_TOKEN}"
}
}
}
}
```
### Custom Toolsets
Load specific toolsets for different workflows:
```json theme={null}
{
"mcpServers": {
"ibmi-performance": {
"command": "npx",
"args": [
"-y",
"@ibm/ibmi-mcp-server@latest",
"--tools", "/path/to/tools",
"--toolsets", "performance,monitoring"
],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "${DB2i_USER}",
"DB2i_PASS": "${DB2i_PASS}",
"MCP_TRANSPORT_TYPE": "stdio"
}
},
"ibmi-security": {
"command": "npx",
"args": [
"-y",
"@ibm/ibmi-mcp-server@latest",
"--tools", "/path/to/tools",
"--toolsets", "security,audit"
],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "${DB2i_USER}",
"DB2i_PASS": "${DB2i_PASS}",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
## Next Steps
Create custom SQL tools for your IBM i workflows
Explore all IBM i MCP Server configuration options
Set up secure IBM i HTTP authentication
Explore other MCP-compatible clients
## Additional Resources
* [IBM Bob Product Page](https://www.ibm.com/products/bob)
* [IBM Bob Documentation](https://pages.github.ibm.com/code-assistant/bob-docs/) (IBM Internal)
* [IBM i MCP Server on IT Jungle](https://www.itjungle.com/2025/10/27/beta-of-mcp-server-opens-up-ibm-i-for-agentic-ai/)
* [IBM i MCP Quick Start](/quickstart)
**Internal Documentation**: For IBM employees, detailed Bob MCP configuration is available at [Bob MCP Documentation](https://pages.github.ibm.com/code-assistant/bob-docs/features/mcp/using-mcp-in-bob/).
# Claude Code
Source: https://ibm-d95bab6e.mintlify.app/clients/claude-code
Configure IBM i MCP Server with Claude Code CLI tool
Claude Code is the official CLI tool for Claude that provides built-in MCP server management commands. It supports both local (stdio) and remote (HTTP) server connections with a simple command-line interface.
**Platform Support**: macOS, Linux, Windows
**Transport Modes**: Stdio (local) and HTTP (remote)
**Authentication**: Bearer Token for HTTP mode
## Prerequisites
Ensure you have Claude Code installed:
```bash theme={null}
# Check if installed
claude --version
# Install if needed (follow official documentation)
```
## Local (Stdio) Setup
Configure a local server that Claude Code will spawn and manage:
### Using CLI Commands
**Option 1: Interactive setup**
```bash theme={null}
claude mcp add ibmi-mcp \
-e DB2i_HOST=your-ibmi-host.com \
-e DB2i_USER=your-username \
-e DB2i_PASS=your-password \
-e DB2i_PORT=8076 \
-e MCP_TRANSPORT_TYPE=stdio \
-- npx -y @ibm/ibmi-mcp-server@latest --tools /absolute/path/to/tools
```
**Option 2: With environment variable file**
```bash theme={null}
# Create .env file with credentials first
claude mcp add ibmi-mcp \
-- npx -y @ibm/ibmi-mcp-server@latest --tools /absolute/path/to/tools
```
### Using Configuration File
Edit `~/.claude.json`:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio",
"NODE_OPTIONS": "--no-deprecation"
}
}
}
}
```
**Important**: The `--tools` path must be an **absolute path**, not relative.
## Remote (HTTP) Setup
Connect to a remote IBM i MCP Server:
### Using CLI Commands
```bash theme={null}
# Add remote HTTP server with authentication
claude mcp add -t http ibmi-mcp \
http://localhost:3010/mcp \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
```
### Using Configuration File
Edit `~/.claude.json`:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
**Getting Access Tokens**: Use `node get-access-token.js --verbose` from the server directory to obtain authentication tokens.
## Environment Variable Expansion
Claude Code supports environment variable expansion for secure credential management:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "${IBMI_TOOLS_PATH}"],
"env": {
"DB2i_HOST": "${DB2i_HOST}",
"DB2i_USER": "${DB2i_USER}",
"DB2i_PASS": "${DB2i_PASS}",
"DB2i_PORT": "${DB2i_PORT:-8076}",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
**Supported syntax:**
* `${VAR}` - Expands to the value of environment variable `VAR`
* `${VAR:-default}` - Expands to `VAR` if set, otherwise uses `default`
## Managing Servers
Claude Code provides convenient commands for managing MCP servers:
```bash theme={null}
# List all configured servers
claude mcp list
# Get details about a specific server
claude mcp get ibmi-mcp
# Remove a server
claude mcp remove ibmi-mcp
# Check server status in Claude Code
/mcp
```
## Testing the Connection
After configuration:
```bash theme={null}
# Start Claude Code and check MCP status
claude
# In Claude Code, check MCP servers
/mcp
# List available tools
"What tools do you have available?"
# Test a tool
"Show me the IBM i system status"
```
## CLI Options for Server Command
When adding servers, you can use various CLI options:
```bash theme={null}
# With specific toolsets
claude mcp add ibmi-mcp \
-- npx -y @ibm/ibmi-mcp-server@latest \
--tools /path/to/tools \
--toolsets performance,security
# With explicit stdio transport
claude mcp add -t stdio ibmi-mcp \
-- npx -y @ibm/ibmi-mcp-server@latest \
--tools /path/to/tools
# List available toolsets
npx -y @ibm/ibmi-mcp-server@latest --list-toolsets --tools /path/to/tools
```
## Troubleshooting
**Symptoms**: `npx: command not found` or `ibmi-mcp-server: not found`
**Solutions**:
* Ensure Node.js and npm are installed: `node --version`
* Install server globally: `npm link` from server directory
* Use full node path:
```bash theme={null}
claude mcp add ibmi-mcp \
-- node /absolute/path/to/ibmi-mcp-server/dist/index.js \
--tools /absolute/path/to/tools
```
**Symptoms**: 401 Unauthorized for remote connections
**Solutions**:
* Get fresh token: `node get-access-token.js --verbose`
* Verify server is running with auth enabled
* Check token hasn't expired (default: 1 hour)
* Ensure header format is correct: `Authorization: Bearer TOKEN`
**Symptoms**: Server starts but no tools available
**Solutions**:
* Verify tools path is absolute: `/full/path/to/tools`
* Check YAML files are valid
* Test tools path: `npx -y @ibm/ibmi-mcp-server@latest --list-toolsets --tools /path`
* Check IBM i connection credentials
## Advanced Configuration
### Multiple Environments
Configure different servers for dev and production:
```json theme={null}
{
"mcpServers": {
"ibmi-dev": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/path/to/dev-tools"],
"env": {
"DB2i_HOST": "dev-ibmi.company.com",
"DB2i_USER": "DEVUSER",
"DB2i_PASS": "devpass",
"MCP_TRANSPORT_TYPE": "stdio"
}
},
"ibmi-prod": {
"url": "https://prod-mcp.company.com/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer ${PROD_MCP_TOKEN}"
}
}
}
}
```
### Custom Tool Paths
Switch between different tool configurations:
```bash theme={null}
# Add server with custom tools
claude mcp add ibmi-performance \
-- npx -y @ibm/ibmi-mcp-server@latest \
--tools /path/to/performance-tools \
--toolsets monitoring,diagnostics
# Add server with all tools
claude mcp add ibmi-all \
-- npx -y @ibm/ibmi-mcp-server@latest \
--tools /path/to/all-tools
```
## Next Steps
Learn all CLI options for the server
Explore environment variables
Create custom SQL operations
Explore other MCP clients
## Additional Resources
* [Claude Code MCP Documentation](https://docs.claude.com/en/docs/claude-code/mcp)
* [IBM i MCP Quick Start](/quickstart)
* [Authentication Setup](/configuration#ibm-i-authentication-settings)
# Claude Desktop
Source: https://ibm-d95bab6e.mintlify.app/clients/claude-desktop
Configure IBM i MCP Server with Claude Desktop app for macOS and Windows
Claude Desktop is the official desktop application for Claude, available for macOS and Windows. It provides a rich interface for interacting with Claude while supporting MCP servers for extended capabilities.
**Platform Support**: macOS and Windows
**Transport Mode**: Stdio (local process management)
**Note**: For remote HTTP servers, use Claude Code instead
## Configuration File Location
Claude Desktop stores its MCP server configuration in:
```bash theme={null}
~/Library/Application Support/Claude/claude_desktop_config.json
```
```bash theme={null}
%APPDATA%\Claude\claude_desktop_config.json
```
## Local (Stdio) Setup
For local development with the server running on your machine:
**Step 1: Ensure server is installed**
```bash theme={null}
cd ibmi-mcp-server
npm install && npm run build
npm link
```
**Step 2: Edit configuration file**
Edit `claude_desktop_config.json`:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio",
"NODE_OPTIONS": "--no-deprecation"
}
}
}
}
```
**Important**:
* The `--tools` path must be an **absolute path**
* Replace credentials with your actual IBM i system details
* User profile must have appropriate database authorities
**Step 3: Restart Claude Desktop**
Close and reopen Claude Desktop to load the new configuration.
**Remote Servers**: Claude Desktop only supports local stdio servers. For connecting to remote MCP servers via HTTP, use [Claude Code](/clients/claude-code#remote-http-setup) instead, which supports HTTP transport.
## Environment Variable Expansion
Claude Desktop supports environment variable expansion for secure credential management:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "${IBMI_TOOLS_PATH}"],
"env": {
"DB2i_HOST": "${DB2i_HOST}",
"DB2i_USER": "${DB2i_USER}",
"DB2i_PASS": "${DB2i_PASS}",
"DB2i_PORT": "${DB2i_PORT:-8076}",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
**Supported syntax:**
* `${VAR}` - Expands to the value of environment variable `VAR`
* `${VAR:-default}` - Expands to `VAR` if set, otherwise uses `default`
**Set environment variables** (before launching Claude Desktop):
```bash theme={null}
# macOS/Linux
export DB2i_HOST=your-ibmi-host.com
export DB2i_USER=your-username
export DB2i_PASS=your-password
export IBMI_TOOLS_PATH=/absolute/path/to/tools
# Windows (PowerShell)
$env:DB2i_HOST="your-ibmi-host.com"
$env:DB2i_USER="your-username"
$env:DB2i_PASS="your-password"
$env:IBMI_TOOLS_PATH="C:\path\to\tools"
```
## Testing the Connection
After configuring and restarting Claude Desktop:
1. **Check MCP status**: Look for the MCP icon (plug symbol) in Claude Desktop
2. **List available tools**: Ask Claude "What tools do you have available?"
3. **Test a tool**: Try "Show me the system status of my IBM i"
If configured correctly, Claude should list the IBM i MCP tools and be able to execute them.
## Troubleshooting
**Symptoms**: MCP server doesn't show up in Claude Desktop
**Solutions**:
* Verify JSON syntax in `claude_desktop_config.json`
* Check that `npx -y @ibm/ibmi-mcp-server@latest` works from terminal
* Ensure absolute paths are used for `--tools`
* Restart Claude Desktop completely (Cmd+Q / Alt+F4, then relaunch)
* Check Claude Desktop logs for errors
**Symptoms**: Connection refused or 401 Unauthorized
**Solutions**:
* Verify server is running: `curl http://localhost:3010/mcp`
* Check token is valid: `echo $IBMI_MCP_ACCESS_TOKEN`
* Ensure token hasn't expired (default: 1 hour)
* Confirm `MCP_AUTH_MODE=ibmi` and `IBMI_HTTP_AUTH_ENABLED=true`
* Get a fresh token: `node get-access-token.js --verbose`
**Symptoms**: Server connects but no tools available
**Solutions**:
* Verify tools path exists and is absolute
* Check YAML files are valid: `npm run validate -- --config tools`
* Ensure IBM i credentials are correct
* Verify Mapepire is running on IBM i: `sc check mapepire`
* Check server logs for tool loading errors
**Symptoms**: Server starts but can't connect to IBM i
**Solutions**:
* Test IBM i connectivity: `ping your-ibmi-host`
* Verify Mapepire is running: `netstat -an | grep 8076`
* Check firewall allows port 8076
* Verify credentials with: `node get-access-token.js --verbose`
* Ensure user has database authorities
## Advanced Configuration
### Multiple IBM i Systems
Configure multiple server instances for different IBM i systems:
```json theme={null}
{
"mcpServers": {
"ibmi-dev": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/path/to/dev-tools"],
"env": {
"DB2i_HOST": "dev-ibmi.company.com",
"DB2i_USER": "DEVUSER",
"DB2i_PASS": "devpass",
"MCP_TRANSPORT_TYPE": "stdio"
}
},
"ibmi-prod": {
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/path/to/prod-tools"],
"env": {
"DB2i_HOST": "prod-ibmi.company.com",
"DB2i_USER": "PRODUSER",
"DB2i_PASS": "${PROD_PASSWORD}",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
### Custom Tool Sets
Load specific toolsets instead of all tools:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": [
"-y",
"@ibm/ibmi-mcp-server@latest",
"--tools", "/absolute/path/to/tools",
"--toolsets", "performance,security"
],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
## Next Steps
Explore all environment variables and settings
Learn how to create custom SQL tools
Set up secure IBM i HTTP authentication
Explore other MCP-compatible clients
## Additional Resources
* [Claude Desktop Documentation](https://modelcontextprotocol.io/quickstart/user)
* [MCP Specification](https://modelcontextprotocol.io/specification)
* [IBM i MCP Quick Start](/quickstart)
* [Troubleshooting Guide](/clients/overview#troubleshooting)
# Cline
Source: https://ibm-d95bab6e.mintlify.app/clients/cline
Configure IBM i MCP Server with Cline VSCode extension
Cline is a VSCode extension that brings AI-powered development capabilities with MCP server support. It can be configured through both the marketplace and manual configuration.
**Platform**: VSCode Extension
**Transport Modes**: Stdio (local) and HTTP (remote)
**Prerequisites**: [Cline](https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev) installed in VSCode
## Installation
Install Cline from the VSCode marketplace:
1. Open VSCode
2. Go to Extensions (Cmd/Ctrl+Shift+X)
3. Search for "Cline"
4. Click Install
## Local (Stdio) Setup
**Step 1: Open Cline configuration**
1. Open **Cline** in VSCode
2. Click the hamburger menu icon (โฐ) โ **MCP Servers**
3. Choose **Local Servers** tab
4. Click **Edit Configuration**
**Step 2: Add configuration**
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
The `--tools` path must be an **absolute path**.
**Step 3: Save and restart**
Save the configuration and restart Cline to load the new server.
## Remote (HTTP) Setup
**Step 1: Start remote server**
```bash theme={null}
# On server machine
npm run start:http
```
**Step 2: Obtain access token**
```bash theme={null}
node get-access-token.js --verbose
```
**Step 3: Open Cline configuration**
1. Open **Cline**
2. Click the hamburger menu icon (โฐ) โ **MCP Servers**
3. Choose **Remote Servers** tab
4. Click **Edit Configuration**
**Step 4: Add remote server**
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "streamableHttp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
Cline uses `"type": "streamableHttp"` for HTTP connections (not just `"http"`).
## Testing the Connection
After configuration:
1. Open Cline panel in VSCode
2. Check that the MCP server appears in the server list
3. Ask "What tools are available?"
4. Test with "Show me the IBM i system status"
## Troubleshooting
**Solutions**:
* Verify JSON syntax in configuration
* Restart VSCode (not just Cline)
* Check that `npx -y @ibm/ibmi-mcp-server@latest` works from terminal
* Ensure all paths are absolute
* Check VSCode Output panel for errors
**Solutions**:
* Verify IBM i credentials are correct
* Check Mapepire is running: `sc check mapepire`
* Test connectivity: `ping your-ibmi-host`
* Ensure port 8076 is accessible
**Solutions**:
* Verify server is running: `curl http://localhost:3010/mcp`
* Check token hasn't expired
* Get fresh token: `node get-access-token.js --verbose`
* Ensure `streamableHttp` type is used (not just `http`)
**Solutions**:
* Verify tools path exists and is absolute
* Check YAML files are valid: `npm run validate -- --config tools`
* Review Cline logs for tool loading errors
* Ensure user has database authorities
## Advanced Configuration
### Multiple Environments
Configure different servers for dev and production:
```json theme={null}
{
"mcpServers": {
"ibmi-dev": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/path/to/dev-tools"],
"env": {
"DB2i_HOST": "dev-ibmi.company.com",
"DB2i_USER": "DEVUSER",
"DB2i_PASS": "devpass",
"MCP_TRANSPORT_TYPE": "stdio"
}
},
"ibmi-prod": {
"url": "https://prod-mcp.company.com/mcp",
"type": "streamableHttp",
"headers": {
"Authorization": "Bearer PROD_TOKEN"
}
}
}
}
```
### Custom Toolsets
Load specific toolsets for focused workflows:
```json theme={null}
{
"mcpServers": {
"ibmi-performance": {
"command": "npx",
"args": [
"@ibm/ibmi-mcp-server@latest", "-y",
"--tools", "/path/to/tools",
"--toolsets", "performance,security"
],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
## MCP Marketplace
Cline also supports discovering MCP servers through the [Cline MCP Marketplace](https://cline.bot/mcp-marketplace), though manual configuration provides more flexibility for custom setups.
## Next Steps
Create custom SQL tools
Explore all configuration options
Set up secure authentication
Explore other MCP clients
## Additional Resources
* [Cline MCP Documentation](https://docs.cline.bot/mcp/mcp-overview)
* [Cline MCP Marketplace](https://cline.bot/mcp-marketplace)
* [IBM i MCP Quick Start](/quickstart)
* [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev)
# Cursor
Source: https://ibm-d95bab6e.mintlify.app/clients/cursor
Configure IBM i MCP Server with Cursor AI-first code editor
Cursor is an AI-first code editor with native MCP support. It provides seamless integration with MCP servers for enhanced AI capabilities.
**Platform Support**: macOS, Linux, Windows
**Transport Modes**: Stdio (local) and HTTP (remote)
**Configuration**: `.cursor/mcp.json` or Cursor settings
## Local (Stdio) Setup
**Configuration file**: Add to Cursor settings or `.cursor/mcp.json` in your project:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
The `--tools` path must be an **absolute path**.
## Remote (HTTP) Setup
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
## Testing the Connection
1. Restart Cursor after configuration
2. Open the AI chat panel
3. Ask "What tools are available?"
4. Test with "Show me the IBM i system status"
## Troubleshooting
* Verify JSON syntax in configuration file
* Restart Cursor completely
* Check that `npx -y @ibm/ibmi-mcp-server@latest` works from terminal
* Ensure all paths are absolute
* Verify server is running with authentication enabled
* Check token hasn't expired
* Get fresh token: `node get-access-token.js --verbose`
## Next Steps
Create custom SQL tools
Explore all configuration options
Basic server setup guide
Explore other MCP clients
## Additional Resources
* [Cursor MCP Documentation](https://docs.cursor.com/context/model-context-protocol)
* [IBM i MCP Quick Start](/quickstart)
* [Configuration Reference](/configuration)
# Gemini CLI
Source: https://ibm-d95bab6e.mintlify.app/clients/gemini-cli
Configure IBM i MCP Server with Google's Gemini CLI
The Gemini CLI provides command-line access to Google's Gemini AI models with MCP server support for enhanced capabilities.
**Platform Support**: macOS, Linux, Windows
**Transport Modes**: Stdio (local) and HTTP (remote)
**Configuration**: `~/.gemini/settings.json`
## Configuration File Location
Gemini CLI stores its MCP server configuration at:
```bash theme={null}
~/.gemini/settings.json
```
Where `~` is your home directory.
## Local (Stdio) Setup
**Step 1: Install Gemini CLI** (if not already installed)
```bash theme={null}
# Follow installation instructions from Gemini CLI documentation
```
**Step 2: Edit settings file**
Open `~/.gemini/settings.json` and add the following to the `mcpServers` object:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
The `--tools` path must be an **absolute path**, not relative.
## Remote (HTTP) Setup
For connecting to a remote IBM i MCP Server:
**Step 1: Start remote server**
```bash theme={null}
# On server machine
npm run start:http
```
**Step 2: Obtain access token**
```bash theme={null}
node get-access-token.js --verbose
```
**Step 3: Edit settings file**
Add to `~/.gemini/settings.json`:
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
**Production**: Replace `http://localhost:3010` with your production server URL and use HTTPS.
## Testing the Connection
After configuration:
```bash theme={null}
# Start Gemini CLI
gemini
# Ask about available tools
> What tools are available?
# Test IBM i integration
> Show me the IBM i system status
```
## Multiple Servers
You can configure multiple MCP servers for different purposes:
```json theme={null}
{
"mcpServers": {
"ibmi-dev": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/path/to/dev-tools"],
"env": {
"DB2i_HOST": "dev-ibmi.company.com",
"DB2i_USER": "devuser",
"DB2i_PASS": "devpass",
"MCP_TRANSPORT_TYPE": "stdio"
}
},
"ibmi-prod": {
"url": "https://prod-mcp.company.com/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer PROD_TOKEN"
}
}
}
}
```
## Troubleshooting
**Solutions**:
* Verify `~/.gemini/settings.json` exists and has valid JSON
* Check that `npx -y @ibm/ibmi-mcp-server@latest` works from terminal
* Ensure Node.js and npm are in PATH
* Restart Gemini CLI after configuration changes
**Solutions**:
* Verify tools path is absolute: `/full/path/to/tools`
* Check YAML files are valid
* Ensure IBM i credentials are correct
* Verify Mapepire is running on IBM i
**Solutions**:
* Confirm server is running with auth enabled
* Verify token hasn't expired
* Get fresh token: `node get-access-token.js --verbose`
* Check Authorization header format
## Custom Toolsets
Load specific toolsets for focused workflows:
```json theme={null}
{
"mcpServers": {
"ibmi-performance": {
"command": "npx",
"args": [
"@ibm/ibmi-mcp-server@latest", "-y",
"--tools", "/path/to/tools",
"--toolsets", "performance,monitoring"
],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
## Next Steps
Create custom SQL operations
Explore all configuration options
Basic server setup
Explore other MCP clients
## Additional Resources
* [Gemini CLI MCP Documentation](https://geminicli.com/docs/tools/mcp-server/)
* [Gemini CLI Installation](https://google-gemini.github.io/gemini-cli/)
* [IBM i MCP Quick Start](/quickstart)
# Client Integration Overview
Source: https://ibm-d95bab6e.mintlify.app/clients/overview
Connect the IBM i MCP Server to Claude Desktop, VSCode, Cursor, and 10+ other MCP-compatible clients
# Client Integration Overview
The IBM i MCP Server can be integrated into any MCP-compatible client using either **local** (stdio) or **remote** (HTTP) connections. This guide provides an overview of supported clients and helps you choose the right integration approach.
**Prerequisites**: Before integrating with clients, ensure you have:
* IBM i MCP Server installed and built (`npm install && npm run build`)
* Mapepire running on your IBM i system (see [Setup Mapepire](/setup-mapepire))
* Your IBM i connection details (host, user, password, port)
## Supported MCP Clients
The IBM i MCP Server works with popular MCP-compatible clients across different platforms:
Official desktop app for macOS and Windows
CLI tool with server management commands
IBM's AI-powered development assistant
GitHub Copilot Chat integration
AI-first code editor
Google AI command-line integration
VSCode extension for AI development
## Transport Modes
The IBM i MCP Server supports two transport protocols:
**Standard Input/Output** - Direct process communication
**Characteristics**:
* Runs locally on your machine
* Lower latency
* No network configuration needed
* Each client spawns its own server process
**Best for**:
* Desktop applications (Claude Desktop, Cursor)
* CLI tools (Claude Code)
* Development and testing
* Single-user scenarios
**Requirements**:
* Server must be installed locally
* Absolute path to tools directory
* Environment variables in client config
**HTTP/WebSocket** - Network-based communication
**Characteristics**:
* Runs on a remote server
* Shared server instance
* Requires authentication (recommended)
* Network accessible
**Best for**:
* Team collaboration
* Production deployments
* Cloud environments
* Multiple users sharing resources
**Requirements**:
* Server running with HTTP transport
* Network accessibility
* Authentication tokens (IBM i auth recommended)
* HTTPS for production
## Client Comparison
| Client | Platform | Stdio | HTTP | Authentication | Notes |
| ------------------ | -------------- | :---: | :--: | :------------: | --------------------------------- |
| **Claude Desktop** | macOS, Windows | โ
| โ | N/A | Official desktop app (stdio only) |
| **Claude Code** | CLI | โ
| โ
| Bearer Token | CLI server management |
| **IBM Bob** | IDE | โ
| โ
| Bearer Token | IBM's AI assistant (6,000+ users) |
| **VSCode** | Editor | โ
| โ
| Bearer Token | Via Copilot Chat |
| **Cursor** | Editor | โ
| โ
| Bearer Token | AI-first code editor |
| **Gemini CLI** | CLI | โ
| โ
| Bearer Token | Google AI integration |
| **Cline** | VSCode Ext | โ
| โ
| Bearer Token | streamableHttp support |
## Setup Prerequisites
### For Local (Stdio) Setup
The easiest way to get started - no installation needed!
1. **Verify npx is available:**
```bash theme={null}
npx --version
```
2. **Test the package:**
```bash theme={null}
npx -y @ibm/ibmi-mcp-server@latest --help
```
3. **Note your tools path:**
* Must be an **absolute path**
* Example: `/Users/yourname/myproject/tools`
* Or use `--tools $(pwd)/tools` for relative paths
**Benefits:**
* โ
Always up-to-date with latest stable release
* โ
No build step required
* โ
Works across all clients (Claude Desktop, VSCode, Cursor)
* โ
Automatic dependency management
For development or custom modifications:
1. **Install the server globally:**
```bash theme={null}
cd ibmi-mcp-server
npm install
npm run build
npm link -w @ibm/ibmi-mcp-server
```
2. **Verify installation:**
```bash theme={null}
which ibmi-mcp-server
```
3. **Note your tools path:**
* Must be an **absolute path**
* Example: `/Users/yourname/ibmi-mcp-server/tools`
**Benefits:**
* Access to latest development features
* Ability to modify and customize
* Debug at source level
### For Remote (HTTP) Setup
1. **Configure server for HTTP with authentication:**
```bash theme={null}
# In your .env file
MCP_TRANSPORT_TYPE=http
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
IBMI_AUTH_ALLOW_HTTP=true # Development only
```
2. **Generate RSA keypair (for IBM i auth):**
```bash theme={null}
mkdir -p secrets
openssl genpkey -algorithm RSA -out secrets/private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in secrets/private.pem -out secrets/public.pem
```
3. **Start the server:**
```bash theme={null}
npm run start:http
```
4. **Obtain access token:**
```bash theme={null}
node get-access-token.js --verbose
export IBMI_MCP_ACCESS_TOKEN="your-token-here"
```
## Authentication Methods
```bash theme={null}
MCP_AUTH_MODE=none
```
**Use for**: Local development, testing, trusted networks
**โ ๏ธ Warning**: Never use in production
```bash theme={null}
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
IBMI_AUTH_KEY_ID=production
IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
```
**Use for**: Per-user credentials, connection pooling, production
**Features**:
* Secure RSA+AES encryption
* Per-user connection pools
* Token-based access
* IBM i credential validation
```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
```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
## Common Configuration Patterns
```json Claude Desktop (Local) theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
```json Claude Desktop (Remote) theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
```bash Claude Code (CLI) theme={null}
# Add local stdio server
claude mcp add ibmi-mcp \
--env DB2i_HOST=your-ibmi-host.com \
--env DB2i_USER=your-username \
--env DB2i_PASS=your-password \
-- npx -y @ibm/ibmi-mcp-server@latest --tools /absolute/path/to/tools
# Add remote HTTP server
claude mcp add --transport http ibmi-mcp \
http://localhost:3010/mcp \
--header "Authorization: Bearer YOUR_TOKEN"
```
```python Python (Agno) theme={null}
import asyncio
from agno.agent import Agent
from agno.tools.mcp import MCPTools, StreamableHTTPClientParams
url = "http://localhost:3010/mcp"
server_params = StreamableHTTPClientParams(
url=url,
headers={"Authorization": f"Bearer {token}"}
)
async def main():
async with MCPTools(
url=url,
server_params=server_params,
transport="streamable-http"
) as tools:
agent = Agent(
model="openai:gpt-4o",
tools=[tools],
name="ibmi-agent"
)
await agent.aprint_response("What is the system status?")
```
## Next Steps
1. **Choose your client** from the list above
2. **Follow the specific setup guide** for your chosen client
3. **Configure authentication** if using remote (HTTP) mode
4. **Test the connection** by listing available tools
5. **Start building** with SQL tools and agents
For detailed setup instructions, click on any client card above or navigate using the sidebar. Each client has unique configuration requirements and capabilities.
## Troubleshooting
* Verify server is running: `ps aux | grep ibmi-mcp-server`
* Check `npm link` worked: `which ibmi-mcp-server`
* Ensure `TOOLS_YAML_PATH` is an absolute path
* Verify IBM i credentials are correct
* Confirm server is running with `IBMI_HTTP_AUTH_ENABLED=true`
* Verify token is valid: `echo $IBMI_MCP_ACCESS_TOKEN`
* Check server logs for authentication errors
* Ensure HTTPS is used in production
* Validate YAML configuration: `npm run validate -- --config tools`
* Check file permissions on tools directory
* Use `--list-toolsets` to see available tools
* Review server startup logs for parsing errors
Use direct node path instead:
```json theme={null}
{
"command": "node",
"args": [
"/absolute/path/to/ibmi-mcp-server/dist/index.js",
"--tools",
"/absolute/path/to/tools"
]
}
```
## Additional Resources
* [Configuration Reference](/configuration) - All environment variables
* [IBM i Authentication](/configuration#ibm-i-authentication-settings) - Secure token setup
* [Quick Start Guide](/quickstart) - Basic server setup
* [SQL Tools](/sql-tools/overview) - Creating custom tools
# VSCode (Copilot Chat)
Source: https://ibm-d95bab6e.mintlify.app/clients/vscode
Configure IBM i MCP Server with VSCode through GitHub Copilot Chat
# VSCode Integration
Visual Studio Code supports MCP servers through GitHub Copilot Chat. You can configure servers at the workspace or user level, enabling your entire team to share MCP configurations.
**Prerequisites**:
* VSCode 1.102+ with [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) installed and enabled
* Copilot subscription (individual, business, or enterprise)
* MCP support is generally available from VS Code 1.102
## Configuration File Locations
**Location**: `.vscode/mcp.json` in your project root
**Benefits**:
* Shared with team via version control
* Project-specific MCP servers
* Consistent across team members
```bash theme={null}
mkdir -p .vscode
touch .vscode/mcp.json
```
**Recommended Method**: Use Command Palette
1. Press `Cmd/Ctrl+Shift+P`
2. Run **MCP: Open User Configuration**
3. Edit in VSCode with IntelliSense support
**File Locations** (if editing manually):
* **macOS/Linux**: `~/.config/Code/User/globalStorage/modelcontextprotocol.mcp/mcp.json`
* **Windows**: `%APPDATA%\Code\User\globalStorage\modelcontextprotocol.mcp\mcp.json`
**Benefits**:
* Available across all projects
* Personal configuration
* Not shared via version control
## Local (Stdio) Setup
### Using Command Palette (Recommended)
1. Press `Cmd/Ctrl+Shift+P`
2. Run **MCP: Add Server**
3. Choose **Workspace** or **Global** scope
4. Paste configuration and edit with IntelliSense
### Using CLI
```bash theme={null}
# Add local stdio server
code --add-mcp '{
"name": "ibmiMcp",
"type": "stdio",
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}'
```
### Using mcp.json
Create or edit `mcp.json`:
```json theme={null}
{
"servers": {
"ibmiMcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
**Important**: The `--tools` path must be an **absolute path**.
**Security**: On first start, VSCode will prompt you to trust the MCP server. Only trust servers from reliable sources as they can execute code on your machine.
## Remote (HTTP/SSE) Setup
VSCode supports both HTTP and SSE (Server-Sent Events) transport for remote servers.
### Using CLI
```bash theme={null}
# Add remote HTTP server
code --add-mcp '{
"name": "ibmiMcp",
"type": "http",
"url": "http://localhost:3010/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}'
```
### Using mcp.json
```json theme={null}
{
"servers": {
"ibmiMcp": {
"type": "http",
"url": "http://localhost:3010/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
```json theme={null}
{
"servers": {
"ibmiMcp": {
"type": "sse",
"url": "http://localhost:3010/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
**SSE (Server-Sent Events)**: Alternative to HTTP transport for real-time server updates. Use when your server supports SSE protocol.
## Secure Credentials with Variables
VSCode supports multiple variable types for secure credential management and flexible configurations:
### Input Variables
Prompt users for sensitive data at runtime:
```json theme={null}
{
"inputs": [
{
"id": "db2iHost",
"type": "promptString",
"description": "IBM i DB2 host address"
},
{
"id": "db2iUser",
"type": "promptString",
"description": "IBM i username"
},
{
"id": "db2iPass",
"type": "promptString",
"description": "IBM i password",
"password": true
}
],
"servers": {
"ibmiMcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "${input:db2iHost}",
"DB2i_USER": "${input:db2iUser}",
"DB2i_PASS": "${input:db2iPass}",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
VSCode will prompt for these values when the server starts, keeping credentials secure and out of version control.
### Built-in Variables
Use VSCode's built-in variables for dynamic paths:
* **`${workspaceFolder}`** - Absolute path to the workspace root
* **`${env:VAR_NAME}`** - Environment variable value
* **`${userHome}`** - User's home directory path
**Example:**
```json theme={null}
{
"servers": {
"ibmiMcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@ibm/ibmi-mcp-server@latest", "--tools", "${workspaceFolder}/tools"],
"env": {
"DB2i_HOST": "${env:IBM_HOST}",
"DB2i_USER": "${env:IBM_USER}",
"DB2i_PASS": "${env:IBM_PASS}"
}
}
}
}
```
**Best Practice**: Use `${workspaceFolder}` for tools paths in team configs so they work regardless of where teammates clone the repo.
## Managing Servers
### List All Servers
1. Open Command Palette (`Cmd/Ctrl+Shift+P`)
2. Run **MCP: List Servers**
3. View all configured servers with status
### View Servers in Chat
* Open the **Copilot Chat** view in the Activity Bar
* Look for MCP servers listed in the chat interface
* Click the MCP indicator to see available tools
### Restart Server
**Method 1 - Command Palette:**
1. Press `Cmd/Ctrl+Shift+P`
2. Run **MCP: Restart Server**
3. Select your server from the list
**Method 2 - Extensions View:**
* Right-click server in Extensions view
* Select "Restart"
### Autostart Servers (Experimental)
Enable automatic server startup:
1. Open VSCode Settings
2. Search for `chat.mcp.autostart`
3. Enable the setting
### Disable Server
Remove or comment out the server entry in `mcp.json`
## Testing the Connection
After configuration:
1. **Reload VSCode**: `Cmd/Ctrl+Shift+P` โ "Developer: Reload Window"
2. **Open Copilot Chat**: Click the chat icon in Activity Bar
3. **Check MCP status**: Look for MCP indicator in Copilot Chat
4. **List tools**: Ask "@mcp what tools are available?"
5. **Test a tool**: Ask "Show me the IBM i system status"
## Troubleshooting
**Solutions**:
* Verify JSON syntax in `mcp.json`
* Reload VSCode window: `Cmd/Ctrl+Shift+P` โ "Developer: Reload Window"
* Check Copilot is installed and enabled
* Verify GitHub Copilot subscription is active
* Look for errors in Output panel: View โ Output โ "MCP"
**Solutions**:
* Verify `npx -y @ibm/ibmi-mcp-server@latest` works from terminal
* Check all paths are absolute
* Ensure IBM i credentials are correct
* Review VSCode Developer Tools: Help โ Toggle Developer Tools
**Solutions**:
* Verify remote server is running
* Check token is valid and not expired
* Ensure correct Authorization header format
* Get fresh token: `node get-access-token.js --verbose`
**Solutions**:
* Ensure `inputs` array is at root level of `mcp.json`
* Verify `${input:id}` syntax is correct
* Restart VSCode completely
* Check that input IDs match between definition and usage
## Advanced Configuration
### Team Workspace Setup
Share MCP configuration with your team via `.vscode/mcp.json`:
```json theme={null}
{
"inputs": [
{
"id": "db2iHost",
"type": "promptString",
"description": "IBM i host (e.g., dev-ibmi.company.com)",
"default": "dev-ibmi.company.com"
},
{
"id": "db2iUser",
"type": "promptString",
"description": "Your IBM i username"
},
{
"id": "db2iPass",
"type": "promptString",
"description": "Your IBM i password",
"password": true
}
],
"servers": {
"ibmiMcp": {
"type": "stdio",
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "${workspaceFolder}/tools"],
"env": {
"DB2i_HOST": "${input:db2iHost}",
"DB2i_USER": "${input:db2iUser}",
"DB2i_PASS": "${input:db2iPass}",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
### Multiple Environments
Configure dev and prod servers:
```json theme={null}
{
"servers": {
"ibmi-dev": {
"type": "stdio",
"command": "npx",
"args": ["@ibm/ibmi-mcp-server@latest", "-y", "--tools", "/path/to/dev-tools"],
"env": {
"DB2i_HOST": "dev-ibmi.company.com",
"DB2i_USER": "${input:devUser}",
"DB2i_PASS": "${input:devPass}",
"MCP_TRANSPORT_TYPE": "stdio"
}
},
"ibmi-prod": {
"type": "http",
"url": "https://prod-mcp.company.com/mcp",
"headers": {
"Authorization": "Bearer ${env:PROD_MCP_TOKEN}"
}
}
}
}
```
### Custom Toolsets
Load specific toolsets for different workflows:
```json theme={null}
{
"servers": {
"ibmi-performance": {
"type": "stdio",
"command": "npx",
"args": [
"@ibm/ibmi-mcp-server@latest", "-y",
"--tools", "/path/to/tools",
"--toolsets", "performance,monitoring"
],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "${input:db2iUser}",
"DB2i_PASS": "${input:db2iPass}",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
```
## Next Steps
Create custom SQL tools for your workflows
Explore all configuration options
Set up secure IBM i authentication
Explore other MCP-compatible clients
## Additional Resources
* [VSCode MCP Documentation](https://code.visualstudio.com/docs/copilot/customization/mcp-servers)
* [GitHub Copilot Marketplace](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot)
* [IBM i MCP Quick Start](/quickstart)
# Server Architecture
Source: https://ibm-d95bab6e.mintlify.app/concepts/architecture
Understand how the IBM i MCP Server transforms SQL queries into AI-accessible tools and integrates with IBM i systems.
The IBM i MCP Server transforms your existing SQL interface into AI-accessible tools using a standardized protocol. Instead of building new APIs or data pipelines, this server exposes IBM i's rich database services directly to AI agents through the SQL interface you already use.
**Core Innovation**: IBM i already has powerful SQL services (QSYS2, Db2 for i, stored procedures). The MCP server doesn't replace theseโit makes them accessible to AI agents through a standardized protocol. No new infrastructure, no data duplication, just a bridge between AI and your existing IBM i capabilities.
**Key Benefits:**
* โ
**Zero New Infrastructure**: Uses IBM i's existing SQL interfaceโno middleware, no ETL
* โ
**Standardized Protocol**: MCP is universalโworks with Claude, VSCode, Cursor, and 10+ AI clients
* โ
**IBM i Native**: Leverages QSYS2 services, Db2 optimization, and existing security model
* โ
**Data Stays Put**: AI queries run against live dataโno copies, no sync, no staleness
***
## The Architecture in One Picture
```mermaid theme={null}
graph TB
subgraph clients["AI Clients"]
direction LR
end
subgraph mcp["IBM i MCP Server "]
direction TB
register["๐ Register SQL tools from YAML"]
validate["โ Validate parameters & security"]
format["๐ Format responses for AI"]
end
subgraph ibmi["IBM i "]
direction TB
db2["โ Db2 for i"]
qsys2["โ QSYS2 Services"]
security["โ Security Model"]
sprocs["โ Stored Procedures"]
end
clients -->|MCP Protocol | mcp
mcp -->|SQL Queries | ibmi
style clients fill:#e3f2fd,stroke:#1976d2,stroke-width:3px,color:#000
style mcp fill:#fff3e0,stroke:#f57c00,stroke-width:3px,color:#000
style ibmi fill:#e8f5e9,stroke:#388e3c,stroke-width:3px,color:#000
style register fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#000
style validate fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#000
style format fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#000
style db2 fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
style qsys2 fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
style security fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
style sprocs fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
```
**MCP Server** (middle layer) and **YAML tool definitions**
This is the only new infrastructure you deploy
**Everything else**: SQL interface, Db2, QSYS2, security, stored procedures
All your existing IBM i capabilities
***
## What is an MCP Server?
An **MCP (Model Context Protocol) server** is a standardized interface that connects AI agents to external systems. Instead of building custom integrations for each AI platform, MCP provides a universal protocol that works across Claude, VSCode, Cursor, and other AI tools.
**The MCP server handles four responsibilities:**
1. **Tool Registration** - Advertises available operations to AI agents
2. **Request Validation** - Ensures parameters are correct and safe
3. **Execution** - Runs operations against your systems
4. **Response Formatting** - Returns structured results AI agents understand
Think of it as translating between "AI language" (tool calls, structured data) and "IBM i language" (SQL queries, result sets).
***
## SQL as MCP Tools: Exposing IBM i's Existing Capabilities
**The key insight**: IBM i already has everything AI agents needโDB2 for i, QSYS2 system services, performance views, security tables. The MCP server simply makes these **existing SQL interfaces** accessible to AI through standardized tool definitions.
### Why SQL is Perfect for IBM i AI Tools
IBM i's SQL interface is uniquely powerful because it provides:
**Already on your system**: 500+ views and functions for monitoring jobs, performance, security, and system healthโno installation required
**Production-ready performance**: Query optimizer, connection pooling, result caching all work out of the box
**Built-in authority checking**: Object-level permissions, special authorities, and audit trails just work
**Existing business logic**: Call RPG, COBOL, or CL programs through SQLโno rewrites needed
**The MCP server's job**: Turn these SQL capabilities into discoverable tools that AI agents can use.
**You're not building new infrastructure**โyou're exposing what's already there. A SQL query that checks system status becomes a tool AI agents can discover and call. No REST endpoints to maintain, no data to sync, no middleware to deploy.
### Example: Exposing QSYS2 Services to AI
Let's see how an **existing IBM i service** becomes an AI tool. No new infrastructureโjust a YAML definition that exposes what's already there.
**Step 1: The SQL Service (Already Exists on IBM i)**
```sql theme={null}
-- QSYS2.ACTIVE_JOB_INFO is a built-in IBM i service
-- It's already running, already optimized, already secured
SELECT job_name, cpu_time
FROM table(qsys2.active_job_info())
order by cpu_time desc
fetch first 10 rows only;
```
**Step 2: Make It an MCP Tool (YAML Definition)**
```yaml theme={null}
# tools/system-monitoring.yaml
tools:
get_active_jobs:
source: ibmi-system
description: "List currently active jobs with CPU usage from QSYS2.ACTIVE_JOB_INFO"
parameters:
- name: limit
type: integer
default: 10
description: "Number of top CPU-consuming jobs to return"
statement: |
SELECT job_name, cpu_time
FROM table(qsys2.active_job_info())
order by cpu_time desc
fetch first :limit rows only
```
**Step 3: AI Agents Discover It Automatically**
When the server starts, it registers this tool. AI agents see:
```json theme={null}
{
"name": "get_active_jobs",
"description": "List currently active jobs with CPU usage from QSYS2.ACTIVE_JOB_INFO",
"inputSchema": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"description": "Number of top CPU-consuming jobs to return",
"default": 10
}
},
"required": []
}
}
```
**Step 4: AI Agents Use It Naturally**
```
User: "Show me the top 5 CPU-consuming jobs"
AI Agent: [Calls get_active_jobs tool with limit=5]
Result:
{
"rows": [
{
"job_name": "QZDASOINIT",
"cpu_time": 45231
},
{
"job_name": "QSYSARB",
"cpu_time": 12450
},
{
"job_name": "QPADEV0001",
"cpu_time": 8932
},
{
"job_name": "QTCPIP",
"cpu_time": 5621
},
{
"job_name": "QDBSRV01",
"cpu_time": 3489
}
],
"rowCount": 5
}
AI: "The top CPU-consuming jobs are QZDASOINIT (45,231ms), QSYSARB (12,450ms), and QPADEV0001 (8,932ms)..."
```
**What just happened**: You exposed an existing IBM i service (QSYS2.ACTIVE\_JOB\_INFO) to AI agents using a simple YAML file. The SQL service was already there, already secured, already optimized. The MCP server just made it discoverable and callable through a standardized protocol.
***
## How Requests Flow Through the Server
Understanding the request flow helps explain how SQL tools maintain security while providing flexibility:
```mermaid theme={null}
graph TB
A[AI Agent] -->|Request Tool| B[MCP Server]
B -->|Validate Parameters| C{Valid?}
C -->|No| D[Return Error]
C -->|Yes| E[Bind Parameters]
E -->|Execute SQL| F[Db2 for i]
F -->|Result Set| G[Format Response]
G -->|Structured Data| A
style A fill:#e3f2fd
style B fill:#e8f5e8
style F fill:#fff3e0
style D fill:#ffebee
```
### Step-by-Step Flow
AI agent identifies a need (e.g., "show me active jobs") and calls the `get_active_jobs` tool
Server validates all parameters against defined constraints (type, range, pattern, etc.)
Parameters are safely bound to SQL using prepared statementsโSQL injection is impossible
SQL executes against Db2 for i using authenticated user's authorities
Results formatted as markdown tables and structured JSON for AI consumption
**Parameter Binding Security**: Parameter binding is the key security feature. Instead of concatenating user input into SQL strings (dangerous), parameters are bound separately by the database driver. The SQL structure cannot be modified, preventing injection attacks entirely.
***
## Server Components
The server is organized into clear functional areas:
### 1. Tool Registry
**What it does:** Manages all available tools and their schemas
**Two types of tools:**
* **SQL Tools** (YAML-defined) - IBM i database operations
* **TypeScript Tools** (code-based) - Custom logic and external integrations
**Tool discovery:**
```bash theme={null}
# AI agents can list all available tools
GET /mcp/tools/list
# Response includes tool names, descriptions, and schemas
{
"tools": [
{"name": "get_active_jobs", "description": "List currently active jobs..."},
{"name": "system_status", "description": "Get system performance metrics..."}
]
}
```
### 2. YAML Tool Engine
**What it does:** Converts YAML configurations into executable SQL tools
**Process:**
1. **Load** YAML files from configured directories
2. **Parse** tool definitions and parameter schemas
3. **Generate** validation logic from parameter constraints
4. **Register** tools with the MCP server
5. **Execute** SQL safely when tools are called
**Configuration flexibility:**
```bash theme={null}
# Load specific YAML file
npx -y @ibm/ibmi-mcp-server@latest --tools tools/my-tools.yaml
# Load entire directory
npx -y @ibm/ibmi-mcp-server@latest --tools tools/
# Load specific toolsets only
npx -y @ibm/ibmi-mcp-server@latest --tools tools/ --toolsets performance,security
```
### 3. Connection Management
**What it does:** Maintains secure, efficient database connections
**Features:**
* Connection pooling for performance
* Automatic reconnection on failures
* Per-user connection isolation (HTTP auth mode)
* Credential encryption (IBM i auth)
**Two authentication modes:**
**Best for:** Development, CLI tools, single-user scenarios
```bash theme={null}
# All operations use same Db2i user
DB2i_HOST=ibmi-system.com
DB2i_USER=MCPUSER
DB2i_PASS=password
```
**Best for:** Production, web apps, multi-user scenarios
```bash theme={null}
# Each user authenticates individually
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
# User JSMITH โ Connects as JSMITH to Db2i
# User AADAMS โ Connects as AADAMS to Db2i
```
### 4. Transport Layer
**What it does:** Handles communication between AI agents and the server
**Two transport modes:**
| Transport | Use Case | Protocol | Port |
| --------- | ---------------------- | ------------ | ---- |
| **STDIO** | Development, CLI tools | stdin/stdout | N/A |
| **HTTP** | Production, web apps | HTTP/SSE | 3010 |
**STDIO** is simpler (direct process communication), while **HTTP** enables remote access, load balancing, and web integration.
***
## Next Steps
Create your first YAML SQL tool in minutes
Study the comprehensive employee-info.yaml example
Connect Claude, VSCode, or other MCP clients
Review all available environment variables
**Architecture Philosophy**: Leverage what exists. IBM i's SQL interface, QSYS2 services, and Db2 optimization are production-proven. Rather than building new infrastructure, this server exposes these existing capabilities to AI agents through a standardized protocol. You write YAML definitions for SQL you already knowโthe server handles discovery, validation, and formatting for AI consumption.
# Understanding MCP
Source: https://ibm-d95bab6e.mintlify.app/concepts/mcp-overview
A practical introduction to the Model Context Protocol (MCP) for IBM i professionalsโwhat it is, why it matters, and how it works.
**MCP is an open standard that connects AI agents to data sources through a universal protocol.** Instead of building custom integrations for each AI tool, you implement MCP once and it works with Claude, VSCode, Cursor, and any other MCP-compatible client.
**Think of it like HTTP for AI agents**: HTTP is the universal protocol for web browsers. MCP is becoming the universal protocol for AI agents to access external data and tools.
Comprehensive protocol specification and guides
***
## MCP in Three Sentences
1. **MCP is a standardized protocol** that lets AI agents discover and use tools you provide
2. **One server, all clients** - Build once, works with any MCP-compatible AI tool
3. **Security first** - Controlled access, authentication, and audit trails built into the protocol
***
## Why MCP Matters for IBM i
**MCP lets AI agents access IBM i data while respecting your existing security model:**
* โ
**SQL runs as the authenticated user** - IBM i object authorities apply
* โ
**Audit trails maintained** - All operations logged with user context
* โ
**Data stays on IBM i** - No ETL pipelines or data copies required
* โ
**Standard tooling** - OpenTelemetry, structured logging, compliance-ready
**Real-world use cases:**
* Ask AI "What jobs are consuming CPU?" โ Queries QSYS2.ACTIVE\_JOB\_INFO
* Ask AI "Show me sales trends" โ Runs your existing SQL queries
* Ask AI "Check system health" โ Executes monitoring queries you define
***
## How MCP Works
```mermaid theme={null}
graph LR
A[AI Agent] -->|Request Tool| B[MCP Server]
B -->|Execute SQL| C[IBM i]
C -->|Results| B
B -->|Response| A
style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px,color:#000
style B fill:#fff3e0,stroke:#f57c00,stroke-width:2px,color:#000
style C fill:#e8f5e9,stroke:#388e3c,stroke-width:2px,color:#000
```
**The Flow:**
1. **AI agent requests a tool** - "I need to query active jobs"
2. **MCP server validates and executes** - Checks auth, runs SQL as authenticated user
3. **IBM i returns data** - SQL results from DB2 for i or QSYS2 services
4. **Agent receives formatted response** - Structured JSON the AI can understand
For detailed protocol specifications, see the [official MCP documentation](https://modelcontextprotocol.io/docs/concepts/architecture).
***
## MCP Core Concepts
MCP defines three main primitives. For IBM i, **tools** are most important:
**Operations AI agents can execute**
For IBM i: SQL queries, stored procedure calls, system commands
[Learn more โ](https://modelcontextprotocol.io/docs/concepts/tools)
**Static content AI agents can read**
For IBM i: Documentation, schemas, configuration files
[Learn more โ](https://modelcontextprotocol.io/docs/concepts/resources)
**Reusable prompt templates**
For IBM i: Common query patterns, analysis templates
[Learn more โ](https://modelcontextprotocol.io/docs/concepts/prompts)
**Example Tool (YAML):**
```yaml theme={null}
tools:
system_status:
description: "Get IBM i system performance metrics"
statement: "SELECT * FROM qsys2.system_status_info"
```
This becomes a tool AI agents can discover and call automatically.
***
## IBM i MCP Server: What Makes It Different
Our implementation adds IBM i-specific features to the standard MCP protocol:
* **YAML SQL Tools** - Define database operations in simple YAML (no coding required)
* **IBM i Authentication** - Per-user authentication with RSA encryption
* **Authority Respect** - SQL runs as the authenticated user, IBM i authorities apply
* **Production Features** - OpenTelemetry, structured logging, audit trails
For detailed architecture and implementation details, see [Server Architecture](/concepts/architecture).
***
## MCP vs. Traditional Integration
| Approach | MCP | REST APIs | Direct DB Access |
| -------------------- | --------------- | ------------------ | ------------------ |
| **Client Support** | Universal | Custom per client | Custom per client |
| **Security** | User-level auth | Varies | Service account |
| **Data Movement** | Query in place | Often requires ETL | Direct access |
| **Audit Trail** | Built-in | Custom | Database logs only |
| **Setup Complexity** | Once | Per client | Per client |
**Key Difference:** MCP is a **standard protocol**. Build once, works with any MCP-compatible AI clientโtoday and in the future.
***
## Next Steps
Ready to try MCP with IBM i? Here's your path:
Install the server and run your first SQL tool
Understand how SQL becomes AI tools
Create custom tools using YAML
Integrate with Claude, VSCode, Cursor, etc.
***
## Learn More About MCP
Protocol specification and reference
SDKs, examples, and community resources
**The MCP Advantage**: One standard protocol, universal AI client compatibility, enterprise security built-in. Your IBM i data becomes accessible to AI agents while maintaining your security and compliance standards.
# Configuration Reference
Source: https://ibm-d95bab6e.mintlify.app/configuration
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.
Always use a `.env` file for local development and secure environment variable management in production. Never commit sensitive credentials to version control.
***
## Loading Your Configuration
Before starting the server, set the `MCP_SERVER_CONFIG` environment variable to point to your configuration file:
```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.
```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
```
**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.
***
## 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
```
| 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 (singleton pool, CLI; YAML uses source `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 |
**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.
***
## 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.
For a step-by-step walkthrough, see the [Quick Start Guide](/quickstart). For production deployment, refer to the [Production Deployment](/deployment/production) guide.
***
## 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 + browser `Origin` allowlist (comma-separated). Governs browsers only โ it does not restrict non-browser clients | (none) | `http://localhost:3000,https://myapp.com` |
| `MCP_ALLOWED_HOSTS` | `Host` header allowlist for DNS rebinding protection; extends the always-allowed loopback set. `*` disables Host checking only โ Origin is still enforced | (loopback only) | `mcp.example.com` |
| `MCP_ALLOW_UNAUTHENTICATED_HTTP` | Explicitly permit unauthenticated HTTP on a non-loopback bind with IBM i credentials present (server refuses to start otherwise). Note `MCP_AUTH_MODE=jwt` without `MCP_AUTH_SECRET_KEY` counts as unauthenticated | `false` | `true` |
```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
```bash theme={null}
MCP_TRANSPORT_TYPE=stdio
```
**Use for**: CLI tools, MCP Inspector, direct process communication
### 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` |
**Session Modes**:
* `auto`: Automatically detects client capabilities (recommended)
* `stateful`: Maintains persistent sessions with connection state
* `stateless`: Each request is independent, no session state
### 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` |
```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
```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
```bash theme={null}
MCP_RATE_LIMIT_ENABLED=false
```
**Use for**: Trusted internal networks, development environments, Docker Compose setups with controlled access
**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.
### 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` |
```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
```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.)
```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
**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.
**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.
### 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` |
**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.
## Authentication Configuration
### Choosing an Authentication Mode
**Which auth mode should you use?** Select based on your deployment scenario:
**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
**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`
**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
**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)
### Authentication Mode Configuration
| Variable | Description | Default | Options |
| --------------- | ------------------- | ------- | ------------------------------ |
| `MCP_AUTH_MODE` | Authentication mode | `none` | `none`, `jwt`, `oauth`, `ibmi` |
```bash theme={null}
MCP_AUTH_MODE=none
```
**Use for**: Development, internal networks, trusted environments
```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
```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
```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
### 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` |
**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.
### 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.
Create a dedicated directory for storing encryption keys:
```bash theme={null}
mkdir -p secrets
```
Store the `secrets/` directory outside of version control. Add it to your `.gitignore` file.
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
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
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
```
**Critical Security Step**: The private key (`private.pem`) must be protected. Anyone with access to this file can decrypt client credentials.
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
**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
**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.
**Security Best Practices:**
* **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
* **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
* **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
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.
## 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` | Empty or unset also defaults to `8076` |
| `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 |
**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)
```bash theme={null}
DB2i_HOST=dev-ibmi.company.com
DB2i_USER=DEVUSER
DB2i_PASS=devpassword
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=true
```
```bash theme={null}
DB2i_HOST=prod-ibmi.company.com
DB2i_USER=PRODUSER
DB2i_PASS=${SECURE_PASSWORD}
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=false
```
**IBM i Requirements**:
* User profile must have appropriate database authorities
* Access to QSYS2 system services
* Mapepire daemon must be running on the specified port
### 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 |
```bash theme={null}
DB2i_JDBC_OPTIONS='libraries=MYLIB,DEVDATA,QGPL'
```
**Use for**: Resolving unqualified object names. Comma-split within the single `libraries=` pair.
```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`
**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.
```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.
#### 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) |
**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.
**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.
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.
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.
**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`
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` |
**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
```
## 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` |
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.
### 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` |
**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.
```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
```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
```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
```bash theme={null}
npx -y @ibm/ibmi-mcp-server@latest --tools ./tools
```
**Use for**: Production with curated YAML tools for controlled access
**Tool Capabilities:**
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.
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
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
**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.
***
## 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 |
**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
#### Log Directory Configuration
**Where logs are stored depends on how you specify the path:**
```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
```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
```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
```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`
**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
#### 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
**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"
}
```
#### Console Output & Colors
**Console behavior depends on environment and transport mode:**
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`
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
In production, logs are **structured JSON** regardless of transport:
```bash theme={null}
NODE_ENV=production
```
**Output**: JSON to `stderr` and log files
**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.
#### 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:
```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"
}
```
**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` |
**Supported OTEL\_LOG\_LEVEL values**: `NONE`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `VERBOSE`, `ALL`
```bash theme={null}
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:14268/api/traces
OTEL_SERVICE_NAME=ibmi-mcp-server
```
```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
```
## Environment-Specific Examples
```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
```
```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_HOSTS=mcp.company.com
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
```
```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
```
For additional security considerations and IBM i authority requirements, see the [Authentication](/api/auth-endpoints) and [Production Deployment](/deployment/production) guides.
# Docker & Podman
Source: https://ibm-d95bab6e.mintlify.app/deployment/docker
Run the IBM i MCP Server using pre-built container images with Docker or Podman.
Run the IBM i MCP Server as a container using the official pre-built images from GitHub Container Registry. Supports **amd64**, **arm64**, and **ppc64le** architectures.
***
## Quick Start
The commands below start a server for clients on the same machine. The server answers at `http://localhost:3010/mcp` and is not reachable from other hosts.
```bash theme={null}
docker run -d \
--name ibmi-mcp-server \
-p 127.0.0.1:3010:3010 \
-e DB2i_HOST=your-ibmi-host \
-e DB2i_USER=your-username \
-e DB2i_PASS=your-password \
-e DB2i_PORT=8076 \
-e DB2i_IGNORE_UNAUTHORIZED=true \
-e MCP_TRANSPORT_TYPE=http \
-e MCP_HTTP_PORT=3010 \
-e MCP_ALLOW_UNAUTHENTICATED_HTTP=true \
ghcr.io/ibm/ibmi-mcp-server:latest
```
```bash theme={null}
podman run -d \
--name ibmi-mcp-server \
-p 127.0.0.1:3010:3010 \
-e DB2i_HOST=your-ibmi-host \
-e DB2i_USER=your-username \
-e DB2i_PASS=your-password \
-e DB2i_PORT=8076 \
-e DB2i_IGNORE_UNAUTHORIZED=true \
-e MCP_TRANSPORT_TYPE=http \
-e MCP_HTTP_PORT=3010 \
-e MCP_ALLOW_UNAUTHENTICATED_HTTP=true \
ghcr.io/ibm/ibmi-mcp-server:latest
```
Verify the server is running:
```bash theme={null}
curl http://localhost:3010/healthz
```
Two parts of this command control who can reach the server:
* `-p 127.0.0.1:3010:3010` publishes the port on the host's loopback address only. `-p 3010:3010` publishes it on every host interface, which makes an unauthenticated server that holds IBM i credentials reachable from the network.
* `MCP_ALLOW_UNAUTHENTICATED_HTTP=true` accepts running without authentication. Without this variable or an `MCP_AUTH_MODE` setting, a container that holds IBM i credentials exits at startup. [Network Exposure and Authentication](#network-exposure-and-authentication) describes both settings.
Replace the `DB2i_*` values with your actual IBM i credentials. Never commit credentials to source control.
***
## Network Exposure and Authentication
The server holds the IBM i credentials it is started with. Any client that can send it a request can run SQL with those credentials. Two checks limit which clients can do so.
### Host header validation
Every request must address the server as `localhost`, `127.0.0.1`, or a name listed in `MCP_ALLOWED_HOSTS`. A request that uses any other name receives `403 Forbidden: Host not allowed.` The check applies to every route, including `/healthz`.
The check blocks DNS rebinding: a web page changes the DNS record for its own hostname to `127.0.0.1` after loading, then sends requests from the browser to the server on the visitor's machine. Those requests carry the page's hostname in the `Host` header and are rejected.
| How the client addresses the server | Setting required |
| ----------------------------------------------------------------------------- | ------------------------------------------ |
| `http://localhost:3010/mcp` from the container host | None |
| Container name from another container, e.g. `http://ibmi-mcp-server:3010/mcp` | `MCP_ALLOWED_HOSTS=ibmi-mcp-server` |
| `http://host.docker.internal:3010/mcp` | `MCP_ALLOWED_HOSTS=host.docker.internal` |
| The host's DNS name, e.g. `http://mcp.example.com:3010/mcp` | `MCP_ALLOWED_HOSTS=mcp.example.com` |
| A web page running in a browser | The page's origin in `MCP_ALLOWED_ORIGINS` |
`MCP_ALLOWED_HOSTS` accepts a comma-separated list. The `403` response body does not include the rejected name; the container log does.
### Startup check for unauthenticated servers
The image sets `MCP_HTTP_HOST=0.0.0.0`, which published ports require. A server bound this way, holding IBM i credentials, with no authentication configured, is usable by anyone who can reach the port. The server refuses this configuration and exits with:
```
Refusing to start: unauthenticated HTTP transport on non-loopback bind 0.0.0.0 with IBM i credentials configured. Auth mode: none - authentication is disabled. Set MCP_AUTH_MODE, or MCP_HTTP_HOST=127.0.0.1, or MCP_ALLOW_UNAUTHENTICATED_HTTP=true.
```
"IBM i credentials" means `DB2i_*` variables or a tools YAML, since YAML `sources:` entries carry their own connection details. Set one of the following:
| Setting | Effect |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `MCP_AUTH_MODE=ibmi` | Clients authenticate with their own IBM i user and password. See [IBM i Authentication](/server-config/ibmi-auth). |
| `MCP_AUTH_MODE=oauth` | Clients present tokens from your OAuth provider. |
| `MCP_AUTH_MODE=jwt` and `MCP_AUTH_SECRET_KEY` | Clients present tokens you issue. `jwt` without a secret key is treated as no authentication. |
| `MCP_ALLOW_UNAUTHENTICATED_HTTP=true` | No authentication. Pair with `-p 127.0.0.1:3010:3010`, or use only on a network you trust. |
Do not set `MCP_HTTP_HOST=127.0.0.1` for a container. Docker and Podman forward published ports to the container's network interface, not to its loopback address, so a server bound to `127.0.0.1` inside the container is unreachable from the host. Limit exposure with `-p 127.0.0.1:3010:3010` instead. The repository's `.env.example` sets `MCP_HTTP_HOST=127.0.0.1`; remove that line from any `.env` file passed to a container.
***
## Available Images
Images are published to [GitHub Container Registry](https://github.com/IBM/ibmi-mcp-server/pkgs/container/ibmi-mcp-server) on each release. Multi-architecture tags select the image for the host's architecture; single-architecture tags pin one platform.
| Tag | Platforms |
| -------------------------------------------- | ---------------------------------------------------- |
| `ghcr.io/ibm/ibmi-mcp-server:latest` | amd64, arm64, ppc64le |
| `ghcr.io/ibm/ibmi-mcp-server:v0.5.1` | amd64, arm64, ppc64le, pinned to a release |
| `ghcr.io/ibm/ibmi-mcp-server:amd64-v0.5.1` | x86-64 only |
| `ghcr.io/ibm/ibmi-mcp-server:arm64-v0.5.1` | ARM 64-bit only (Apple Silicon, ARM cloud instances) |
| `ghcr.io/ibm/ibmi-mcp-server:ppc64le-v0.5.1` | IBM Power (little-endian) only |
Running on **IBM Power Systems**? Use the `ppc64le` image to run the MCP server natively on the same hardware as your IBM i partition โ no emulation overhead.
***
## Using an Environment File
Store the configuration in a `.env` file:
```ini theme={null}
# .env
DB2i_HOST=your-ibmi-host
DB2i_USER=your-username
DB2i_PASS=your-password
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=true
MCP_TRANSPORT_TYPE=http
MCP_HTTP_PORT=3010
MCP_LOG_LEVEL=info
# Authentication. Set MCP_AUTH_MODE, or accept an unauthenticated server.
MCP_ALLOW_UNAUTHENTICATED_HTTP=true
# Names other than localhost that clients use to reach the server.
# MCP_ALLOWED_HOSTS=ibmi-mcp-server
```
Then run with the env file:
```bash theme={null}
docker run -d \
--name ibmi-mcp-server \
-p 127.0.0.1:3010:3010 \
--env-file .env \
ghcr.io/ibm/ibmi-mcp-server:latest
```
```bash theme={null}
podman run -d \
--name ibmi-mcp-server \
-p 127.0.0.1:3010:3010 \
--env-file .env \
ghcr.io/ibm/ibmi-mcp-server:latest
```
***
## Mounting Custom SQL Tools
To use your own YAML tool configurations, mount them into the container:
```bash theme={null}
docker run -d \
--name ibmi-mcp-server \
-p 127.0.0.1:3010:3010 \
--env-file .env \
-v $(pwd)/tools:/usr/src/app/tools:ro \
ghcr.io/ibm/ibmi-mcp-server:latest \
npx @ibm/ibmi-mcp-server --tools /usr/src/app/tools
```
```bash theme={null}
podman run -d \
--name ibmi-mcp-server \
-p 127.0.0.1:3010:3010 \
--env-file .env \
-v $(pwd)/tools:/usr/src/app/tools:ro \
ghcr.io/ibm/ibmi-mcp-server:latest \
npx @ibm/ibmi-mcp-server --tools /usr/src/app/tools
```
The `:ro` flag mounts the directory as read-only inside the container, which is a security best practice.
A mounted tools directory counts as IBM i credentials for the startup check, because YAML `sources:` entries carry connection details. The `.env` file must set `MCP_AUTH_MODE` or `MCP_ALLOW_UNAUTHENTICATED_HTTP=true`.
***
## Docker Compose
For a more complete setup, use Docker Compose to run the MCP server alongside supporting services.
### Standalone Server
Create a `docker-compose.yml`:
```yaml theme={null}
services:
ibmi-mcp-server:
image: ghcr.io/ibm/ibmi-mcp-server:latest
ports:
- "127.0.0.1:3010:3010"
env_file:
- .env
volumes:
- ./tools:/usr/src/app/tools:ro
command: ["npx", "ibmi-mcp-server", "--tools", "/usr/src/app/tools"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3010/healthz"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
```
The `.env` file is the one from [Using an Environment File](#using-an-environment-file). The healthcheck addresses the server as `localhost` and passes the Host check. Other services in the same Compose file reach the server as `http://ibmi-mcp-server:3010/mcp`; that name must be listed in `MCP_ALLOWED_HOSTS`.
Start the service:
```bash theme={null}
docker compose up -d
```
```bash theme={null}
podman-compose up -d
```
### With MCP Context Forge Gateway
The repository includes a full-stack Docker Compose configuration with [MCP Context Forge](https://github.com/IBM/mcp-context-forge) โ a gateway that provides tool federation, authentication, rate limiting, and an admin UI.
```bash theme={null}
# Clone the repository
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server
# Configure environment
cp .env.example .env
# Start the full stack
docker compose -f deployment/mcpgateway/docker-compose.yml up -d
```
Before starting the stack, edit `.env`:
* Set `DB2i_HOST`, `DB2i_USER`, and `DB2i_PASS`.
* Set `MCP_ALLOWED_HOSTS=ibmi-mcp-server`. The gateway addresses the server by container name.
* Set `MCP_AUTH_MODE`, or set `MCP_ALLOW_UNAUTHENTICATED_HTTP=true`. The stack mounts the repository's `tools/` directory, which counts as IBM i credentials for the startup check.
* Remove the `MCP_HTTP_HOST=127.0.0.1` line. Compose passes `.env` to the container, and that value makes the server unreachable through the published port.
This starts the following services:
| Service | Port | Description |
| --------------------- | ---- | -------------------------------------------- |
| **MCP Context Forge** | 4444 | Gateway with admin UI, tool federation, auth |
| **IBM i MCP Server** | 3010 | SQL tools MCP server |
| **PostgreSQL** | โ | Gateway metadata storage (internal) |
| **Redis** | 6379 | Session cache |
| **pgAdmin** | 5050 | Database admin UI |
| **Redis Insight** | 5540 | Cache admin UI |
The MCP Context Forge Gateway image must be built locally before starting the stack. See the [MCP Context Forge docs](https://ibm.github.io/mcp-context-forge/deployment/) for build instructions.
***
## Container Management
### Viewing Logs
```bash theme={null}
# Follow logs
docker logs -f ibmi-mcp-server
# Last 100 lines
docker logs --tail=100 ibmi-mcp-server
```
```bash theme={null}
# Follow logs
podman logs -f ibmi-mcp-server
# Last 100 lines
podman logs --tail=100 ibmi-mcp-server
```
### Stopping and Removing
```bash theme={null}
docker stop ibmi-mcp-server
docker rm ibmi-mcp-server
```
```bash theme={null}
podman stop ibmi-mcp-server
podman rm ibmi-mcp-server
```
### Health Checks
The server exposes a health endpoint at `/healthz`:
```bash theme={null}
# From the host
curl http://localhost:3010/healthz
# From inside the container
docker exec ibmi-mcp-server curl http://localhost:3010/healthz
```
The health endpoint is subject to the Host check. Both commands above address the server as `localhost` and pass. A probe that addresses the server by IP address, such as a Kubernetes probe using the pod IP, receives `403`. Set a `Host: localhost` header on such probes; the repository's OpenShift deployment manifest does this.
***
## Building from Source
The image is built from `packages/server/Dockerfile` with the repository root as the build context. The root is required because the npm workspaces layout keeps a single `package-lock.json` there.
```bash theme={null}
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server
docker build -t ibmi-mcp-server:local -f packages/server/Dockerfile .
```
To run the local image, substitute `ibmi-mcp-server:local` for `ghcr.io/ibm/ibmi-mcp-server:latest` in any command on this page.
The Dockerfile has three stages:
1. **builder** โ installs all workspace dependencies and runs `npm run build -w @ibm/ibmi-mcp-server`
2. **prod-deps** โ installs the server's production dependencies only; the CLI workspace is excluded
3. **runner** โ copies `node_modules` from `prod-deps` and the compiled `packages/server/dist` from `builder`, then starts `node packages/server/dist/index.js`
`.dockerignore` keeps `node_modules/`, `dist/`, `.git/`, `.github/`, `.claude/`, `agents/`, and `.env` files out of the build context.
The image runs as a non-root user (`appuser`) for security. Port 3010 is exposed by default.
***
## Troubleshooting
Check the container logs for error details:
```bash theme={null}
docker logs ibmi-mcp-server
```
Common causes:
* The log contains `Refusing to start`. See the next entry.
* Missing or incorrect `DB2i_*` environment variables
* Mapepire not running on the IBM i system
* Network connectivity issues to IBM i host
The server holds IBM i credentials, has no authentication configured, and is bound to `0.0.0.0`. It refuses this combination. Set `MCP_AUTH_MODE`, or set `MCP_ALLOW_UNAUTHENTICATED_HTTP=true` and publish the port with `-p 127.0.0.1:3010:3010`. See [Network Exposure and Authentication](#network-exposure-and-authentication).
`MCP_AUTH_MODE=jwt` without `MCP_AUTH_SECRET_KEY` produces the same error, with `Auth mode: jwt - MCP_AUTH_SECRET_KEY is unset` in the message.
`Forbidden: Host not allowed.` means the client addresses the server by a name that is not `localhost` and is not listed in `MCP_ALLOWED_HOSTS`. The container log records the rejected name. Add it to `MCP_ALLOWED_HOSTS` and restart the container.
`Forbidden: Origin not allowed.` means the request came from a browser page whose origin is not listed in `MCP_ALLOWED_ORIGINS`. Add the origin, for example `MCP_ALLOWED_ORIGINS=http://localhost:3000`.
Verify the container can reach your IBM i system:
```bash theme={null}
docker exec ibmi-mcp-server nc -zv your-ibmi-host 8076
```
If using Docker Desktop on macOS/Windows, ensure the IBM i host is reachable from within the VM.
If port 3010 is already in use, map to a different host port:
```bash theme={null}
docker run -d -p 127.0.0.1:3011:3010 --env-file .env ghcr.io/ibm/ibmi-mcp-server:latest
```
The container runs as a non-root user. Ensure mounted files are readable:
```bash theme={null}
chmod -R 644 tools/
```
On SELinux-enabled systems (RHEL/Fedora), add the `:z` flag:
```bash theme={null}
-v $(pwd)/tools:/usr/src/app/tools:ro,z
```
# OpenShift
Source: https://ibm-d95bab6e.mintlify.app/deployment/openshift
Deploy the IBM i MCP Server to Red Hat OpenShift using Kustomize and source-to-image builds.
Deploy the IBM i MCP Server on Red Hat OpenShift using Kustomize with source-to-image (S2I) builds. New image builds automatically trigger redeployment.
***
## Overview
The OpenShift deployment uses:
* **Source-to-Image (S2I)** builds from the GitHub repository
* **Kustomize** for configuration management
* **ImageStreamTag** triggers for automatic redeployment on new builds
* **OpenShift Routes** for TLS-terminated external access
The manifests deploy the IBM i MCP Server alongside optional components including MCP Context Forge Gateway and agent infrastructure.
***
## Prerequisites
You need access to an OpenShift cluster with permissions to create BuildConfigs, Deployments, Services, and Routes.
```bash theme={null}
# Verify CLI access
oc whoami
oc project
```
* **`oc` CLI**: [Install guide](https://docs.redhat.com/en/documentation/openshift_container_platform/4.20/html/cli_tools/openshift-cli-oc)
* **Kustomize**: [Install guide](https://kubectl.docs.kubernetes.io/installation/kustomize/)
The S2I builds require the OpenShift internal image registry. Follow the [Red Hat documentation](https://docs.redhat.com/en/documentation/openshift_container_platform/4.20/html/registry/setting-up-and-configuring-the-registry) to enable it if not already active.
You will need `.env` files with IBM i credentials and server configuration for the deployment.
***
## Deployment Steps
```bash theme={null}
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server/deployment/openshift/apps/openshift
```
Copy required configuration files into the deployment directories:
```bash theme={null}
# Get env file for the MCP server
cp ../../../../.env.example ./ibmi-mcp-server/.env
# Edit with your IBM i credentials
vi ./ibmi-mcp-server/.env
# Copy SQL tools and secrets directories
cp -r ../../../../tools ./ibmi-mcp-server/
cp -r ../../../../secrets ./ibmi-mcp-server/
```
Edit the `.env` file with your actual IBM i credentials before deploying. The file should contain `DB2i_HOST`, `DB2i_USER`, `DB2i_PASS`, and other required variables.
Update the root `kustomization.yaml` with your OpenShift namespace:
Replace `` with your actual namespace, then switch to it:
```bash theme={null}
oc project your-namespace
```
```bash theme={null}
kustomize build . | oc apply -f -
```
This creates all required resources: BuildConfig, ImageStream, Deployment, Service, and Route.
Watch the S2I build progress:
```bash theme={null}
oc logs -f bc/ibmi-mcp-server
```
The build clones the repository, runs the Dockerfile multi-stage build, and pushes the resulting image to the internal registry.
```bash theme={null}
# Check pod status
oc get pods
# Get the external URL
echo "https://$(oc get route ibmi-mcp-server -o jsonpath='{.spec.host}')"
```
***
## What Gets Deployed
The Kustomize manifests create the following OpenShift resources:
### IBM i MCP Server
| Resource | Purpose |
| --------------- | ------------------------------------------ |
| **BuildConfig** | S2I build from GitHub repository |
| **ImageStream** | Tracks built images, triggers redeployment |
| **Deployment** | Runs the MCP server pod |
| **Service** | Internal cluster networking (port 3010) |
| **Route** | External TLS-terminated access |
### Optional Components
The full Kustomize overlay can also deploy:
| Component | Description |
| --------------------- | ----------------------------------------------- |
| **MCP Context Forge** | Gateway with tool federation, auth, admin UI |
| **Agent UI** | Web interface for interacting with agents |
| **Agent OS API** | Backend API for agent infrastructure |
| **pgvector** | PostgreSQL with vector extension for embeddings |
Edit the root `kustomization.yaml` to select which components to deploy. You can deploy only the IBM i MCP Server if you don't need the full agent infrastructure.
***
## Triggering Rebuilds
### Automatic
New image builds are triggered automatically when the ImageStreamTag is updated. Push a code change and start a build:
```bash theme={null}
oc start-build ibmi-mcp-server
```
### From Local Source
Build directly from your local working directory:
```bash theme={null}
oc start-build ibmi-mcp-server --from-dir=.
```
This uploads your local source code to OpenShift for building, useful for testing changes before pushing to Git.
### From Remote Repository
```bash theme={null}
# Trigger a new build from the configured Git source
oc start-build ibmi-mcp-server
```
***
## Manifest Structure
The deployment manifests are organized under `deployment/openshift/apps/openshift/`:
```
deployment/openshift/apps/openshift/
โโโ kustomization.yaml # Root Kustomize config
โโโ ibmi-mcp-server/
โ โโโ kustomization.yaml
โ โโโ ibmi-mcp-server-buildconfig.yaml # S2I build configuration
โ โโโ ibmi-mcp-server-imagestream.yaml # Image tracking
โ โโโ ibmi-mcp-server-deployment.yaml # Pod specification
โ โโโ ibmi-mcp-server-service.yaml # Internal networking
โ โโโ ibmi-mcp-server-route.yaml # External access
โโโ mcpgateway/ # MCP Context Forge (optional)
โโโ ibmi-agent-infra/ # Agent infrastructure (optional)
```
***
## Troubleshooting
Check the build logs for detailed error information:
```bash theme={null}
oc logs -f bc/ibmi-mcp-server
```
Common causes:
* Missing Dockerfile in the repository
* Node.js dependency installation failures
* Insufficient build resources (memory/CPU limits)
Check the pod logs:
```bash theme={null}
oc logs $(oc get pods -l app=ibmi-mcp-server -o name | head -1)
```
Verify environment variables are set correctly:
```bash theme={null}
oc get deployment ibmi-mcp-server -o jsonpath='{.spec.template.spec.containers[0].env}'
```
Verify the route exists and has an assigned host:
```bash theme={null}
oc get route ibmi-mcp-server
```
Check that the service is targeting the correct port:
```bash theme={null}
oc get svc ibmi-mcp-server
```
If persistent volume claims are pending:
```bash theme={null}
oc get pvc
oc describe pvc
```
Ensure your cluster has available storage classes with sufficient capacity.
Verify that your OpenShift cluster has network access to the IBM i system. In restricted environments, you may need:
* Firewall rules allowing egress to IBM i on port 8076
* Network policies permitting the MCP server pod to reach external hosts
* DNS resolution for the IBM i hostname
# Deployment Overview
Source: https://ibm-d95bab6e.mintlify.app/deployment/overview
Deploy the IBM i MCP Server using container images, Docker Compose, or OpenShift with Kustomize.
Deploy the IBM i MCP Server in containerized environments for production use, team access, or integration with AI gateway platforms.
***
## Deployment Options
Run the server using pre-built container images from GitHub Container Registry. Supports **amd64**, **arm64**, and **ppc64le** architectures.
Deploy to Red Hat OpenShift using Kustomize with source-to-image (S2I) builds, auto-redeployment triggers, and enterprise-grade routing.
***
## Container Images
Official container images are published to GitHub Container Registry on each release:
```
ghcr.io/ibm/ibmi-mcp-server
```
| Architecture | Tag Pattern | Use Case |
| ------------ | ---------------- | --------------------------------------------- |
| **amd64** | `amd64-v0.3.1` | Standard x86-64 servers and cloud VMs |
| **arm64** | `arm64-v0.3.1` | Apple Silicon Macs, ARM-based cloud instances |
| **ppc64le** | `ppc64le-v0.3.1` | IBM Power Systems, running alongside IBM i |
Images are built automatically by GitHub Actions when a new version tag is pushed. Each architecture gets its own tagged image.
***
## Prerequisites
All deployment methods require:
1. **Mapepire running on IBM i** โ The WebSocket-based SQL gateway that the MCP server connects to. See the [Setup Mapepire guide](/setup-mapepire) if not already configured.
2. **IBM i credentials** โ Hostname, user profile, and password with database authorities.
3. **Network connectivity** โ The container must be able to reach your IBM i system on the Mapepire port (default: 8076).
***
## Quick Comparison
| | Docker / Podman | OpenShift |
| ---------------- | ------------------------------------------------------ | ---------------------------------------------------- |
| **Best for** | Local development, small teams, standalone deployments | Enterprise production, multi-tenant, CI/CD pipelines |
| **Setup time** | 5 minutes | 30 minutes |
| **Scaling** | Manual (docker-compose replicas) | Automatic (pod autoscaling) |
| **TLS** | Manual (reverse proxy) | Built-in (OpenShift Routes) |
| **Image builds** | Pre-built from GHCR | Source-to-Image (S2I) from Git |
| **Monitoring** | Container logs | OpenShift console, OpenTelemetry |
Run the server directly with **npx** or from source โ no container runtime required. See the Quick Start Guide.
# IBM i MCP Server
Source: https://ibm-d95bab6e.mintlify.app/index
Connect AI agents to IBM i systems through secure, YAML-configured SQL tools with enterprise authentication and observability.
A production-ready **Model Context Protocol (MCP) server** for IBM i.
***
## What is This?
The IBM i MCP Server transforms your IBM i SQL expertise into AI-accessible tools:
* **SQL โ AI Tools**: Write SQL in YAML files, get AI-ready tools automatically
* **Zero Code**: No TypeScript, no REST APIsโjust SQL you already know
* **Secure by Default**: IBM i authorities, parameter binding, audit trails built-in
* **Universal Protocol**: Works with 10+ AI clients (Claude Desktop, VSCode, Cursor, etc.)
**Example**: A 10-line YAML file defining a "system status" query becomes a tool that AI agents can discover, understand, and executeโwith built-in validation and formatting.
***
## Quick Start Path
New to the Model Context Protocol? Read [What is MCP?](/concepts/mcp-overview) to understand how AI agents connect to IBM i.
**Already familiar?** Skip to Step 2.
Install [Mapepire](/setup-mapepire) on your IBM i systemโthe database connectivity layer required for MCP.
**Already installed?** Verify it's running and note the port (default: 8076).
Follow the [Quick Start Guide](/quickstart) to install the server, configure your connection, and execute your first tool.
**Result**: A working MCP server connected to your IBM i system.
Choose an AI client and connect it to your server:
* [Claude Desktop](/clients/claude-desktop) - Most popular, easiest setup
* [VSCode](/clients/vscode) - For development workflows
* [Claude Code](/clients/claude-code) - CLI and automation
* [See all 10+ clients](/clients/overview)
**Time to First Query**: Following this path takes 30-40 minutes from start to your first successful AI-powered IBM i query.
***
## Choose Your Path
Different goals? Jump directly to what you need:
**Start from scratch**
Install the server, connect to IBM i, and execute your first tool in 30 minutes.
โ [Quick Start Guide](/quickstart)
**Make data AI-accessible**
Already have the server running? Learn to create custom SQL tools using YAML.
โ [SQL Tools Guide](/sql-tools/overview)
**Create specialized agents**
Build intelligent IBM i agents that understand system monitoring, security, and more.
โ [Agent Development](/agents/building-agents)
***
## Core Features
**Create database operations in minutes**
Define tools using simple YAMLโno TypeScript or programming required. Built-in parameter validation, SQL injection prevention, and result formatting.
[Learn SQL Tools โ](/sql-tools/overview)
**IBM i security integration**
Respects user profiles, object authorities, and audit requirements. Multiple auth modes including IBM i HTTP authentication with RSA encryption.
[See Configuration โ](/configuration)
**Works with your tools**
Connect Claude Desktop, VSCode, Cursor, Gemini CLI, Cline, and more. Supports both stdio (development) and HTTP (production) transports.
[View Clients โ](/clients/overview)
**Built for enterprise IBM i**
OpenTelemetry observability, structured logging, connection pooling, error handling, and comprehensive audit trails.
[Review Architecture โ](/concepts/architecture)
***
## Key Concepts
MCP is an open standard that enables AI agents to securely access and interact with your data through a universal interface. Instead of building custom integrations for each AI tool, MCP provides a standardized way for any MCP-compatible agent to access your IBM i systems.
**Key Benefits:**
* ๐ Secure, controlled access to enterprise data
* ๐ Universal protocol understood by all MCP clients
* ๐ก๏ธ Preserves IBM i security and audit requirements
* โก Real-time data access without ETL or data exports
[Read the full MCP overview โ](/concepts/mcp-overview)
The IBM i MCP Server's core innovation is **transforming SQL queries into MCP tools** that AI agents can discover and use. This approach is ideal for IBM i because:
* **Zero Code Required**: Define tools in YAML files
* **IBM i Native**: Direct access to DB2, QSYS2 services, stored procedures
* **Security Built-In**: Parameter binding prevents SQL injection automatically
* **Rapid Development**: Create new tools in minutes
**Example**: A simple SQL query becomes a discoverable, validated, secure tool that AI agents can call naturally.
[Learn about SQL Tools โ](/sql-tools/overview)
The server supports multiple authentication modes to fit your deployment:
**For Development:**
* **Shared credentials** (stdio): All operations use same Db2i user
* Fast setup for testing and local development
**For Production:**
* **Per-user authentication** (HTTP): Each user connects with their own credentials
* **IBM i HTTP Auth**: RSA-encrypted credential exchange
* **JWT/OAuth**: Custom authentication systems
All modes respect IBM i object authorities and maintain audit trails.
[See authentication setup โ](/configuration#authentication-settings)
The server enables AI agents to perform any database operation you configure:
**Common Use Cases:**
* ๐ System monitoring and performance analysis
* ๐ Business data queries and reporting
* ๐ Security audits and compliance checks
* ๐ฆ Inventory and resource management
* ๐งช Development and debugging tools
**Example Agents:**
* Performance monitoring agent tracking CPU, memory, jobs
* Discovery agent analyzing schemas and dependencies
* Business intelligence agent answering data questions
* System administration agent managing resources
[Explore agent examples โ](/agents/building-agents)
***
## Common Questions
The server works with any IBM i version that supports:
* DB2 for i (Db2 for IBM i)
* QSYS2 system services
* Mapepire server for WebSocket connectivity
Tested on IBM i 7.3+, but should work on older versions with proper DB2 support.
**No!** The SQL Tools system uses simple YAML configuration files. You only need SQL knowledge to create database operations.
TypeScript is only required if you want to create custom tool types beyond SQL operations.
**MCP Advantages:**
* AI agents discover tools automatically (no hardcoded endpoints)
* Built-in validation and security patterns
* Universal protocol works with any MCP client
* Structured responses optimized for AI consumption
**REST APIs require:**
* Custom integration code for each AI tool
* Manual endpoint documentation
* Custom authentication per client
* Response parsing and adaptation
**Yes!** The server includes production-ready features:
* OpenTelemetry observability
* Comprehensive audit logging
* Connection pooling
* Error handling and categorization
* Rate limiting and resource protection
* Multi-environment configuration
Use HTTP transport with IBM i authentication for production deployments.
**Resources:**
* ๐ Documentation: You're reading it!
* ๐ฌ GitHub Issues: [Report bugs or request features](https://github.com/IBM/ibmi-mcp-server/issues)
* ๐ง Configuration: See [environment variables](/configuration)
* ๐ Examples: Review [SQL tools](/sql-tools/building-tools) and [agents](/agents/building-agents)
***
## Ready to Start?
**15-minute setup**
Install, configure, and execute your first tool
**Build custom tools**
Transform SQL into AI-accessible operations
### More Resources
* [What is MCP?](/concepts/mcp-overview) - Understand the protocol
* [Configuration Reference](/configuration) - All environment variables
* [Client Integrations](/clients/overview) - Connect your AI client
* [Agent Development](/agents/building-agents) - Build specialized agents
***
**About This Project**: The IBM i MCP Server is an open-source project that brings modern AI agent capabilities to IBM i environments while maintaining enterprise security and operational standards. Contributions and feedback are welcome on [GitHub](https://github.com/IBM/ibmi-mcp-server).
# Quick Start Guide
Source: https://ibm-d95bab6e.mintlify.app/quickstart
Get your IBM i MCP Server running in under 15 minutes with step-by-step setup instructions.
Get your IBM i MCP Server up and running in under 15 minutes. This guide walks you through installation, configuration, and your first successful tool execution.
***
## Before You Begin
Complete these prerequisites before starting the installation:
Ensure Node.js 18 or higher is installed on your development machine:
```bash theme={null}
node --version
# Should show v18.0.0 or higher
```
**Don't have Node.js?** Download from [nodejs.org](https://nodejs.org/)
Mapepire must be running on your IBM i system before proceeding.
**Not installed yet?** Follow the [Setup Mapepire guide](/setup-mapepire) (takes \~10 minutes)
**Already installed?** Verify it's running:
```bash theme={null}
# On IBM i
sc check mapepire
# Should show "running"
```
**Note the port**: Default is 8076โyou'll need this for configuration.
You'll need:
* IBM i hostname or IP address
* User profile with database authorities
* User password
* Access to QSYS2 system services (verify with your system administrator)
Plan for 15-20 minutes of uninterrupted setup time.
โ **Ready to proceed?** All prerequisites met? Continue to installation.
***
## Step 1: Installation
Choose your installation method based on your needs:
**Best for:** Production use, quick setup, always-updated package
The official npm package provides instant installation without building from source.
```bash theme={null}
# No installation needed - npx downloads and runs automatically
npx -y @ibm/ibmi-mcp-server@latest --help
```
**Benefits:**
* โ
Always up-to-date with latest stable release
* โ
No build step required
* โ
Instant setup in seconds
* โ
Automatic dependency management
* โ
Perfect for CI/CD pipelines
The `-y` flag automatically accepts the npm package installation prompt. You can omit it if you want to confirm before installation.
โ **Verify the package works:**
```bash theme={null}
npx -y @ibm/ibmi-mcp-server@latest --help
```
You should see the help output with available options.
**Next:** Skip to [Step 2: Configuration](#step-2-configuration)
**Best for:** Development, customization, contributing, latest features
**Repository Structure**: The IBM i MCP Server follows a modular architecture:
* `server/` - MCP server implementation (main package)
* `tools/` - SQL tool YAML configurations
* `agents/` - Agent implementations and examples
* `deployment/` - Deployment configurations (Docker, Gateway, OpenShift)
Clone the repository and install dependencies:
```bash theme={null}
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server
npm install
```
Build the project:
```bash theme={null}
npm run build
```
Use `npm run rebuild` for a clean install if you encounter any issues.
โ **Verify the build succeeded:**
* No error messages in the output
* `dist/` directory was created
* `dist/index.js` exists
**Build failed?** Check that Node.js 18+ is installed and all dependencies downloaded successfully.
**Benefits:**
* โ
Access to latest development features
* โ
Ability to modify and customize code
* โ
Contribute back to the project
* โ
Debug and troubleshoot at source level
***
## Step 2: Configuration
Create your environment configuration file:
Create a `.env` file in your current directory:
```bash theme={null}
cat > .env << 'EOF'
# IBM i DB2 for i Connection Settings
DB2i_HOST=your-ibmi-host
DB2i_USER=your-username
DB2i_PASS=your-password
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=true
# Server Configuration
MCP_TRANSPORT_TYPE=http
MCP_HTTP_PORT=3010
EOF
```
Edit the file and replace the placeholder values with your actual IBM i credentials.
Copy the example configuration and edit it:
```bash theme={null}
# From ibmi-mcp-server directory
cp .env.example .env
```
Edit the `.env` file with your IBM i connection details:
```bash theme={null}
# IBM i DB2 for i Connection Settings
DB2i_HOST=your-ibmi-host
DB2i_USER=your-username
DB2i_PASS=your-password
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=true
# Server Configuration
MCP_TRANSPORT_TYPE=http
MCP_HTTP_PORT=3010
```
Replace the connection values with your actual IBM i system credentials. The user profile must have appropriate authorities for database operations.
**Mapepire is Required**: Before proceeding, you must have Mapepire running on your IBM i system. Mapepire is a modern database server for IBM i that provides SQL query execution over WebSocket connections, optimized for AI agent workloads. If you haven't installed it yet, follow our [Setup Mapepire guide](/setup-mapepire) to install and configure it. Default port: **8076**.
โ **Verify your configuration:**
* `.env` file exists in the root directory
* `DB2i_HOST` is set to your IBM i hostname (not `127.0.0.1` if running in Docker)
* `DB2i_USER` and `DB2i_PASS` are valid IBM i credentials
* `DB2i_PORT` matches your Mapepire port (default: 8076; empty/unset also defaults to 8076)
**Having connection issues?** See the [troubleshooting section](#troubleshooting) below.
The Configuration guide covers authentication modes (JWT, OAuth, IBM i), HTTP/HTTPS settings, OpenTelemetry observability, and all environment variables with examples for development and production.
***
## Step 3: Create Your First SQL Tool
SQL tools are YAML-based configurations that define SQL queries the MCP server can execute. Each tool specifies a data source, parameters, and the SQL statement to run.
### Create Tools Directory
First, create a directory to store your tool configurations:
```bash theme={null}
mkdir -p tools
```
### Create a Simple Tool Configuration
Create a file named `tools/quickstart.yaml` with the following content:
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
ignore-unauthorized: true
tools:
system_activity:
source: ibmi-system
description: "Current system activity information including active jobs and resource utilization"
parameters: []
statement: |
SELECT * FROM TABLE(QSYS2.SYSTEM_ACTIVITY_INFO())
toolsets:
performance:
tools:
- system_activity
```
### Understanding the YAML Structure
The YAML configuration has three main sections:
Defines the IBM i data sources your tools will connect to. The environment variables (`${DB2i_HOST}`, etc.) are automatically replaced with values from your `.env` file.
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
```
Defines the SQL operations available to AI agents. Each tool specifies:
* `source`: Which data source to use
* `description`: What the tool does (helps AI understand when to use it)
* `parameters`: Input parameters (empty array `[]` means no parameters required)
* `statement`: The SQL query to execute
```yaml theme={null}
tools:
system_activity:
source: ibmi-system
description: "Current system activity information including active jobs and resource utilization"
parameters: []
statement: |
SELECT * FROM TABLE(QSYS2.SYSTEM_ACTIVITY_INFO())
```
Groups related tools together for easier management. You can load specific toolsets when starting the server using `--toolsets performance`.
```yaml theme={null}
toolsets:
performance:
tools:
- system_activity
```
โ **Verify your tool configuration:**
* `tools/quickstart.yaml` file exists
* YAML syntax is valid (no tabs, proper indentation with spaces)
* Environment variables are wrapped in `${}` syntax
* SQL statement uses the pipe `|` character for multi-line strings
**Start with ready-made tools!** Learn how to run the server with pre-built SQL tools for performance monitoring, security analysis, and system administration.
**Ready to build more tools?** The SQL Tools documentation covers parameters, validation, multiple data sources, complex queries, and the full YAML configuration reference.
***
## Step 4: Start the Server
Start the server in HTTP mode with your new SQL tool:
```bash theme={null}
export MCP_SERVER_CONFIG=.env
npx -y @ibm/ibmi-mcp-server@latest --transport http --tools ./tools/quickstart.yaml
```
**Session Modes**:
* `auto` (default): Automatically detects client capabilities โ **Start with this**
* `stateful`: Maintains persistent sessions with connection state
* `stateless`: Each request is independent, no session state
Set via environment: `MCP_SESSION_MODE=stateful npx -y @ibm/ibmi-mcp-server@latest --transport http`
```bash theme={null}
# From server/ directory
npm run start:http -- --tools ../tools/quickstart.yaml
```
**Session Modes**:
* `auto` (default): Automatically detects client capabilities โ **Start with this**
* `stateful`: Maintains persistent sessions with connection state
* `stateless`: Each request is independent, no session state
Set via environment: `MCP_SESSION_MODE=stateful npm run start:http`
**Alternative: Stdio Transport** - For MCP Inspector or CLI tools, use `--transport stdio` (NPM package) or `npm run start:stdio` (build from source). However, HTTP transport is recommended for most use cases.
**Available CLI Options**:
| Option | Description | Example |
| -------------------- | --------------------------- | --------------------------------- |
| `--tools ` | Override YAML tools path | `--tools ./my-configs` |
| `--toolsets ` | Load specific toolsets only | `--toolsets performance,security` |
| `--transport ` | Force transport type | `--transport http` |
| `--help` | Show help information | `--help` |
| `--list-toolsets` | List available toolsets | `--list-toolsets` |
You should see output similar to:
```
โ Server ready!
Transport: http
Host: 127.0.0.1:3010
Endpoint: http://127.0.0.1:3010/mcp
Tools loaded: 1
```
โ **Verify the server started successfully:**
* See "Server ready!" message
* HTTP endpoint is displayed (or "Stdio ready" for stdio mode)
* Number of tools loaded shown (should be > 0)
* No error messages about Mapepire connection
* Server process remains running (doesn't exit immediately)
**Server not starting?** Check:
1. Mapepire is running on IBM i: `sc check mapepire`
2. Firewall allows connection to port 8076
3. IBM i credentials are correct in `.env`
4. No other process is using port 3010 (HTTP mode)
***
## Step 5: Test with Sample MCP Client
Now that your server is running, test it with the example Python client from the [GitHub repository](https://github.com/IBM/ibmi-mcp-server/tree/main/client) to verify connectivity and tool execution.
**Example Client Location**: The sample client scripts are available in the [`client/`](https://github.com/IBM/ibmi-mcp-server/tree/main/client) directory of the GitHub repository. Clone the repository or download the files to follow along.
### Install uv (Python Package Manager)
If you don't have `uv` installed:
```bash theme={null}
curl -LsSf https://astral.sh/uv/install.sh | sh
```
**Why uv?** [uv](https://github.com/astral-sh/uv) is a fast Python package manager that handles virtual environments and dependencies automatically. It's the recommended way to run the client examples.
### Run the MCP Client Script
In a **new terminal window** (keep the server running in the first terminal):
```bash theme={null}
# Clone the repository if you haven't already
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server/client
# Install dependencies and run the test client
uv run mcp_client.py
```
**Already have the repo cloned?** Just navigate to the `client/` directory and run `uv run mcp_client.py`
You should see output like this:
```
================================================================================
AVAILABLE TOOLS
================================================================================
1. system_activity
โโ Get real-time IBM i system activity metrics
================================================================================
SYSTEM ACTIVITY RESULT
================================================================================
โ Query executed successfully in 145ms
SQL: SELECT * FROM QSYS2.SYSTEM_ACTIVITY_INFO
Results (1 row(s)):
----------------------------------------------------------------------------
SYSTEM_NAME : YOURSYSTEM
CURRENT_TIMESTAMP : 2024-12-10-15:30:45.123456
CPU_UTILIZATION : 15.2
MEMORY_USED_MB : 8192
ACTIVE_JOBS : 542
----------------------------------------------------------------------------
```
โ **Verify your connection works:**
* List of available tools displayed
* `system_activity` tool executed successfully
* Real data from your IBM i system returned
* No connection errors or timeouts
**Not seeing data?** Check:
1. MCP server is still running (check first terminal)
2. Server started on port 3010 (matches script's `localhost:3010`)
3. No firewall blocking local connections
4. Server logs show the incoming request
The `mcp_client.py` script:
1. Connects to your running MCP server at `http://localhost:3010/mcp`
2. Lists all available tools (SQL tools loaded from your YAML configs)
3. Executes the `system_activity` tool (a pre-built IBM i monitoring query)
4. Formats and displays the results
**View Source**: See the implementation at [`client/mcp_client.py`](https://github.com/IBM/ibmi-mcp-server/blob/main/client/mcp_client.py) to understand how to use the MCP client SDK.
***
## Step 6: Run an AI Agent (Optional)
Now that you've verified the MCP server works, try the example AI agent from the [GitHub repository](https://github.com/IBM/ibmi-mcp-server/tree/main/client) that can answer natural language questions about your IBM i system.
**Agent Script Location**: The `agent.py` script is in the [`client/`](https://github.com/IBM/ibmi-mcp-server/tree/main/client) directory of the GitHub repository. If you haven't cloned the repo yet (from Step 5), you'll need to do so first.
### Configure API Key
The agent uses an LLM to understand your questions and call the appropriate MCP tools. You'll need an API key:
Create a `.env` file in the `client/` directory:
```bash theme={null}
# From the client directory
echo "OPENAI_API_KEY=your-openai-api-key-here" > .env
```
**Get your API key**: Visit [OpenAI API Keys](https://platform.openai.com/api-keys)
Install and run Ollama locally:
```bash theme={null}
# Install Ollama (macOS)
brew install ollama
# Start Ollama and pull a model
ollama run qwen2.5
```
No API key neededโOllama runs locally.
### Run the Agent
From the `client/` directory (where you ran the previous step), ask natural language questions about your IBM i system:
```bash theme={null}
# If you skipped Step 5, clone the repo first:
# git clone https://github.com/IBM/ibmi-mcp-server.git
# cd ibmi-mcp-server/client
# Run the agent with OpenAI
uv run agent.py -p "What is my system performing?" --model-id "openai:gpt-4o"
# Or use the default prompt
uv run agent.py --model-id "openai:gpt-4o"
```
```bash theme={null}
# If you skipped Step 5, clone the repo first:
# git clone https://github.com/IBM/ibmi-mcp-server.git
# cd ibmi-mcp-server/client
# Run the agent with local Ollama
uv run agent.py -p "What is my system performing?" --model-id "ollama:qwen2.5"
# Or use the default prompt
uv run agent.py --model-id "ollama:qwen2.5"
```
**Example interaction**:
```
You: What is my system status?
Agent: Your IBM i system "YOURSYSTEM" is running normally with:
- CPU utilization at 15.2%
- 8GB of memory in use
- 542 active jobs
- System is responsive and healthy
```
The agent automatically:
1. Analyzes your natural language question
2. Selects the appropriate MCP tool(s) to call
3. Executes the tool(s) on your IBM i system
4. Synthesizes the results into a natural language response
**View Source**: See [`client/agent.py`](https://github.com/IBM/ibmi-mcp-server/blob/main/client/agent.py) for the implementation details.
**Ready for more?** Explore our **Agent Integrations** documentation to build production-ready agents with Agno, Google ADK, or LangChain. Learn about FilteredMCPTools, specialized agent patterns, persistent memory, and multi-agent architectures.
***
## ๐ Congratulations!
You've successfully set up the IBM i MCP Server! Here's what you accomplished:
Built and configured the MCP server with IBM i connection
Connected to Mapepire and your IBM i database
Listed and executed SQL tools via the MCP client
Ran an AI agent that understands natural language queries
Your MCP server is now ready for:
* **Connecting AI clients** (Claude Desktop, VSCode, Cursor)
* **Creating custom SQL tools** for your specific use cases
* **Building specialized agents** for IBM i administration and monitoring
***
## Next Steps
Connect the server to Claude Desktop, VSCode, Cursor, and 10+ other MCP clients
Learn how to create custom SQL operations using YAML configurations
Explore all configuration options and environment variables
Build sophisticated AI agents that understand IBM i concepts
## Troubleshooting
* Verify your IBM i host is reachable: `ping your-ibmi-host`
* Check that the Mapepire daemon is running on port 8076
* Ensure your user profile has database authorities
* Verify your IBM i username and password are correct
* Check that your user profile is not disabled or expired
* Ensure you have appropriate authorities for QSYS2 services
Change the port in your `.env` file:
```bash theme={null}
MCP_HTTP_PORT=3011
```
Then restart the server.
* Check that `prebuiltconfigs/` directory exists
* Verify your YAML tool configurations are valid
* Use `--list-toolsets` to see available tools:
```bash theme={null}
npm run start:http -- --list-toolsets
```
**Connection refused or timeout:**
* Ensure MCP server is running: check for "Server ready!" message
* Verify server is on port 3010 (or update script if using different port)
* Server must use HTTP transport (not stdio)
**uv command not found:**
```bash theme={null}
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Restart terminal or reload shell
source ~/.bashrc # or ~/.zshrc
```
**Python version error:**
* Client requires Python 3.13+ (check pyproject.toml)
* Install Python 3.13: `brew install python@3.13` (macOS)
* Or use `uv python install 3.13`
**Dependencies fail to install:**
```bash theme={null}
# Clear uv cache and retry
cd client
rm -rf .venv
uv sync
```
**Completion Time**: This quickstart should take 20-30 minutes including the optional agent setup. Most time is spent waiting for installations and builds. If you encounter issues, check the [configuration guide](/configuration) or review the troubleshooting section above.
# IBM i Authentication
Source: https://ibm-d95bab6e.mintlify.app/server-config/ibmi-auth
Complete guide to IBM i HTTP authentication with token-based access, RSA encryption, and per-user connection pooling.
IBM i HTTP authentication enables secure, token-based access to the MCP server with per-user connection pooling. Clients authenticate with IBM i credentials to obtain Bearer tokens for subsequent API requests.
**When to use IBM i authentication:**
* **Multi-user environments**: Each user gets their own connection pool with their credentials
* **Production deployments**: Token-based auth with automatic expiry and session management
* **Enhanced security**: Credentials encrypted during transmission using RSA/AES
* **Audit trails**: Per-user tracking of database operations
**When to use simpler auth:**
* **Development**: Use shared `DB2i_USER`/`DB2i_PASS` credentials (no token auth needed)
* **Single-user scenarios**: JWT or OAuth may be sufficient
***
## How It Works
### Authentication Flow
```mermaid theme={null}
sequenceDiagram
participant Client
participant Server
participant IBM i
Client->>Server: 1. GET /api/v1/auth/public-key
Server-->>Client: RSA Public Key
Client->>Client: 2. Generate AES session key
Client->>Client: 3. Encrypt credentials with session key
Client->>Client: 4. Encrypt session key with RSA public key
Client->>Server: 5. POST /api/v1/auth (encrypted payload)
Server->>Server: 6. Decrypt session key with private key
Server->>Server: 7. Decrypt credentials with session key
Server->>IBM i: 8. Authenticate with decrypted credentials
IBM i-->>Server: Authentication Success
Server->>Server: 9. Create access token & connection pool
Server-->>Client: Bearer Token
Client->>Server: 10. API requests with Bearer token
Server-->>Client: Authenticated responses
```
**Key Features:**
* **End-to-end encryption**: Credentials never transmitted in plain text
* **Per-user pools**: Each token gets its own dedicated DB2 connection pool
* **Token lifecycle**: Automatic expiry and cleanup of stale sessions
* **Key rotation**: Support for multiple keypairs for zero-downtime rotation
***
## Configuration
### Environment Variables
| Variable | Description | Default | Required |
| ------------------------------------ | -------------------------- | ------------ | -------- |
| `MCP_AUTH_MODE` | Must be set to `ibmi` | `none` | โ
Yes |
| `IBMI_HTTP_AUTH_ENABLED` | Enable auth endpoints | `false` | โ
Yes |
| `IBMI_AUTH_KEY_ID` | Identifier for RSA keypair | (none) | โ
Yes |
| `IBMI_AUTH_PRIVATE_KEY_PATH` | Path to RSA private key | (none) | โ
Yes |
| `IBMI_AUTH_PUBLIC_KEY_PATH` | Path to RSA public key | (none) | โ
Yes |
| `IBMI_AUTH_ALLOW_HTTP` | Allow HTTP (dev only) | `false` | No |
| `IBMI_AUTH_TOKEN_EXPIRY_SECONDS` | Token lifetime | `3600` (1hr) | No |
| `IBMI_AUTH_CLEANUP_INTERVAL_SECONDS` | Cleanup interval | `300` (5min) | No |
| `IBMI_AUTH_MAX_CONCURRENT_SESSIONS` | Max sessions | `100` | No |
**Complete Reference**: See the [IBM i Authentication Settings](/configuration#ibm-i-authentication-settings) section in the Configuration Reference for all available environment variables and their defaults.
### Db2i Credentials: Important Notes
**Common Pitfall**: When using IBM i HTTP authentication, you may encounter validation errors about `DB2i_USER` and `DB2i_PASS` even though the Bearer token provides authentication.
**Solution**: Either **omit these variables entirely** from your `.env` file, or set them to placeholder values like `TOKEN_AUTH`.
**Why this happens**: The validation schema requires these fields to be either undefined or have non-empty values. Empty strings (`DB2i_USER=""`) fail validation. When using token authentication, the Bearer token supplies user credentials, so `DB2i_USER` and `DB2i_PASS` are not used.
```bash theme={null}
# .env for IBM i HTTP Authentication
# Authentication Mode
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
# Encryption Keys
IBMI_AUTH_KEY_ID=production
IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
# IBM i Connection (host only, no credentials)
DB2i_HOST=ibmi-prod.company.com
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=false
# DO NOT INCLUDE DB2i_USER or DB2i_PASS
# Token authentication provides user credentials
```
**This is the cleanest approach**: Variables are completely absent from the configuration.
```bash theme={null}
# .env for IBM i HTTP Authentication
# Authentication Mode
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
# Encryption Keys
IBMI_AUTH_KEY_ID=production
IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
# IBM i Connection
DB2i_HOST=ibmi-prod.company.com
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=false
# Placeholders (not used during token auth)
DB2i_USER=TOKEN_AUTH
DB2i_PASS=TOKEN_AUTH
```
**Why this works**: Validation passes because values are non-empty, but they're never used since token auth provides real credentials.
**Reference**: See [GitHub Issue #77](https://github.com/IBM/ibmi-mcp-server/issues/77) for the original discussion of this validation behavior.
***
## Setup: 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.
Create a dedicated directory for storing encryption keys:
```bash theme={null}
mkdir -p secrets
```
Store the `secrets/` directory outside of version control. Add it to your `.gitignore` file.
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
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
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
```
**Critical Security Step**: The private key (`private.pem`) must be protected. Anyone with access to this file can decrypt client credentials.
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
**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
**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.
***
## Start the Server
After configuring IBM i authentication and generating your RSA keys, start the MCP server with authentication enabled.
**Complete Configuration Example:**
```bash theme={null}
# .env file with IBM i HTTP Authentication
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
# Encryption Keys
IBMI_AUTH_KEY_ID=production
IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
# IBM i Connection (host only - no DB2i_USER/DB2i_PASS needed)
DB2i_HOST=ibmi-prod.company.com
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=false
# Server Settings
MCP_TRANSPORT_TYPE=http
MCP_HTTP_PORT=3010
MCP_LOG_LEVEL=info
# Security (production)
IBMI_AUTH_ALLOW_HTTP=false
IBMI_AUTH_TOKEN_EXPIRY_SECONDS=3600
```
**Start the Server:**
```bash theme={null}
# Set configuration file path
export MCP_SERVER_CONFIG=.env
# Start the server
npx -y @ibm/ibmi-mcp-server@latest --transport http --tools ./tools
```
You should see:
```
โ IBM i HTTP authentication enabled
โ Public key loaded from secrets/public.pem
โ Private key loaded from secrets/private.pem
โ Server ready!
Transport: http
Host: 127.0.0.1:3010
Endpoint: http://127.0.0.1:3010/mcp
Auth: IBM i HTTP (key_id: production)
```
```bash theme={null}
# From the repository root
export MCP_SERVER_CONFIG=.env
cd packages/server
npm run start:http -- --tools ../../tools
```
You should see:
```
โ IBM i HTTP authentication enabled
โ Public key loaded from secrets/public.pem
โ Private key loaded from secrets/private.pem
โ Server ready!
Transport: http
Host: 127.0.0.1:3010
Endpoint: http://127.0.0.1:3010/mcp
Auth: IBM i HTTP (key_id: production)
```
โ **Verify authentication is working:**
Test the public key endpoint:
```bash theme={null}
curl http://localhost:3010/api/v1/auth/public-key
```
Should return:
```json theme={null}
{
"keyId": "production",
"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhki..."
}
```
If you see the public key, authentication is properly configured!
**Production HTTPS**: In production, ensure `IBMI_AUTH_ALLOW_HTTP=false` and use HTTPS. The server will reject HTTP authentication requests for security.
***
## Usage Examples
### Getting an Access Token
The repository includes a helper script to obtain authentication tokens: [`get-access-token.js`](https://github.com/IBM/ibmi-mcp-server/blob/main/get-access-token.js)
**Script Location**: The `get-access-token.js` script is included in the root of the [GitHub repository](https://github.com/IBM/ibmi-mcp-server/blob/main/get-access-token.js). Clone the repository or download this file to use the token helper.
**What it does**: This script authenticates with your IBM i credentials and generates a Bearer token, then outputs a command to set the `IBMI_MCP_ACCESS_TOKEN` environment variable.
```bash theme={null}
# Clone the repository if you haven't already
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server
# ONE-LINER: Generate token and set IBMI_MCP_ACCESS_TOKEN automatically
eval $(node get-access-token.js --quiet)
# Verify the token was set
echo $IBMI_MCP_ACCESS_TOKEN
# Alternative: View token details with verbose output
node get-access-token.js --verbose
# Alternative: Specify credentials explicitly
node get-access-token.js \
--user myuser \
--password mypass \
--host my-ibmi-host \
--quiet
```
**Quick Setup**: The one-liner `eval $(node get-access-token.js --quiet)` does everything:
1. Reads your IBM i credentials from `.env`
2. Encrypts and sends them to the MCP server
3. Receives the Bearer token
4. Automatically sets `export IBMI_MCP_ACCESS_TOKEN=your-token`
5. Token is now available in your shell session
Use this token with any MCP client by including the header: `Authorization: Bearer $IBMI_MCP_ACCESS_TOKEN`
**Example Output:**
```bash theme={null}
$ eval $(node get-access-token.js --quiet)
$ echo $IBMI_MCP_ACCESS_TOKEN
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiTVlVU0VSIiwiaG9zdCI6...
# Token is now set and ready to use with MCP clients
```
**Common Options:**
| Option | Short | Description | Default |
| ------------ | ----- | ----------------------------------------- | --------------------- |
| `--user` | `-u` | IBM i username | `DB2i_USER` from .env |
| `--password` | `-p` | IBM i password | `DB2i_PASS` from .env |
| `--host` | `-h` | IBM i host address | `DB2i_HOST` from .env |
| `--server` | | MCP server address | `localhost` |
| `--port` | | MCP server port | `3010` |
| `--https` | | Use HTTPS instead of HTTP | HTTP |
| `--verbose` | `-v` | Enable verbose output with metadata | (quiet mode) |
| `--quiet` | `-q` | Output only export command for shell eval | (normal mode) |
For advanced use cases, the script supports additional configuration:
| Option | Description |
| ------------------- | -------------------------------------------------------- |
| `--duration` | Token duration in seconds |
| `--pool-start` | Initial connection pool size |
| `--pool-max` | Maximum connection pool size |
| `--public-key-path` | Path to PEM-encoded server public key (skips HTTP fetch) |
| `--key-id` | Key identifier when using `--public-key-path` |
**Example with advanced options:**
```bash theme={null}
node get-access-token.js \
--server prod-mcp.company.com \
--port 443 \
--https \
--duration 7200 \
--quiet
```
The script automatically:
* Loads IBM i credentials from `.env` with CLI fallback
* Fetches the server's public key (or uses local file with `--public-key-path`)
* Encrypts credentials client-side using RSA/AES
* Requests an access token from the MCP server
* Outputs the token (or export command in quiet mode)
**View Source**: See the full implementation at [`get-access-token.js`](https://github.com/IBM/ibmi-mcp-server/blob/main/get-access-token.js)
### Using the Token with MCP Clients
Once you have a token, configure your MCP client:
```python theme={null}
import asyncio
import os
from agno.agent import Agent
from agno.tools.mcp import MCPTools, StreamableHTTPClientParams
# Get access token from environment
token = os.environ.get('IBMI_MCP_ACCESS_TOKEN')
if not token:
raise ValueError("IBMI_MCP_ACCESS_TOKEN not set")
url = "http://localhost:3010/mcp"
server_params = StreamableHTTPClientParams(
url=url,
headers={"Authorization": f"Bearer {token}"}
)
async def main():
async with MCPTools(
url=url,
server_params=server_params,
transport="streamable-http"
) as tools:
agent = Agent(
model="openai:gpt-4o",
tools=[tools],
name="ibmi-agent",
show_tool_calls=True
)
await agent.aprint_response("What is the system status?")
if __name__ == "__main__":
asyncio.run(main())
```
```python theme={null}
import asyncio
import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
token = os.environ.get('IBMI_MCP_ACCESS_TOKEN')
if not token:
raise ValueError("IBMI_MCP_ACCESS_TOKEN not set")
headers = {"Authorization": f"Bearer {token}"}
async with streamablehttp_client(
"http://localhost:3010/mcp",
headers=headers
) as (read_stream, write_stream, _):
async with ClientSession(read_stream, write_stream) as session:
await session.initialize()
# List tools
tools = await session.list_tools()
print(f"Tools: {[t.name for t in tools.tools]}")
# Execute a tool
result = await session.call_tool("system_status", {})
print(result)
if __name__ == "__main__":
asyncio.run(main())
```
```json theme={null}
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
```json theme={null}
{
"servers": {
"ibmiMcp": {
"type": "http",
"url": "http://localhost:3010/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}
```
***
## Security Best Practices
* **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
* **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
* **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
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.
* **HTTPS Only**: Never allow `IBMI_AUTH_ALLOW_HTTP=true` in production
* **Firewall Rules**: Restrict access to auth endpoints
* **Rate Limiting**: Configure rate limits on authentication endpoints
* **IP Whitelisting**: Restrict auth access to known client IPs when possible
***
## Troubleshooting
**Symptom**: Server fails to start with error requiring `DB2i_USER` and `DB2i_PASS` even though you're using token authentication.
**Solution**: Either completely omit these variables from your `.env` file, or set them to placeholder values like `TOKEN_AUTH`. Do not use empty strings (`DB2i_USER=""`).
See the [Configuration](#configuration) section above for detailed examples.
**Why**: Validation requires these fields to be either undefined or have non-empty values. When using token auth, credentials come from the Bearer token, not environment variables.
**Possible causes:**
* Token has expired (check `IBMI_AUTH_TOKEN_EXPIRY_SECONDS`)
* Token was obtained from a different server instance
* Authorization header missing or malformed
**Check:**
```bash theme={null}
# Verify header format
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3010/mcp
# Get a fresh token
node get-access-token.js --verbose
```
**Symptom**: Server fails to start or auth requests fail with encryption errors.
**Solutions:**
* Verify file paths in `.env` are correct
* Check file permissions: `ls -la secrets/`
* Ensure private key is valid: `openssl rsa -in secrets/private.pem -check`
* Regenerate keypair if corrupted
**Symptom**: "Max concurrent sessions reached" errors.
**Solutions:**
* Increase `IBMI_AUTH_MAX_CONCURRENT_SESSIONS`
* Reduce `IBMI_AUTH_TOKEN_EXPIRY_SECONDS` to clean up idle sessions faster
* Monitor active sessions and adjust cleanup interval
***
## Authentication Endpoints
When enabled (`IBMI_HTTP_AUTH_ENABLED=true`), the server provides these endpoints:
| Endpoint | Method | Description |
| ------------------------- | ------ | ---------------------------------------------------------------------- |
| `/api/v1/auth/public-key` | GET | Retrieve server's RSA public key for client-side encryption |
| `/api/v1/auth` | POST | Authenticate with encrypted IBM i credentials and receive Bearer token |
| `/healthz` | GET | Health check endpoint (no authentication required) |
For detailed API specifications, see the [API Reference](/api/auth-endpoints).
***
## Next Steps
Explore all configuration options for the MCP server
Connect Claude Desktop, VSCode, Cursor, and other MCP clients
Create custom SQL operations for authenticated users
Deploy with Docker, HTTPS, and secrets management
# Setup Mapepire
Source: https://ibm-d95bab6e.mintlify.app/setup-mapepire
Complete guide to installing and configuring Mapepire server on IBM i for MCP database connectivity
**Before you can use the IBM i MCP Server, you must install and configure Mapepire on your IBM i system.** Mapepire is the database connectivity layer that enables MCP tools and AI agents to communicate with Db2 for i.
**Mapepire is Required**: The IBM i MCP Server cannot function without Mapepire. Install and configure Mapepire first before proceeding with server setup.
**Prerequisites**: You need SSH access to your IBM i system and appropriate administrative privileges to install software and configure network services.
## What is Mapepire?
[Mapepire](https://mapepire-ibmi.github.io/) is a modern, high-performance database server for IBM i that provides SQL query execution capabilities over WebSocket connections. It acts as a gateway between modern application architectures (like MCP servers, AI agents, and REST APIs) and IBM i's Db2 for i database.
**Key Features**:
* Modern database server for IBM i
* SQL query execution over WebSocket connections
* Secure, encrypted connections to Db2 for i
* Optimized for AI agent workloads
* Supports modern authentication methods
* Low-latency responses for interactive applications
## Why Mapepire Enables AI and MCP Workloads
Traditional IBM i database access methods (ODBC, JDBC) don't align well with modern AI and MCP architectures that require:
* **Fast, lightweight connections**: AI agents make frequent, short-lived database queries
* **WebSocket support**: Enables real-time, bidirectional communication for streaming results
* **Modern JSON-based protocols**: Simplifies integration with TypeScript/JavaScript ecosystems
* **Low-latency responses**: Essential for interactive AI conversations and tool executions
Mapepire bridges this gap by providing a modern, WebSocket-based SQL query interface that's optimized for the request/response patterns of AI agents and MCP tools.
## Installation Methods
### Option 1: RPM Installation (Recommended)
The easiest way to install Mapepire is using the RPM package manager:
```bash theme={null}
# 1. Install Mapepire using yum
yum install mapepire-server
# 2. Install Service Commander (if not already installed)
yum install service-commander
# 3. Start Mapepire service
sc start mapepire
```
If you need help getting started with RPMs on IBM i, see the [IBM i Open Source RPM Guide](http://ibm.biz/ibmi-rpms).
**Full Documentation**: For comprehensive setup and configuration instructions, see the [Mapepire System Administrator Guide](https://mapepire-ibmi.github.io/guides/sysadmin/).
### Option 2: Manual Installation
If RPM installation isn't available, you can install manually:
1. **Create download directory:**
```bash theme={null}
mkdir -p /opt/download
```
2. **Download the distribution:**
```bash theme={null}
cd /opt/download
wget -O mapepire-server-dist.zip \
https://github.com/Mapepire-IBMi/mapepire-server/releases/latest/download/mapepire-server-dist.zip
```
3. **Extract and set permissions:**
```bash theme={null}
mkdir -p /opt/mapepire
cd /opt/mapepire
jar xvf /opt/download/mapepire-server-dist.zip
chown -R qsys .
```
## Starting Mapepire
### Service Commander (Recommended for RPM)
If you installed via RPM, use Service Commander for easy management:
```bash theme={null}
# Install Service Commander (if not already installed)
yum install service-commander
# Start the service
sc start mapepire
# Check if it's running
sc check mapepire
# Stop the service (when needed)
sc stop mapepire
```
### Manual Startup
**For RPM installation:**
```bash theme={null}
nohup /QOpenSys/pkgs/bin/mapepire &
```
**For manual installation:**
```bash theme={null}
nohup /opt/mapepire/bin/mapepire &
```
**For manual installation with Service Commander:**
```bash theme={null}
cd /opt/mapepire/lib/mapepire
sc start mapepire.yaml
```
## Configuration
### Port Configuration
Mapepire uses **port 8076** by default. This is the standard port and changing it is not recommended.
**Important**: You'll need port 8076 when configuring the `DB2i_PORT` variable in your `.env` file. Ensure your IBM i firewall allows inbound connections on this port.
If you need to change the port:
```bash theme={null}
# Set environment variable
export PORT=8077
# Or edit Service Commander configuration
scedit mapepire
```
### TLS/SSL Configuration
Mapepire supports several TLS certificate options:
#### Option 1: Let's Encrypt (Recommended)
If you have Let's Encrypt certificates (e.g., from CertBot), Mapepire will automatically use them:
```bash theme={null}
# Certificates should be located at:
/etc/letsencrypt/live//
```
#### Option 2: Custom Certificate
Create a custom certificate store with these specifications:
| Setting | Value |
| ----------------- | ---------------------------------------- |
| File location | `/QOpenSys/etc/mapepire/cert/server.jks` |
| Format | JKS |
| Store password | `mapepire` |
| Key password | `mapepire` |
| Certificate alias | `mapepire` |
**Example using DCM Tools:**
```bash theme={null}
dcmexport --password=changeit --dcm-store=system --format=pkcs12 mystore.p12
keytool -importkeystore \
-srckeystore mystore.p12 \
-srcstoretype pkcs12 \
-srcstorepass changeit \
-srcalias "mydcmalias" \
-destkeystore /QOpenSys/etc/mapepire/cert/server.jks \
-deststoretype JKS \
-deststorepass mapepire \
-destkeypass mapepire \
-destalias mapepire
```
#### Option 3: Self-Signed Certificate
If no certificate is configured, Mapepire will automatically generate a self-signed certificate. This is suitable for development but not recommended for production.
### Security Configuration
#### Exit Points
Mapepire uses the same exit points as standard JDBC applications. For more information, see the [IBM Support page on JDBC exit points](https://www.ibm.com/support/pages/node/7073452).
Due to Mapepire's architecture, all client connections appear to come from `127.0.0.1`. IP-based exit point rules will need to inspect the `CLIENT_WRKSTNNAME` client special register to get the actual client IP address.
#### Connection Rules
Configure user and IP-based access restrictions in:
```bash theme={null}
/QOpenSys/etc/mapepire/iprules.conf
```
**Rule format:**
* `allow @`
* `deny @`
* Use `*` as wildcard
* Last matching rule takes precedence
* Comments start with `#`
**Example - Disable Q* user profiles:*\*
```bash theme={null}
# Allow connections from all hosts
allow *@*
# Deny logins from users starting with Q
deny q*@*
```
**Example - Restrict to specific users and IP range:**
```bash theme={null}
# Deny by default
deny *@*
# Allow only specific users from 192.168.x.x
allow appusr1@192.168.*
allow appusr2@192.168.*
```
## Testing the Installation
### Verify Mapepire is Running
1. **Check the process:**
```bash theme={null}
ps aux | grep mapepire
```
2. **Test connectivity:**
```bash theme={null}
netstat -an | grep 8076
```
3. **Test with Service Commander:**
```bash theme={null}
sc check mapepire
```
### Configure IBM i MCP Server
Once Mapepire is running, configure your IBM i MCP Server `.env` file:
```bash theme={null}
# IBM i connection settings
DB2i_HOST=your-ibmi-hostname
DB2i_USER=your-username
DB2i_PASS=your-password
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=true
```
Set `DB2i_IGNORE_UNAUTHORIZED=true` if using self-signed certificates. For production with proper certificates, set this to `false`.
## Troubleshooting
### Common Issues
**Port already in use:**
```bash theme={null}
# Check what's using the port
netstat -an | grep 8076
# Kill existing process if needed
pkill mapepire
```
**Permission denied:**
```bash theme={null}
# Ensure proper ownership
chown -R qsys /opt/mapepire
```
**Certificate issues:**
```bash theme={null}
# Check certificate location and permissions
ls -la /QOpenSys/etc/mapepire/cert/
```
### Log Files
Check Mapepire logs for detailed error information:
```bash theme={null}
# Service Commander logs
sc logs mapepire
# Manual startup logs (if using nohup)
tail -f nohup.out
```
## Next Steps
After setting up Mapepire:
1. [Configure your IBM i MCP Server](/configuration)
2. [Test the connection](/quickstart#test-connection)
3. [Set up SQL tools](/sql-tools/building-tools)
4. [Build your first agent](/agents/building-agents)
## Additional Resources
* [Mapepire GitHub Repository](https://github.com/Mapepire-IBMi/mapepire-server)
* [Mapepire Documentation](https://mapepire-ibmi.github.io/)
* [IBM i Open Source Documentation](https://ibmi-oss-docs.readthedocs.io/)
* [DCM Tools for Certificate Management](https://github.com/ThePrez/DCM-tools/)
# Built-in Tools
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/built-in-tools
Reference for the built-in TypeScript tools that ship with the IBM i MCP Server โ schema discovery, query validation, SQL execution, and DDL generation with zero configuration.
The IBM i MCP Server includes 7 built-in tools compiled directly into the server. These tools provide a complete text-to-SQL workflow out of the box โ from schema discovery to query execution โ without any YAML configuration or `--tools` flag.
**Built-in vs YAML tools**: Built-in tools are TypeScript implementations compiled into the server binary. [YAML tools](/sql-tools/overview) are user-defined SQL queries loaded at runtime via `--tools`. Both types coexist and appear identically to AI agents.
***
## Quick Start
Enable built-in tools with the `--builtin-tools` and `--execute-sql` flags:
```bash theme={null}
# Set credentials
export DB2i_HOST="your-ibmi-system.local"
export DB2i_USER="YOURUSERID"
export DB2i_PASS="YourPassword"
# Start with full text-to-SQL workflow
npx -y @ibm/ibmi-mcp-server@latest --builtin-tools --execute-sql --transport http
```
* `--builtin-tools` enables the 5 schema discovery tools (`list_schemas`, `list_tables_in_schema`, `get_table_columns`, `get_related_objects`, `validate_query`)
* `--execute-sql` enables `execute_sql` for running queries
* `describe_sql_object` is always available regardless of flags
Use `--builtin-tools` without `--execute-sql` to let agents explore the schema but route query execution through curated [YAML tools](/sql-tools/overview) with parameterized queries and security controls.
***
## Recommended Workflow
The built-in tools are designed to be chained in a progressive discovery pattern:
```mermaid theme={null}
flowchart LR
A[list_schemas] --> B[list_tables_in_schema]
B --> C[get_table_columns]
C --> D[validate_query]
D --> E[execute_sql]
B --> F[get_related_objects]
B --> G[describe_sql_object]
```
Use `list_schemas` to find available libraries/schemas on the system.
Use `list_tables_in_schema` to list tables, views, and physical files within a schema.
Use `get_table_columns` to understand a table's structure before writing queries.
Optionally use `get_related_objects` for impact analysis or `describe_sql_object` to view DDL.
Use `validate_query` to check syntax and verify that referenced objects exist.
Use `execute_sql` to run the validated query and retrieve results.
***
## Tool Reference
### list\_schemas
List available schemas/libraries on the IBM i system. Use this as the first step in schema discovery to find which schemas contain relevant tables.
**Catalog view:** `QSYS2.SYSSCHEMAS`
#### Parameters
| Name | Type | Required | Default | Description |
| ---------------- | ------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
| `filter` | string | No | โ | Schema name pattern using SQL LIKE syntax (e.g., `'MY%'`, `'LIB%'`). Max 128 characters. |
| `include_system` | boolean | No | `false` | Include system schemas (Q\* and SYS\* prefixed). |
| `limit` | integer | No | `50` | Maximum rows to return (1โ500). |
| `offset` | integer | No | `0` | Number of rows to skip for pagination. |
#### Response columns
| Column | Description |
| -------------------- | ----------------------- |
| `SCHEMA_NAME` | SQL schema name |
| `SCHEMA_TEXT` | Schema description text |
| `SYSTEM_SCHEMA_NAME` | System library name |
| `SCHEMA_SIZE` | Schema size in bytes |
**Pagination**: The response includes `hasMore: true` when additional rows are available beyond the current page. Increment `offset` by `limit` to fetch the next page.
***
### list\_tables\_in\_schema
List tables, views, and physical files in a specific schema with metadata including row counts. Use after `list_schemas` to find tables before querying column details.
**Catalog views:** `QSYS2.SYSTABLES` joined with `QSYS2.SYSTABLESTAT`
#### Parameters
| Name | Type | Required | Default | Description |
| -------------- | ------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `schema_name` | string | **Yes** | โ | Schema name to list tables from (1โ128 characters). |
| `table_filter` | string | No | `*ALL` | Filter by name pattern using SQL LIKE syntax (e.g., `'CUST%'`). Use `'*ALL'` for all tables. Max 128 characters. |
| `limit` | integer | No | `50` | Maximum rows to return (1โ500). |
| `offset` | integer | No | `0` | Number of rows to skip for pagination. |
#### Response columns
| Column | Description |
| -------------- | -------------------------------------------- |
| `TABLE_SCHEMA` | Schema containing the table |
| `TABLE_NAME` | Table name |
| `TABLE_TYPE` | `T` = Table, `V` = View, `P` = Physical file |
| `TABLE_TEXT` | Table description text |
| `NUMBER_ROWS` | Approximate row count |
| `COLUMN_COUNT` | Number of columns |
***
### get\_table\_columns
Get column metadata for a table including names, data types, lengths, nullability, defaults, and descriptions. Use this to understand table structure before writing SQL queries.
**Catalog view:** `QSYS2.SYSCOLUMNS2`
#### Parameters
| Name | Type | Required | Default | Description |
| ------------- | ------ | -------- | ------- | ------------------------------------------------- |
| `schema_name` | string | **Yes** | โ | Schema containing the table (1โ128 characters). |
| `table_name` | string | **Yes** | โ | Table name to get columns for (1โ128 characters). |
#### Response columns
| Column | Description |
| -------------------- | -------------------------------------- |
| `COLUMN_NAME` | SQL column name |
| `SYSTEM_COLUMN_NAME` | 10-character DDS column name |
| `DATA_TYPE` | SQL data type (VARCHAR, DECIMAL, etc.) |
| `LENGTH` | Column length |
| `NUMERIC_SCALE` | Decimal places (numeric columns) |
| `NUMERIC_PRECISION` | Total digits (numeric columns) |
| `IS_NULLABLE` | `Y` or `N` |
| `HAS_DEFAULT` | `Y` or `N` |
| `COLUMN_DEFAULT` | Default value expression |
| `COLUMN_TEXT` | Column description text |
| `COLUMN_HEADING` | DDS column heading |
| `ORDINAL_POSITION` | Position in table (1-based) |
| `CCSID` | Character set identifier |
| `HIDDEN` | `P` = implicitly hidden, `N` = visible |
| `IS_IDENTITY` | `YES` or `NO` |
Null or undefined values are automatically stripped from each row to reduce response size. Only columns with values are included in the output.
***
### get\_related\_objects
Get all objects that depend on a database file โ views, indexes, triggers, foreign keys, logical files, and more. Use for impact analysis before schema changes or to understand a table's dependency graph.
**Catalog function:** `SYSTOOLS.RELATED_OBJECTS`
#### Parameters
| Name | Type | Required | Default | Description |
| -------------------- | ------ | -------- | ------- | --------------------------------------------------------------- |
| `library_name` | string | **Yes** | โ | Library containing the database file (1โ10 characters). |
| `file_name` | string | **Yes** | โ | System name of the database file (1โ10 characters). |
| `object_type_filter` | enum | No | โ | Filter to a specific dependent object type. Omit for all types. |
**Valid `object_type_filter` values:**
`ALIAS`, `FOREIGN KEY`, `FUNCTION`, `HISTORY TABLE`, `INDEX`, `KEYED LOGICAL FILE`, `LOGICAL FILE`, `MASK`, `MATERIALIZED QUERY TABLE`, `PERMISSION`, `PROCEDURE`, `TEXT INDEX`, `TRIGGER`, `VARIABLE`, `VIEW`, `XML SCHEMA`
#### Response columns
| Column | Description |
| -------------------- | ------------------------------- |
| `SOURCE_SCHEMA_NAME` | Schema of the referenced object |
| `SOURCE_SQL_NAME` | Name of the referenced object |
| `SQL_OBJECT_TYPE` | Type of the dependent object |
| `SCHEMA_NAME` | Schema of the dependent object |
| `SQL_NAME` | Name of the dependent object |
| `LIBRARY_NAME` | System library name |
| `SYSTEM_NAME` | System object name |
| `OBJECT_OWNER` | Object owner profile |
| `LONG_COMMENT` | Long comment text |
| `OBJECT_TEXT` | Object text description |
| `LAST_ALTERED` | Last modification timestamp |
***
### validate\_query
Validate SQL query syntax and verify that referenced tables, columns, functions, and procedures exist in the system catalog. This tool performs multi-step validation:
1. **Syntax check** โ Uses `QSYS2.PARSE_STATEMENT` to parse the SQL statement
2. **Table verification** โ Cross-references parsed table names against `QSYS2.SYSTABLES`
3. **Column verification** โ Checks columns against `QSYS2.SYSCOLUMNS`
4. **Routine verification** โ Verifies functions/procedures against `QSYS2.SYSROUTINES`
#### Parameters
| Name | Type | Required | Default | Description |
| --------------- | ------ | -------- | ------- | ------------------------------------------------ |
| `sql_statement` | string | **Yes** | โ | SQL statement to validate (5โ10,000 characters). |
#### Response structure
```json theme={null}
{
"data": [ /* PARSE_STATEMENT result rows */ ],
"objectValidation": {
"tables": {
"valid": [{ "TABLE_SCHEMA": "...", "TABLE_NAME": "..." }],
"invalid": [{ "TABLE_SCHEMA": "...", "TABLE_NAME": "..." }]
},
"columns": {
"valid": [{ "TABLE_SCHEMA": "...", "TABLE_NAME": "...", "COLUMN_NAME": "..." }],
"invalid": [{ "TABLE_SCHEMA": "...", "TABLE_NAME": "...", "COLUMN_NAME": "..." }]
},
"routines": {
"valid": [{ "ROUTINE_SCHEMA": "...", "ROUTINE_NAME": "..." }],
"invalid": [{ "ROUTINE_SCHEMA": "...", "ROUTINE_NAME": "..." }]
}
}
}
```
**Confidence levels**: Table validation is high-confidence โ invalid tables will definitely cause query failures. Column and routine validation is advisory โ CTE columns, UDTF outputs, and unqualified references may appear as false positives.
***
### execute\_sql
Execute a SQL query on the IBM i database and return the results. Use this after validating your query with `validate_query`.
#### Parameters
| Name | Type | Required | Default | Description |
| ----- | ------ | -------- | ------- | ----------------------------------------------- |
| `sql` | string | **Yes** | โ | The SQL query to execute (1โ10,000 characters). |
#### Response structure
```json theme={null}
{
"data": [ /* result rows */ ],
"rowCount": 42,
"executionTime": 156,
"metadata": {
"columns": [
{ "name": "COLUMN_NAME", "type": "VARCHAR" }
]
}
}
```
#### Security
`execute_sql` applies two layers of validation before running any query:
1. **AST/regex validation** via `SqlSecurityValidator` โ checks read-only mode constraints and query length
2. **Native IBM i validation** via `QSYS2.PARSE_STATEMENT` โ confirms `SQL_STATEMENT_TYPE = 'QUERY'` when in read-only mode
By default, only SELECT queries are allowed (`IBMI_EXECUTE_SQL_READONLY=true`). Set `IBMI_EXECUTE_SQL_READONLY=false` to allow INSERT, UPDATE, DELETE, and other statement types.
***
### describe\_sql\_object
Generate the SQL DDL statement for an IBM i database object. Use this to see the full CREATE definition of a table, view, index, procedure, function, or other object.
**Catalog procedure:** `QSYS2.GENERATE_SQL`
#### Parameters
| Name | Type | Required | Default | Description |
| ---------------- | ------ | -------- | ------- | ------------------------------------------------------- |
| `object_name` | string | **Yes** | โ | Name of the database object (1โ128 characters). |
| `object_library` | string | No | `QSYS2` | Library where the object is located (1โ128 characters). |
| `object_type` | enum | No | `TABLE` | Type of database object. |
**Valid `object_type` values:**
`ALIAS`, `CONSTRAINT`, `FUNCTION`, `INDEX`, `MASK`, `PERMISSION`, `PROCEDURE`, `SCHEMA`, `SEQUENCE`, `TABLE`, `TRIGGER`, `TYPE`, `VARIABLE`, `VIEW`, `XSR`
#### Response structure
```json theme={null}
{
"sql": "CREATE OR REPLACE TABLE ...",
"object_name": "MYTABLE",
"object_library": "MYLIB",
"object_type": "TABLE",
"executionTime": 230
}
```
***
## Pagination
Tools that support pagination (`list_schemas`, `list_tables_in_schema`) use a consistent pattern:
| Parameter | Description |
| --------- | ------------------------------------------- |
| `limit` | Maximum rows per page (default 50, max 500) |
| `offset` | Rows to skip (default 0) |
The response includes a `hasMore` boolean indicating whether additional pages exist. To paginate:
```
Page 1: limit=50, offset=0 โ hasMore: true
Page 2: limit=50, offset=50 โ hasMore: true
Page 3: limit=50, offset=100 โ hasMore: false (last page)
```
The server internally fetches `limit + 1` rows to determine `hasMore`, then returns only `limit` rows. This avoids an extra count query.
***
## Configuration
Built-in tools are controlled via CLI flags or environment variables. CLI flags take precedence over environment variables.
### CLI Flags
| Flag | Description |
| ----------------- | ----------------------------------- |
| `--builtin-tools` | Enable the 5 schema discovery tools |
| `--execute-sql` | Enable the `execute_sql` tool |
Combine both flags for the complete text-to-SQL workflow. Each flag can also be used independently.
### Environment Variables
| Variable | Default | Description |
| --------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| `IBMI_ENABLE_DEFAULT_TOOLS` | `false` | Enable the 5 schema discovery tools. |
| `IBMI_ENABLE_EXECUTE_SQL` | `false` | Enable the `execute_sql` tool. |
| `IBMI_EXECUTE_SQL_READONLY` | `true` | When `true`, `execute_sql` only allows SELECT queries. Set to `false` to permit data modification statements. |
`describe_sql_object` is **always registered** regardless of these flags. It generates DDL definitions and does not modify data.
### Examples
```bash theme={null}
# Full text-to-SQL workflow (schema discovery + query execution)
npx -y @ibm/ibmi-mcp-server@latest --builtin-tools --execute-sql --transport http
# Schema discovery only (agents explore but can't run arbitrary SQL)
npx -y @ibm/ibmi-mcp-server@latest --builtin-tools --tools ./tools
# Execute SQL only alongside YAML tools
npx -y @ibm/ibmi-mcp-server@latest --execute-sql --tools ./tools
# Only YAML tools (default โ no built-in tools)
npx -y @ibm/ibmi-mcp-server@latest --transport http --tools ./tools
# Enable write access for execute_sql
IBMI_EXECUTE_SQL_READONLY=false npx -y @ibm/ibmi-mcp-server@latest --builtin-tools --execute-sql
```
***
## Tool Annotations
All built-in tools include [MCP tool annotations](https://modelcontextprotocol.io/specification) that help AI agents understand tool behavior:
| Tool | `readOnlyHint` | `destructiveHint` |
| ----------------------- | -------------- | ----------------- |
| `list_schemas` | `true` | `false` |
| `list_tables_in_schema` | `true` | `false` |
| `get_table_columns` | `true` | `false` |
| `get_related_objects` | `true` | `false` |
| `validate_query` | `true` | `false` |
| `execute_sql` | Dynamic\* | Dynamic\* |
| `describe_sql_object` | `true` | `false` |
\*`execute_sql` annotations change based on `IBMI_EXECUTE_SQL_READONLY`: when `true` (default), `readOnlyHint=true` and `destructiveHint=false`; when `false`, `readOnlyHint=false` and `destructiveHint=true`.
***
## Next Steps
Build custom SQL tools with zero TypeScript using YAML configuration
Load pre-built YAML tool collections for system admin, security, and performance
Get the server running with your first AI agent
Complete environment variable and server configuration reference
# Output Formats
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/output-formats
Configure table styles, row limits, and result formatting for SQL tool outputs
SQL tools support configurable output formatting to optimize readability and control the display of query results. Configure table styles, row limits, and output formats to match your use case.
Output formatting options only apply when `responseFormat: markdown` is set. Tools using `responseFormat: json` return raw JSON data without formatting.
## Overview
The output formatting system provides:
* **Multiple table styles** for different display contexts
* **Type-aware column alignment** (numeric right-aligned, text left-aligned)
* **NULL value handling** with configurable replacements
* **Row truncation** with clear truncation indicators
* **Metadata display** including execution time, row counts, and NULL statistics
## Configuration Options
Output formatting is configured using optional fields in the tool definition:
| Field | Type | Default | Description |
| ---------------- | ------- | ---------- | -------------------------------------------------------------------- |
| `responseFormat` | enum | `markdown` | Response format (`markdown` or `json`) - **required for formatting** |
| `tableFormat` | enum | `markdown` | Table formatting style (see styles below) |
| `maxDisplayRows` | integer | `100` | Maximum rows to display before truncation |
The `tableFormat` and `maxDisplayRows` fields are optional. If omitted, the tool uses default values.
***
## Table Format Styles
Four table styles are available to suit different display contexts:
### 1. `markdown` (Default)
GitHub-flavored markdown table format with column type indicators. Best for documentation, web viewers, and LLM consumption.
**Characteristics:**
* Uses `|` for column separators
* Includes `---` header separator with alignment indicators
* Column headers include type information: `EMPLOYEE_ID (INTEGER)`
* Numeric columns automatically right-aligned
* Most readable in markdown renderers
**Example:**
```markdown theme={null}
| EMPLOYEE_ID (INTEGER) | FIRST_NAME (VARCHAR) | SALARY (DECIMAL) |
|----------------------:|:---------------------|------------------:|
| 000010 | John | 75000.00 |
| 000020 | Alice | 82500.00 |
```
**Use Cases:**
* Default choice for most tools
* Documentation and reports
* Web-based interfaces
* LLM-friendly output
***
### 2. `ascii`
Plain ASCII table format using `+`, `-`, and `|` characters. Compatible with any text display.
**Characteristics:**
* Uses `+` for corners and intersections
* Uses `-` for horizontal borders
* Uses `|` for vertical borders
* Works in any text editor or terminal
* Fixed-width display for consistent alignment
**Example:**
```
+-------------+------------+----------+
| EMPLOYEE_ID | FIRST_NAME | SALARY |
+-------------+------------+----------+
| 000010 | John | 75000.00 |
| 000020 | Alice | 82500.00 |
+-------------+------------+----------+
```
**Use Cases:**
* Plain text environments
* Email or text file output
* Legacy system integration
* Terminal-based tools
***
### 3. `grid`
Unicode box-drawing characters for a polished, professional appearance.
**Characteristics:**
* Uses Unicode box-drawing characters (`โ`, `โ`, `โ`, `โ`, `โค`, `โด`, `โฌ`, `โ`, `โ`)
* Visually distinct and modern
* Requires Unicode support
* Slightly more compact than ASCII
**Example:**
```
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโ
โ EMPLOYEE_ID โ FIRST_NAME โ SALARY โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ 000010 โ John โ 75000.00 โ
โ 000020 โ Alice โ 82500.00 โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโ
```
**Use Cases:**
* Modern terminal output
* Professional reports
* Rich text environments
* Visual clarity over compatibility
***
### 4. `compact`
Minimal spacing for space-constrained displays.
**Characteristics:**
* Reduced column padding (1 space instead of 2)
* Still uses markdown-style separators
* Maintains alignment and readability
* Most space-efficient option
**Example:**
```markdown theme={null}
|EMPLOYEE_ID|FIRST_NAME|SALARY |
|----------:|:---------|--------:|
| 000010|John | 75000.00|
| 000020|Alice | 82500.00|
```
**Use Cases:**
* Mobile or narrow displays
* High-density information display
* Logs with space constraints
* Minimalist output preferences
***
## Maximum Display Rows
The `maxDisplayRows` field controls how many rows are displayed before truncation occurs.
**Display vs. fetch:** `maxDisplayRows` only truncates the rendered table โ the server still fetched those rows from the database. To change how many rows are **pulled from Db2 for i**, see [fetch-row controls](/sql-tools/tools#fetch-row-controls) in the Tools Reference.
### Configuration
**Constraints:**
* Minimum: `1`
* Maximum: `1000`
* Default: `100`
**Behavior:**
* If result row count โค `maxDisplayRows`: All rows are displayed
* If result row count > `maxDisplayRows`: First `maxDisplayRows` rows shown with truncation alert
### Truncation Alert
When truncation occurs, a clear alert message is displayed:
```markdown theme={null}
> โ ๏ธ **Truncated Results**
> Showing 100 of 1,247 rows. 1,147 additional rows were truncated.
```
### Use Cases for Different Limits
| Limit | Use Case |
| ---------- | ------------------------------- |
| `1-10` | Quick previews, debugging |
| `10-50` | Interactive queries, dashboards |
| `50-100` | Standard reports (default) |
| `100-500` | Detailed analysis |
| `500-1000` | Comprehensive exports |
***
## Configuration Examples
### Example 1: Default Configuration
Most tools work well with defaults (markdown format, 100-row limit):
```yaml theme={null}
tools:
list_employees:
source: ibmi-system
description: "List all employees"
statement: "SELECT EMPNO, FIRSTNME, SALARY FROM SAMPLE.EMPLOYEE"
# Defaults: responseFormat: markdown, tableFormat: markdown, maxDisplayRows: 100
```
***
### Example 2: ASCII Format
```yaml theme={null}
tools:
system_status:
source: ibmi-system
description: "System status in plain text format"
statement: "SELECT * FROM TABLE(QSYS2.SYSTEM_STATUS())"
responseFormat: markdown # Required for formatting
tableFormat: ascii # Plain text compatible
maxDisplayRows: 50
```
**Use for:** Plain text files, emails, legacy terminals, non-Unicode systems
***
### Example 3: Grid Format
```yaml theme={null}
tools:
monthly_report:
source: ibmi-system
description: "Monthly sales report"
statement: "SELECT MONTH_NAME, TOTAL_SALES FROM SALES.MONTHLY_SUMMARY"
responseFormat: markdown
tableFormat: grid # Unicode box characters
maxDisplayRows: 12
```
**Use for:** Professional reports, dashboards, modern terminals
***
### Example 4: Compact Format
```yaml theme={null}
tools:
active_jobs:
source: ibmi-system
description: "List active jobs"
statement: "SELECT JOB_NAME, USER_NAME, CPU_USED FROM QSYS2.ACTIVE_JOB_INFO"
responseFormat: markdown
tableFormat: compact # Minimal spacing
maxDisplayRows: 200
```
**Use for:** Space-constrained displays, logs, high-density data
***
### Example 5: High Row Limit
```yaml theme={null}
tools:
export_customers:
source: ibmi-system
description: "Export customer list"
statement: "SELECT * FROM CUSTOMERS.MASTER WHERE STATUS = 'ACTIVE'"
responseFormat: markdown
maxDisplayRows: 1000 # Maximum allowed
```
**Use for:** Data exports, comprehensive analysis, admin tools
***
## Automatic Features
### Column Type Awareness
Columns are automatically aligned based on database types:
* **Right-aligned:** INTEGER, DECIMAL, FLOAT, NUMERIC (all numeric types)
* **Left-aligned:** VARCHAR, CHAR, DATE, TIME, TIMESTAMP (text and temporal types)
Column headers include type information: `SALARY (DECIMAL)`
**Example Output:**
```markdown theme={null}
| EMPNO (INTEGER) | FIRSTNME (VARCHAR) | SALARY (DECIMAL) |
|----------------:|:-------------------|------------------:|
| 000010 | John | 75000.00 |
```
### NULL Value Handling
* NULL values display as `-` (dash)
* NULL counts tracked per column in metadata
* Consistent across all table formats
**Example Output with NULLs:**
```markdown theme={null}
| EMPNO (INTEGER) | PHONENO (CHAR) | EMAIL (VARCHAR) |
|----------------:|:---------------|:----------------|
| 000010 | 555-0100 | john@example.com |
| 000020 | - | - |
### Metadata
- **NULL Values:** PHONENO (1), EMAIL (1)
```
***
## Complete Output Structure
A fully-formatted SQL tool response includes:
1. **Tool Name Header** (H2)
2. **Success Alert** with checkmark
3. **Result Table** with type-aware formatting
4. **Truncation Alert** (if applicable)
5. **Metadata Section** with:
* Execution time
* Row counts (displayed and total)
* NULL value statistics
* Parameter values used
6. **Performance Metrics** (optional)
### Example Complete Output
```markdown theme={null}
## query_employees
> โ
Query completed successfully
| EMPNO (INTEGER) | FIRSTNME (VARCHAR) | LASTNAME (VARCHAR) | SALARY (DECIMAL) |
|----------------:|:-------------------|:-------------------|------------------:|
| 000010 | John | Smith | 75000.00 |
| 000020 | Alice | Johnson | 82500.00 |
| 000030 | Bob | Williams | 68000.00 |
### Metadata
- **Execution Time:** 0.156s
- **Rows Returned:** 3
- **NULL Values:** None
### Parameters
- **department**: 'A00'
- **min_salary**: 50000
```
***
## Best Practices
### Format Selection
**Choose the right format for your context:**
**Use for:**
* LLM consumption (default)
* Web-based UIs
* Documentation
* Markdown renderers
**Characteristics:**
* Most readable
* Type annotations
* Alignment indicators
**Use for:**
* Plain text compatibility
* Email output
* Legacy systems
* Non-Unicode environments
**Characteristics:**
* Universal compatibility
* Fixed-width display
* Clear borders
**Use for:**
* Professional reports
* Modern terminals
* Rich text environments
* Visual polish
**Characteristics:**
* Modern appearance
* Unicode box-drawing
* Clean presentation
**Use for:**
* Space-constrained displays
* Mobile viewers
* High-density data
* Minimalist preference
**Characteristics:**
* Minimal padding
* Space-efficient
* Still readable
### Row Limits by Use Case
| Use Case | Recommended Limit | Rationale |
| ----------------- | ----------------- | ------------------------------- |
| Interactive tools | 10-50 rows | Quick response, focused results |
| Standard reports | 50-100 rows | Balanced (default) |
| Analysis tools | 100-500 rows | Comprehensive view |
| Export tools | 500-1000 rows | Maximum data |
| Debug/preview | 1-10 rows | Minimal output |
### Performance Considerations
* Faster response times
* Reduced network transfer
* Better for interactive use
* Combine with SQL LIMIT
* Use SQL `LIMIT` clauses at database level
* Add `ORDER BY` for most relevant rows first
* Consider pagination for large datasets
* Index columns used in ORDER BY
### Combining with SQL
**Best practice:** Use both SQL-level and display-level limits:
```yaml theme={null}
tools:
top_earners:
source: ibmi-system
description: "Top 100 highest-paid employees"
statement: |
SELECT EMPNO, FIRSTNME, LASTNAME, SALARY
FROM SAMPLE.EMPLOYEE
ORDER BY SALARY DESC
FETCH FIRST 100 ROWS ONLY -- SQL limit
responseFormat: markdown
maxDisplayRows: 100 -- Display limit
```
**Benefits:**
* Database does less work (FETCH FIRST)
* Network transfers less data
* Display limit acts as safety net
* Consistent results across reruns
***
## Comparison: All Table Styles
```markdown theme={null}
| EMPNO (INTEGER) | FIRSTNME (VARCHAR) | SALARY (DECIMAL) |
|----------------:|:-------------------|------------------:|
| 000010 | John | 75000.00 |
| 000020 | Alice | 82500.00 |
```
```
+----------+------------+----------+
| EMPNO | FIRSTNME | SALARY |
+----------+------------+----------+
| 000010 | John | 75000.00 |
| 000020 | Alice | 82500.00 |
+----------+------------+----------+
```
```
โโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโ
โ EMPNO โ FIRSTNME โ SALARY โ
โโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ 000010 โ John โ 75000.00 โ
โ 000020 โ Alice โ 82500.00 โ
โโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโ
```
```markdown theme={null}
|EMPNO |FIRSTNME|SALARY |
|-------:|:-------|--------:|
| 000010|John | 75000.00|
| 000020|Alice | 82500.00|
```
***
## Next Steps
Learn about parameter types and constraints
Understand parameter validation
Step-by-step tool creation guide
Introduction to the SQL tools system
# SQL Tools Overview
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/overview
Learn how YAML-defined SQL tools enable rapid development of IBM i database operations without writing TypeScript code.
The IBM i MCP Server's SQL Tools system allows you to create powerful database operations using simple YAML configurations. Define SQL queries in YAML files, and the server automatically converts them into AI-accessible tools with parameter validation, security controls, and response formatting.
**No TypeScript required** - SQL professionals can build sophisticated IBM i tools using familiar SQL syntax and simple YAML structure.
***
## Pre-Built Tool Categories
The `tools/` directory contains pre-built tool configurations organized by category:
| Directory | Category | Description | Key Tools |
| -------------------------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [**sample/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/sample) | Sample Data | Demonstration tools using IBM i SAMPLE schema (employee, department, project data) | Employee lookup, department analysis, project management |
| [**sys-admin/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/sys-admin) | System Administration | High-level system service discovery and metadata exploration | Service catalogs, schema browsing, example queries |
| [**security/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/security) | Security Analysis | Library list security assessment and vulnerability detection | Library list configuration, authority checks, security analysis |
| [**performance/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/performance) | Performance Monitoring | System performance metrics and resource utilization | System status, active jobs, memory pools, HTTP server stats |
| [**developer/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/developer) | Development Tools | Object statistics and dependency analysis for developers | Recently used objects, stale object detection, dependency tracking |
**List Available Toolsets:**
```bash theme={null}
npx -y @ibm/ibmi-mcp-server@latest --list-toolsets --tools tools
```
***
## YAML File Format
SQL tools are defined in YAML files with three main sections:
**Database connections**
Define IBM i system connections with credentials, ports, and connection options
[Sources Reference โ](/sql-tools/sources)
**SQL operations**
Individual queries with parameters, validation, and security controls
[Tools Reference โ](/sql-tools/tools)
**Logical groups**
Organize related tools for discovery and selective loading
[Toolsets Reference โ](/sql-tools/toolsets)
### Basic Structure
```yaml theme={null}
# 1. Sources - Database connections
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
# 2. Tools - SQL operations
tools:
system_status:
source: ibmi-system
description: "Get system performance metrics"
statement: |
SELECT * FROM TABLE(QSYS2.SYSTEM_STATUS()) X
parameters: []
# 3. Toolsets - Logical groupings
toolsets:
performance_monitoring:
title: "Performance Monitoring"
description: "System performance and resource tools"
tools: [system_status]
```
**Why YAML?** Separating SQL definitions from application code enables SQL professionals to build and maintain tools without TypeScript knowledge while ensuring security through parameter validation and prepared statements.
## Key Concepts
### Sources - Database Connections
Define reusable connection configurations with environment variables for security:
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
```
**Key features:**
* Environment variable substitution for credentials
* Multiple environment support (dev, test, prod)
* Connection pooling and timeouts
* SSL/TLS configuration
Learn about all source configuration options, security best practices, and troubleshooting โ
***
### Tools - SQL Operations
Individual SQL queries with parameter validation and security controls:
```yaml theme={null}
tools:
active_job_info:
source: ibmi-system
description: "Find top CPU consumers"
parameters:
- name: limit
type: integer
default: 10
minimum: 1
maximum: 100
statement: |
SELECT CPU_TIME, JOB_NAME FROM
TABLE(QSYS2.ACTIVE_JOB_INFO()) A
ORDER BY CPU_TIME DESC
FETCH FIRST :limit ROWS ONLY
```
**Parameter types:**
* **String** - Pattern validation, length constraints, enums
* **Integer** - Range validation, defaults
* **Float** - Decimal numbers for calculations
* **Boolean** - True/false flags
* **Array** - Lists of values for IN clauses
Explore all tool configuration options, parameter types, security features, and examples โ
***
### Toolsets - Logical Organization
Group related tools for discovery and selective loading:
```yaml theme={null}
toolsets:
performance_monitoring:
title: "Performance Monitoring"
description: "System performance and resource tools"
tools:
- system_status
- active_job_info
- memory_pools
```
**Organization strategies:**
* By functional domain (monitoring, security, reporting)
* By business process (onboarding, payroll, inventory)
* By user role (developer, DBA, auditor)
* By environment (production, development, testing)
Learn about toolset organization, selective loading, and best practices โ
***
## Security & Validation
### Automatic Security
* **SQL Injection Protection** - All parameters use prepared statements
* **Type Validation** - Parameters validated against defined schemas
* **IBM i Authorities** - Queries respect object-level permissions
* **Audit Logging** - Optional detailed execution logs
### Security Configuration
Mark sensitive tools for enhanced protection:
```yaml theme={null}
security:
readOnly: true
audit: true
requiredAuthority: "*AUDIT"
scopes: ["security:read"]
warning: "Accesses sensitive data"
```
***
## Loading and Configuration
### Load Specific Toolsets
```bash theme={null}
# Load single toolset
npx -y @ibm/ibmi-mcp-server@latest --tools tools/ --toolsets performance_monitoring
# Load multiple toolsets
npx -y @ibm/ibmi-mcp-server@latest --tools tools/ --toolsets performance_monitoring,security_audit
```
### Environment Variables
```bash theme={null}
# Development environment
DB2i_HOST=ibmi-dev.local
DB2i_USER=DEVUSER
DB2i_PASS=DevPassword
# Load specific toolsets
SELECTED_TOOLSETS=development_full,testing_validation
```
***
## Complete Example
A simple but complete YAML configuration:
```yaml theme={null}
# 1. Define database connection
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
# 2. Create SQL tools
tools:
system_status:
source: ibmi-system
description: "Overall system performance metrics"
statement: |
SELECT * FROM TABLE(QSYS2.SYSTEM_STATUS()) X
parameters: []
active_job_info:
source: ibmi-system
description: "Find top CPU consumers"
parameters:
- name: limit
type: integer
default: 10
minimum: 1
maximum: 100
statement: |
SELECT CPU_TIME, JOB_NAME, USER_NAME
FROM TABLE(QSYS2.ACTIVE_JOB_INFO()) A
ORDER BY CPU_TIME DESC
FETCH FIRST :limit ROWS ONLY
# 3. Organize into toolsets
toolsets:
performance_monitoring:
title: "Performance Monitoring"
description: "System performance and resource tools"
tools:
- system_status
- active_job_info
```
**Complete Examples**: See the [Building SQL Tools](/sql-tools/building-tools) guide for the comprehensive `employee-info.yaml` example that demonstrates all parameter types and SQL patterns in a production-ready configuration.
***
## Next Steps
Database connection configuration
SQL tool definitions and parameters
Organizing tools into groups
Step-by-step guide with complete examples
Server configuration and environment variables
**Design Philosophy**: YAML SQL tools democratize AI agent development for IBM i environments. SQL professionals build sophisticated tools using familiar SQL syntax, while the MCP server handles AI integration, security, parameter validation, and protocol management automatically.
# SQL Tools Examples Guide
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/parameter-guide
Practical examples and patterns for using parameters in SQL tools with validation, constraints, and best practices.
**Official Schema**: See the [JSON Schema definition](https://github.com/IBM/ibmi-mcp-server/blob/main/packages/server/src/ibmi-mcp-server/schemas/json/sql-tools-config.json) for parameter specifications.
This guide provides practical examples for using parameters in SQL tools. Parameters make tools dynamic and reusable by accepting inputs that are validated and safely bound to SQL statements.
## Quick Reference
**All parameter types and their constraints:**
| Type | Constraints | Use Cases |
| --------- | ------------------------------------------- | ---------------------------------------------- |
| `string` | `minLength`, `maxLength`, `pattern`, `enum` | Library names, object names, search patterns |
| `integer` | `minimum`, `maximum`, `enum` | Row limits, IDs, counts, numeric filters |
| `float` | `min`, `max`, `enum` | Percentages, thresholds, measurements |
| `boolean` | None | Flags, enable/disable options |
| `array` | `minLength`, `maxLength`, `itemType` | Multiple filters, batch operations, IN clauses |
**Common parameter properties:**
| Property | Required | Description |
| ------------- | ----------- | ----------------------------------------------------------------------- |
| `name` | โ
Yes | Parameter name used in SQL (`:parameter_name`) |
| `type` | โ
Yes | One of: `string`, `integer`, `float`, `boolean`, `array` |
| `description` | Recommended | AI-facing description with usage guidance |
| `required` | No | Whether parameter must be provided (default: true unless `default` set) |
| `default` | No | Default value when parameter is not provided |
***
## String Parameters
String parameters accept text values with optional length, pattern, and enum constraints.
### Basic String
**Use case:** Simple text input without validation
```yaml theme={null}
parameters:
- name: search_term
type: string
description: "Search term to find in service names. Example: 'ACTIVE_JOB'"
required: true
```
**SQL usage:**
```sql theme={null}
WHERE service_name LIKE '%' || :search_term || '%'
```
**Tool call:**
```json theme={null}
{
"name": "search_services",
"arguments": {
"search_term": "ACTIVE_JOB"
}
}
```
***
### String with Length Constraints
**Use case:** Enforce minimum/maximum length (e.g., IBM i object names)
```yaml theme={null}
parameters:
- name: object_name
type: string
description: "IBM i object name (1-10 characters). Example: 'CUSTFILE', 'MYLIB'"
required: true
minLength: 1
maxLength: 10
```
**Validation:**
* โ
`"CUSTFILE"` - Valid (8 characters)
* โ `""` - Error: Too short (0 \< 1)
* โ `"VERYLONGOBJECTNAME"` - Error: Too long (18 > 10)
***
### String with Pattern (Regex)
**Use case:** Enforce specific format (e.g., IBM i naming conventions)
```yaml theme={null}
parameters:
- name: library_name
type: string
description: "IBM i library name (uppercase alphanumeric, starts with letter). Example: 'APPLIB', 'MYLIB'"
required: true
pattern: "^[A-Z][A-Z0-9_]*$"
maxLength: 10
```
**Common patterns:**
```yaml theme={null}
# IBM i library/object name
pattern: "^[A-Z][A-Z0-9_]*$"
# Employee ID (6 digits)
pattern: "^[0-9]{6}$"
# Email address
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
# Phone number (US format)
pattern: "^\\d{3}-\\d{3}-\\d{4}$"
```
**Validation:**
* โ
`"MYLIB"` - Valid
* โ
`"APP_LIB"` - Valid
* โ `"mylib"` - Error: Doesn't match pattern (lowercase)
* โ `"123LIB"` - Error: Doesn't match pattern (starts with number)
***
### String with Enum
**Use case:** Restrict to specific allowed values
```yaml theme={null}
parameters:
- name: object_type
type: string
description: "IBM i object type to filter by"
required: true
enum: ["*FILE", "*PGM", "*SRVPGM", "*DTAARA"]
default: "*FILE"
```
**Validation:**
* โ
`"*FILE"` - Valid
* โ
`"*PGM"` - Valid
* โ `"*TABLE"` - Error: Not in enum list
**SQL usage:**
```sql theme={null}
WHERE object_type = :object_type
```
**AI Agent Benefit**: Enum parameters are automatically described to AI agents as "Must be one of: '\*FILE', '\*PGM', '\*SRVPGM', '\*DTAARA'" which helps them select valid values.
***
### Optional String
**Use case:** Allow filtering that can be skipped
```yaml theme={null}
parameters:
- name: user_filter
type: string
description: "Optional user name filter. Leave empty to show all users."
required: false
```
**SQL usage with NULL handling:**
```sql theme={null}
WHERE (:user_filter IS NULL OR user_name = :user_filter)
```
**Tool calls:**
```json theme={null}
// With filter
{"user_filter": "JSMITH"}
// Without filter (shows all)
{"user_filter": null}
// or omit entirely: {}
```
***
## Integer Parameters
Integer parameters accept whole numbers with optional min/max constraints.
### Basic Integer
**Use case:** Row limits, counts, IDs
```yaml theme={null}
parameters:
- name: limit
type: integer
description: "Maximum number of rows to return (1-100)"
default: 10
minimum: 1
maximum: 100
```
**SQL usage:**
```sql theme={null}
FETCH FIRST :limit ROWS ONLY
```
**Validation:**
* โ
`10` - Valid
* โ
`100` - Valid (at maximum)
* โ `0` - Error: Below minimum
* โ `150` - Error: Above maximum
* โ `"10"` - Error: Must be integer, not string
***
### Pagination Parameters
**Use case:** Page number and size for result pagination
```yaml theme={null}
parameters:
- name: page_size
type: integer
description: "Number of results per page (1-100)"
default: 25
minimum: 1
maximum: 100
- name: page_number
type: integer
description: "Page number to retrieve (starts at 1)"
default: 1
minimum: 1
```
**SQL usage:**
```sql theme={null}
LIMIT :page_size OFFSET (:page_number - 1) * :page_size
```
**Tool call:**
```json theme={null}
{
"page_size": 25,
"page_number": 2 // Gets rows 26-50
}
```
***
### Integer with Enum
**Use case:** Specific numeric choices
```yaml theme={null}
parameters:
- name: priority
type: integer
description: "Priority level (1=High, 2=Medium, 3=Low)"
enum: [1, 2, 3]
default: 2
```
***
## Float Parameters
Float parameters accept decimal numbers for percentages, thresholds, and measurements.
### Basic Float
**Use case:** Percentage multiplier, threshold value
```yaml theme={null}
parameters:
- name: performance_multiplier
type: float
description: "Performance rating multiplier for bonus calculation (0.0-0.3)"
required: true
min: 0.0
max: 0.3
default: 0.1
```
**SQL usage:**
```sql theme={null}
SELECT
employee_id,
salary,
salary * :performance_multiplier AS bonus
FROM employees
```
**Tool call:**
```json theme={null}
{
"performance_multiplier": 0.15 // 15% bonus
}
```
**Validation:**
* โ
`0.1` - Valid
* โ
`0.25` - Valid
* โ `0.5` - Error: Exceeds maximum (0.5 > 0.3)
* โ `-0.1` - Error: Below minimum
***
### Threshold Example
```yaml theme={null}
parameters:
- name: cpu_threshold
type: float
description: "CPU usage threshold percentage (0.0-100.0)"
min: 0.0
max: 100.0
default: 80.0
```
**SQL usage:**
```sql theme={null}
WHERE cpu_utilization >= :cpu_threshold
```
***
## Boolean Parameters
Boolean parameters accept true/false values for flags and options.
### Basic Boolean
**Use case:** Include/exclude certain data
```yaml theme={null}
parameters:
- name: include_completed
type: boolean
description: "Include completed projects (true) or only active projects (false)"
default: true
```
**SQL usage:**
```sql theme={null}
WHERE (:include_completed = 1 OR end_date IS NULL)
```
**Boolean to SQL**: Booleans are passed as `1` (true) or `0` (false) in SQL. Use `= 1` or `= 0` in WHERE clauses.
**Tool calls:**
```json theme={null}
// Show all projects
{"include_completed": true}
// Show only active projects
{"include_completed": false}
```
***
### Boolean Flag Examples
```yaml theme={null}
# Case-sensitive search
- name: case_sensitive
type: boolean
description: "Perform case-sensitive search (true) or case-insensitive (false)"
default: false
# Include inactive records
- name: show_inactive
type: boolean
description: "Include inactive records in results"
default: false
# Verbose output
- name: detailed
type: boolean
description: "Include detailed information in results"
default: false
```
**SQL with boolean:**
```sql theme={null}
WHERE
CASE
WHEN :case_sensitive = 1
THEN name = :search_term
ELSE
UPPER(name) = UPPER(:search_term)
END
```
***
## Array Parameters
Array parameters accept lists of values, commonly used with SQL IN clauses.
### Basic Array
**Use case:** Filter by multiple values
```yaml theme={null}
parameters:
- name: project_ids
type: array
itemType: string
description: "List of project IDs to search for. Example: ['MA2100', 'AD3100', 'PL2100']"
required: true
minLength: 1
maxLength: 10
```
**SQL usage:**
```sql theme={null}
WHERE project_id IN (:project_ids)
```
**Tool call:**
```json theme={null}
{
"project_ids": ["MA2100", "AD3100", "PL2100"]
}
```
**Array Format**: Arrays must be JSON arrays (`["A", "B"]`), NOT strings (`"('A', 'B')"`) or SQL syntax.
**Validation:**
* โ
`["MA2100"]` - Valid (1 item, within minLength)
* โ
`["MA2100", "AD3100", "PL2100"]` - Valid (3 items)
* โ `[]` - Error: Below minLength (0 \< 1)
* โ `["A", "B", ... "K"]` (11 items) - Error: Exceeds maxLength
***
### Array with Different Item Types
**Integer array:**
```yaml theme={null}
- name: employee_ids
type: array
itemType: integer
description: "List of employee IDs"
minLength: 1
maxLength: 50
```
**Tool call:**
```json theme={null}
{"employee_ids": [1001, 1002, 1003]}
```
**Boolean array:**
```yaml theme={null}
- name: status_flags
type: array
itemType: boolean
description: "List of status flags"
```
**Tool call:**
```json theme={null}
{"status_flags": [true, false, true]}
```
***
## Validation and Error Handling
### Validation Process
Parameters are validated in this order:
1. **Type Check** - Ensure value matches declared type
2. **Required Check** - Ensure required parameters are provided
3. **Constraint Check** - Validate min/max, length, pattern, enum
4. **SQL Binding** - Safely bind validated parameters to SQL
### Common Validation Errors
**Error:** `Expected integer, got string for parameter 'limit'`
**Cause:** Passing wrong type
```json theme={null}
// โ Wrong
{"limit": "10"}
// โ
Correct
{"limit": 10}
```
**Error:** `Required parameter 'employee_id' is missing`
**Cause:** Not providing a required parameter
```yaml theme={null}
parameters:
- name: employee_id
type: string
required: true # Must be provided
```
```json theme={null}
// โ Missing required parameter
{}
// โ
Provided
{"employee_id": "000010"}
```
**Error:** `String length 18 exceeds maximum 10 for parameter 'library_name'`
**Cause:** Value violates constraint
```yaml theme={null}
parameters:
- name: library_name
type: string
maxLength: 10
```
```json theme={null}
// โ Too long
{"library_name": "VERYLONGLIBRARYNAME"}
// โ
Valid
{"library_name": "MYLIB"}
```
**Error:** `Value does not match pattern '^[A-Z][A-Z0-9_]*$' for parameter 'library_name'`
**Cause:** Value doesn't match regex pattern
```yaml theme={null}
parameters:
- name: library_name
type: string
pattern: "^[A-Z][A-Z0-9_]*$"
```
```json theme={null}
// โ Doesn't match (lowercase)
{"library_name": "mylib"}
// โ
Matches
{"library_name": "MYLIB"}
```
**Error:** `Value must be one of: *FILE, *PGM, *SRVPGM for parameter 'object_type'`
**Cause:** Value not in enum list
```yaml theme={null}
parameters:
- name: object_type
type: string
enum: ["*FILE", "*PGM", "*SRVPGM"]
```
```json theme={null}
// โ Not in list
{"object_type": "*TABLE"}
// โ
Valid
{"object_type": "*FILE"}
```
***
## Best Practices
### 1. Write AI-Friendly Descriptions
The `description` field is shown to AI agents. Make it helpful:
```yaml theme={null}
# โ
Good - includes examples and format
description: "Employee ID (6 digits). Example: '000010', '000250'"
# โ Vague
description: "Employee ID"
```
### 2. Use Appropriate Constraints
Match constraints to your data requirements:
```yaml theme={null}
# IBM i library name
- name: library
type: string
pattern: "^[A-Z][A-Z0-9_]*$"
maxLength: 10
# Row limit
- name: limit
type: integer
minimum: 1
maximum: 1000
default: 50
# Search term (at least 2 characters to avoid broad searches)
- name: search
type: string
minLength: 2
maxLength: 100
```
### 3. Provide Sensible Defaults
For optional parameters, include defaults:
```yaml theme={null}
- name: page_size
type: integer
default: 25
minimum: 1
maximum: 100
- name: include_inactive
type: boolean
default: false
```
### 4. Use Enums for Fixed Choices
When values are limited, use enums:
```yaml theme={null}
# Status values
- name: status
type: string
enum: ["ACTIVE", "INACTIVE", "PENDING"]
default: "ACTIVE"
# Priority levels
- name: priority
type: integer
enum: [1, 2, 3]
default: 2
```
### 5. Handle Optional Parameters in SQL
Use NULL checks for optional parameters:
```sql theme={null}
-- Optional string filter
WHERE (:user_filter IS NULL OR user_name = :user_filter)
-- Optional integer threshold
WHERE (:min_salary IS NULL OR salary >= :min_salary)
-- Optional boolean flag with special value
WHERE (:department_id = '*ALL' OR department = :department_id)
```
***
## Security: Parameter Binding
**Critical**: Parameters are automatically bound using prepared statements. This prevents SQL injection attacks. NEVER concatenate parameters into SQL strings.
**โ
Safe (parameter binding):**
```yaml theme={null}
statement: |
SELECT * FROM employees
WHERE employee_id = :employee_id
```
**โ Dangerous (string concatenation):**
```yaml theme={null}
# DO NOT DO THIS
statement: |
SELECT * FROM employees
WHERE employee_id = '${employee_id}'
```
**How parameter binding works:**
1. SQL statement is prepared with placeholders: `SELECT * FROM employees WHERE employee_id = ?`
2. Parameters are validated against constraints
3. Parameters are bound separately from the SQL structure
4. Database executes the prepared statement with bound parameters
This ensures the SQL structure cannot be modified by user input, preventing injection attacks entirely.
***
## Complete Examples
### Example 1: Employee Search Tool
```yaml theme={null}
tools:
search_employees:
source: ibmi-sample
description: "Search for employees by name with pagination"
parameters:
- name: name_search
type: string
description: "Name to search for (partial match, minimum 2 characters). Example: 'Smith', 'John'"
required: true
minLength: 2
maxLength: 50
- name: page_size
type: integer
description: "Number of results per page (1-100)"
default: 25
minimum: 1
maximum: 100
- name: page_number
type: integer
description: "Page number to retrieve (starts at 1)"
default: 1
minimum: 1
statement: |
SELECT empno, firstnme, lastname, job, workdept
FROM SAMPLE.EMPLOYEE
WHERE UPPER(firstnme) LIKE UPPER('%' || :name_search || '%')
OR UPPER(lastname) LIKE UPPER('%' || :name_search || '%')
ORDER BY lastname, firstnme
LIMIT :page_size OFFSET (:page_number - 1) * :page_size
```
### Example 2: Project Team Finder
```yaml theme={null}
tools:
find_project_team:
source: ibmi-sample
description: "Find all employees working on specific projects"
parameters:
- name: project_ids
type: array
itemType: string
description: "List of project IDs. Example: ['MA2100', 'AD3100']"
required: true
minLength: 1
maxLength: 10
- name: include_completed
type: boolean
description: "Include employees with completed assignments (true) or only active assignments (false)"
default: false
statement: |
SELECT E.empno, E.firstnme, E.lastname, EPA.projno, EPA.emstdate, EPA.emendate
FROM SAMPLE.EMPPROJACT EPA
JOIN SAMPLE.EMPLOYEE E ON EPA.empno = E.empno
WHERE EPA.projno IN (:project_ids)
AND (:include_completed = 1 OR EPA.emendate IS NULL)
ORDER BY EPA.projno, E.lastname
```
### Example 3: System Monitoring Tool
```yaml theme={null}
tools:
monitor_cpu_usage:
source: ibmi-system
description: "Monitor jobs exceeding CPU threshold"
parameters:
- name: cpu_threshold
type: float
description: "CPU usage threshold in milliseconds (minimum to report)"
default: 1000.0
min: 0.0
- name: limit
type: integer
description: "Maximum number of jobs to return (1-500)"
default: 50
minimum: 1
maximum: 500
- name: job_type
type: string
description: "Job type filter"
enum: ["BATCH", "INTERACTIVE", "AUTOSTART", "*ALL"]
default: "*ALL"
statement: |
SELECT job_name, user_name, cpu_used, job_type, job_status
FROM TABLE(QSYS2.ACTIVE_JOB_INFO()) A
WHERE cpu_used >= :cpu_threshold
AND (:job_type = '*ALL' OR job_type = :job_type)
ORDER BY cpu_used DESC
FETCH FIRST :limit ROWS ONLY
```
***
## Next Steps
Complete tool configuration reference
Step-by-step guide to creating tools
Database connection configuration
Organizing tools into groups
**Parameter Design Philosophy**: Good parameters make tools flexible without sacrificing safety. Use constraints to enforce data quality, provide defaults for convenience, and write clear descriptions to guide AI agents in using your tools correctly.
# Sources Reference
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/sources
Complete reference for configuring database connection sources in YAML SQL tools.
**Official Schema**: See the [JSON Schema definition](https://github.com/IBM/ibmi-mcp-server/blob/main/packages/server/src/ibmi-mcp-server/schemas/json/sql-tools-config.json) for the authoritative source configuration specification.
Sources define database connections that your SQL tools use to execute queries against IBM i systems. Each source specifies connection parameters, credentials, and behavior options.
## Quick Reference
**All source configuration fields:**
| Field | Type | Required | Default | Description |
| --------------------- | ------- | -------- | ------- | -------------------------------------------------------------------------------------------- |
| `host` | string | โ
Yes | - | IBM i hostname or IP address |
| `user` | string | โ
Yes | - | IBM i user profile |
| `password` | string | โ
Yes | - | User profile password |
| `port` | integer | No | `8076` | Mapepire daemon port |
| `ignore-unauthorized` | boolean | No | `false` | Accept self-signed SSL certs |
| `jdbc-options` | object | No | `{}` | JDBC connection options passed to the mapepire driver (libraries, naming, date format, etc.) |
***
## Basic Source Configuration
Every YAML file starts with a `sources` section that defines one or more database connections:
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
ignore-unauthorized: true
```
**Source Naming**: Choose descriptive source names like `ibmi-production`, `ibmi-dev`, or `ibmi-system`. Tools reference these names in their `source` field to specify which connection to use.
***
## Source Fields Reference
### Required Fields
All sources must include these three fields:
| Field | Type | Description | Example |
| ---------- | ------ | -------------------------------------------------------------- | -------------- |
| `host` | string | Hostname or IP address of IBM i system running Mapepire daemon | `${DB2i_HOST}` |
| `user` | string | IBM i user profile for database authentication | `${DB2i_USER}` |
| `password` | string | Password for the IBM i user profile | `${DB2i_PASS}` |
**Security Requirement**: Always use environment variables for credentials. Never hardcode sensitive values in YAML files.
**Examples:**
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
```
**.env file:**
```bash theme={null}
DB2i_HOST=ibmi-prod.example.com
DB2i_USER=MCPUSER
DB2i_PASS=SecurePassword123
```
โ
**Best for**: All environments (development, testing, production)
โ
**Security**: Credentials never stored in version control
```yaml theme={null}
sources:
ibmi-dev:
host: ibmi-dev.local
user: DEVUSER
password: DevPassword123
```
โ ๏ธ **Use only for**: Local development with test credentials
โ **Never use for**: Production or shared repositories
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST} # Can be IP: 192.168.1.100
user: ${DB2i_USER}
password: ${DB2i_PASS}
```
**.env file:**
```bash theme={null}
DB2i_HOST=192.168.1.100
DB2i_USER=MCPUSER
DB2i_PASS=SecurePassword123
```
โ
**Best for**: Systems without DNS resolution
**Authority Requirements:**
The IBM i user profile must have:
* Object authority to tables, views, and procedures accessed by tools
* Special authorities for system services (e.g., `*AUDIT` for security tools)
* IBM i object-level security applies to all SQL queries
***
### Optional Fields
These fields have sensible defaults and can be omitted for most configurations:
| Field | Type | Default | Description |
| --------------------- | ------- | ------- | -------------------------------------------------------- |
| `port` | integer | `8076` | Port number where Mapepire daemon listens |
| `ignore-unauthorized` | boolean | `false` | Accept self-signed SSL certificates |
| `jdbc-options` | object | `{}` | JDBC connection options forwarded to the mapepire driver |
**Detailed Configuration:**
**Default port (8076):**
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
# port: 8076 โ Can be omitted (uses default)
```
**Custom port:**
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 9000
```
**Environment variable (same value as server `.env`):**
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: ${DB2i_PORT}
```
Interpolation supports `${VAR_NAME}` only โ there is no `${VAR:default}` syntax. If `DB2i_PORT` is unset at YAML load time, the placeholder stays literal and validation fails; omit `port` instead to use Mapepire's default **8076**, or set `DB2i_PORT` in `.env` before starting the server.
**Production (valid certificates):**
```yaml theme={null}
sources:
ibmi-production:
host: ${PROD_DB2i_HOST}
user: ${PROD_DB2i_USER}
password: ${PROD_DB2i_PASS}
port: 8076
ignore-unauthorized: false # Require valid certs
```
**Development (self-signed certificates):**
```yaml theme={null}
sources:
ibmi-dev:
host: ${DEV_DB2i_HOST}
user: ${DEV_DB2i_USER}
password: ${DEV_DB2i_PASS}
port: 8076
ignore-unauthorized: true # Allow self-signed
```
**Environment-specific:**
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
ignore-unauthorized: ${DB2i_IGNORE_UNAUTHORIZED:false}
```
**Production Security**: Only use `ignore-unauthorized: true` in development. Production must use valid SSL certificates with `ignore-unauthorized: false`.
***
## JDBC Options
**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.** The `jdbc-options` field accepts any property supported by the IBM i JDBC driver โ library list, SQL naming convention, date format, time format, and many more.
### Common Options
| Option | Purpose | Example |
| ---------------- | -------------------------------------------- | --------------------------------------------------------- |
| `libraries` | Library list for unqualified name resolution | `[MYLIB, DEVDATA, QGPL]` |
| `naming` | SQL naming convention | `sql` or `system` |
| `date format` | Date literal format | `iso`, `usa`, `eur`, `jis`, `mdy`, `dmy`, `ymd`, `julian` |
| `time format` | Time literal format | `hms`, `usa`, `iso`, `eur`, `jis` |
| `date separator` | Date component separator | `/`, `-`, `.`, `,`, `b` |
```yaml theme={null}
sources:
ibmi-dev:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
jdbc-options:
libraries:
- MYLIB
- DEVDATA
- QGPL
```
**Use for**: Resolving unqualified object names against a specific set of libraries.
`libraries` also accepts a comma-separated string: `libraries: "MYLIB, DEVDATA, QGPL"` โ the server splits and trims it into an array.
```yaml theme={null}
sources:
ibmi-iso:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
jdbc-options:
date format: iso # YYYY-MM-DD
```
**Output**: `CURRENT_DATE` โ `2026-04-17` (ISO 8601)
**Other formats:**
* `usa` โ `04/17/2026` (MM/DD/YYYY)
* `eur` โ `17.04.2026` (DD.MM.YYYY)
* `jis` โ `2026-04-17` (same as ISO)
**Job default caveat**: If you don't set `date format`, the driver inherits the connected job's `DATFMT` system value โ which on many systems produces **two-digit years** (e.g., `04/17/26`). Set `date format: iso` explicitly if unambiguous serialization matters to your application.
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
jdbc-options:
naming: system # LIBRARY/OBJECT syntax
```
**Use for**: Legacy SQL using `LIBRARY/OBJECT` slash-notation instead of standard `LIBRARY.OBJECT` dot-notation.
**Values:**
* `sql` (default) โ standard `SCHEMA.OBJECT`
* `system` โ IBM i legacy `LIBRARY/OBJECT`
```yaml theme={null}
sources:
ibmi-reporting:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
jdbc-options:
libraries: [REPORTS, SALESDATA, QGPL]
naming: system
date format: iso
time format: iso
```
**Use for**: Reporting pipelines that need ISO-formatted dates and access to a specific library set.
### Full Property List
The field accepts any property from the mapepire `JDBCOptions` interface โ over 60 settings covering SQL behavior, date/time formatting, locale, tracing, and more. Refer to the [IBM i JDBC properties reference](https://javadoc.io/static/net.sf.jt400/jt400/21.0.0/com/ibm/as400/access/doc-files/JDBCProperties.html) for the complete catalog.
**Passthrough validation**: Unknown keys pass through the schema validator without error and are forwarded to the driver as-is. This is intentional โ it avoids coupling the schema to the driver's exact property surface. The tradeoff is that typos (e.g., `librarys` instead of `libraries`) are silently accepted at config load time and only surface when the driver rejects them at connection time.
### Environment Variable Override
The `DB2i_JDBC_OPTIONS` environment variable overrides `jdbc-options` set in YAML โ operators can enforce a fleet-wide JDBC configuration without editing per-deployment YAML. Env values are shallow-merged over YAML values (env wins on each key).
```bash theme={null}
# Every source in every YAML file runs with these options,
# plus whatever is set per-source in YAML (env wins on collisions)
export DB2i_JDBC_OPTIONS='naming=system;date format=iso;libraries=AUDITLIB,QGPL'
```
See the [Configuration Reference โ DB2i\_JDBC\_OPTIONS](/configuration#db2i-jdbc-options-env-var) for the full syntax and parser rules.
### Security: Credential Logging
The server logs only the `libraries` field of `jdbc-options` at pool initialization. All other JDBC fields โ including potentially sensitive ones like `key ring password`, `proxy server`, and `trace` โ are **intentionally excluded** from logs to prevent credential leakage.
If you need to verify other JDBC options took effect, query the JDBC driver's runtime metadata (for example, execute `SELECT CURRENT_DATE` and inspect the format) rather than relying on log inspection.
***
## Environment Variables
Use environment variables to externalize sensitive configuration and support multiple environments:
### Basic Pattern
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
```
**.env file:**
```bash theme={null}
DB2i_HOST=ibmi-prod.example.com
DB2i_USER=MCPUSER
DB2i_PASS=SecurePassword123
```
### Default Values
Provide fallback values for optional settings:
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: ${DB2i_PORT:8076} # Defaults to 8076
ignore-unauthorized: ${DB2i_IGNORE_UNAUTHORIZED:false} # Defaults to false
```
**Syntax**: `${VARIABLE_NAME:default_value}` - Use `:` to specify default values that apply when the environment variable is not set.
***
## Multiple Sources
Define multiple sources for different environments, systems, or use cases:
### Multi-Environment Setup
```yaml theme={null}
sources:
production:
host: ${PROD_DB2i_HOST}
user: ${PROD_DB2i_USER}
password: ${PROD_DB2i_PASS}
port: 8076
ignore-unauthorized: false
connectionTimeout: 30000
requestTimeout: 120000
development:
host: ${DEV_DB2i_HOST}
user: ${DEV_DB2i_USER}
password: ${DEV_DB2i_PASS}
port: 8076
ignore-unauthorized: true # Self-signed certs OK in dev
connectionTimeout: 10000
requestTimeout: 60000
testing:
host: ${TEST_DB2i_HOST}
user: ${TEST_DB2i_USER}
password: ${TEST_DB2i_PASS}
port: 8076
ignore-unauthorized: true
connectionTimeout: 15000
requestTimeout: 30000
```
**Tool Usage:**
```yaml theme={null}
tools:
production_health_check:
source: production # Uses production source
description: "Production system health metrics"
# ... rest of configuration
development_sandbox:
source: development # Uses development source
description: "Development environment testing"
# ... rest of configuration
```
### Multi-System Setup
Connect to multiple IBM i systems in a single configuration:
```yaml theme={null}
sources:
primary-ibmi:
host: ${PRIMARY_DB2i_HOST}
user: ${PRIMARY_DB2i_USER}
password: ${PRIMARY_DB2i_PASS}
port: 8076
ignore-unauthorized: false
secondary-ibmi:
host: ${SECONDARY_DB2i_HOST}
user: ${SECONDARY_DB2i_USER}
password: ${SECONDARY_DB2i_PASS}
port: 8076
ignore-unauthorized: false
reporting-ibmi:
host: ${REPORTING_DB2i_HOST}
user: ${REPORTING_DB2i_USER}
password: ${REPORTING_DB2i_PASS}
port: 8076
ignore-unauthorized: false
```
***
## Complete Configuration Examples
### Development Configuration
```yaml theme={null}
sources:
ibmi-dev:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
ignore-unauthorized: true
```
**.env:**
```bash theme={null}
DB2i_HOST=ibmi-dev.local
DB2i_USER=DEVUSER
DB2i_PASS=DevPassword123
```
### Production Configuration
```yaml theme={null}
sources:
ibmi-production:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
ignore-unauthorized: false
```
**.env:**
```bash theme={null}
DB2i_HOST=ibmi-prod.example.com
DB2i_USER=MCPUSER
DB2i_PASS=SecureProductionPassword
```
### Custom Port Configuration
```yaml theme={null}
sources:
ibmi-custom:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 9000 # Custom Mapepire port
ignore-unauthorized: false
```
***
## Security Best Practices
**Always use environment variables for:**
* Hostnames
* User profiles
* Passwords
* Ports (if non-standard)
**Never hardcode:**
```yaml theme={null}
# โ BAD - Hardcoded credentials
sources:
ibmi-system:
host: ibmi-prod.example.com
user: ADMIN
password: Password123
# โ
GOOD - Environment variables
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
```
**Regular rotation strategy:**
1. **Update .env file** with new credentials
2. **Restart MCP server** to apply changes
3. **Test connection** with simple tool
4. **Update production** after successful testing
**Automated rotation:**
* Use secrets management systems (Vault, AWS Secrets Manager)
* Configure automatic credential refresh
* Monitor for rotation failures
**Production requirements:**
* Valid SSL certificates from trusted CA
* `ignore-unauthorized: false` enforced
* Regular certificate renewal
* Strong cipher suites
**Development exceptions:**
* Self-signed certificates allowed
* `ignore-unauthorized: true` for testing only
* Never deploy to production with this setting
**Protect YAML configuration files:**
```bash theme={null}
# Restrict to owner read/write only
chmod 600 my-tools.yaml
# Protect .env files
chmod 600 .env
# Never commit to version control
echo ".env" >> .gitignore
echo "*.yaml" >> .gitignore # If contains secrets
```
***
## Troubleshooting
**Symptom:** `ECONNREFUSED` or "Connection refused" errors
**Solutions:**
1. Verify Mapepire daemon is running on IBM i:
```bash theme={null}
netstat -an | grep 8076
```
2. Check firewall rules allow connections
3. Verify hostname resolves correctly:
```bash theme={null}
ping ${DB2i_HOST}
```
4. Test port connectivity:
```bash theme={null}
telnet ${DB2i_HOST} 8076
```
**Symptom:** "Invalid credentials" or "User not authorized" errors
**Solutions:**
1. Verify environment variables are set:
```bash theme={null}
echo $DB2i_USER
echo $DB2i_HOST
```
2. Test credentials directly on IBM i
3. Check user profile status (not disabled/expired)
4. Verify user has database authorities
**Symptom:** "Request timeout" or "Connection timeout" errors
**Solutions:**
1. Increase `requestTimeout` for long-running queries
2. Increase `connectionTimeout` for slow networks
3. Optimize SQL queries to run faster
4. Check network latency between server and IBM i
**Symptom:** "Certificate verification failed" or "Self-signed certificate" errors
**Solutions:**
1. **Development:** Set `ignore-unauthorized: true`
2. **Production:** Install valid SSL certificates on IBM i
3. Update certificate trust store if needed
4. Verify certificate has not expired
***
## Next Steps
Learn about tool definitions and configuration
Organize tools into logical groups
Step-by-step guide to creating custom tools
Complete server configuration reference
**Source Design Philosophy**: Sources represent database connections, not business logic. Keep source configurations simple, secure, and environment-specific. Use environment variables for all sensitive data and support multiple environments with distinct source names.
# Tools Reference
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/tools
Complete reference for defining SQL tools including parameters, validation, security, and response formatting.
**Official Schema**: See the [JSON Schema definition](https://github.com/IBM/ibmi-mcp-server/blob/main/packages/server/src/ibmi-mcp-server/schemas/json/sql-tools-config.json) for the authoritative tool configuration specification.
Tools are individual SQL operations that AI agents can discover and execute. Each tool encapsulates a SQL statement, parameter definitions, validation rules, and execution metadata.
## Tool Structure
Every tool definition follows this structure:
```yaml theme={null}
tools:
tool_name:
source: ibmi-system
description: "What this tool does and when to use it"
statement: |
SELECT * FROM qsys2.system_status_info
parameters: []
security: {}
metadata: {}
```
***
## Required Fields
All SQL tools must include these fields:
| Field | Type | Description |
| ------------- | ----------------- | ----------------------------------------------------------------- |
| `tool_name` | string (YAML key) | Unique identifier for the tool, used by AI agents to call it |
| `source` | string | Name of the database connection source (from `sources` section) |
| `description` | string | Clear explanation of what the tool does, for AI agent consumption |
| `statement` | string | SQL query to execute when the tool is called |
***
### Field Details
**Unique identifier for the tool**
The tool name is the YAML key and must be unique across all tools.
**Naming conventions:**
* Use lowercase with underscores: `get_active_jobs`
* Be descriptive: `find_employees_by_department` not `emp_search`
* Prefix by domain if needed: `perf_system_status`, `sec_audit_trail`
```yaml theme={null}
# โ
Good names
tools:
get_employee_details:
find_employees_by_department:
calculate_employee_bonus:
# โ Avoid
tools:
emp:
query1:
temp_tool:
```
**Database connection reference**
References a source name defined in the `sources` section.
```yaml theme={null}
sources:
ibmi-system:
host: ${DB2i_HOST}
# ...
tools:
system_status:
source: ibmi-system # Must match source key
description: "Get system performance metrics"
# ...
```
**Source Reference**: The source name must match a key in the `sources` section. Each tool can only use one source - if you need to query multiple systems, create separate tools.
**Tool purpose and usage**
Clear, concise explanation written for AI agent consumption.
**Best practices:**
* **Be specific**: "List active jobs sorted by CPU usage" not "Show jobs"
* **Include context**: "Get employee details including department and manager information"
* **Mention limitations**: "Returns maximum of 100 rows"
* **Note requirements**: "Requires \*AUDIT special authority"
```yaml theme={null}
# โ
Good descriptions
description: "Get system performance metrics including CPU usage, memory, and active jobs"
description: "Find employees by department code (A00, B01, etc.) with salary information"
description: "Search for IBM i services by name pattern with optional case-insensitive matching"
# โ Avoid vague descriptions
description: "Gets data"
description: "Employee tool"
description: "System query"
```
**SQL query to execute**
The SQL statement executed when the tool is called. Use pipe `|` for multiline.
```yaml theme={null}
statement: |
SELECT job_name, user_name, cpu_used, elapsed_time
FROM qsys2.active_job_info
WHERE job_status = 'ACTIVE'
ORDER BY cpu_used DESC
FETCH FIRST :limit ROWS ONLY
```
**SQL requirements:**
* Must be valid IBM i SQL (Db2 for i syntax)
* Use `:parameter_name` syntax for parameter binding
* Include `FETCH FIRST n ROWS ONLY` for result limiting
* Test SQL independently before adding to tool
**Parameter Binding**: ALWAYS use parameter binding (`:parameter_name`) for dynamic values. NEVER use string concatenation - this prevents SQL injection attacks and ensures proper type handling.
***
## Parameters
Parameters define dynamic inputs for SQL tools. Each parameter specifies type, validation rules, and usage information.
**See the full Parameter Guide** for detailed examples of all parameter types, validation patterns, and best practices for building SQL tools with parameters.
### Parameter Structure
```yaml theme={null}
parameters:
- name: employee_id
type: string
description: "Employee ID (6 digits)"
required: true
pattern: "^[0-9]{6}$"
```
### Parameter Types
**Text values with validation**
```yaml theme={null}
parameters:
- name: library_name
type: string
description: "IBM i library name (uppercase alphanumeric)"
required: true
pattern: "^[A-Z][A-Z0-9_]*$"
minLength: 1
maxLength: 10
default: "QSYS2"
```
**Validation options:**
* `pattern` - Regular expression for validation
* `minLength` - Minimum string length
* `maxLength` - Maximum string length
* `enum` - Fixed list of allowed values
* `default` - Default value if not provided
**Example with enum:**
```yaml theme={null}
parameters:
- name: object_type
type: string
enum: ["*PGM", "*FILE", "*SRVPGM", "*DTAARA"]
default: "*FILE"
description: "IBM i object type filter"
```
**Whole number values with range validation**
```yaml theme={null}
parameters:
- name: max_rows
type: integer
description: "Maximum number of rows to return"
required: false
minimum: 1
maximum: 1000
default: 50
```
**Validation options:**
* `minimum` - Minimum value (inclusive)
* `maximum` - Maximum value (inclusive)
* `default` - Default value if not provided
**Usage in SQL:**
```sql theme={null}
FETCH FIRST :max_rows ROWS ONLY
```
**Decimal number values**
```yaml theme={null}
parameters:
- name: performance_multiplier
type: float
description: "Performance rating multiplier (0.0-0.3)"
required: true
min: 0.0
max: 0.3
default: 0.1
```
**Validation options:**
* `min` - Minimum value (inclusive)
* `max` - Maximum value (inclusive)
* `default` - Default value if not provided
**Usage in SQL:**
```sql theme={null}
SELECT salary * :performance_multiplier AS bonus
FROM employee
```
**True/false values**
```yaml theme={null}
parameters:
- name: include_completed
type: boolean
description: "Include completed projects (true) or only active (false)"
default: true
```
**Usage in SQL:**
```sql theme={null}
WHERE (:include_completed = 1 OR end_date IS NULL)
```
**SQL Conversion**: Boolean parameters are passed as `1` (true) or `0` (false) to SQL. Use `= 1` or `= 0` in WHERE clauses.
**Lists of values**
```yaml theme={null}
parameters:
- name: project_ids
type: array
itemType: string
description: "List of project IDs to search for"
required: true
minLength: 1
maxLength: 10
```
**Validation options:**
* `itemType` - Type of array elements (string, integer, float, boolean)
* `minLength` - Minimum array length
* `maxLength` - Maximum array length
**Usage in SQL:**
```sql theme={null}
WHERE project_id IN (:project_ids)
```
**MCP call format:**
```json theme={null}
{
"name": "find_projects",
"arguments": {
"project_ids": ["MA2100", "AD3100", "PL2100"]
}
}
```
**Array Format**: Arrays must be passed as JSON arrays (`["A", "B"]`), not strings or SQL syntax (`('A', 'B')`).
### Optional Parameters
Parameters without `required: true` or with `default` values are optional:
```yaml theme={null}
parameters:
- name: user_filter
type: string
required: false
description: "Optional user name filter"
```
**SQL handling for optional parameters:**
```sql theme={null}
WHERE (:user_filter IS NULL OR user_name = :user_filter)
```
***
## Security Configuration
Add security controls to tools for enhanced protection:
```yaml theme={null}
tools:
execute_dynamic_sql:
source: ibmi-system
description: "Execute dynamic SQL with safety controls"
statement: |
SELECT * FROM user_profiles WHERE user_name = :user_name
security:
readOnly: true
maxQueryLength: 15000
forbiddenKeywords: ["DROP", "DELETE", "UPDATE", "TRUNCATE"]
```
### Security Fields
| Field | Type | Default | Description |
| ------------------- | ------- | ------- | ------------------------------------------------- |
| `readOnly` | boolean | `true` | Restrict to read-only operations (SELECT queries) |
| `maxQueryLength` | number | `10000` | Maximum SQL query length in characters |
| `forbiddenKeywords` | array | `[]` | Additional forbidden SQL keywords beyond defaults |
**Mark tools as read-only (SELECT queries only):**
```yaml theme={null}
security:
readOnly: true # Enforce SELECT-only operations
```
**Best Practice**: Mark all tools that don't modify data as `readOnly: true`. This provides clear documentation and can be used for access control.
**Default:** `true` (for safety - tools are read-only by default)
**Limit SQL statement length to prevent abuse:**
```yaml theme={null}
security:
maxQueryLength: 15000 # Limit statement to 15KB
```
**Default:** `10000` characters
**Use case:** Prevents excessively long or complex queries that could impact performance
**Block specific SQL keywords:**
```yaml theme={null}
security:
forbiddenKeywords: ["DROP", "DELETE", "UPDATE", "TRUNCATE", "ALTER"]
```
**Default:** `[]` (empty - uses built-in defaults)
**Use case:** Useful for `execute_sql` tools that accept dynamic SQL. Prevents destructive operations while allowing flexible queries.
These keywords are added to the default forbidden list. The server has built-in protections against destructive operations.
***
## Response Formatting
Control how tool results are formatted for AI agents:
### responseFormat
**Type:** `string`
**Options:** `json` (default), `markdown`
```yaml theme={null}
tools:
markdown_report:
source: ibmi-system
description: "Generate formatted system report"
responseFormat: markdown
statement: |
SELECT
'# System Status Report' AS header,
'## CPU: ' || cpu_utilization || '%' AS cpu,
'## Memory: ' || ROUND((used_memory * 100.0 / total_memory), 2) || '%' AS memory
FROM TABLE(QSYS2.SYSTEM_STATUS()) X
```
**Response types:**
* **json** - Structured data (default, best for AI processing)
* **markdown** - Formatted text with markdown syntax
***
## Fetch-Row Controls
Control how many rows are **fetched from the database** per tool call. These are distinct from [`maxDisplayRows`](/sql-tools/output-formats#maximum-display-rows), which only truncates the rendered markdown table.
**Database vs. display limits:** `rowsToFetch` / `fetchAllRows` change how many rows the server pulls from Db2 for i. `maxDisplayRows` only affects how many rows appear in the formatted output. A tool can fetch 500 rows from the database but render only the first 100 in markdown.
### Fields
The two fields **compose**: `fetchAllRows` is the pagination *policy*; `rowsToFetch`, when set, is the per-fetch *size* in pagination mode, or a single-shot row cap when `fetchAllRows` is off.
| Field | Type | Default | Description |
| -------------- | ------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rowsToFetch` | integer (โฅ 1) | `100` (mapepire default) | With `fetchAllRows: true`, the number of rows per `fetchMore` call. Without `fetchAllRows`, a single-shot cap applied to `FETCH FIRST :limit ROWS ONLY`-style queries. |
| `fetchAllRows` | boolean | `false` | When `true`, paginate until the database reports `is_done` or the safety ceiling (`IBMI_PAGINATION_MAX_ROWS`, default `30000`) is reached. |
### Composition
| Config | Behavior |
| ------------------------------------ | ---------------------------------------------------------------------------- |
| `rowsToFetch: N` alone | Single-shot `execute(N)` โ up to N rows, one round-trip |
| `fetchAllRows: true` alone | Paginate with `IBMI_PAGINATION_DEFAULT_PAGE_SIZE` (default `1000`) per fetch |
| `fetchAllRows: true, rowsToFetch: N` | Paginate with **N rows per fetch** โ tune per tool for wide rows |
When the paginated result hits `IBMI_PAGINATION_MAX_ROWS`, the server truncates the rows returned and emits a warning log. The CLI surfaces the truncation in the output footer so callers know the result was clipped.
**Context-bloat warning:** Large result sets consume LLM context quickly. Prefer `rowsToFetch` with a deliberate small value; only use `fetchAllRows` for small catalogs or when the caller has explicitly requested a full dump.
**Lift the 100-row cap for a single call**
```yaml theme={null}
tools:
list_customers:
source: ibmi-system
description: "List up to 500 customers"
rowsToFetch: 500 # lets FETCH FIRST :limit ROWS ONLY actually return 500
statement: |
SELECT ID, NAME FROM MYLIB.CUSTOMERS
FETCH FIRST :limit ROWS ONLY
parameters:
- name: limit
type: integer
default: 500
minimum: 1
maximum: 500
```
**Use when:**
* Your `FETCH FIRST :limit ROWS ONLY` clause needs more than 100 rows
* You know the expected result size and want a predictable ceiling
* You want row-count safety without running paginated fetches
Setting `rowsToFetch` alone does **not** automatically raise your SQL's `FETCH FIRST` clause โ you still need a parameter or literal that matches. `rowsToFetch` is the ceiling at the driver level.
**Fetch everything (small catalogs only)**
```yaml theme={null}
tools:
list_all_schemas:
source: ibmi-system
description: "List every schema (small catalog)"
fetchAllRows: true # paginates until is_done, bounded by IBMI_PAGINATION_MAX_ROWS
statement: |
SELECT SCHEMA_NAME FROM QSYS2.SYSSCHEMAS
ORDER BY SCHEMA_NAME
```
**Use when:**
* The result set is known to be small (reference tables, catalogs, enums)
* The caller explicitly asks for a complete dump
* You don't know the result size up front but want completeness
Paginated fetches are bounded by `IBMI_PAGINATION_MAX_ROWS` (default `30000`). Beyond that the server truncates and flags the result โ do not rely on `fetchAllRows` for true bulk exports.
**Compose both fields for wide-row tables**
```yaml theme={null}
tools:
export_all_columns:
source: ibmi-system
description: "Stream every column of every table in SAMPLE"
fetchAllRows: true # paginate until exhausted
rowsToFetch: 500 # 500 rows per fetchMore call
statement: |
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, LENGTH
FROM QSYS2.SYSCOLUMNS2
WHERE TABLE_SCHEMA = 'SAMPLE'
```
**Use when:**
* The result set is large **and** you need a smaller per-fetch page (wide rows, memory-sensitive environments)
* The default page size (1000) produces fetches that are too large for your link
* You want explicit control over the WebSocket round-trip/memory tradeoff per tool
Both fields working together is the most expressive option: policy (paginate) and size (per-fetch page) are independent knobs. `rowsToFetch` without `fetchAllRows` stays a single-shot cap.
**Backward-compatible 100-row cap**
```yaml theme={null}
tools:
recent_jobs:
source: ibmi-system
description: "Recent active jobs (up to 100)"
statement: |
SELECT JOB_NAME, USER_NAME, CPU_USED
FROM QSYS2.ACTIVE_JOB_INFO
ORDER BY CPU_USED DESC
# No rowsToFetch / fetchAllRows โ 100 rows
```
Tools with neither property set fetch up to **100 rows** โ the mapepire driver default. This is the pre-existing behavior and requires no changes to keep working.
***
## Metadata
Add descriptive metadata for tool organization and discovery:
```yaml theme={null}
tools:
inventory_analysis:
source: ibmi-system
description: "Comprehensive inventory analysis report"
statement: |
SELECT * FROM inventory_summary
metadata:
title: "Inventory Analysis Report"
version: "2.1.0"
author: "IBM i Development Team"
keywords: ["inventory", "analysis", "reporting"]
lastUpdated: "2024-01-15"
domain: business
category: reporting
environment: production
```
### Metadata Fields
Human-readable title for the tool
Semantic version for tracking tool changes
Individual or team responsible for the tool
Search keywords for tool discovery
Date of last modification (ISO format)
Business domain classification (monitoring, security, business, etc.)
Functional category within domain
Target environment (production, development, testing)
***
## Complete Tool Examples
### Simple Query (No Parameters)
```yaml theme={null}
tools:
system_status:
source: ibmi-system
description: "Overall system performance statistics with CPU, memory, and I/O metrics"
statement: |
SELECT * FROM TABLE(QSYS2.SYSTEM_STATUS(
RESET_STATISTICS=>'YES',
DETAILED_INFO=>'ALL'
)) X
parameters: []
```
### String Parameter with Validation
```yaml theme={null}
tools:
get_employee_details:
source: ibmi-sample
description: "Retrieve detailed employee information including department and manager"
statement: |
SELECT
E.EMPNO,
E.FIRSTNME,
E.LASTNAME,
E.JOB,
E.SALARY,
D.DEPTNAME,
M.LASTNAME AS MGR_LASTNAME
FROM SAMPLE.EMPLOYEE E
LEFT JOIN SAMPLE.DEPARTMENT D ON E.WORKDEPT = D.DEPTNO
LEFT JOIN SAMPLE.EMPLOYEE M ON D.MGRNO = M.EMPNO
WHERE E.EMPNO = :employee_id
parameters:
- name: employee_id
type: string
description: "Employee ID (e.g., '000010') - Must be 6 digits"
required: true
pattern: "^[0-9]{6}$"
```
### Multiple Parameters with Different Types
```yaml theme={null}
tools:
search_employees:
source: ibmi-sample
description: "Search for employees by name with pagination"
statement: |
SELECT
E.EMPNO,
E.FIRSTNME,
E.LASTNAME,
E.JOB,
E.WORKDEPT,
D.DEPTNAME
FROM SAMPLE.EMPLOYEE E
LEFT JOIN SAMPLE.DEPARTMENT D ON E.WORKDEPT = D.DEPTNO
WHERE UPPER(E.FIRSTNME) LIKE UPPER('%' || :name_search || '%')
OR UPPER(E.LASTNAME) LIKE UPPER('%' || :name_search || '%')
ORDER BY E.LASTNAME, E.FIRSTNME
LIMIT :page_size OFFSET (:page_number - 1) * :page_size
parameters:
- name: name_search
type: string
description: "Name to search for (partial match)"
required: true
minLength: 2
- name: page_size
type: integer
description: "Number of results per page"
default: 10
minimum: 1
maximum: 100
- name: page_number
type: integer
description: "Page number (starting from 1)"
default: 1
minimum: 1
```
### Tool with Security Configuration
```yaml theme={null}
tools:
user_profile_audit:
source: ibmi-system
description: "Audit user profile security settings (requires *AUDIT authority)"
statement: |
SELECT
user_profile_name,
status,
previous_signon,
days_until_password_expires,
user_class_name,
group_profile_name
FROM qsys2.user_info
WHERE user_profile_name = :user_profile
parameters:
- name: user_profile
type: string
required: true
pattern: "^[A-Z][A-Z0-9_]*$"
maxLength: 10
description: "User profile name to audit"
security:
readOnly: true
audit: true
requiredAuthority: "*AUDIT"
scopes: ["security:audit"]
warning: "Accesses sensitive user profile information. Requires *AUDIT authority."
```
### Array Parameter Tool
```yaml theme={null}
tools:
find_project_team_members:
source: ibmi-sample
description: "Find all employees working on specific projects"
statement: |
SELECT
E.EMPNO,
E.FIRSTNME,
E.LASTNAME,
E.JOB,
EPA.PROJNO,
EPA.EMSTDATE AS PROJECT_START_DATE
FROM SAMPLE.EMPPROJACT EPA
JOIN SAMPLE.EMPLOYEE E ON EPA.EMPNO = E.EMPNO
WHERE EPA.PROJNO IN (:project_ids)
ORDER BY EPA.PROJNO, E.LASTNAME
parameters:
- name: project_ids
type: array
itemType: string
description: "List of project IDs (e.g., ['MA2100', 'AD3100'])"
required: true
minLength: 1
maxLength: 10
```
***
## Best Practices
**Optimization:**
* Always include `FETCH FIRST n ROWS ONLY` to limit results
* Use `LEFT JOIN` instead of `INNER JOIN` when relationships are optional
* Add `ORDER BY` for consistent result ordering
* Use column aliases for better AI understanding
**Example:**
```sql theme={null}
SELECT
job_name AS "Job Name",
user_name AS "User",
cpu_used AS "CPU Time (ms)"
FROM qsys2.active_job_info
WHERE job_status = 'ACTIVE'
ORDER BY cpu_used DESC
FETCH FIRST 100 ROWS ONLY
```
**Always validate:**
* String patterns for IBM i names: `^[A-Z][A-Z0-9_]*$`
* String lengths: `maxLength: 10` for library names
* Integer ranges: `minimum: 1, maximum: 1000`
* Required vs optional: Mark appropriately
**Example:**
```yaml theme={null}
parameters:
- name: library
type: string
required: true
pattern: "^[A-Z][A-Z0-9_]*$"
maxLength: 10
description: "IBM i library name (uppercase, max 10 chars)"
```
**Write for AI agents:**
* Be specific about what data is returned
* Mention any special authority requirements
* Include parameter examples in descriptions
* Note any result limits or performance considerations
**Good example:**
```yaml theme={null}
description: "List active jobs sorted by CPU usage. Returns top 100 jobs. Requires connection to production system. Results updated every 5 seconds."
```
**Mark sensitive tools:**
* Set `audit: true` for all tools accessing user data
* Use `readOnly: true` for SELECT-only operations
* Document required authorities in `security.requiredAuthority`
* Add warnings for potentially destructive operations
**Example:**
```yaml theme={null}
security:
readOnly: true
audit: true
requiredAuthority: "*SECADM"
warning: "Accesses security configuration. Use with caution."
```
***
## Next Steps
Configure database connection sources
Organize tools into logical groups
Step-by-step guide with examples
Deep dive into validation rules
**Tool Design Philosophy**: Effective tools are **discoverable** (clear names and descriptions), **safe** (proper validation and security), and **performant** (optimized SQL with result limits). Write tools for AI agent consumption, not just human readability.
# Toolsets Reference
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/toolsets
Complete reference for organizing SQL tools into logical groups using toolsets.
**Official Schema**: See the [JSON Schema definition](https://github.com/IBM/ibmi-mcp-server/blob/main/packages/server/src/ibmi-mcp-server/schemas/json/sql-tools-config.json) for the authoritative toolset configuration specification.
Toolsets organize related tools into logical groups that can be discovered, filtered, and deployed together. They provide a way to structure large collections of tools by functional area, business domain, or use case.
## What Are Toolsets?
Toolsets are named collections of tools that share a common purpose or domain. They enable:
* **Selective loading** - Load only the tools you need
* **Logical organization** - Group related capabilities together
* **Discoverability** - Help AI agents find relevant tools
* **Access control** - Manage permissions by toolset
* **Deployment flexibility** - Deploy different toolsets to different environments
**Design Principle**: Toolsets are purely organizational - they don't change tool behavior. A tool works the same whether loaded individually or as part of a toolset.
***
## Toolset Structure
Define toolsets in the `toolsets` section of your YAML configuration:
```yaml theme={null}
toolsets:
toolset_name:
title: "Human-Readable Title"
description: "What this toolset provides"
tools:
- tool_name_1
- tool_name_2
- tool_name_3
```
### Basic Example
```yaml theme={null}
tools:
system_status:
source: ibmi-system
description: "Get system performance metrics"
# ... tool configuration
active_job_info:
source: ibmi-system
description: "List active jobs"
# ... tool configuration
memory_pools:
source: ibmi-system
description: "Show memory pool statistics"
# ... tool configuration
toolsets:
performance_monitoring:
title: "Performance Monitoring"
description: "Tools for monitoring IBM i system performance and resource utilization"
tools:
- system_status
- active_job_info
- memory_pools
```
***
## Toolset Fields Reference
### Required Fields
All toolsets must include these fields:
| Field | Type | Description |
| -------------- | ----------------- | ---------------------------------------------------------------- |
| `toolset_name` | string (YAML key) | Unique identifier for the toolset, used to reference and load it |
| `tools` | array of strings | List of tool names to include in this toolset |
**Tool References**: Each tool name in the `tools` array must match a key in the `tools` section. The server will error if a referenced tool doesn't exist.
***
### Field Details
**Unique identifier for the toolset**
The toolset name is the YAML key and must be unique across all toolsets in the configuration.
**Naming conventions:**
* Use lowercase with underscores: `performance_monitoring`
* Be descriptive of the domain: `employee_information`, `security_audit`
* Group logically: `system_administration`, `business_reporting`
```yaml theme={null}
# โ
Good names
toolsets:
performance_monitoring:
employee_information:
security_audit:
business_reporting:
# โ Avoid
toolsets:
tools1:
misc:
temp:
```
**Array of tool names to include**
**Type:** `array` of strings (tool names)
**Required:** Yes
Lists the tools that belong to this toolset. Each name must match a tool defined in the `tools` section.
```yaml theme={null}
toolsets:
employee_information:
title: "Employee Information"
description: "Tools for retrieving and analyzing employee data"
tools:
- get_employee_details
- find_employees_by_department
- find_employees_by_job
- search_employees
```
**Cross-toolset tools**: A tool can appear in multiple toolsets. This is useful for shared utilities or tools that serve multiple purposes.
**Human-readable display name**
**Type:** `string`
**Required:** No (but recommended)
Provides a clear, user-friendly name for the toolset displayed in documentation and tooling.
```yaml theme={null}
toolsets:
performance_monitoring:
title: "Performance Monitoring" # Displayed to users
description: "Tools for monitoring system performance"
tools:
- system_status
- active_jobs
```
**Explanation of toolset purpose**
**Type:** `string`
**Required:** No (but recommended)
Describes what capabilities this toolset provides and who should use it.
**Best practices:**
* Describe the business purpose, not just the tools
* Mention target users or use cases
* Note any special requirements
```yaml theme={null}
toolsets:
security_audit:
title: "Security Audit Tools"
description: "Comprehensive security analysis and audit trail tools for compliance reporting. Requires *AUDIT special authority."
tools:
- user_audit
- authority_check
```
***
## Organization Strategies
### By Functional Domain
Organize tools by what they do:
```yaml theme={null}
toolsets:
performance_monitoring:
title: "Performance Monitoring"
description: "System performance and resource utilization"
tools:
- system_status
- active_job_info
- memory_pools
- http_server_stats
system_administration:
title: "System Administration"
description: "Administrative tools for system management"
tools:
- describe_object
- list_services_by_category
- search_services_by_name
- library_list_info
security_audit:
title: "Security Audit"
description: "Security analysis and compliance reporting"
tools:
- user_profile_audit
- object_authority_check
- audit_trail_analysis
```
### By Business Process
Organize tools by business workflow:
```yaml theme={null}
toolsets:
employee_onboarding:
title: "Employee Onboarding"
description: "Tools for new employee setup and validation"
tools:
- create_employee_record
- assign_department
- initialize_benefits
- setup_security_access
payroll_processing:
title: "Payroll Processing"
description: "Payroll calculation and reporting tools"
tools:
- calculate_gross_pay
- compute_deductions
- generate_pay_stub
- tax_withholding_report
performance_review:
title: "Performance Review"
description: "Employee performance evaluation workflow"
tools:
- get_employee_metrics
- calculate_bonus
- generate_review_report
- update_salary_grade
```
### By User Role
Organize tools by who uses them:
```yaml theme={null}
toolsets:
developer_tools:
title: "Developer Tools"
description: "Development and debugging utilities"
tools:
- object_dependencies
- recently_used_objects
- stale_object_detection
- source_code_search
dba_tools:
title: "Database Administrator Tools"
description: "Database management and optimization"
tools:
- table_analysis
- index_statistics
- foreign_key_relationships
- database_health_check
auditor_tools:
title: "Auditor Tools"
description: "Compliance and security auditing"
tools:
- user_access_audit
- privilege_escalation_check
- data_modification_log
- security_configuration_review
```
### By Environment
Organize tools by deployment environment:
```yaml theme={null}
toolsets:
production_monitoring:
title: "Production Monitoring"
description: "Production system monitoring (read-only)"
tools:
- prod_system_health
- prod_performance_metrics
- prod_job_status
- prod_error_logs
development_utilities:
title: "Development Utilities"
description: "Development and testing tools (write-enabled)"
tools:
- dev_create_test_data
- dev_reset_environment
- dev_debug_trace
- dev_schema_compare
```
***
## Selective Loading
Control which toolsets are loaded at server startup:
### Load All Toolsets
```bash theme={null}
# No --toolsets parameter loads everything
npx -y @ibm/ibmi-mcp-server@latest --tools tools/my-tools.yaml
```
### Load Specific Toolsets
```bash theme={null}
# Load single toolset
npx -y @ibm/ibmi-mcp-server@latest --tools tools/my-tools.yaml --toolsets performance_monitoring
# Load multiple toolsets (comma-separated)
npx -y @ibm/ibmi-mcp-server@latest --tools tools/my-tools.yaml --toolsets performance_monitoring,security_audit
# Load from environment variable
SELECTED_TOOLSETS=employee_information,payroll_processing
npx -y @ibm/ibmi-mcp-server@latest --tools tools/my-tools.yaml --toolsets $SELECTED_TOOLSETS
```
### List Available Toolsets
```bash theme={null}
# Show all toolsets without starting the server
npx -y @ibm/ibmi-mcp-server@latest --list-toolsets --tools tools/my-tools.yaml
```
**Output:**
```
Available toolsets in tools/my-tools.yaml:
performance_monitoring:
Title: Performance Monitoring
Description: Tools for monitoring IBM i system performance
Tools: system_status, active_job_info, memory_pools (3 tools)
security_audit:
Title: Security Audit
Description: Security analysis and compliance reporting
Tools: user_profile_audit, object_authority_check (2 tools)
employee_information:
Title: Employee Information
Description: Employee data retrieval and analysis
Tools: get_employee_details, find_employees_by_department, search_employees (3 tools)
```
***
## Multiple File Organization
Structure large tool collections across multiple files with consistent toolsets:
### File Structure
```
tools/
โโโ performance.yaml # Performance monitoring tools
โโโ security.yaml # Security and audit tools
โโโ employee.yaml # Employee management tools
โโโ business.yaml # Business logic tools
```
### Consistent Toolsets Across Files
**tools/performance.yaml:**
```yaml theme={null}
sources:
ibmi-system:
# ... connection config
tools:
system_status:
# ... tool config
active_job_info:
# ... tool config
toolsets:
performance_monitoring:
title: "Performance Monitoring"
tools:
- system_status
- active_job_info
```
**tools/security.yaml:**
```yaml theme={null}
sources:
ibmi-system:
# ... connection config
tools:
user_audit:
# ... tool config
authority_check:
# ... tool config
toolsets:
security_audit:
title: "Security Audit"
tools:
- user_audit
- authority_check
```
**Load all files:**
```bash theme={null}
# Load entire directory
npx -y @ibm/ibmi-mcp-server@latest --tools tools/
# Load directory with specific toolsets
npx -y @ibm/ibmi-mcp-server@latest --tools tools/ --toolsets performance_monitoring,security_audit
```
***
## Complete Examples
### Example 1: Sample Database Toolsets
```yaml theme={null}
tools:
get_employee_details:
# ... tool config
find_employees_by_department:
# ... tool config
get_employee_projects:
# ... tool config
find_project_team_members:
# ... tool config
get_department_salary_stats:
# ... tool config
calculate_employee_bonus:
# ... tool config
toolsets:
employee_information:
title: "Employee Information"
description: "Tools for retrieving and analyzing employee data"
tools:
- get_employee_details
- find_employees_by_department
- find_employees_by_job
- search_employees
project_management:
title: "Project Management"
description: "Tools for managing project assignments and team members"
tools:
- get_employee_projects
- find_project_team_members
salary_analysis:
title: "Salary Analysis"
description: "Tools for analyzing salary data across departments"
tools:
- get_department_salary_stats
- calculate_employee_bonus
```
### Example 2: System Administration Toolsets
```yaml theme={null}
toolsets:
system_monitoring:
title: "System Monitoring"
description: "Real-time system health and performance monitoring"
tools:
- system_status
- subsystem_status
- active_job_info
- memory_pools
- http_server_stats
object_management:
title: "Object Management"
description: "Database object inspection and analysis"
tools:
- describe_object
- list_services_by_category
- search_services_by_name
- object_statistics
- object_dependencies
security_management:
title: "Security Management"
description: "User and authority management tools"
tools:
- user_profile_info
- object_authority_check
- library_list_security
- audit_trail_analysis
```
### Example 3: Multi-Environment Toolsets
```yaml theme={null}
toolsets:
production_readonly:
title: "Production Read-Only Tools"
description: "Safe monitoring tools for production environment"
tools:
- prod_system_health
- prod_job_status
- prod_performance_metrics
- prod_error_logs
development_full:
title: "Development Full Access"
description: "All development tools including write operations"
tools:
- dev_system_health
- dev_job_status
- dev_create_test_data
- dev_reset_environment
- dev_debug_trace
testing_validation:
title: "Testing Validation Tools"
description: "Tools for test execution and validation"
tools:
- test_data_validation
- test_result_comparison
- test_coverage_analysis
```
***
## Best Practices
**Optimal size:** 3-10 tools per toolset
* **Too small** (1-2 tools): Defeats the purpose of grouping
* **Too large** (20+ tools): Reduces discoverability and increases load time
* **Just right** (3-10 tools): Easy to understand and manage
**Example:**
```yaml theme={null}
# โ
Good size
toolsets:
performance_monitoring:
tools: [system_status, active_jobs, memory_pools, cpu_usage]
# โ Too small
toolsets:
single_tool_set:
tools: [system_status]
# โ Too large
toolsets:
everything:
tools: [tool1, tool2, ... tool25]
```
**Use consistent naming patterns:**
* Domain-based: `{domain}_{purpose}` โ `security_audit`, `performance_monitoring`
* Role-based: `{role}_tools` โ `developer_tools`, `dba_tools`
* Environment-based: `{env}_{category}` โ `prod_monitoring`, `dev_utilities`
**Be consistent within a project:**
```yaml theme={null}
# โ
Consistent pattern
toolsets:
performance_monitoring:
security_monitoring:
application_monitoring:
# โ Inconsistent
toolsets:
performance: # Missing "_monitoring"
sec_audit: # Abbreviated
app_mon_tools: # Different pattern
```
**Tools can belong to multiple toolsets:**
```yaml theme={null}
tools:
system_health:
# ... config
toolsets:
production_monitoring:
tools:
- system_health
- prod_metrics
development_monitoring:
tools:
- system_health # Same tool in different toolset
- dev_metrics
```
**Use cases:**
* Shared utility tools (logging, health checks)
* Cross-domain tools (system information)
* Different access levels to same tool
**Always include:**
* `title`: Clear, human-readable name
* `description`: Purpose and target users
* Mention any special requirements (authorities, environments)
```yaml theme={null}
toolsets:
security_audit:
title: "Security Audit Tools"
description: "Comprehensive security analysis and audit trail tools for compliance reporting. Requires *AUDIT special authority. Production use only."
tools:
- user_audit
- authority_check
- compliance_report
```
***
## Environment-Specific Toolset Loading
Use environment variables to control toolset loading across environments:
**Development:**
```bash theme={null}
# .env.development
SELECTED_TOOLSETS=development_full,testing_validation
```
**Production:**
```bash theme={null}
# .env.production
SELECTED_TOOLSETS=production_readonly,system_monitoring
```
**Start server:**
```bash theme={null}
npx -y @ibm/ibmi-mcp-server@latest --tools tools/ --toolsets $SELECTED_TOOLSETS
```
***
## Next Steps
Configure database connection sources
Define individual SQL tool operations
Step-by-step guide to creating tools and toolsets
High-level overview of the SQL tools system
**Toolset Design Philosophy**: Toolsets are organizational constructs that improve discoverability and deployment flexibility. Design toolsets around how tools are **used** (functional domains, business processes, user roles) rather than how they're **built** (database schemas, file structure). Good toolsets help AI agents and humans quickly find the right tool for their task.
# Using Default Tools
Source: https://ibm-d95bab6e.mintlify.app/sql-tools/using-default-tools
Comprehensive guide to starting the MCP server with pre-built SQL tools for IBM i operations.
The IBM i MCP Server includes a curated collection of pre-built SQL tools in the `tools/` directory. These production-ready tools cover common IBM i operations from system monitoring to security analysis, allowing you to start building AI agents immediately without writing custom YAML configurations.
**Prerequisites**: This guide assumes you've completed the [Quickstart](/quickstart) and have:
* IBM i database credentials configured (`DB2i_HOST`, `DB2i_USER`, `DB2i_PASS`)
* Access to the pre-built tools directory (clone or download from [GitHub](https://github.com/IBM/ibmi-mcp-server/tree/main/tools))
## Getting the Tools Directory
Download the pre-built tools from the repository:
```bash theme={null}
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server
```
All examples use `npx @ibm/ibmi-mcp-server` to run the published package. Point `--tools` to wherever you've saved the `tools/` directory.
***
## Available Tool Categories
The `tools/` directory contains pre-built tool configurations organized by functional domain:
| Directory | Category | Description | Key Tools |
| -------------------------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [**sample/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/sample) | Sample Data | Demonstration tools using IBM i SAMPLE schema (employee, department, project data) | Employee lookup, department analysis, project management |
| [**sys-admin/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/sys-admin) | System Administration | High-level system service discovery and metadata exploration | Service catalogs, schema browsing, example queries |
| [**security/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/security) | Security Analysis | Library list security assessment and vulnerability detection | Library list configuration, authority checks, security analysis |
| [**performance/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/performance) | Performance Monitoring | System performance metrics and resource utilization | System status, active jobs, memory pools, HTTP server stats |
| [**developer/**](https://github.com/IBM/ibmi-mcp-server/tree/main/tools/developer) | Development Tools | Object statistics and dependency analysis for developers | Recently used objects, stale object detection, dependency tracking |
**List All Available Toolsets:**
```bash theme={null}
npx @ibm/ibmi-mcp-server --list-toolsets --tools ./tools
```
This command shows all toolsets with descriptions and tool counts.
***
## Loading Strategies
### 1. Load All Tools from Directory
Load every YAML file in the `tools/` directory and all subdirectories:
```bash theme={null}
# Set environment variable to allow duplicate sources
export YAML_ALLOW_DUPLICATE_SOURCES=true
# HTTP transport (recommended for testing)
npx @ibm/ibmi-mcp-server --transport http --tools ./tools
# STDIO transport (for MCP client integration)
npx @ibm/ibmi-mcp-server --transport stdio --tools ./tools
```
**Important**: When loading all tools from the directory, you **must** set `YAML_ALLOW_DUPLICATE_SOURCES=true`. Multiple YAML files define the same database sources (e.g., `ibmi-system`), and this setting allows the server to merge them instead of failing with a duplicate source error.
**Alternative: Use .env file**
Create a `.env` file in your working directory:
```bash theme={null}
# .env
YAML_ALLOW_DUPLICATE_SOURCES=true
DB2i_HOST=your-ibmi-system.local
DB2i_USER=YOURUSERID
DB2i_PASS=YourPassword
```
Then start the server:
```bash theme={null}
npx @ibm/ibmi-mcp-server --transport http --tools ./tools
```
**What happens:**
* Recursively scans `tools/` for all `.yaml` files
* Loads all tools from all categories
* Makes every toolset available to AI agents
* Merges sources, tools, and toolsets across files
* Allows duplicate source definitions (e.g., `ibmi-system` appears in multiple files)
**Why Duplicate Sources?** Each YAML file is designed to be self-contained with its own source definitions. When loading multiple files, the same database connection (like `ibmi-system`) appears in multiple files. The `YAML_ALLOW_DUPLICATE_SOURCES=true` setting intelligently merges these duplicate definitions.
***
### 2. Load Specific Configuration File
Target a single YAML file for focused operations:
```bash theme={null}
# Load only performance monitoring tools
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools/performance/performance.yaml
```
**Includes tools for:**
* System status and health
* Active job monitoring
* Memory pool utilization
* HTTP server statistics
```bash theme={null}
# Load only security analysis tools
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools/security/library-list-security.yaml
```
**Includes tools for:**
* Library list configuration
* Authority validation
* Security vulnerability detection
```bash theme={null}
# Load sample employee database tools
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools/sample/employee-info.yaml
```
**Includes tools for:**
* Employee information lookup
* Department analysis
* Project assignment queries
**Benefits:**
* **Fast startup** - Only loads tools from specified file
* **Clear scope** - Agent sees only relevant tools for the task
* **Easy debugging** - Isolated tool configuration
* **Production ready** - Minimal resource usage
* **No duplicate sources** - Single file = single source definition
***
### 3. Load Specific Toolsets
Select logical groups of tools across multiple files using toolset filtering:
**Discover Available Toolsets**: Before loading specific toolsets, list all available default toolsets and their tools:
```bash theme={null}
npx @ibm/ibmi-mcp-server --list-toolsets --tools ./tools
```
This shows toolset names, descriptions, and tool counts to help you choose which ones to load.
#### Single Toolset
```bash theme={null}
export YAML_ALLOW_DUPLICATE_SOURCES=true
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets performance_monitoring
```
**Result**: Only tools tagged with `performance_monitoring` toolset are loaded, even though all YAML files are scanned.
```bash theme={null}
export YAML_ALLOW_DUPLICATE_SOURCES=true
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets security_audit
```
**Result**: Only security analysis tools are available to AI agents.
#### Multiple Toolsets
Combine related toolsets for comprehensive operations:
```bash theme={null}
# Required when loading from directory
export YAML_ALLOW_DUPLICATE_SOURCES=true
# System administration and monitoring
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets performance_monitoring,system_admin
# Development workflow
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets developer_tools,sample_data
# Security and compliance
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets security_audit,system_admin
```
**Toolset Names**: Use the exact toolset identifiers from the YAML configurations. Run `--list-toolsets` to see available names.
***
## Environment Variables
Configure database connections and runtime behavior:
### Required Database Credentials
```bash theme={null}
# IBM i connection details
export DB2i_HOST="your-ibmi-system.local"
export DB2i_USER="YOURUSERID"
export DB2i_PASS="YourPassword"
# Optional: Custom port (default: 8076)
export DB2i_PORT=8076
# Optional: SSL validation (default: true in production)
export DB2i_IGNORE_UNAUTHORIZED=true # Development only
```
### Server Configuration
```bash theme={null}
# HTTP transport settings
export MCP_HTTP_PORT=3010
export MCP_HTTP_HOST="127.0.0.1" # loopback-only; see note below before using 0.0.0.0
# Logging configuration
export MCP_LOG_LEVEL=debug # debug | info | warning | error
# Pre-select toolsets at startup
export SELECTED_TOOLSETS="performance_monitoring,security_audit"
# YAML configuration (important when loading all tools)
export YAML_ALLOW_DUPLICATE_SOURCES=true # Required when loading tools/ directory
export YAML_ALLOW_DUPLICATE_TOOLS=false # Prevent accidental tool name conflicts
```
**Binding beyond loopback requires authentication.** The server refuses to start when it is bound to a non-loopback address (`MCP_HTTP_HOST=0.0.0.0`) with IBM i credentials configured and authentication not enforced โ otherwise anyone with network reach could execute these SQL tools with your credentials.
To expose the server on a network, set `MCP_AUTH_MODE` (note that `jwt` also needs `MCP_AUTH_SECRET_KEY`, or verification is bypassed) and allowlist the hostname clients use:
```bash theme={null}
export MCP_HTTP_HOST="0.0.0.0"
export MCP_ALLOWED_HOSTS="mcp.mycompany.local"
export MCP_AUTH_MODE=ibmi
```
To accept the risk on a trusted network instead, set `MCP_ALLOW_UNAUTHENTICATED_HTTP=true` explicitly.
### Complete Example
```bash theme={null}
# Set environment variables
export DB2i_HOST="ibmi-dev.mycompany.local"
export DB2i_USER="DEVUSER"
export DB2i_PASS="DevPassword123"
export MCP_LOG_LEVEL=debug
export MCP_HTTP_PORT=3010
# Required when loading all tools from directory
export YAML_ALLOW_DUPLICATE_SOURCES=true
# Start server with specific toolsets
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets performance_monitoring,developer_tools
```
**Use `.env` Files**: Create a `.env` file in your working directory for persistent configuration:
```bash theme={null}
# .env
DB2i_HOST=ibmi-dev.mycompany.local
DB2i_USER=DEVUSER
DB2i_PASS=DevPassword123
MCP_LOG_LEVEL=debug
YAML_ALLOW_DUPLICATE_SOURCES=true
```
The server automatically loads environment variables from `.env` files in the current directory.
***
## Usage Scenarios
**Testing Your Server**: Each scenario includes examples for testing with:
* **MCP Inspector**: Interactive browser-based tool for exploring and testing MCP tools
* **Agno Agent** (Python): Quick AI agent testing with natural language prompts ([setup guide](https://github.com/IBM/ibmi-mcp-server/tree/main/client))
### Scenario 1: Quick System Health Check
**Goal**: Monitor IBM i system health with AI assistance.
**Start the server:**
```bash theme={null}
# Load performance monitoring tools (single file - no duplicate sources needed)
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools/performance/performance.yaml
```
```bash theme={null}
# Open MCP Inspector in browser
npx @modelcontextprotocol/inspector \
npx @ibm/ibmi-mcp-server --transport stdio --tools ./tools/performance/performance.yaml
```
**In Inspector**: Select any performance tool and fill in parameters to execute queries.
```bash theme={null}
# From the client directory (requires setup - see link above)
cd client
uv run agent.py -p "Check the system health and identify any resource bottlenecks. Show me the top 5 CPU consumers."
```
The agent will automatically select and execute appropriate tools based on your natural language prompt.
***
### Scenario 2: Security Audit
**Goal**: Perform comprehensive security analysis.
**Start the server:**
```bash theme={null}
# Allow duplicate sources when loading multiple toolsets
export YAML_ALLOW_DUPLICATE_SOURCES=true
# Load security and system admin tools
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets security_audit,system_admin
```
```bash theme={null}
# Set environment variable first
export YAML_ALLOW_DUPLICATE_SOURCES=true
# Open MCP Inspector
npx @modelcontextprotocol/inspector \
npx @ibm/ibmi-mcp-server --transport stdio --tools ./tools --toolsets security_audit,system_admin
```
**In Inspector**: Explore security tools like library list analysis and authority checks.
```bash theme={null}
# From the client directory
cd client
uv run agent.py -p "Analyze the library list configuration for security vulnerabilities. Check for any unauthorized access or suspicious authority levels."
```
The agent will use security-focused tools to perform the analysis.
***
### Scenario 3: Development Workflow
**Goal**: Help developers find and manage IBM i objects.
**Start the server:**
```bash theme={null}
# Allow duplicate sources when loading multiple toolsets
export YAML_ALLOW_DUPLICATE_SOURCES=true
# Load developer tools and sample data
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets developer_tools,sample_data
```
```bash theme={null}
# Set environment variable first
export YAML_ALLOW_DUPLICATE_SOURCES=true
# Open MCP Inspector
npx @modelcontextprotocol/inspector \
npx @ibm/ibmi-mcp-server --transport stdio --tools ./tools --toolsets developer_tools,sample_data
```
**In Inspector**: Test developer tools for object statistics and dependency tracking.
```bash theme={null}
# From the client directory
cd client
uv run agent.py -p "Find all objects I modified in the last 7 days. Show me any stale objects that haven't been accessed recently."
```
The agent will query object statistics and provide development insights.
***
### Scenario 4: Production Monitoring Dashboard
**Goal**: Create a monitoring agent with specific tool access.
**Start the server:**
```bash theme={null}
# Production configuration
export MCP_LOG_LEVEL=info
export MCP_HTTP_PORT=8080
export DB2i_IGNORE_UNAUTHORIZED=false # Enforce SSL in production
export YAML_ALLOW_DUPLICATE_SOURCES=true # Required for directory loading
# Start with performance monitoring only
npx @ibm/ibmi-mcp-server \
--transport http \
--tools ./tools \
--toolsets performance_monitoring
```
```bash theme={null}
# Set environment variables
export YAML_ALLOW_DUPLICATE_SOURCES=true
export MCP_LOG_LEVEL=info
# Open MCP Inspector
npx @modelcontextprotocol/inspector \
npx @ibm/ibmi-mcp-server --transport stdio --tools ./tools --toolsets performance_monitoring
```
**In Inspector**: Monitor real-time system performance metrics.
```bash theme={null}
# From the client directory
# Update url in agent.py if using custom port (default: 3010)
cd client
uv run agent.py -p "Show me current system status and identify any performance issues."
```
The agent provides continuous monitoring with natural language queries.
***
## Command Reference
### CLI Options
| Option | Alias | Description | Example |
| -------------------- | ----- | ----------------------------------------------------- | -------------------------------------------------- |
| `--tools ` | - | Path to YAML tools (file, directory, or glob pattern) | `--tools tools/performance/performance.yaml` |
| `--toolsets ` | `-ts` | Comma-separated list of toolsets to load | `--toolsets performance_monitoring,security_audit` |
| `--transport ` | `-t` | Transport protocol: `stdio` or `http` | `--transport http` |
| `--list-toolsets` | - | Show all available toolsets and exit | `--list-toolsets --tools tools` |
| `--help` | `-h` | Display help message and exit | `--help` |
### Path Formats
The `--tools` argument accepts multiple formats:
```bash theme={null}
# Specific YAML file
--tools tools/performance/performance.yaml
--tools /absolute/path/to/config.yaml
--tools ../relative/path/to/config.yaml
```
```bash theme={null}
# All YAML files in directory (recursive)
--tools tools
--tools tools/performance
--tools /absolute/path/to/tools
```
```bash theme={null}
# Pattern matching (quote for shell safety)
--tools "tools/**/*.yaml"
--tools "tools/performance/*.yaml"
--tools "custom-tools/**/*-dev.yaml"
```
***
## Troubleshooting
### No Tools Loaded
**Symptom**: Server starts but no tools are available.
**Solutions**:
1. **Verify path exists**:
```bash theme={null}
ls -la ./tools/performance/performance.yaml
```
2. **Check path is relative to current directory**:
```bash theme={null}
# Use ./ prefix for relative paths
npx @ibm/ibmi-mcp-server --tools ./tools
# Or use absolute paths
npx @ibm/ibmi-mcp-server --tools /full/path/to/tools
```
3. **Check for duplicate source errors**:
```bash theme={null}
# If loading from directory, ensure this is set
export YAML_ALLOW_DUPLICATE_SOURCES=true
```
4. **Review server logs**:
The server outputs to console when using `--transport http`. Look for YAML parsing errors in the startup output.
***
### Connection Failures
**Symptom**: Tools load but queries fail with connection errors.
**Solutions**:
1. **Verify environment variables**:
```bash theme={null}
echo $DB2i_HOST
echo $DB2i_USER
# DB2i_PASS won't echo for security
```
2. **Test connection manually**:
```bash theme={null}
# Use IBM i Access Client Solutions or similar tool
# to verify credentials and network access
```
3. **Check SSL configuration**:
```bash theme={null}
# For development, disable SSL verification
export DB2i_IGNORE_UNAUTHORIZED=true
```
***
### Toolset Not Found
**Symptom**: `--toolsets` specified but tools don't load.
**Solutions**:
1. **List available toolsets**:
```bash theme={null}
npx @ibm/ibmi-mcp-server \
--list-toolsets \
--tools ./tools
```
2. **Check exact toolset names**:
* Toolset names are case-sensitive
* Use underscores, not spaces: `performance_monitoring` not `performance monitoring`
3. **Verify toolset exists in YAML**:
```bash theme={null}
grep -r "toolsets:" ./tools/
```
***
## Best Practices
**Development:**
* Use `--transport http` for easier debugging
* Load all tools: `--tools ./tools` (no toolset filter)
* Enable debug logging: `MCP_LOG_LEVEL=debug`
* Allow SSL bypass: `DB2i_IGNORE_UNAUTHORIZED=true`
* Set `YAML_ALLOW_DUPLICATE_SOURCES=true` in `.env`
**Production:**
* Use `--transport stdio` for MCP client integration
* Load specific toolsets: `--toolsets performance_monitoring`
* Use info logging: `MCP_LOG_LEVEL=info`
* Enforce SSL: `DB2i_IGNORE_UNAUTHORIZED=false`
* Still need `YAML_ALLOW_DUPLICATE_SOURCES=true` if loading from directory
Create environment-specific configurations:
```bash theme={null}
# Developer access
--toolsets developer_tools,sample_data,system_admin
# DBA access
--toolsets performance_monitoring,security_audit,system_admin
# Auditor access (read-only)
--toolsets security_audit
```
1. **Load only needed tools**: Use `--toolsets` to reduce memory
2. **Use specific files**: Target exact YAML files instead of directories
3. **Monitor resource usage**: Check `logs/combined.log` for performance metrics
4. **Cache connections**: The server automatically pools database connections
1. **Credential management**: Use environment variables, never hardcode
2. **Least privilege**: Load only toolsets needed for the agent's role
3. **Audit logging**: Enable `MCP_LOG_LEVEL=info` in production
4. **SSL enforcement**: Set `DB2i_IGNORE_UNAUTHORIZED=false` for production
5. **Read-only tools**: Prefer query-only tools for non-admin agents
***
## Next Steps
Learn to create your own YAML SQL tools for custom IBM i operations
Complete YAML tools configuration reference with all options
Organize tools into logical groups for better agent discovery
Complete server configuration and environment variables
***
## Examples Repository
Browse the complete collection of pre-built YAML tools with documentation and examples โ
**Contributing**: Found a bug or want to add a new default tool? Contributions are welcome! See the [Contributing Guide](https://github.com/IBM/ibmi-mcp-server/blob/main/CONTRIBUTING.md) for details.