Skip to content

AutoGen for automating Mainframe CICS data entry

Automating Mainframe CICS Data Entry with AutoGen

Section titled “Automating Mainframe CICS Data Entry with AutoGen”

Legacy Mainframe systems running CICS (Customer Information Control System) process billions of transactions daily. However, these systems were designed for human operators sitting at “Green Screen” (3270) terminals, not for modern API-driven workflows.

This guide provides a bridge for AutoGen agents to interact directly with CICS transaction screens using the Model Context Protocol (MCP) and the TN3270 protocol. By containerizing a 3270 emulator, we allow AI agents to “type” data into mainframe fields just like a human operator, bypassing the need for expensive middleware or fragile screen-scraping scripts.

We utilize py3270, a Python wrapper for the robust s3270 terminal emulator. The MCP server acts as the interface, exposing tools that allow an Agent to:

  1. Connect to a TN3270 host.
  2. Navigate to a specific CICS Transaction ID (TRANSID).
  3. Input data into specific screen coordinates.
  4. Scrape the resulting screen for confirmation messages.
  • Docker: For running the s3270 binary in a consistent environment.
  • Network Access: A VPN connection to the mainframe (often required for internal CICS regions).

This server uses fastmcp to expose CICS interaction tools. It handles the low-level telnet negotiation and screen field handling.

from fastmcp import FastMCP
from py3270 import Emulator
import time
# Ensure your container has network access (e.g. via NordLayer)
# Initialize FastMCP
mcp = FastMCP("Mainframe-CICS-Gateway")
@mcp.tool()
def execute_cics_transaction(
host: str,
trans_id: str,
inputs: dict[str, str] = None
) -> str:
"""
Connects to a Mainframe CICS region, enters a transaction ID, and optionally fills fields.
Args:
host: The IP or hostname of the Mainframe TN3270 server (e.g., '192.168.1.100').
trans_id: The 4-character CICS Transaction ID (e.g., 'CESN', 'ACCT').
inputs: A dictionary where keys are 'row,col' and values are the text to type.
Example: {"10,25": "USERID", "11,25": "PASSWORD"}
"""
# Initialize the 3270 emulator (requires s3270 installed in OS)
em = Emulator(visible=False, timeout=30)
log = []
try:
# 1. Connect
log.append(f"Connecting to {host}...")
em.connect(host)
em.wait_for_field()
# 2. Clear screen (typical for starting fresh) and enter Trans ID
em.send_clear()
em.wait_for_field()
em.send_string(trans_id)
em.send_enter()
em.wait_for_field()
# 3. Handle Inputs if provided
if inputs:
for coords, text in inputs.items():
try:
r, c = map(int, coords.split(','))
# Move cursor to specific coordinates
em.move_to(r, c)
em.send_string(text)
except ValueError:
log.append(f"Skipping invalid coordinate format: {coords}")
# Submit the form
em.send_enter()
em.wait_for_field()
# 4. Scrape the result screen
screen_content = []
# py3270 string_get_screen returns a list of strings (rows)
for line in em.string_get_screen():
screen_content.append(line)
full_screen = "\n".join(screen_content)
return f"Transaction '{trans_id}' executed.\nLogs: {log}\n\n--- SCREEN OUTPUT ---\n{full_screen}"
except Exception as e:
return f"CICS Error: {str(e)}\nLogs: {log}"
finally:
# Always terminate the emulator process
if not em.is_terminated:
em.terminate()
if __name__ == "__main__":
mcp.run()

This Dockerfile is critical because py3270 depends on the system-level s3270 binary. We also expose port 8000 for Railway/cloud compatibility.

# Use a slim Python base
FROM python:3.11-slim
# Install system dependencies
# s3270 is the backend engine for py3270
RUN apt-get update && apt-get install -y \
s3270 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Install Python libraries
# fastmcp for the server, py3270 for mainframe emulation
RUN pip install --no-cache-dir fastmcp py3270
COPY server.py .
# EXPOSE 8000 for Railway compatibility
EXPOSE 8000
# Run the MCP server
CMD ["python", "server.py"]

Once your MCP server is running (locally or on Railway), you can configure an AutoGen agent to use it. The agent will treat the Mainframe as just another tool, capable of reading the screen and deciding what to type next.

from autogen import UserProxyAgent, AssistantAgent
# Configuration for the agent to connect to your MCP server
config_list = [{"model": "gpt-4-turbo", "api_key": "YOUR_KEY"}]
# Define the user proxy
user_proxy = UserProxyAgent(
name="Admin",
system_message="A human admin.",
code_execution_config=False,
)
# Define the Mainframe Agent
mainframe_agent = AssistantAgent(
name="CICS_Operator",
system_message="You are an expert Mainframe Operator. Use the 'execute_cics_transaction' tool to enter data into the system.",
llm_config={
"config_list": config_list,
"functions": [
{
"name": "execute_cics_transaction",
"description": "Run a CICS transaction on the mainframe.",
"parameters": {
"type": "object",
"properties": {
"host": {"type": "string"},
"trans_id": {"type": "string"},
"inputs": {"type": "object", "description": "Dictionary of 'row,col': 'value'"}
},
"required": ["host", "trans_id"]
}
}
]
}
)
# Start the conversation
user_proxy.initiate_chat(
mainframe_agent,
message="Connect to mainframe at 10.0.0.5, start transaction 'ORD1', and enter user 'ADMIN' at row 10, col 15."
)
  • Keyboard Locked (X SYSTEM): This usually means the system is processing or waiting for an input. em.wait_for_field() is used to handle this, but network lag can sometimes cause timeouts. Increase the timeout in Emulator(timeout=60).
  • PROG753: Invalid transaction ID. Ensure the trans_id passed to the tool is exactly 4 characters if required by your site standards.
  • Connection Refused: Verify that your container has VPN access to the mainframe IP. Docker containers often default to bridge networks that cannot route to internal corporate VLANs.

This implementation passes raw text to the mainframe. Ensure that:

  1. SSL/TLS is enabled on the TN3270 server if possible.
  2. Sensitive credentials are managed via environment variables, not hardcoded in the agent prompt.

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

Transparency: This page may contain affiliate links.