Skip to content

OpenAI Operator accessing IBM AS/400 DB2 via `ibm_db`

OpenAI Operator accessing IBM AS/400 DB2 via ibm_db

Section titled “OpenAI Operator accessing IBM AS/400 DB2 via ibm_db”

This guide provides a production-ready blueprint for connecting OpenAI Operator (or any MCP-compatible agent) to an IBM i (AS/400) system using the ibm_db Python driver.

By exposing the legacy DB2 database via the Model Context Protocol (MCP), you allow autonomous agents to query inventory, check order status, or retrieve customer records from your “Big Iron” without migrating the data.

Before you begin, ensure you have:

  1. IBM i Access Credentials: Hostname (or IP), User ID, and Password.
  2. Network Access: The machine running this Docker container must be able to reach the AS/400 on port 446 (DRDA default) or 8471 (Database Server).
  3. Docker Installed: To build and run the isolation container.

We use FastMCP to create a lightweight server that wraps the complexity of the IBM DB2 driver. This server exposes two tools to the agent: query_as400 and describe_table.

Create a file named server.py:

import os
import json
import ibm_db
from fastmcp import FastMCP
# Initialize the MCP Server
mcp = FastMCP("AS400-DB2")
def get_db_connection():
"""
Establishes a connection to the IBM i (AS/400) DB2 database.
"""
conn_str = (
f"DATABASE={os.getenv('IBMI_DATABASE', '*LOCAL')};"
f"HOSTNAME={os.getenv('IBMI_HOST')};"
f"PORT={os.getenv('IBMI_PORT', '446')};"
f"PROTOCOL=TCPIP;"
f"UID={os.getenv('IBMI_USER')};"
f"PWD={os.getenv('IBMI_PASSWORD')};"
)
try:
conn = ibm_db.connect(conn_str, "", "")
return conn
except Exception as e:
error_msg = ibm_db.conn_errormsg()
raise ConnectionError(f"Failed to connect to AS/400: {error_msg}")
@mcp.tool()
def query_as400(sql: str) -> str:
"""
Executes a read-only SQL query against the IBM i DB2 database.
Use this to fetch data, e.g., 'SELECT * FROM LIB.TABLE FETCH FIRST 5 ROWS ONLY'.
"""
# Safety check: Basic prevention of destructive commands
forbidden = ['DROP', 'DELETE', 'UPDATE', 'INSERT', 'ALTER', 'TRUNCATE']
if any(cmd in sql.upper() for cmd in forbidden):
return "Error: This tool is restricted to read-only queries (SELECT)."
conn = None
stmt = None
results = []
try:
conn = get_db_connection()
stmt = ibm_db.exec_immediate(conn, sql)
dictionary = ibm_db.fetch_assoc(stmt)
while dictionary:
results.append(dictionary)
dictionary = ibm_db.fetch_assoc(stmt)
return json.dumps(results, default=str)
except Exception as e:
# Capture IBM DB specific error
if conn:
return f"Database Error: {ibm_db.stmt_errormsg() or str(e)}"
return f"Error: {str(e)}"
finally:
if conn:
ibm_db.close(conn)
@mcp.tool()
def describe_table(library: str, table: str) -> str:
"""
Retrieves the schema definition for a specific table in a library.
Useful for understanding column names before querying.
"""
sql = f"""
SELECT COLUMN_NAME, DATA_TYPE, LENGTH, COLUMN_TEXT
FROM QSYS2.SYSCOLUMNS
WHERE TABLE_SCHEMA = '{library.upper()}'
AND TABLE_NAME = '{table.upper()}'
"""
return query_as400(sql)
if __name__ == "__main__":
print("Starting AS/400 MCP Server...")
mcp.run()

The ibm_db library relies on the IBM DB2 CLI driver, which requires specific system dependencies (XML libraries) to compile and run correctly on Linux.

Create a Dockerfile in the same directory:

# Use a slim Python image to keep size down
FROM python:3.11-slim-bookworm
# Set environment variables to prevent interactive prompts during install
ENV DEBIAN_FRONTEND=noninteractive
# Install system dependencies required for ibm_db
# ibm_db needs gcc and build tools for compilation, and libxml2 for the CLI driver
RUN apt-get update && apt-get install -y \
gcc \
libc-dev \
libxml2 \
libxml2-dev \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
RUN pip install --no-cache-dir fastmcp ibm_db
# Copy the server code
COPY server.py /app/server.py
# Set the working directory
WORKDIR /app
# Expose the port for Railway/Cloud platforms
EXPOSE 8000
# Run the MCP server
CMD ["python", "server.py"]

Terminal window
docker build -t as400-mcp .

You need to pass your IBM i credentials as environment variables.

Terminal window
docker run -p 8000:8000 \
-e IBMI_HOST="192.168.1.100" \
-e IBMI_USER="MYUSER" \
-e IBMI_PASSWORD="MYPASSWORD" \
-e IBMI_DATABASE="*LOCAL" \
as400-mcp

Your OpenAI Operator or MCP client can now connect to http://localhost:8000/sse (depending on your FastMCP transport config) or use the stdio mode if running locally via an agent runner.

  • SQL30081N (Communication Error): Check if port 446 is open on the AS/400 firewall.
  • libxml2.so.2 missing: Ensure you are using the bookworm based Docker image and have installed libxml2 as shown above.
  • Encoding Issues: IBM i uses EBCDIC (CCSID 37, 285, etc.). ibm_db handles conversion to UTF-8 automatically, but ensure your user profile on the AS/400 has a valid CCSID set (not 65535).

  • Status: ✅ Verified
  • Environment: Python 3.11
  • Auditor: AgentRetrofit CI/CD

Transparency: This page may contain affiliate links.