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.
🛠️ Prerequisites
Section titled “🛠️ Prerequisites”Before you begin, ensure you have:
- IBM i Access Credentials: Hostname (or IP), User ID, and Password.
- Network Access: The machine running this Docker container must be able to reach the AS/400 on port
446(DRDA default) or8471(Database Server). - Docker Installed: To build and run the isolation container.
💻 The Agent Server Code
Section titled “💻 The Agent Server Code”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 osimport jsonimport ibm_dbfrom fastmcp import FastMCP
# Initialize the MCP Servermcp = 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 Dockerfile
Section titled “🐳 The Dockerfile”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 downFROM python:3.11-slim-bookworm
# Set environment variables to prevent interactive prompts during installENV DEBIAN_FRONTEND=noninteractive
# Install system dependencies required for ibm_db# ibm_db needs gcc and build tools for compilation, and libxml2 for the CLI driverRUN apt-get update && apt-get install -y \ gcc \ libc-dev \ libxml2 \ libxml2-dev \ && rm -rf /var/lib/apt/lists/*
# Install Python dependenciesRUN pip install --no-cache-dir fastmcp ibm_db
# Copy the server codeCOPY server.py /app/server.py
# Set the working directoryWORKDIR /app
# Expose the port for Railway/Cloud platformsEXPOSE 8000
# Run the MCP serverCMD ["python", "server.py"]🚀 How to Run
Section titled “🚀 How to Run”1. Build the Image
Section titled “1. Build the Image”docker build -t as400-mcp .2. Run the Container
Section titled “2. Run the Container”You need to pass your IBM i credentials as environment variables.
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-mcp3. Connect the Agent
Section titled “3. Connect the Agent”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.
⚠️ Common Troubleshooting
Section titled “⚠️ Common Troubleshooting”SQL30081N(Communication Error): Check if port446is open on the AS/400 firewall.libxml2.so.2missing: Ensure you are using thebookwormbased Docker image and have installedlibxml2as shown above.- Encoding Issues: IBM i uses EBCDIC (CCSID 37, 285, etc.).
ibm_dbhandles conversion to UTF-8 automatically, but ensure your user profile on the AS/400 has a valid CCSID set (not 65535).
🛡️ Quality Assurance
Section titled “🛡️ Quality Assurance”- Status: ✅ Verified
- Environment: Python 3.11
- Auditor: AgentRetrofit CI/CD
Transparency: This page may contain affiliate links.