mcp-for-i 0.1.13 → 0.2.0
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.
- package/README.md +17 -0
- package/dist/config/store.js +229 -109
- package/dist/controlplane/auth.js +128 -0
- package/dist/controlplane/clientIntegrationService.js +83 -4
- package/dist/controlplane/commands.js +14 -9
- package/dist/controlplane/connectionService.js +110 -5
- package/dist/controlplane/connectionTest.js +329 -0
- package/dist/controlplane/errors.js +12 -0
- package/dist/controlplane/runtimeService.js +98 -26
- package/dist/controlplane/server.js +122 -11
- package/dist/controlplane/serverShared.js +25 -6
- package/dist/controlplane/serviceManager.js +113 -100
- package/dist/controlplane/ui.js +1742 -920
- package/dist/ibmi/CompileTools.js +29 -1
- package/dist/ibmi/IBMiContent.js +435 -63
- package/dist/ibmi/IbmDocs.js +685 -0
- package/dist/ibmi/LocalLanguageActions.js +129 -3
- package/dist/ibmi/Search.js +158 -52
- package/dist/ibmi/Tools.js +7 -10
- package/dist/ibmi/client.js +220 -31
- package/dist/ibmi/evfevent.js +256 -0
- package/dist/ibmi/knownHosts.js +190 -0
- package/dist/ibmi/libraryList.js +93 -0
- package/dist/ibmi/sourceInspect.js +815 -0
- package/dist/ibmi/sqlJob.js +888 -0
- package/dist/ibmi/sqlParse.js +317 -0
- package/dist/ibmi/tn5250/certTrust.js +59 -0
- package/dist/ibmi/tn5250/client.js +310 -0
- package/dist/ibmi/tn5250/datastream.js +109 -0
- package/dist/ibmi/tn5250/ebcdic.js +74 -0
- package/dist/ibmi/tn5250/index.js +6 -0
- package/dist/ibmi/tn5250/screen.js +827 -0
- package/dist/ibmi/tn5250/telnet.js +186 -0
- package/dist/ibmi/variables.js +18 -7
- package/dist/index.js +43 -22
- package/dist/mcp/annotations.js +155 -0
- package/dist/mcp/audit.js +490 -133
- package/dist/mcp/confirm.js +48 -0
- package/dist/mcp/context.js +43 -5
- package/dist/mcp/deployMethods.js +192 -0
- package/dist/mcp/logger.js +5 -10
- package/dist/mcp/modules/bulkMembers.js +476 -0
- package/dist/mcp/modules/changedLines.js +189 -0
- package/dist/mcp/modules/compare.js +198 -0
- package/dist/mcp/modules/compile.js +515 -0
- package/dist/mcp/modules/ifsOps.js +123 -0
- package/dist/mcp/modules/index.js +38 -0
- package/dist/mcp/modules/inspect.js +811 -0
- package/dist/mcp/modules/libl.js +246 -0
- package/dist/mcp/modules/members.js +171 -0
- package/dist/mcp/modules/objects.js +339 -0
- package/dist/mcp/modules/system.js +266 -0
- package/dist/mcp/modules/tn5250.js +515 -0
- package/dist/mcp/policy.js +412 -0
- package/dist/mcp/tools.js +1700 -698
- package/dist/security/credentialStore.js +62 -13
- package/dist/security/localPaths.js +138 -0
- package/dist/security/redact.js +79 -0
- package/dist/util/atomicWrite.js +101 -0
- package/dist/util/fileLock.js +206 -0
- package/docs/capabilities.md +50 -7
- package/docs/configuration.md +189 -60
- package/docs/examples.md +109 -73
- package/docs/overview.md +15 -15
- package/docs/security.md +101 -16
- package/docs/tools.md +363 -188
- package/package.json +56 -53
package/docs/capabilities.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This document summarizes what `mcp-for-i` can do today across the MCP server and local control-plane workflow.
|
|
4
4
|
|
|
5
|
-
Version context: `0.
|
|
5
|
+
Version context: `0.2.0`.
|
|
6
6
|
|
|
7
7
|
## 1) Platform Capabilities
|
|
8
8
|
|
|
@@ -14,20 +14,22 @@ Version context: `0.1.8` codebase.
|
|
|
14
14
|
|
|
15
15
|
### 1.2 Runtime Safety and Policy Guardrails
|
|
16
16
|
- Strict tool input schemas (`additionalProperties: false`) with runtime validation.
|
|
17
|
-
- Guarded approval model
|
|
17
|
+
- Guarded approval model: the user confirms sensitive operations in the MCP client.
|
|
18
18
|
- Read-only mode enforcement.
|
|
19
19
|
- Validation for critical identifiers (QSYS names, journaling object names, etc.).
|
|
20
20
|
|
|
21
21
|
### 1.3 Session Lifecycle
|
|
22
22
|
- Multi-session tracking.
|
|
23
23
|
- Session status/list/keepalive/terminate operations.
|
|
24
|
+
- One-call session bootstrap with release, library-list, policy, transports, and supported fast-path capabilities.
|
|
24
25
|
- Sliding inactivity timeout.
|
|
25
26
|
- Heartbeat and reconnect behavior.
|
|
27
|
+
- Persistent SQL job per connection (Mapepire, when installed on the IBM i): SQL, SQL-run CL, library list changes and the job log share one job across calls; falls back to a new QZDFMDB2 job per call when Mapepire is not available. Timed-out statements are cancelled on the IBM i. See [configuration](configuration.md#persistent-sql-job-mapepire) for `sqlTransport` and how to install Mapepire.
|
|
26
28
|
|
|
27
29
|
### 1.4 Agent-Safe Structured Results
|
|
28
30
|
- Tool responses expose structured payloads for automation.
|
|
29
31
|
- SQL/CL/diagnostic outputs normalized where applicable.
|
|
30
|
-
- TN5250
|
|
32
|
+
- TN5250 screens are returned as text rows plus machine-readable fields (position, label, protected/hidden flags); hidden field contents are never returned.
|
|
31
33
|
|
|
32
34
|
### 1.5 Auditing and Compliance Foundations
|
|
33
35
|
- Tamper-evident hash-chain audit record for tool calls.
|
|
@@ -51,6 +53,7 @@ Version context: `0.1.8` codebase.
|
|
|
51
53
|
- `ibmi.session.status`
|
|
52
54
|
- `ibmi.session.keepalive`
|
|
53
55
|
- `ibmi.session.terminate`
|
|
56
|
+
- `ibmi.session.bootstrap`
|
|
54
57
|
- `ibmi.connections.list`
|
|
55
58
|
- `ibmi.connections.add`
|
|
56
59
|
- `ibmi.connections.update`
|
|
@@ -66,8 +69,14 @@ Version context: `0.1.8` codebase.
|
|
|
66
69
|
- `ibmi.qsys.members.create`
|
|
67
70
|
- `ibmi.qsys.members.rename`
|
|
68
71
|
- `ibmi.qsys.members.delete`
|
|
72
|
+
- `ibmi.qsys.members.copy`
|
|
73
|
+
- `ibmi.qsys.members.changeText`
|
|
74
|
+
- `ibmi.qsys.members.changeType`
|
|
69
75
|
- `ibmi.qsys.sourcefiles.create`
|
|
70
76
|
- `ibmi.qsys.libraries.create`
|
|
77
|
+
- `ibmi.objects.copy`, `ibmi.objects.move`, `ibmi.objects.rename`, `ibmi.objects.delete`, `ibmi.objects.changeDescription`
|
|
78
|
+
- `ibmi.libraries.copy`
|
|
79
|
+
- Legacy-compatible member list/read responses plus opt-in filtered paging, ranged reads, metadata, version/hash checks, caching, and complete fallback reads.
|
|
71
80
|
|
|
72
81
|
### IFS Operations
|
|
73
82
|
- `ibmi.ifs.list`
|
|
@@ -75,18 +84,31 @@ Version context: `0.1.8` codebase.
|
|
|
75
84
|
- `ibmi.ifs.write`
|
|
76
85
|
- `ibmi.ifs.mkdir`
|
|
77
86
|
- `ibmi.ifs.delete`
|
|
87
|
+
- `ibmi.ifs.copy`
|
|
88
|
+
- `ibmi.ifs.move`
|
|
78
89
|
- `ibmi.ifs.upload`
|
|
79
90
|
- `ibmi.ifs.download`
|
|
80
91
|
|
|
81
92
|
### Search and Resolution
|
|
82
93
|
- `ibmi.search.members`
|
|
94
|
+
- `ibmi.source.resolve`
|
|
95
|
+
- `ibmi.source.inspect`
|
|
83
96
|
- `ibmi.search.ifs`
|
|
84
97
|
- `ibmi.find.ifs`
|
|
98
|
+
- `ibmi.search.changedLines`
|
|
85
99
|
- `ibmi.resolve.path`
|
|
86
100
|
|
|
101
|
+
### System Information
|
|
102
|
+
- `ibmi.system.info`
|
|
103
|
+
|
|
104
|
+
### Official IBM i Documentation
|
|
105
|
+
- `ibmi.docs.search`
|
|
106
|
+
- `ibmi.docs.open` (any `https://www.ibm.com/docs/` page)
|
|
107
|
+
- MCP resources at `ibmi-docs://catalog` and `ibmi-docs://topic/{ref}`
|
|
108
|
+
|
|
87
109
|
### Actions, Filters, Profiles, Library List
|
|
88
110
|
- `ibmi.actions.list`
|
|
89
|
-
- `ibmi.actions.run`
|
|
111
|
+
- `ibmi.actions.run` (compiles members or streamfiles and returns EVFEVENT errors by file; see docs/tools.md "Compile and errors")
|
|
90
112
|
- `ibmi.actions.save`
|
|
91
113
|
- `ibmi.actions.delete`
|
|
92
114
|
- `ibmi.filters.list`
|
|
@@ -102,22 +124,41 @@ Version context: `0.1.8` codebase.
|
|
|
102
124
|
- `ibmi.libl.remove`
|
|
103
125
|
- `ibmi.libl.setCurrent`
|
|
104
126
|
- `ibmi.libl.validate`
|
|
127
|
+
- `ibmi.libl.move`
|
|
128
|
+
- `ibmi.libl.prune`
|
|
129
|
+
- `ibmi.libl.runProfileCommand`
|
|
105
130
|
- `ibmi.ifs.shortcuts.list`
|
|
106
131
|
- `ibmi.ifs.shortcuts.add`
|
|
107
132
|
- `ibmi.ifs.shortcuts.delete`
|
|
108
133
|
|
|
134
|
+
### Compare and Inspection
|
|
135
|
+
- `ibmi.compare.text`
|
|
136
|
+
- `ibmi.objects.describe`
|
|
137
|
+
- `ibmi.members.describe`
|
|
138
|
+
- `ibmi.ifs.stat`
|
|
139
|
+
- `ibmi.programs.info`
|
|
140
|
+
- `ibmi.objects.whereUsed`
|
|
141
|
+
- `ibmi.tables.describe`
|
|
142
|
+
- `ibmi.routines.describe`
|
|
143
|
+
|
|
109
144
|
### Deploy and File Sync
|
|
110
145
|
- `ibmi.deploy.compare`
|
|
111
146
|
- `ibmi.deploy.sync`
|
|
112
147
|
- `ibmi.deploy.uploadDirectory`
|
|
113
148
|
- `ibmi.deploy.uploadFiles`
|
|
114
149
|
- `ibmi.deploy.setCcsid`
|
|
150
|
+
- `ibmi.deploy.sync` methods: `all`, `changed` (SHA-256), `gitChanged`, `selection`
|
|
151
|
+
|
|
152
|
+
### Bulk Source Members
|
|
153
|
+
- `ibmi.members.downloadAll`
|
|
154
|
+
- `ibmi.members.uploadChanged`
|
|
115
155
|
|
|
116
156
|
### SQL, CL, Diagnostics, Spool, Debug
|
|
117
157
|
- `ibmi.sql.query`
|
|
118
158
|
- `ibmi.sql.execute`
|
|
119
159
|
- `ibmi.cl.run`
|
|
120
160
|
- `ibmi.diagnostics.parseEvfevent`
|
|
161
|
+
- `ibmi.compile.listing`
|
|
121
162
|
- `ibmi.joblog.get`
|
|
122
163
|
- `ibmi.spool.list`
|
|
123
164
|
- `ibmi.spool.read`
|
|
@@ -166,7 +207,9 @@ Version context: `0.1.8` codebase.
|
|
|
166
207
|
- `ibmi.journal.endIfs`
|
|
167
208
|
- `ibmi.journal.receivers.retention`
|
|
168
209
|
|
|
169
|
-
### TN5250
|
|
210
|
+
### TN5250 (5250 green-screen sessions)
|
|
211
|
+
A real TN5250 client: connects to the saved connection's host on port 23 (or 992 with TLS), reads the actual screen and fields, fills fields and presses keys (Enter, F1-F24, PageUp/PageDown, Clear, Help, Attn, SysReq). Optional sign-on uses the stored credentials. AID keys go through the write gate: read-only connections cannot press them, and text on a `===>` command line is checked against the command policy. See [tools](tools.md#tn5250-notes) for details and limits.
|
|
212
|
+
|
|
170
213
|
- `ibmi.tn5250.connect`
|
|
171
214
|
- `ibmi.tn5250.readScreen`
|
|
172
215
|
- `ibmi.tn5250.setField`
|
|
@@ -178,8 +221,8 @@ Version context: `0.1.8` codebase.
|
|
|
178
221
|
## 3) High-Value Behaviors Users Often Miss
|
|
179
222
|
|
|
180
223
|
### 3.1 Guarded Approvals
|
|
181
|
-
-
|
|
182
|
-
-
|
|
224
|
+
- In guarded policy, risky operations wait for the user to confirm them in the MCP client; the agent cannot approve them itself.
|
|
225
|
+
- With `approvalMode: "agent"` (for clients without prompts), `approve=true` from the agent is accepted instead.
|
|
183
226
|
|
|
184
227
|
### 3.2 Audit Data Lifecycle
|
|
185
228
|
- Verify chain integrity with `ibmi.audit.verify`.
|
package/docs/configuration.md
CHANGED
|
@@ -1,60 +1,189 @@
|
|
|
1
|
-
# Configuration
|
|
2
|
-
|
|
3
|
-
Config file is stored under the user config directory:
|
|
4
|
-
- Windows: `%APPDATA%\mcp-for-i\config.json`
|
|
5
|
-
- macOS: `~/Library/Application Support/mcp-for-i/config.json`
|
|
6
|
-
- Linux: `${XDG_CONFIG_HOME:-~/.config}/mcp-for-i/config.json`
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- `
|
|
11
|
-
- `
|
|
12
|
-
- `
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
18
|
-
- `
|
|
19
|
-
- `
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- `
|
|
28
|
-
- `
|
|
29
|
-
- `
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Config file is stored under the user config directory:
|
|
4
|
+
- Windows: `%APPDATA%\mcp-for-i\config.json`
|
|
5
|
+
- macOS: `~/Library/Application Support/mcp-for-i/config.json`
|
|
6
|
+
- Linux: `${XDG_CONFIG_HOME:-~/.config}/mcp-for-i/config.json`
|
|
7
|
+
|
|
8
|
+
### How the config file is written
|
|
9
|
+
- Defaults are created only when `config.json` does not exist (an empty file counts as missing).
|
|
10
|
+
- If the file exists but cannot be parsed, it is never overwritten. A copy is saved next to it as `config.json.corrupt-<timestamp>` and every config operation fails with an error naming the file, until the file is repaired or removed.
|
|
11
|
+
- Writes are atomic: the new content goes to a temporary file in the same folder, is flushed to disk, and is renamed over `config.json`. On Windows the rename is retried when antivirus or the search indexer briefly locks the file; there is no non-atomic fallback.
|
|
12
|
+
- Every change (connections, settings, actions, profiles) re-reads the file and writes it back while holding `config.json.lock`, so the MCP server, the control plane and the CLI can update the config at the same time without losing each other's changes. A lock left behind by a crashed process is taken over after 30 seconds, or immediately if its process no longer exists.
|
|
13
|
+
|
|
14
|
+
## Settings
|
|
15
|
+
Default settings (editable in the config file):
|
|
16
|
+
- `readOnlyMode`: boolean. When true, every tool that changes the system is refused, including `ibmi.sql.execute`, `ibmi.cl.run` and every AID key sent by `ibmi.tn5250.sendKeys`.
|
|
17
|
+
- `tempLibrary`: string
|
|
18
|
+
- `tempDir`: string
|
|
19
|
+
- `autoClearTempData`: boolean
|
|
20
|
+
- `sourceFileCCSID`: string (default `*FILE`)
|
|
21
|
+
- `enableSourceDates`: boolean (Phase 2+)
|
|
22
|
+
- `sourceReadMaxBytes`: number (default `2000000`): largest member, in UTF-8 bytes after trimming trailing blanks, that a full `members.read` returns. Larger members fail with `SOURCE_TOO_LARGE` and the agent is told to read line ranges or search instead. `0` disables the byte cap.
|
|
23
|
+
- `sourceReadMaxLines`: number (default `50000`): the same cap in lines. Checked against the catalog row count before any content is downloaded. `0` disables the line cap.
|
|
24
|
+
- `homeDirectory`: string
|
|
25
|
+
- `libraryList`: string[]
|
|
26
|
+
- `currentLibrary`: string
|
|
27
|
+
- `customVariables`: list of `{ name, value }`
|
|
28
|
+
- `sqlTransport`: `auto` (default), `mapepire` or `qzdfmdb2`. How SQL and SQL-run CL are executed; see "Persistent SQL job (Mapepire)" below.
|
|
29
|
+
- `mapepireMode`: `auto` (default), `daemon` or `ssh`.
|
|
30
|
+
- `mapepirePort`: number (default `8076`), the Mapepire server port for `daemon` mode.
|
|
31
|
+
- `mapepireServerPath`: path of `mapepire-server.jar` on the IBM i for `ssh` mode (default: `/QOpenSys/pkgs/lib/mapepire/mapepire-server.jar`, then `/opt/mapepire/lib/mapepire/mapepire-server.jar`).
|
|
32
|
+
- `mapepireJavaPath`: Java for `ssh` mode (default: the newest of jdk21, jdk17, jdk11, jdk80 under `/QOpenSys/QIBM/ProdData/JavaVM`).
|
|
33
|
+
- `allowedLocalRoots`: string[] (global settings only; see "Local file access" below)
|
|
34
|
+
- `tn5250Port`: number. TN5250 telnet port (default 23, or 992 when `tn5250Tls` is true).
|
|
35
|
+
- `tn5250Tls`: boolean. Use TLS for TN5250 (default true when the port is 992).
|
|
36
|
+
- `tn5250DeviceName`: string. Virtual device name requested for TN5250 sessions (1-10 characters).
|
|
37
|
+
|
|
38
|
+
`tempLibrary` remains accepted for configuration compatibility. Source member reads and source-date writes now use job-local `QTEMP` objects and do not require a persistent `ILEDITOR` library.
|
|
39
|
+
|
|
40
|
+
## Persistent SQL job (Mapepire)
|
|
41
|
+
|
|
42
|
+
By default every SQL statement (and every CL command run through SQL) starts a new QZDFMDB2 job over SSH, so a library list change, the current library, QTEMP objects and the job log are gone by the next call. When [Mapepire](https://mapepire-ibmi.github.io/) is installed on the IBM i, mcp-for-i keeps one database job per connection instead:
|
|
43
|
+
|
|
44
|
+
- The job is opened on the first SQL call of a session (not at connect time) and reused by `ibmi.sql.query`, `ibmi.sql.execute`, `ibmi.cl.run` (environment `ile`), `ibmi.joblog.get` and every other tool that runs SQL. Statements run one at a time in it.
|
|
45
|
+
- Before the first statement, the connection's `libraryList` and `currentLibrary` (from the active profile or settings) are applied with one `CHGLIBL LIBL(...) CURLIB(...)` (`CHGCURLIB` when the list is empty). It is applied again only when that setting changes, so a library list change made with `ibmi.cl.run` stays in effect until then.
|
|
46
|
+
- If a library in the setting does not exist (`CHGLIBL` then fails as a whole), the list is applied without it and `ibmi.session.status` shows `sqlJob.libraryListWarning` naming the missing libraries. SQL keeps working.
|
|
47
|
+
- Every CL command (`ibmi.cl.run`, `@` lines in SQL, a literal `CALL QSYS2.QCMDEXC('...')` statement, `ibmi.libl.*`) runs in this job, so its library list changes apply to later SQL and CL. Unqualified names resolve through the library list (system naming).
|
|
48
|
+
- `ibmi.libl.set`, `ibmi.libl.add`, `ibmi.libl.remove`, `ibmi.libl.setCurrent`, `ibmi.libl.move`, `ibmi.libl.prune`, `ibmi.libl.runProfileCommand` and `ibmi.profiles.activate` update the setting, so the next SQL or CL call uses the new list either way; `applyToJob: true` applies it immediately and returns any missing-library warning.
|
|
49
|
+
- `ibmi.joblog.get` reads this job's log (`QSYS2.JOBLOG_INFO('*')`), so it shows the messages of earlier calls. It leaves out `MCH3401 Cannot resolve to object PPTT`, which the database logs on every statement on some systems.
|
|
50
|
+
- Commitment control is off (`transaction isolation: none`), as with QZDFMDB2.
|
|
51
|
+
- When a `timeoutMs` is reached, the statement is cancelled on the IBM i with `QSYS2.CANCEL_SQL` (run from a separate QZDFMDB2 job). If it is still running 5 seconds later, the job is ended and a new one is opened on the next call (QTEMP and ad-hoc job changes are lost; the configured library list is applied again).
|
|
52
|
+
- If the job ends (network drop, server restart), the next call opens a new one. A read-only statement that was interrupted this way is retried once; a write is not retried.
|
|
53
|
+
- `ibmi.disconnect` and `ibmi.session.terminate` end the job. `ibmi.session.status` (field `sqlJob`) and `ibmi.session.bootstrap` (`transports.sqlJob`) show which transport is in use, the job name and the last error.
|
|
54
|
+
- Tools that run CL through a qsh `system` command (for example some source and object helpers) still run in their own job.
|
|
55
|
+
|
|
56
|
+
In `ssh` mode Mapepire first connects with its in-process CLI connection, which ignores the JDBC properties (so SQL naming) and runs each SQL request on its own thread; on IBM i the library list belongs to the thread, so a `CHGLIBL` run that way is lost when the request ends. mcp-for-i therefore switches the job to Mapepire's TCP technique right after it starts: a database host server job (`QZDASOINIT`, as in `daemon` mode) on the same system, signed on as the same user, where system naming applies and the library list persists. `sqlJob.technique` in `ibmi.session.status` shows `tcp`. This needs the database host server (`*DATABASE`, `STRHOSTSVR`) to be running. If the switch fails the CLI connection is kept (`technique: cli`): CL still keeps its library list changes because it is sent as a Mapepire CL request, which runs on the thread later SQL requests inherit from, but SQL naming applies, so unqualified table names resolve to the current schema instead of the library list.
|
|
57
|
+
|
|
58
|
+
Without the persistent job (QZDFMDB2, every call a new job) the configured library list is still applied: each SQL batch starts with `@CHGLIBL LIBL(...) CURLIB(...)` in the same QZDFMDB2 job, and CL that falls back to a qsh `system` command gets it through the qsh `liblist` builtin first. The list is checked once per setting value (one extra call); libraries that do not exist are left out and reported in `sqlJob.libraryListWarning`. QZDFMDB2 uses SQL naming, so there unqualified table names resolve to the current schema (normally the user profile name), not the library list; qualify them or use the Mapepire job.
|
|
59
|
+
|
|
60
|
+
`sqlTransport`:
|
|
61
|
+
- `auto` (default): use Mapepire when it can be reached, otherwise QZDFMDB2. The first failure is remembered for the session, so later calls go straight to QZDFMDB2 without waiting; reconnect to try again.
|
|
62
|
+
- `mapepire`: always use Mapepire; SQL fails with the reason when it cannot be opened.
|
|
63
|
+
- `qzdfmdb2`: never use Mapepire (the previous behaviour).
|
|
64
|
+
|
|
65
|
+
`mapepireMode`:
|
|
66
|
+
- `daemon`: connects to the Mapepire server (`mapepirePort`, default 8076) over TLS with the connection's user and password. Needs a password; key-only connections cannot use it.
|
|
67
|
+
- `ssh`: starts `mapepire-server.jar` in single-user mode over the connection's existing SSH session (`java -jar ... --single`). Works with key-based logins and needs no open port or running service, only the JAR and Java on the IBM i. Startup takes a few seconds (one JVM per session). Nothing is uploaded to the IBM i.
|
|
68
|
+
- `auto` (default): `daemon` when the connection has a password, falling back to `ssh` if the server is not reachable; `ssh` for key-only connections.
|
|
69
|
+
|
|
70
|
+
The daemon's server certificate is trusted on first use: Mapepire generates a self-signed certificate, so its fingerprint is stored in `known_hosts.json` (under `certificates`) the first time and must match afterwards (see [security](security.md)). Certificates from a public CA are checked the normal way. Certificate errors are never ignored.
|
|
71
|
+
|
|
72
|
+
### Installing Mapepire on the IBM i
|
|
73
|
+
|
|
74
|
+
Mapepire is an open-source database server for IBM i. In short, from an SSH session with the IBM i open-source package manager (yum) installed, as a user allowed to install packages:
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
yum install mapepire-server # installs /QOpenSys/pkgs/lib/mapepire/mapepire-server.jar
|
|
78
|
+
# daemon mode only: run it as a service with Service Commander
|
|
79
|
+
/QOpenSys/pkgs/bin/sc start mapepire
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The daemon listens on port 8076 and needs Java 11 or later. For `ssh` mode the package install is enough; no service has to run. See the Mapepire documentation for running it at IPL, certificates and any port or exit-point rules at your site.
|
|
83
|
+
|
|
84
|
+
## Local file access
|
|
85
|
+
|
|
86
|
+
Tools that read or write files on your PC (`ibmi.ifs.upload`, `ibmi.ifs.download`, `ibmi.deploy.*`, `ibmi.audit.export` and `ibmi.compliance.report.generate`) only accept local paths inside the allowed local roots. Paths are resolved first: `..` and `~` are expanded and symlinks are followed, so a link that points outside a root is refused.
|
|
87
|
+
|
|
88
|
+
Allowed roots, first match wins:
|
|
89
|
+
1. `MCP_FOR_I_ALLOWED_LOCAL_ROOTS`: a list of directories separated by the OS path delimiter (`;` on Windows, `:` elsewhere).
|
|
90
|
+
2. `allowedLocalRoots` in the global `settings` of `config.json`.
|
|
91
|
+
3. Default: the server's working directory and your home directory. A working directory that is a drive or filesystem root is ignored.
|
|
92
|
+
|
|
93
|
+
These locations are always refused, even inside an allowed root: `~/.ssh`, `~/.aws`, `~/.gnupg`, `~/.azure`, `~/.kube`, `~/.docker`, `~/.config/gcloud`, `~/.config/gh`, any `credentials` file under `~/.config`, `~/.netrc`, `~/.git-credentials`, `~/.pgpass`, `~/.npmrc`, `~/.pypirc`, the mcp-for-i config directory, and on Windows `%APPDATA%` plus everything in `%LOCALAPPDATA%` except its `Temp` folder (macOS: `~/Library/Keychains`).
|
|
94
|
+
|
|
95
|
+
Example:
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"settings": {
|
|
99
|
+
"allowedLocalRoots": ["C:/work/ibmi-projects", "D:/exports"]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## IBM Documentation
|
|
105
|
+
|
|
106
|
+
Official documentation needs no credentials. The built-in catalog covers IBM i 7.4, 7.5, and 7.6 roots for the site map, manuals, RPG, CL, APIs, IBM i SQL services, security, database performance, and IFS commands. Optional environment settings:
|
|
107
|
+
|
|
108
|
+
- `MCP_FOR_I_IBM_DOCS_SEEDS`: JSON array of additional `{ title, url, release, categories, keywords }` entries. Every URL is still restricted to `https://www.ibm.com/docs/`.
|
|
109
|
+
- `MCP_FOR_I_IBM_DOCS_CACHE_DIR`: override the local documentation cache directory.
|
|
110
|
+
- `MCP_FOR_I_IBM_DOCS_CACHE_TTL_DAYS`: days before a cached documentation page is fetched again (default 7). An expired copy is still served, with a warning, when the refresh fails.
|
|
111
|
+
|
|
112
|
+
`ibmi.docs.search` is local/indexed by default. Use `freshness: "prefer-live"` for a bounded refresh of matching catalog entries. `ibmi.docs.open` uses cached content by default; use `freshness: "require-live"` when a live fetch is required.
|
|
113
|
+
|
|
114
|
+
## Connections
|
|
115
|
+
Connections are stored without passwords. Passwords are stored in OS keychain (or in-session fallback). Each connection can include optional `settings` overrides.
|
|
116
|
+
The control plane health response and Overview page report whether password storage is persistent (`keychain`) or process-only (`session`).
|
|
117
|
+
WSL users should note that Linux Secret Service is separate from Windows Credential Manager; if WSL has no working keychain, passwords must be re-entered after the process exits.
|
|
118
|
+
Set `MCP_FOR_I_CREDENTIAL_STORE=session` to force process-only password storage even when a keychain is available.
|
|
119
|
+
Set `MCP_FOR_I_CREDENTIAL_STORE=keychain` to require the OS keychain. In this mode saving or reading a password fails with a clear error when the keychain is unavailable, instead of silently keeping the password in memory where other processes (for example the MCP server) cannot see it. The default mode (`auto`) keeps the in-memory fallback.
|
|
120
|
+
Older config files may contain a plaintext `password` on a connection. It is moved to the keychain when the config is loaded and removed from the file only after the keychain confirms it was stored. Without a persistent keychain the plaintext stays in the file (a warning is printed to stderr) and is moved on a later run once a keychain is available.
|
|
121
|
+
Connections can also define policy, for example:
|
|
122
|
+
- `read-only`
|
|
123
|
+
- `guarded` (default; approvals required for risky operations)
|
|
124
|
+
- `power-user`
|
|
125
|
+
|
|
126
|
+
Policy lists (all optional, matched case-insensitively):
|
|
127
|
+
- `denyCommands` / `allowCommands`: CL command names. A library qualifier is ignored on both sides, so `DLTLIB` also blocks `QSYS/DLTLIB` and `*LIBL/DLTLIB`. A trailing `*` makes a generic entry (`DLT*`). When `allowCommands` is not empty, only listed commands may run, and QSH/PASE commands are refused because they cannot be verified. The lists apply to `ibmi.cl.run`, text on a recognised `===>` command line when `ibmi.tn5250.sendKeys` presses an AID key (other 5250 input cannot be checked; see [security](security.md)), the expanded command of `ibmi.actions.run`, and CL embedded in SQL (lines starting with `@` and `QCMDEXC` calls; a `QCMDEXC` call whose command is not a string literal is refused while a command list is set).
|
|
128
|
+
- `denyLibraries` / `allowLibraries`: library names, with optional trailing `*`. They apply to every tool argument that names a library (`library`, `journalLibrary`, `libraryList`, qualified `LIB/OBJ` values, `/QSYS.LIB/<lib>.LIB/...` paths). With `allowLibraries` set, special values such as `*LIBL` and generic names are refused because they cannot be checked.
|
|
129
|
+
- `denyPaths` / `allowPaths`: absolute IFS paths. An entry covers the path and everything below it; `*` matches within one path segment. With `allowPaths` set, relative paths are refused. Remote symlinks are not resolved.
|
|
130
|
+
- Deny entries always win over allow entries.
|
|
131
|
+
|
|
132
|
+
Approvals under `guarded`:
|
|
133
|
+
- `requireApprovalFor`: operations that ask the user first (default `["sql.write", "cl.run", "deploy.sync", "ifs.delete", "qsys.write"]`).
|
|
134
|
+
- `approvalMode`: `"prompt"` (default) asks the user through the MCP client and ignores the agent's `approve` flag. `"agent"` accepts `approve: true` from the agent instead, for clients that can't show prompts.
|
|
135
|
+
- The policy can only be changed in the web UI or in this file, not by the agent.
|
|
136
|
+
|
|
137
|
+
Example:
|
|
138
|
+
```json
|
|
139
|
+
"policy": {
|
|
140
|
+
"profile": "guarded",
|
|
141
|
+
"denyCommands": ["DLTLIB", "CLRLIB", "PWRDWNSYS"],
|
|
142
|
+
"allowLibraries": ["DEV*", "QGPL", "QTEMP"],
|
|
143
|
+
"allowPaths": ["/home/devuser", "/tmp"]
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Example:
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"connections": [
|
|
151
|
+
{
|
|
152
|
+
"name": "DEV400",
|
|
153
|
+
"host": "dev400.myco.com",
|
|
154
|
+
"port": 22,
|
|
155
|
+
"username": "DEVUSER",
|
|
156
|
+
"privateKeyPath": "C:/keys/id_rsa",
|
|
157
|
+
"settings": {
|
|
158
|
+
"readOnlyMode": false
|
|
159
|
+
},
|
|
160
|
+
"policy": {
|
|
161
|
+
"profile": "guarded",
|
|
162
|
+
"requireApprovalFor": ["sql.write", "cl.run", "deploy.sync"]
|
|
163
|
+
},
|
|
164
|
+
"profiles": [
|
|
165
|
+
{
|
|
166
|
+
"name": "projectA",
|
|
167
|
+
"currentLibrary": "PROJALIB",
|
|
168
|
+
"libraryList": ["QSYS", "QGPL", "PROJALIB"],
|
|
169
|
+
"customVariables": [{ "name": "ENV", "value": "DEV" }]
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
"currentProfile": "projectA"
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Control plane
|
|
179
|
+
|
|
180
|
+
- `MCP_FOR_I_CONTROL_HOST` (default `127.0.0.1`) and `MCP_FOR_I_CONTROL_PORT` (default `3980`) set where the control plane listens. The background-service launchers record the port configured when `mcp-for-i control enable` ran; the Bash launcher also honours `MCP_FOR_I_CONTROL_PORT` at start-up.
|
|
181
|
+
- The API token lives in `controlplane.token` in the same directory as `config.json`. See [security](security.md#control-plane).
|
|
182
|
+
|
|
183
|
+
## Audit log files
|
|
184
|
+
The audit log lives in `<configDir>/audit/` (or next to `MCP_FOR_I_AUDIT_LOG_PATH` when set):
|
|
185
|
+
- `tool-audit.jsonl`: one record per tool call.
|
|
186
|
+
- `tool-audit.key`: per-install secret used to sign records (HMAC-SHA256), created on first use with owner-only permissions. Set `MCP_FOR_I_AUDIT_KEY_PATH` to keep it elsewhere. Losing or replacing it makes existing records unverifiable.
|
|
187
|
+
- `tool-audit.anchor.json`: signed checkpoint with the first record hash, the last sequence number and the last hash, updated on every append and purge.
|
|
188
|
+
- `tool-audit.head`: last record hash (kept for older versions).
|
|
189
|
+
- `tool-audit.lock`: held briefly while appending, purging or verifying, so several MCP processes write one chain.
|
package/docs/examples.md
CHANGED
|
@@ -1,73 +1,109 @@
|
|
|
1
|
-
# Examples
|
|
2
|
-
|
|
3
|
-
## Add connection profile
|
|
4
|
-
```json
|
|
5
|
-
{
|
|
6
|
-
"tool": "ibmi.connections.add",
|
|
7
|
-
"arguments": {
|
|
8
|
-
"name": "DEV400",
|
|
9
|
-
"host": "dev400.myco.com",
|
|
10
|
-
"port": 22,
|
|
11
|
-
"username": "DEVUSER",
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
## Connect by saved name
|
|
20
|
-
```json
|
|
21
|
-
{
|
|
22
|
-
"tool": "ibmi.connect",
|
|
23
|
-
"arguments": { "name": "DEV400" }
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## List libraries
|
|
28
|
-
```json
|
|
29
|
-
{
|
|
30
|
-
"tool": "ibmi.qsys.libraries.list",
|
|
31
|
-
"arguments": { "filter": "*ALL" }
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Read a member
|
|
36
|
-
```json
|
|
37
|
-
{
|
|
38
|
-
"tool": "ibmi.qsys.members.read",
|
|
39
|
-
"arguments": {
|
|
40
|
-
"library": "MYLIB",
|
|
41
|
-
"sourceFile": "QRPGLESRC",
|
|
42
|
-
"member": "MYPGM"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
##
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Add connection profile
|
|
4
|
+
```json
|
|
5
|
+
{
|
|
6
|
+
"tool": "ibmi.connections.add",
|
|
7
|
+
"arguments": {
|
|
8
|
+
"name": "DEV400",
|
|
9
|
+
"host": "dev400.myco.com",
|
|
10
|
+
"port": 22,
|
|
11
|
+
"username": "DEVUSER",
|
|
12
|
+
"policy": { "profile": "guarded" }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Set or update the password through the local control-plane UI so it can be stored in the operating-system credential store; MCP tool arguments do not accept secrets.
|
|
18
|
+
|
|
19
|
+
## Connect by saved name
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"tool": "ibmi.connect",
|
|
23
|
+
"arguments": { "name": "DEV400" }
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## List libraries
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"tool": "ibmi.qsys.libraries.list",
|
|
31
|
+
"arguments": { "filter": "*ALL" }
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Read a member
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"tool": "ibmi.qsys.members.read",
|
|
39
|
+
"arguments": {
|
|
40
|
+
"library": "MYLIB",
|
|
41
|
+
"sourceFile": "QRPGLESRC",
|
|
42
|
+
"member": "MYPGM"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Inspect a member in one versioned operation
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"tool": "ibmi.source.inspect",
|
|
52
|
+
"arguments": {
|
|
53
|
+
"connectionName": "DEV400",
|
|
54
|
+
"library": "MYLIB",
|
|
55
|
+
"member": "MYPGM",
|
|
56
|
+
"candidateSourceFiles": ["QRPGLESRC", "QCLSRC"],
|
|
57
|
+
"operations": [
|
|
58
|
+
{ "operation": "metadata" },
|
|
59
|
+
{ "operation": "outline" },
|
|
60
|
+
{ "operation": "search", "terms": ["PCFCID", "CHAIN"], "before": 2, "after": 3 },
|
|
61
|
+
{ "operation": "read_ranges", "ranges": [{ "start": 120, "end": 180 }] },
|
|
62
|
+
{ "operation": "dependencies" }
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use the returned `version` or `sha256` as `expectedVersion` / `expectedSha256` on a later structured read or member write.
|
|
69
|
+
|
|
70
|
+
## Search official IBM i documentation
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"tool": "ibmi.docs.search",
|
|
75
|
+
"arguments": {
|
|
76
|
+
"query": "QSYS2 SQL services HTTP functions",
|
|
77
|
+
"connectionName": "DEV400",
|
|
78
|
+
"limit": 5
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Run an action
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"tool": "ibmi.actions.run",
|
|
87
|
+
"arguments": {
|
|
88
|
+
"actionName": "Create RPGLE Program",
|
|
89
|
+
"targetType": "member",
|
|
90
|
+
"targetPath": "MYLIB/QRPGLESRC/MYPGM",
|
|
91
|
+
"library": "MYLIB",
|
|
92
|
+
"sourceFile": "QRPGLESRC",
|
|
93
|
+
"member": "MYPGM",
|
|
94
|
+
"extension": "RPGLE"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Activate a profile
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"tool": "ibmi.profiles.activate",
|
|
103
|
+
"arguments": {
|
|
104
|
+
"connectionName": "DEV400",
|
|
105
|
+
"name": "projectA",
|
|
106
|
+
"applyToJob": true
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
package/docs/overview.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# MCP-for-i Overview
|
|
2
|
-
|
|
3
|
-
MCP-for-i is a local MCP server and control plane that exposes IBM i operations as MCP tools for agent-driven workflows (Codex CLI/Desktop and other MCP clients).
|
|
4
|
-
|
|
5
|
-
Current platform scope includes:
|
|
6
|
-
- Secure onboarding and connection lifecycle management.
|
|
7
|
-
- Guarded policy and approval-gated operations.
|
|
8
|
-
- Session lifecycle controls with keepalive/reconnect behavior.
|
|
9
|
-
- QSYS, IFS, search, deploy, SQL/CL, diagnostics, and TN5250
|
|
10
|
-
- Audit-chain integrity features plus journaling and compliance-report tooling.
|
|
11
|
-
- IBM i operations-control tooling for spool/job/subsystem/message-queue lifecycles, lock/authority visibility, and data queue/data area operations.
|
|
12
|
-
|
|
13
|
-
For the complete up-to-date feature inventory, see:
|
|
14
|
-
- `docs/capabilities.md`
|
|
15
|
-
- `docs/tools.md`
|
|
1
|
+
# MCP-for-i Overview
|
|
2
|
+
|
|
3
|
+
MCP-for-i is a local MCP server and control plane that exposes IBM i operations as MCP tools for agent-driven workflows (Codex CLI/Desktop and other MCP clients).
|
|
4
|
+
|
|
5
|
+
Current platform scope includes:
|
|
6
|
+
- Secure onboarding and connection lifecycle management.
|
|
7
|
+
- Guarded policy and approval-gated operations.
|
|
8
|
+
- Session lifecycle controls with keepalive/reconnect behavior.
|
|
9
|
+
- QSYS, IFS, search, deploy, SQL/CL, diagnostics, and TN5250 (5250 green-screen) sessions.
|
|
10
|
+
- Audit-chain integrity features plus journaling and compliance-report tooling.
|
|
11
|
+
- IBM i operations-control tooling for spool/job/subsystem/message-queue lifecycles, lock/authority visibility, and data queue/data area operations.
|
|
12
|
+
|
|
13
|
+
For the complete up-to-date feature inventory, see:
|
|
14
|
+
- `docs/capabilities.md`
|
|
15
|
+
- `docs/tools.md`
|