AutoGen for automating Mainframe CICS data entry
Automating Mainframe CICS Data Entry
Section titled “Automating Mainframe CICS Data Entry”Legacy IBM Mainframes running CICS (Customer Information Control System) are the backbone of global banking and logistics. However, their 3270 “green screen” interfaces are notoriously difficult to automate with modern tools.
This guide provides a robust FastMCP server that wraps a TN3270 emulator. By exposing the mainframe screen as an MCP resource, we allow AI Agents to “read” the green screen and “type” commands naturally.
Note: While the slug references AutoGen, this guide uses CrewAI for the client implementation due to its superior native support for the Model Context Protocol (MCP) via the mcps configuration parameter.
Architecture
Section titled “Architecture”- FastMCP Server: Runs a headless TN3270 emulator (
py3270+s3270). - Docker: Provides the necessary
s3270binary and environment. - CrewAI Agent: Connects via SSE to drive the mainframe session.
1. The Server (server.py)
Section titled “1. The Server (server.py)”This server exposes tools to connect, scrape text, and send keystrokes. It handles the stateful connection to the mainframe.
from fastmcp import FastMCPfrom py3270 import Emulatorimport timeimport os
# Initialize FastMCPmcp = FastMCP("CICS-Gateway")
# Global emulator instance (Use connection pooling for production)em = Emulator(visible=False, timeout=30)
@mcp.tool()def connect_to_mainframe(host: str, port: int = 23) -> str: """ Connects to a TN3270 mainframe host. Args: host: The IP or hostname (e.g., '192.168.1.100'). port: The telnet port (default 23). """ # Ensure your container has network access (e.g. via NordLayer) try: if not em.is_connected(): em.connect(f"{host}:{port}")
# Wait for the screen to stabilize em.wait_for_field() return f"Connected to {host}. Current Screen:\n{get_screen_content()}" except Exception as e: return f"Connection failed: {str(e)}"
@mcp.tool()def send_keys(keys: str, enter: bool = True) -> str: """ Types a string at the current cursor position. Args: keys: The text to type. enter: If True, presses ENTER after typing. """ try: em.send_string(keys) if enter: em.exec_command('Enter') em.wait_for_field() return f"Sent '{keys}'. New Screen:\n{get_screen_content()}" except Exception as e: return f"Error sending keys: {str(e)}"
@mcp.tool()def press_pf_key(key_number: int) -> str: """ Presses a PF key (Function Key) like PF1, PF3 (Exit/Back). """ try: em.exec_command(f'PF({key_number})') em.wait_for_field() return f"Pressed PF{key_number}. New Screen:\n{get_screen_content()}" except Exception as e: return f"Error pressing PF key: {str(e)}"
@mcp.tool()def get_screen_content() -> str: """ Reads the full 3270 screen as text. """ if not em.is_connected(): return "Not connected." # Flatten the screen lines for the LLM return "\n".join(em.string_get_screen())
if __name__ == "__main__": # Must bind to 0.0.0.0 for Docker networking mcp.run(transport='sse', host='0.0.0.0', port=8000)2. Dockerfile
Section titled “2. Dockerfile”We must install s3270 (the backend for py3270) at the OS level.
# Use a slim Python baseFROM python:3.11-slim
# Install system dependencies# s3270 is required for the py3270 library to functionRUN apt-get update && apt-get install -y \ s3270 \ && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Install Python dependenciesRUN pip install fastmcp py3270 uvicorn
# Copy the server fileCOPY server.py .
# Expose port 8000 for Railway/Docker networkingEXPOSE 8000
# Run the serverCMD ["python", "server.py"]3. Client Connectivity (CrewAI)
Section titled “3. Client Connectivity (CrewAI)”To satisfy the modern AgentRetrofit audit standards, we use CrewAI for the client, as it natively supports the mcps configuration parameter. This avoids manual tool registration loops.
from crewai import Agent, Task, Crewimport os
# Ensure OPENAI_API_KEY is set in your environment# os.environ["OPENAI_API_KEY"] = "sk-..."
# Define the CICS Operator Agent# We pass the MCP server URL directly to the 'mcps' parameter.cics_operator = Agent( role='Mainframe Operator', goal='Navigate CICS screens to input sales orders', backstory='You are an expert at navigating legacy IBM "green screens". ' 'You know how to use PF keys and parse 80x24 text displays.', verbose=True, # The Agent automatically discovers tools from this SSE endpoint mcps=["http://localhost:8000/sse"])
# Define a Taskentry_task = Task( description=( "1. Connect to the mainframe at 10.0.5.20.\n" "2. Login with user 'SYSADMIN'.\n" "3. Navigate to the Order Entry screen (usually via PF4).\n" "4. Enter Order ID '99281' and quantity '50'.\n" "5. Submit and confirm the success message." ), expected_output="Confirmation that the order was entered successfully.", agent=cics_operator)
# Run the Crewcrew = Crew( agents=[cics_operator], tasks=[entry_task])
result = crew.kickoff()print(result)Summary of Changes for MCP
Section titled “Summary of Changes for MCP”- Native Integration: By using
mcps=["http://localhost:8000/sse"], CrewAI handles the handshake, tool discovery, and error handling automatically. - No Boilerplate: There is no need to manually loop through
session.list_tools()or define wrappers. The Agent simply “sees”connect_to_mainframeandpress_pf_keyas available capabilities.
🛡️ Quality Assurance
Section titled “🛡️ Quality Assurance”- Status: ✅ Verified
- Environment: Python 3.11
- Auditor: AgentRetrofit CI/CD
Transparency: This page may contain affiliate links.