Skip to main content
Glama
nba67000

mcp_cobol

by nba67000

mcp_cobol — comprendre une base COBOL legacy avec un LLM

Un serveur MCP (Model Context Protocol) qui donne a un LLM les moyens d'explorer une base COBOL mainframe qu'il n'a jamais vue : graphe d'appels, usage des copybooks, tables DB2, analyse d'impact.

Le LLM de la demo est Mistral (La Plateforme). Le serveur, lui, est agnostique : n'importe quel client MCP peut le consommer.

Base de demonstration : AWS CardDemo, une application CICS / DB2 / VSAM de gestion de cartes de credit publiee par AWS. Aucun code client n'est utilise.

Le probleme

Une base COBOL de 20 ans, c'est quelques centaines de programmes, des copybooks partages par tout le monde, des XCTL CICS qui sautent de programme en programme, et personne qui sait plus repondre a « qu'est-ce qui casse si je rallonge ce champ ? ».

Un LLM seul ne peut pas repondre : la base ne tient pas dans son contexte, et il ne l'a jamais vue. Donner au LLM des outils pour interroger la base — plutot que d'esperer qu'il la memorise — c'est exactement ce que resout MCP.

Related MCP server: arch-viewer

Architecture

  vendor/carddemo          parser/              data/index.json
  (COBOL brut)      ──▶    cobol_parser.py ──▶  faits extraits
                           build_index.py        + index inverse
                                                       │
                                                       ▼
   demo/ask.py    ◀──   mistral/client.py   ◀──   server/mcp_server.py
  (question NL)        (function calling)         (outils MCP)

Trois etages, volontairement decouples :

  1. Parsing — lent, heuristique, sans reseau. Produit un JSON.

  2. Serveur MCP — lit le JSON, expose 5 outils. Zero dependance LLM.

  3. Client LLM — Mistral decide quels outils appeler et dans quel ordre.

Le serveur ne relit jamais le COBOL : chaque appel d'outil est quasi instantane, ce qui rend la demo fluide en live.

Outils MCP

Outil

Question a laquelle il repond

list_programs

Qu'est-ce qu'il y a dans cette base ?

explain_program

Que fait ce programme, avec quoi travaille-t-il ?

call_graph

Qui appelle qui ?

who_uses_copybook

Qui depend de cette structure de donnees ?

impact_analysis

Qu'est-ce qui casse si je modifie ca ?

Installation

Prerequis : Python ≥ 3.10, git, et une cle API Mistral (console.mistral.ai).

bash setup.sh        # venv + dependances + clone de CardDemo + .env

Puis renseigne ta cle dans .env :

MISTRAL_API_KEY=...

.env est gitignore — la cle ne quitte jamais ta machine.

Utilisation

# 1. Indexer la base COBOL (a refaire si le code source change)
.venv/Scripts/python.exe -m parser.build_index

# 2. Poser une question en langage naturel
.venv/Scripts/python.exe demo/ask.py "Que fait le programme COACTVWC ?"

(Sous Linux/macOS : .venv/bin/python au lieu de .venv/Scripts/python.exe.)

Questions de demonstration

demo/ask.py "Que fait le programme COACTVWC et quelles tables DB2 utilise-t-il ?"
demo/ask.py "Qu'est-ce qui casse si je modifie le copybook CVACT01Y ?"
demo/ask.py "Montre-moi la chaine d'appels depuis le menu principal."

Etat d'avancement

  • Etape 1 — fondation : arborescence, setup, gestion des secrets

  • Etape 2 — parseur COBOL fixed-format + index inverse

  • Etape 2b — graphe de flot interne + outil explain_program

  • Etape 3 — serveur MCP : 5 outils, autotest 32/32

  • Etape 4 — integration Mistral : wrapper + pont de function calling

  • Etape 5 — demo de bout en bout + doc

La chaine complete est validee de bout en bout avec mistral-medium-latest : trois questions, dont une resolue en 5 appels d'outils sur 6 tours.

Si python -m demo.ask repond 429 avec x-ratelimit-limit-req-minute: 0, ce n'est pas une limitation passagere : le compte n'a aucun droit d'appel sur les completions (alors que /v1/models repond 200 — lister et appeler relevent de droits differents). python -m mistral.client le diagnostique en une seconde. En attendant, --simulate exerce tout le pont sans API.

Ce que le parseur extrait

Sur les 44 programmes de CardDemo (22 893 lignes de code) :

Programmes

25 transactionnels CICS, 17 batch, 2 sous-programmes

Copybooks

62 presents + 8 externes identifies (MQ, CICS systeme)

Paragraphes

870, relies par 1 163 PERFORM et 185 GO TO

Graphe d'appels

92 aretes

Donnees

8 fichiers VSAM, 2 tables DB2, 2 segments IMS

Ecrans

transaction CICS et map BMS resolues par programme

Le point dur : les appels indirects

CardDemo n'ecrit jamais le nom du programme cible dans un XCTL :

MOVE LIT-MENUPGM TO CDEMO-TO-PROGRAM        *> LIT-MENUPGM VALUE 'COMEN01C'
EXEC CICS XCTL PROGRAM(CDEMO-TO-PROGRAM) END-EXEC

Un grep XCTL ne remonte donc aucun appel exploitable. Le parseur remonte la chaine (clauses VALUE, MOVE successifs, tables OCCURS declarees dans les copybooks) et etiquette chaque arete par sa methode de resolution :

Methode

Aretes

Confiance

nom litteral dans l'instruction

64

certain

clause VALUE / MOVE de litteral

17

certain

chaine de deux MOVE

11

probable

table de programmes d'un copybook

3

heuristique

Aucune arete ne reste non resolue. Et surtout : une arete heuristique est presentee comme telle, avec sa provenance (« table declaree dans COMEN02Y »). Un outil d'analyse d'impact qui affirme sans nuancer est pire qu'inutile.

Essayer un outil sans serveur ni cle API

La logique des outils (server/tools.py) est separee de la plomberie MCP. On peut donc interroger l'index directement :

.venv/Scripts/python.exe -m server.tools list --role batch
.venv/Scripts/python.exe -m server.tools explain COACTVWC
.venv/Scripts/python.exe -m server.tools graph COMEN01C --depth 2
.venv/Scripts/python.exe -m server.tools copybook CVACT01Y
.venv/Scripts/python.exe -m server.tools impact CVACT01Y
# COACTVWC — Accept and process Account View request

- Role : transactionnel-cics
- Source : app/cbl/COACTVWC.cbl (703 lignes de code, 35 paragraphes)
- Transaction CICS : CAVW
- Ecran BMS : CACTVWA (mapset COACTVW)

## Donnees manipulees
- VSAM ACCTDAT — lecture (READ)
- VSAM CUSTDAT — lecture (READ)
- VSAM CXACAIX — lecture (READ)

## Navigation
- Appele par : COMEN01C
- Appelle : COMEN01C via XCTL (l. 349) — probable

## Flot interne
Point d'entree : 0000-MAIN — 17 PERFORM, 9 GO TO, 1 gestionnaire CICS
    358  1000-SEND-MAP THRU 1000-SEND-MAP-EXIT
    362  2000-PROCESS-INPUTS THRU 2000-PROCESS-INPUTS-EXIT
    369  9000-READ-ACCT THRU 9000-READ-ACCT-EXIT

## A savoir avant de conclure
- 2 copybooks absents du depot (DFHAID, DFHBMSCA) : dependances CICS
- Ecran designe par une variable non resolue (CCARD-NEXT-MAP) : valeur
  transmise par l'appelant via la COMMAREA
- 3 paragraphes cible d'aucun PERFORM/GO TO/LABEL

Chaque outil produit une section « A savoir avant de conclure » : ce qu'il ne sait pas. C'est elle qui empeche le LLM d'affirmer ce que l'analyse statique n'etablit pas.

Le serveur MCP

.venv/Scripts/python.exe -m server.selftest     # verifie les 5 outils
.venv/Scripts/python.exe server/mcp_server.py   # lance le serveur

Le serveur dialogue en JSON-RPC sur stdin/stdout : lance seul, il n'affiche rien. C'est normal. L'autotest, lui, le verifie de deux facons — branche en memoire sur l'objet serveur, puis lance comme un vrai sous-processus. Le second mode est le seul qui detecte une ecriture parasite sur stdout, laquelle corrompt le protocole de maniere tres difficile a diagnostiquer.

Exemple : « qu'est-ce qui casse si je modifie le copybook CVACT01Y ? »

# Impact d'une modification de copybook CVACT01Y

23 programme(s) concerne(s) : 14 a recompiler, 9 a retester.
Repartition : 7 batch, 16 transactionnel-cics

## A recompiler — embarquent la modification
- CBACT01C (batch) — inclut CVACT01Y directement
- COACTVWC (transactionnel-cics) — inclut CVACT01Y directement
  ... 12 autres

## A retester — appellent un programme modifie
- COMEN01C (transactionnel-cics) — chaine : COMEN01C -> COACTUPC
- COPAUS1C (transactionnel-cics) — chaine : COPAUS1C -> COPAUS0C
  ... 7 autres

## Perimetre de recette
- Transactions CICS : CAUP, CAVW, CB00, CC00, CCDL, CCLI, CCUP, CM00,
                      CPVD, CPVS, CR00, CT00, CT01, CT02
- Fichiers VSAM : ACCTDAT, CARDAIX, CARDDAT, CCXREF, CUSTDAT, CXACAIX,
                  TRANSACT, USRSEC
- Segments IMS : PAUTDTL1, PAUTSUM0

La separation a recompiler / a retester n'est pas cosmetique : inclure un copybook modifie impose une recompilation, appeler un programme modifie n'impose qu'une recette. Ce sont deux charges de travail differentes.

Brancher un autre client MCP

Le serveur ne contient aucune reference a un modele particulier. N'importe quel client MCP le consomme avec une configuration de cette forme :

{
  "mcpServers": {
    "cobol-legacy": {
      "command": "/chemin/vers/mcp_cobol/.venv/Scripts/python.exe",
      "args": ["/chemin/vers/mcp_cobol/server/mcp_server.py"]
    }
  }
}

L'integration Mistral

python -m mistral.client                          # pre-vol : config, modeles, appel test
python -m demo.ask "Que fait le programme COACTVWC ?"
python -m demo.ask --simulate "..."               # le pont, sans appeler l'API

Mistral ne parle pas MCP : le pont

Il n'existe aucun lien direct entre les deux protocoles. demo/ask.py fait trois traductions :

MCP

Mistral

Declaration

{name, description, input_schema}

{"type":"function","function":{name, description, parameters}}

Appel

mcp.call_tool(nom, args)

tool_calls[].function.arguments (JSON texte)

Resultat

blocs de contenu

message {"role":"tool", "tool_call_id", "content"}

Puis on boucle : tant que le modele demande des outils, on execute et on renvoie. Le tool_call_id est ce qui relie une reponse a sa question quand le modele appelle plusieurs outils d'un seul coup.

Le serveur MCP tourne dans un vrai sous-processus, en JSON-RPC sur stdin/stdout. Il ignore l'existence de Mistral. Changer de fournisseur ne touche que demo/ask.py et mistral/client.py.

Souverainete

Le SDK expose trois endpoints : api.mistral.ai, api.eu.mistral.ai, api.us.mistral.ai. Mettre MISTRAL_SERVER=eu dans .env route tout le trafic par l'Union europeenne.

Verifier le pont sans quota API

python -m demo.ask --simulate "Qu'est-ce qui casse si je modifie le copybook CVACT01Y ?"
[demo] 5 outils MCP disponibles : list_programs, explain_program, call_graph,
       who_uses_copybook, impact_analysis
  [tour 1] impact_analysis(target='CVACT01Y')
      -> 2726 caracteres | # Impact d'une modification de copybook CVACT01Y
[demo] termine en 2 tour(s)

--simulate remplace le modele par une doublure scriptee et exerce la meme boucle sur les vrais outils MCP : les trois traductions sont donc reellement testees. La doublure annonce explicitement qu'aucun modele n'a repondu — elle ne peut pas etre confondue avec une reponse du LLM.

Limites assumees

  • Analyse statique et non sensible au flot : la resolution est faite par variable, pas par chemin d'execution. Si un programme charge deux valeurs differentes dans la meme variable a deux endroits, les deux cibles sont listees. C'est une sur-approximation volontaire : en analyse d'impact, mieux vaut un candidat de trop qu'un oubli.

  • Les 47 JCL ne sont pas analyses. Un programme classe batch l'est parce qu'aucun COBOL ne l'appelle, pas parce qu'on a lu sa carte EXEC PGM=.

  • Le parseur cible le fixed-format (colonnes 7-72), le format historique mainframe. Le free-format n'est pas l'objectif.

  • Pas de vocation a remplacer un outil commercial d'analyse d'impact : la valeur demontree ici est le couplage base legacy ↔ LLM.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Connects legacy COBOL mainframe systems to modern AI governance via MCP, with tools for parsing copybooks, assessing CICS, scanning JCL, mapping VSAM, and translating EBCDIC.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides AI-powered architecture analysis and visualization of codebases, exposing 17 MCP tools for querying components, dependencies, and generating interactive diagrams.
    557 npm
    3
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides AI agents with a function-level dependency graph of the codebase through 30 MCP tools, enabling structural queries about code dependencies, callers, and impact analysis.
    1,605 npm
    94
    Apache 2.0