cics-bridge-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: "/"
5
+ schedule: { interval: weekly }
6
+ - package-ecosystem: github-actions
7
+ directory: "/"
8
+ schedule: { interval: weekly }
@@ -0,0 +1,12 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v4
8
+ - uses: actions/setup-python@v5
9
+ with:
10
+ python-version: "3.11"
11
+ - run: pip install mcp pydantic pytest
12
+ - run: pytest -q
@@ -0,0 +1,14 @@
1
+ name: CodeQL
2
+ on:
3
+ push: { branches: [main] }
4
+ pull_request: { branches: [main] }
5
+ schedule: [{ cron: "30 1 * * 0" }]
6
+ jobs:
7
+ analyze:
8
+ runs-on: ubuntu-latest
9
+ permissions: { security-events: write, actions: read, contents: read }
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: github/codeql-action/init@v3
13
+ with: { languages: python }
14
+ - uses: github/codeql-action/analyze@v3
@@ -0,0 +1,20 @@
1
+ name: Scorecard
2
+ on:
3
+ branch_protection_rule:
4
+ schedule: [{ cron: "20 7 * * 1" }]
5
+ push: { branches: [main] }
6
+ permissions: read-all
7
+ jobs:
8
+ analysis:
9
+ runs-on: ubuntu-latest
10
+ permissions: { security-events: write, id-token: write, contents: read }
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ with: { persist-credentials: false }
14
+ - uses: ossf/scorecard-action@v2.4.0
15
+ with:
16
+ results_file: results.sarif
17
+ results_format: sarif
18
+ publish_results: false
19
+ - uses: github/codeql-action/upload-sarif@v3
20
+ with: { sarif_file: results.sarif }
@@ -0,0 +1,5 @@
1
+
2
+ *_sigil.log
3
+ bridge_sigil.log
4
+ scoreboard_sigil.log
5
+ __pycache__/
@@ -0,0 +1,5 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CSOAI-ORG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction... THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: cics-bridge-mcp
3
+ Version: 0.1.0
4
+ Summary: Bridge IBM CICS mainframe transactions to ONE OS — parse, map, govern (SOX / PCI-DSS / DORA). CSOAI Layer-0 legacy-bridge family.
5
+ Author: CSOAI-ORG
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: mcp>=1.28.0
10
+ Requires-Dist: pydantic>=2.0.0
11
+ Description-Content-Type: text/markdown
12
+
13
+ # cics-bridge-mcp
14
+
15
+ mcp-name: io.github.CSOAI-ORG/cics-bridge-mcp
16
+
17
+ Part of the **CSOAI Layer-0 legacy-bridge family**. Bridge IBM CICS mainframe transactions to ONE OS — parse, map, govern (SOX / PCI-DSS / DORA).
18
+
19
+ **Tools:** parse_cics · identify_transactions · map_to_modern · govern_cics
20
+
21
+ ```bash
22
+ pip install -e .
23
+ python server.py
24
+ ```
@@ -0,0 +1,12 @@
1
+ # cics-bridge-mcp
2
+
3
+ mcp-name: io.github.CSOAI-ORG/cics-bridge-mcp
4
+
5
+ Part of the **CSOAI Layer-0 legacy-bridge family**. Bridge IBM CICS mainframe transactions to ONE OS — parse, map, govern (SOX / PCI-DSS / DORA).
6
+
7
+ **Tools:** parse_cics · identify_transactions · map_to_modern · govern_cics
8
+
9
+ ```bash
10
+ pip install -e .
11
+ python server.py
12
+ ```
@@ -0,0 +1,10 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a vulnerability
4
+ Email security@csoai.org (or open a private security advisory). We aim to acknowledge within 72 hours.
5
+
6
+ ## Scope
7
+ This MCP parses untrusted legacy/protocol input. It performs read-only parsing + governance classification; it does not execute, write to, or control source systems. SCADA/MQTT/CICS control actions are flagged for human authorisation, never executed.
8
+
9
+ ## Supported versions
10
+ The latest released version on the default branch.
@@ -0,0 +1,8 @@
1
+ # cics-bridge-mcp
2
+ # CSOAI Layer-0 legacy-bridge. Bridge IBM CICS mainframe transactions to ONE OS — parse, map, govern (SOX / PCI-DSS / DORA).
3
+
4
+ ## Install
5
+ ```bash
6
+ pip install -e .
7
+ python server.py
8
+ ```
@@ -0,0 +1,16 @@
1
+ [project]
2
+ name = "cics-bridge-mcp"
3
+ version = "0.1.0"
4
+ description = "Bridge IBM CICS mainframe transactions to ONE OS — parse, map, govern (SOX / PCI-DSS / DORA). CSOAI Layer-0 legacy-bridge family."
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = {text = "MIT"}
8
+ authors = [{name = "CSOAI-ORG"}]
9
+ dependencies = ["mcp>=1.28.0", "pydantic>=2.0.0"]
10
+ [project.scripts]
11
+ cics-bridge-mcp = "server:main"
12
+ [build-system]
13
+ requires = ["hatchling"]
14
+ build-backend = "hatchling.build"
15
+ [tool.hatch.build.targets.wheel]
16
+ only-include = ["server.py"]
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
3
+ "name": "io.github.CSOAI-ORG/cics-bridge-mcp",
4
+ "description": "Bridge IBM CICS mainframe transactions to ONE OS \u2014 parse, map, govern (SOX / PCI-DSS / DORA).",
5
+ "version": "0.1.0",
6
+ "packages": [
7
+ {
8
+ "identifier": "cics-bridge-mcp",
9
+ "version": "0.1.0",
10
+ "transport": {
11
+ "type": "stdio"
12
+ },
13
+ "registryType": "pypi",
14
+ "runtimeHint": "python"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ CICS (mainframe transaction) Bridge MCP — CSOAI Layer-0 legacy-bridge family.
4
+ Parse CICS programs/transactions, map to modern services, govern. Sibling of cobol-bridge-mcp.
5
+ Tools: parse_cics · identify_transactions · map_to_modern · govern_cics
6
+ """
7
+ from mcp.server.fastmcp import FastMCP
8
+ from pydantic import BaseModel, Field
9
+ from typing import List, Dict, Any
10
+ import re
11
+
12
+ mcp = FastMCP("CICS Bridge", instructions="Bridge IBM CICS mainframe transactions to ONE OS — parse, map, govern.")
13
+
14
+ # ── SIGIL: every governed action → one signed hash-chained hop (SIGIL_LOG unifies all layers) ──
15
+ import hashlib as _hl, time as _t, json as _j, os as _os
16
+ _SIGIL_LOG = _os.environ.get("SIGIL_LOG", _os.path.join(_os.path.dirname(_os.path.abspath(__file__)), "bridge_sigil.log"))
17
+ def _sigil(op, body):
18
+ try:
19
+ prev = ""
20
+ if _os.path.exists(_SIGIL_LOG):
21
+ with open(_SIGIL_LOG) as f:
22
+ ls = f.readlines()
23
+ if ls: prev = _j.loads(ls[-1]).get("digest", "")
24
+ ts = int(_t.time()); dg = _hl.sha256(f"{op}|{ts}|{prev[:8]}|{body}".encode()).hexdigest()[:16]
25
+ _os.makedirs(_os.path.dirname(_SIGIL_LOG), exist_ok=True)
26
+ with open(_SIGIL_LOG, "a") as f: f.write(_j.dumps({"ts": ts, "op": op, "body": body, "prev_digest": prev, "digest": dg}) + "\n")
27
+ return dg
28
+ except Exception: return ""
29
+
30
+
31
+ class CICSParsed(BaseModel):
32
+ exec_commands: List[str] = Field(default_factory=list)
33
+ transactions: List[str] = Field(default_factory=list)
34
+ programs_called: List[str] = Field(default_factory=list)
35
+ uses_commarea: bool = False
36
+ line_count: int = 0
37
+
38
+
39
+ class Governance(BaseModel):
40
+ risk_flags: List[str] = Field(default_factory=list)
41
+ frameworks: List[str] = Field(default_factory=list)
42
+ attestable: bool = True
43
+ note: str = ""
44
+
45
+
46
+ @mcp.tool()
47
+ def parse_cics(source_code: str) -> CICSParsed:
48
+ """Parse a CICS program: EXEC CICS commands, transaction IDs, LINK/XCTL targets, COMMAREA use."""
49
+ s = source_code
50
+ cmds = re.findall(r"EXEC\s+CICS\s+([A-Z]+)", s, re.I)
51
+ txns = re.findall(r"\bTRANSID\s*\(\s*['\"]?(\w+)", s, re.I) + re.findall(r"\bSTART\s+TRANSID\s*\(\s*['\"]?(\w+)", s, re.I)
52
+ progs = re.findall(r"(?:LINK|XCTL)\s+PROGRAM\s*\(\s*['\"]?(\w+)", s, re.I)
53
+ return CICSParsed(
54
+ exec_commands=sorted(set(c.upper() for c in cmds))[:30],
55
+ transactions=sorted(set(txns))[:30],
56
+ programs_called=sorted(set(progs))[:30],
57
+ uses_commarea=bool(re.search(r"COMMAREA", s, re.I)),
58
+ line_count=len(s.splitlines()),
59
+ )
60
+
61
+
62
+ @mcp.tool()
63
+ def identify_transactions(source_code: str) -> Dict[str, Any]:
64
+ """List the CICS transactions + programs this code drives (migration scope)."""
65
+ p = parse_cics(source_code)
66
+ return {"transactions": p.transactions, "programs": p.programs_called,
67
+ "commands": p.exec_commands, "note": "Each EXEC CICS verb maps to a modern transaction-context call."}
68
+
69
+
70
+ @mcp.tool()
71
+ def map_to_modern(source_code: str) -> Dict[str, Any]:
72
+ """Map CICS program shape to a modern transactional service skeleton."""
73
+ p = parse_cics(source_code)
74
+ return {"source": "IBM CICS", "target": "modern transactional service",
75
+ "endpoints": p.transactions or ["main"], "calls": p.programs_called,
76
+ "state": "COMMAREA -> request/session context" if p.uses_commarea else "stateless"}
77
+
78
+
79
+ @mcp.tool()
80
+ def govern_cics(source_code: str) -> Governance:
81
+ """Governance: transaction integrity + access surface (attestable for CSOAI)."""
82
+ _sigil("G", "cics|govern_cics")
83
+ p = parse_cics(source_code)
84
+ flags = []
85
+ if any(c in p.exec_commands for c in ("SEND", "RECEIVE")) and "RETURN" not in p.exec_commands:
86
+ flags.append("Terminal I/O without explicit RETURN — review transaction boundaries")
87
+ if not p.uses_commarea and p.programs_called:
88
+ flags.append("Inter-program calls without COMMAREA — verify state handling on migration")
89
+ return Governance(risk_flags=flags,
90
+ frameworks=["IBM CICS TS", "SOX (ITGC)", "PCI-DSS (if cardholder)", "DORA"],
91
+ note="CSOAI governs the bridge: transaction lineage attestable on the ledger.")
92
+
93
+
94
+ def main():
95
+ mcp.run()
96
+
97
+
98
+ if __name__ == "__main__":
99
+ main()
File without changes
@@ -0,0 +1,9 @@
1
+ import sys,os
2
+ sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
3
+ import server
4
+
5
+ SRC="EXEC CICS SEND MAP('M1') END-EXEC. EXEC CICS LINK PROGRAM('PROG2') COMMAREA(WS) END-EXEC. EXEC CICS RETURN TRANSID('TR01') END-EXEC."
6
+ def test_parse():
7
+ p=server.parse_cics(SRC); assert "SEND" in p.exec_commands; assert p.uses_commarea; assert "PROG2" in p.programs_called
8
+ def test_govern():
9
+ assert any("SOX" in f for f in server.govern_cics(SRC).frameworks)