Legacy analyser in your editor (MCP)
日本語: エディタでレガシー解析(MCP)
kurahi legacy mcp serves the legacy analyser to the tools engineers
already use: VS Code, Eclipse-based mainframe IDEs, or any client that speaks the Model Context
Protocol (MCP). It is a separate, product server: it reads one project folder and nothing else,
needs no gateway and no Kurahi configuration, and shares nothing with a running Kurahi service.
kurahi legacy mcp --root /path/to/project # stdio (the client starts it)kurahi legacy mcp --root /path/to/project --http 7465 # loopback HTTP, http://127.0.0.1:7465/mcp| Option | Meaning |
|---|---|
--root <dir> |
The project folder. Required. Every tool is confined to it. |
--http <port> |
Serve streamable HTTP on 127.0.0.1:<port> instead of stdio. |
--max-bytes <n> |
Cap on one response, in bytes (default 65536, from 4096). |
--allow-host <host...> |
With --http: also accept these Host names, for a TLS reverse proxy in front (remote toolkit). |
All tools are read-only (readOnlyHint) and take three common arguments: path (a sub-folder or
file of the project, relative to the root; default the root), offset and limit (pagination).
| Tool | What it returns |
|---|---|
legacy_index_status |
Whether a fresh index exists for the scope, with counts. Never parses. |
legacy_index_build |
Parses COBOL, copybooks and JCL and builds the fact index; programs, copybooks, jobs, diagnostics. |
legacy_query |
Structure: callers, callees, call and perform graphs, file access, data items and references, job steps, data sets, unresolved references. |
legacy_rules |
Rule candidates: conditions, arithmetic with constants, rounding, 88-level values, constants. |
legacy_dictionary |
Copybook data dictionary: level, PIC, usage, length, offset, positions, OCCURS, REDEFINES, values. |
legacy_impact |
What a change to a data item reaches, with the fact that links each entry. |
legacy_design_doc |
Design document (設計書) from the code in Japanese or English, one section per entry; every fact cites path:line. |
legacy_wave_plan |
Proposed migration waves for human review, ordered by dependencies and risk. |
modernise_plan |
Detected languages, inventory of the COBOL/JCL, Java, SQL DDL, FORTRAN, PL/I and PLC engines, shared tables, coverage, planned assistants (which analyse nothing). |
modernise_crud |
CRUD of SQL tables across COBOL, PL/I, Java and JCL utilities, and of files (COBOL, FORTRAN, PL/I), with the evidence of each operation. |
modernise_impact |
What a change to a table, column, file, FORTRAN COMMON block, Java class or program reaches across languages. |
modernise_inventory |
Java types, SQL tables, FORTRAN units and COMMON blocks, or PL/I procedures: the list, or one entry in full. |
Other tools build the index on first use; legacy_index_build forces a rebuild. The index is
rebuilt automatically when any file under the scope changes.
Responses
Section titled “Responses”Each result has a short text summary (first content block), the full JSON (second content block)
and the same JSON as structuredContent:
{ "tool": "legacy_query", "scope": ".", "summary": "Query callers: calledBy 1, performedBy 0, jobSteps 0. Entries 1-1 of 1 (last page).", "page": { "offset": 0, "limit": 100, "total": 1, "lists": { "calledBy": 1, "performedBy": 0, "jobSteps": 0 }, "nextOffset": null }, "result": { "name": "ORDTAX", "kind": "program", "calledBy": [ { "program": "ORDCALC", "paragraph": "1000-PRICE", "file": "source/cobol/ORDCALC.cbl", "line": 28, "text": "CALL 'ORDTAX' USING WS-NET.", "at": "source/cobol/ORDCALC.cbl:28" } ], "performedBy": [], "jobSteps": [] }}- Every fact carries
at: "path:line", relative to the project root, next to the analyser’s ownfileandline. Cite it; open it in the editor. - Pagination. Every top-level list of a result is windowed by
offsetandlimit(default 100, max 1000).page.totalis the longest list,page.nextOffsetthe next window (nullon the last page). - Size cap. When a page would exceed
--max-bytes, the page shrinks first (reduced.reasonsays so andnextOffsetfollows the smaller page), then long text (for example a DOT graph) is clipped at 2,000 characters. When even one entry does not fit, the call fails with a request to narrow it (apath, aprogram, a smallerlimit).
Client configuration
Section titled “Client configuration”VS Code (.vscode/mcp.json)
Section titled “VS Code (.vscode/mcp.json)”{ "servers": { "kurahi-legacy": { "type": "stdio", "command": "kurahi", "args": ["legacy", "mcp", "--root", "${workspaceFolder}"] } }}Over loopback HTTP (start kurahi legacy mcp --root … --http 7465 yourself first):
{ "inputs": [ { "type": "promptString", "id": "kurahi-legacy-token", "description": "kurahi-legacy token", "password": true } ], "servers": { "kurahi-legacy": { "type": "http", "url": "http://127.0.0.1:7465/mcp", "headers": { "Authorization": "Bearer ${input:kurahi-legacy-token}" } } }}Any MCP client (Eclipse-based IDEs included)
Section titled “Any MCP client (Eclipse-based IDEs included)”Most clients accept the common mcpServers form; give the project folder as an absolute path:
{ "mcpServers": { "kurahi-legacy": { "command": "kurahi", "args": ["legacy", "mcp", "--root", "/path/to/project"] } }}A client that only connects to a URL uses the HTTP form: URL http://127.0.0.1:<port>/mcp,
header Authorization: Bearer <token>. If kurahi is not on the client’s PATH, give the full
path of the executable as command.
Security
Section titled “Security”- One root, confined. The root is resolved to its real path at start. Each
pathargument is resolved against it and refused when it leaves it:../, an absolute path elsewhere, or a symbolic link whose target is outside (checked on the real path). Folders the analyser never reads (_answer-keys,.git,node_modules, the.kurahifolder) are refused too. The indexer does not follow symbolic links inside the tree. - Read-only. The tools parse source text. They never run code, scripts or JCL from the repository, never call out to the network, and never write to the sources.
- The only writes are in the project’s Kurahi folder:
.kurahi/legacy-mcp/cache/(the index) and.kurahi/legacy-mcp/audit.jsonl. The server creates these folders itself (mode 0700) and refuses to start when.kurahior a folder below it is a symbolic link; files are opened without following links. Add.kurahi/to.gitignore. - Audit. One JSON line per call: time, tool, SHA-256 of the arguments (the arguments
themselves are not stored),
ok, result size in bytes, duration, anderror(path-refused,error,overflow) on failure. - HTTP is loopback only (
127.0.0.1), requires a bearer token (KURAHI_LEGACY_MCP_TOKEN, at least 16 characters, or one generated and printed to stderr at start), checksHostandOriginagainst the loopback address (DNS rebinding), acceptsPOSTonly and requests up to 1 MiB byContent-Length. It has no TLS; do not forward the port.
Limits
Section titled “Limits”- Facts, not meaning. The analyser reports structure and exact source text. Business meaning is never inferred; the reader interprets and cites.
- Analyser coverage. Dialect support, the 5,000-file and 4 MiB-per-file limits and the parsing diagnostics are those of the legacy analyser; a partial index says so in its diagnostics.
- Freshness is conservative. Each call walks the scope and compares size and modification time
of every file (not only sources); any change rebuilds the index. On very large trees, scope
calls with
path. Indexing is synchronous: other calls wait while it runs. - The audit log is append-only by the server, not tamper-evident. Anyone who can write the project folder can edit it. It is not the gateway’s hash-chained audit log, and it is not rotated.
- The cache is trusted when its fingerprint matches the tree. Someone with write access to the
project could plant a forged cache file;
legacy_index_buildrebuilds from the sources, and deleting.kurahi/legacy-mcp/cache/is always safe. - Pagination is one level deep. It windows the top-level lists of a result; nested lists come whole and fall under the size cap.
- HTTP is stateless. No server-initiated messages, no sessions; each request is independent.
- Client compatibility is checked with the protocol’s reference client (stdio, in-memory and HTTP).